You can translate the question and the replies:

Logging Architecture Question: how can I setup logging such that all my query history from all my denodo servers are stored in a relational database?

I'm managing 20 denodo servers and I setup logging such that all my queries are stored in a daily log (I added a DailyRollingFileAppender the log4j.xml). I then wrote a virtual database to read the local log files (utilizing the Log Custom Wrapper from Denodo Connect) and turn the query history into a nice view (but just for the local logs). I then wrote another virtual database to call the first virtual database via denodo-restfulws web service to pull all the log information into a single view... I use this second virtual database to call ALL the other denodo servers (all 20 of them) to retrieve logs from all the servers. I then exposed my single view (the one that gets all the logs) to my users so they can see the query history across all the denodo servers (we have denodo clusters and users don't know which servers their queries run on, the only know the environment). This setup has proven to be somewhat awkward...although it works, we are converting log files to virtual tables and sending data all over the place and it runs kind of slow. I know that Denodo Monitor can store the query history in a database and I started looking into this as a solution... but it seems that I can't have ONE denodo monitor that monitors all twenty servers, and instead I'd have to have 20 denodo monitors (probably one on each server). Furthermore, the jdbcagent config in Denodo monitor doesn't have a setting to include the server name in the INSERT statement... thus it seems I'd have to hard code the server name in the denodo monitor config (since I do not want ONE table per Denodo server... I'd want to store all the queries in one table). Hard-coding the server name is okay... but I'd rather not do that since I've been using the same configuration on all my servers and I copy config files between servers as part of deployments... having to manage a hard coded server name in the denodo monitor config adds an extra thing that we have to remember to watch out for. =-=-=-= Thus my question: architecturally, what is a good way to be able to: 1) store a query history of all the denodo queries for every server I'm managing (20 servers) 2) make sure the query history for each server is 'tagged' with the server where the query ran 3) make this information easily accessible so people can query the query history So far the only thing I've come up with is my current solution OR 20 denodo monitors and hard-coding the server name. Thanks~! UPDATE: Another solution is have log4j insert into a database... I could use a JDBCAppender and then write my own PatternLayout class that includes a hostname variable. Or I could write another process that runs every night that inserts all the rows from the log file into a relational database... Nothing is sticking out as a great solution right now, though...
user
12-12-2014 16:09:51 -0500
code

6 Answers

Hi, First of all a comment on your current solution. In the second database, we think the performance will be better if you import the views coming from the different servers using JDBC data sources instead of the restful web service. With this change the process should be faster. Regarding the use of the Denodo Monitor. It is possible to enable the vdpqueries log for any number of servers using one single Denodo Monitor. To do that you just have to specify the monitors using the following property: monitors.remote=vdp,vdp1,vdp2,vdp3,... and then replicate all the properties that start with the "vdp." prefix using the prefix that you specified in the "monitors.report" in the property name. For instance: vdp1.monitors=vdpqueries vdp2.monitors=vdpqueries ... vdp1.jmx.host=ipaddress1 vdp2.jmx.host=ipaddress2 This said, you are right about assuming that the server name is not available in the context and you would need to hard code the server name, so this solution is still not valid for you. We see 2 alternative solutions to the one that you already have implemented: 1) - Using the logger for VDP on each server you can define a JDBC appender as you planned to do with the Denodo Monitor but individual for each server so you can specify a different server name for each one. - In this case you avoid having to run so many Denodo Monitors as the VDP logger will always be configured and working along with the VDP server. - This the more direct/simple approach, the only drawback is that the log4j will be slightly different for each server to include the host name. Do you also copy the log4j.xml file from one server to another when deploying to different servers? 2) - Using the databases that you already have in place to access the log file of each server you can create one Scheduler job for each database with a JDBC exporter configured. These JDBC exporters can populate the same database table periodically refreshing the data and using the previous execution data as a reference to start the new process. - With this solution as part of the queries for each job you can include a new field with the server name.
Denodo Team
15-12-2014 11:14:09 -0500
code
Hello, Thank you for your ideas. I've done some reading up on log4j and settings and I have a question: Can I specify a custom layout in the Denodo Monitor ConfigurationParameters.properties? That properties file looks a LOT like a log4j.properties file. I ask because I found out how to write a custom layout and I can now log the hostname from within the $DENODO_HOME/conf/vdp/log4j.xml settings. Since I have my custom PatternLayout, I was hoping to use that same layout in the Denodo Monitor (since that is based on log4j, and my custom layout extends org.apache.log4j.PattenLayout). If you could let me know about custom layouts in Denodo Monitor, that'd be great. So, with my custom layout and the log4j.xml file, I can push that single file to ALL my servers and the hostname gets properly logged. I can now use the JDBC Appender or use a batch/scheduler job to read the existing log files and insert them into a database. HOWEVER, I'm trying to keep this simple ;-) Both of those options feel too complicated right now (and the JDBC Appender has to be done carefully so performance doesn't suffer) So, in an effort to keep things simple and not jeopardize Denodo performance...I'm thinking about just using Denodo Monitor...I already have Denodo Monitor running on all my servers... and I can use Denodo Monitor to insert to a database (and it is my understanding that Denodo monitor is separate from Denodo)...I'd only need to update one line in each Denodo Monitor configuration file by adding "myhostname" as one of the columns in the insert statement: vdpqueries.jdbcagent.insertStatement=INSERT INTO request_notification values(%X{Id}, myhostname, %X{Database}, %X{UserName}, %X{NotificationType}, %X{SessionId}, to_timestamp(%X{StartTime},'YYYY-MM-DD"T"HH24:MI:SS.FF3'), to_timestamp(%X{EndTime},'YYYY-MM-DD"T"HH24:MI:SS.FF3'), %X{Duration}, %X{WaitingTime}, %X{NumRows}, %X{State}, %X{Completed}, %X{Cache}, %X{Query}, %X{RequestType}, %X{Elements}) AND The only thing I'll need to do is write a script as part of my denodo-monitor deployments to keep that hostname up-to-date on each server (not too bad). With Denodo Monitor running on all my servers and all of them inserting the query history into a database, this feels reasonable for me right now. If we add servers, I just need to deploy the denodo monitor setup to the new servers. I'll give this a try for awhile to see how things go. Again, please let me know if it is possible to add my own layout to the Denodo Monitor configuration. Thanks~! Here is my custom layout: //taken from http://lifeinide.blogspot.com/2011/06/host-and-user-name-in-log4j-logs.html package com.company.denodo.log4j; import java.net.InetAddress; import java.net.UnknownHostException; import org.apache.log4j.PatternLayout; import org.apache.log4j.helpers.PatternConverter; import org.apache.log4j.helpers.PatternParser; import org.apache.log4j.spi.LoggingEvent; public class ContextPatternLayout extends PatternLayout { protected String host; protected String getHostname(){ if(host==null){ try{ InetAddress addr = InetAddress.getLocalHost(); this.host = addr.getHostName(); } catch (UnknownHostException e){ this.host = "localhost"; } } return host; } @Override protected PatternParser createPatternParser(String pattern){ return new PatternParser(pattern){ @Override protected void finalizeConverter(char c){ PatternConverter pc = null; switch(c){ case 'h': pc = new PatternConverter(){ @Override protected String convert(LoggingEvent event){ return getHostname(); } }; break; }//switch if (pc == null) super.finalizeConverter(c); else addConverter(pc); }//finalizeConverter }; //return new }//createPatternParser }//class ContextPatternLayout
user
18-12-2014 13:21:04 -0500
Hi, It is not possible to configure a custom layout in the Denodo Monitor. In future updates of the Denodo Platform we will add the possibility of using the hostname in the pattern that you specify as insertStatement for the JDBC appender.
Denodo Team
23-12-2014 11:14:05 -0500
code
Okay, so I'm closer, but I'm still running into some awkwardness: As mentioned, I have 20 denodo servers. I've configured a denodo monitor to run on EACH server and each monitor loads the queries into the same oracle database. When I deploy the configuration file to each denodo server the deployment process updates the configuration file to use the server's hostname when doing the query inserts into the query history table. Unfortunately, I have servers in different timezones and the timestamp fields aren't storing timezone, so the timestamps in the database are LOCAL to the denodo server but not LOCAL to the oracle database. This isn't good (when you query the oracle database, two queries that occurred at the EXACT SAME TIME on two denodo servers in separate timezones are showing up as showing multiple hours apart, even though they occurred at the same time). So, I updated the oracle table to include the timezone: CREATE TABLE oppen_query_history( id NUMBER, servername VARCHAR2(4000), databasename VARCHAR2(4000) NOT NULL, username VARCHAR2(4000) NOT NULL, notificationtype VARCHAR2(4000) NOT NULL, sessionid NUMBER, starttime TIMESTAMP WITH TIME ZONE, endtime TIMESTAMP WITH TIME ZONE, duration NUMBER, waitingtime NUMBER, numrows INTEGER, state VARCHAR2(4000), completed NUMBER, cache NUMBER, query VARCHAR2(4000) NOT NULL, requesttype VARCHAR2(4000) NOT NULL, elements VARCHAR2(4000) ); Now, I have the timezone as part of the starttime and endtime tables... HOWEVER, the servers in Denver are storing the time as "Navajo". Although this is correct, I'm not used to seeing "Navajo" as a timezone. How can you configure the Denodo Monitor (running on RHEL) to store the timezone as "America/Denver" instead of "Navajo"? (Note: I removed /usr/share/zoneinfo/Navajo and that fixed it... but I'd rather not remove that zoneinfo file... what is the right way to get the rows in the oracle database to be stored as "America/Denver"?) Thank you!
user
24-12-2014 14:33:24 -0500
I fixed it... I changed my CREATE TABLE statement to be: CREATE TABLE oppen_query_history( id NUMBER, servername VARCHAR2(4000), databasename VARCHAR2(4000) NOT NULL, username VARCHAR2(4000) NOT NULL, notificationtype VARCHAR2(4000) NOT NULL, sessionid NUMBER, starttime TIMESTAMP WITH LOCAL TIME ZONE, endtime TIMESTAMP WITH LOCAL TIME ZONE, duration NUMBER, waitingtime NUMBER, numrows INTEGER, state VARCHAR2(4000), completed NUMBER, cache NUMBER, query VARCHAR2(4000) NOT NULL, requesttype VARCHAR2(4000) NOT NULL, elements VARCHAR2(4000) ); Now the timezone information gets properly INSERTED by the Denodo monitor and the timezone is always displayed as the timezone of the client that is querying oracle.
user
24-12-2014 14:35:18 -0500
Hi When you use the data type TIMESTAMP WITH LOCAL TIME ZONE the data stored in the database is normalized to the database time zone, and the time zone offset is not actually stored as part of the column data. And, as you say, when a client retrieves the data, Oracle will return it in the local session time zone of the client.
Denodo Team
26-12-2014 05:32:21 -0500
code
You must sign in to add an answer. If you do not have an account, you can register here