I have web application in Java (JSP + Servlets) and logging with log4j 1.2.17.
When user login on site he take ID. I wanna see all his actions in log file with ID prefix like this:
01.05.2015 11:12:30 INFO [Roy] - login correct
But i don't want to pass ID in every calling method to logging events in that method.
I want to save ID somewhere and take it when need.
What you probably want is a Mapped Diagnostic Context. This effectively gives you a stack of ThreadLocal to put data elements into that you can log later.
In java...
MDC.put('LOGIN_ID', 'Roy');
In your log pattern:
"%d %p [%X{LOGIN_ID}] %m
Related
My log4j.properties file look like
log4j.rootLogger = ERROR,sql, Appender1
log4j.logger.com.endeca=ERROR
log4j.logger.com.endeca.itl.web.metrics=ERROR
log4j.appender.sql=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.sql.URL=jdbc:mysql://192.168.70.39:3306/cortex_mcss_ip
log4j.appender.sql.driver=com.mysql.jdbc.Driver
log4j.appender.sql.user=root
log4j.appender.sql.password=123456
log4j.appender.sql.sql=INSERT INTO errorlog(Level,Msg,CreatedDate) VALUES ('%p','%m',now())
log4j.appender.sql.layout=org.apache.log4j.PatternLayout
log4j.appender.Appender1=org.apache.log4j.ConsoleAppender
log4j.appender.Appender1.layout=org.apache.log4j.PatternLayout
log4j.appender.Appender1.layout.ConversionPattern=%-7p %d [%t] %c %x - %m%n
log4j.appender.Appender2=org.apache.log4j.FileAppender
log4j.appender.Appender2.File=D:/Logs/Log4jWebDemo.log
log4j.appender.Appender2.layout=org.apache.log4j.PatternLayout
log4j.appender.Appender2.layout.ConversionPattern=%-7p %d [%t] %c %x - %m%n
when error occurs it works fine on console and file appender,but does not insert into databse anything ?
Note : databse parameters are 100% accurate in every corner.
Any one please help me to solve this...plz...
To directly address your question:
you should debug this appender to see what happens.
Make sure that DB driver (mysql in this case) appears in the classpath of the application.
Make sure that the table / schema exist, because this appender by its own does not create a schema for you
Note that it has a "bufferSize" parameter, so only if the non-stored message count exceeds the buffer, the actual DB request gets performed.
Place a breakpoint on org.apache.log4j.jdbc.JDBCAppender#execute and see how it really executes
Overall observation/side notes, not directly related to your answer but still can be valuable.
This appender is really outdated and is not a really good solution for modern production applications (unless you have a very small number of logs).
This appender doesn't use batch inserts supported by probably all modern RDBMSs.
This appender doesn't use prepared statements.
All-in-all storing logs in RDBMS doesn't really make sense nowadays, logs are meant to be read and analyzed, and RDBMS doesn't offer really handy tools for this (both visual and from the maintenance standpoint: how do delete obsolete messages? Bulk DELETE is very expensive, partitioning? Retention Policies for records are not really supported in many RDBMSs...
So, a much more modern approach is using tools like ElasticSearch + Kibana (+ some log shipper) or even streaming logs to the cloud (like Logz.io)
We are using log4j2 in our tomcat application. We would like to add session ID to each log line (please don't judge us for that, maybe it is not the best thing to do, but it is very practical).
So we would like to achieve something like this:
2018-05-08 21:55:20,828 INFO SessionId CurrentClass LogMessage
To achieve this, we would need to create some kind of callback for each logged line. Is this feasible with log4j2?
You can add any information in your log by doing:
String sessionId = "my-session" // this is dynamic.. You can get it in a filter..
org.apache.log4j.MDC.put("sessionId", sessionId);
Then, define your log pattern as something like:
%d{ISO8601}] %X{sessionId} %p %c - %m%n
After that, the logger will print the sessionId.
I want to use pgAdmin to configure to log all sql insert statements. But how?
I found the Backend Configuration Editor and enabled log_statement=all. But how can I control the file to that the log statements are written? (eg: c\logs.txt)
log_destination = 'stderr,csvlog'
log_statement = 'all'
#see C:\Program Files\PostgreSQL\9.3\data\pg_log
See the manual. You probably want to set log_directory and log_filename.
You cannot set individual log destinations for particular categories of log line - say, log statements to one file, other logs to another file. This would be a nice feature; if you have time, consider raising the idea on pgsql-hackers and after discussion submitting a suitable patch.
Most people use csvlog, or use text logs with a log_line_prefix set, then filter the logs with simple tools like grep to extract the desired information.
For statement data collection, also have a look at the pg_stat_statements extension.
I want to intercept logs from the specific thread in my application for the certain period of time. I'm using log4j.
The code below does that, but I'm getting logs from others threads too.
WriterAppender appender = new WriterAppender(new PatternLayout("%d{ISO8601} %p - %m%n"), consoleWriter);
appender.setName("STR_APPENDER");
appender.setThreshold(org.apache.log4j.Level.INFO);
Logger.getRootLogger().addAppender(appender);
//Some Logic here (I'm using other classes and jars here and I want to get this logs as well)
Logger.getRootLogger().removeAppender("STR_APPENDER");
I'm aware that Logger.getRootLogger() is not a good solution here, but I don't have any other idea.
You can use MDC.put.
eg
MDC.put("threadName",Thread.currentThread().getName());
Using that you can put thread name.
Using Log4j appender you can print the thread name [%X{threadName} in logs
I have a log4j logger that I instantiate like this:
logger = Logger.getLogger("EQUIP(" + id + ")");
Doing so, when I call logger.info("message"), I should get an output like this (with some date formatting):
13/11/12 15:08:27 INFO: EQUIP(1): message
But I'm only getting:
13/11/12 15:08:27 INFO: message
I'm also printing logger.getName() to the console for debugging and it gives me back the correct "EQUIP(1)" name. This behaviour is happening in some cases in my program, where I have several loggers like this, but mostly in this specific class. I want to know if I'm doing something wrong, if this name should be only the class/package name, or if it can be anything (it works well in 80+% of my loggers). I need to print the ID of each equipment because I have several of them working simultaneous, and tracking them without this would be next to impossible.
How should I fix this, preferably without resourcing to changing all my log calls to include this prefix?
The output format depends on the pattern you've configured for the appender. If the pattern string includes %c then you'll get the logger name included, if it doesn't then you won't.
An alternative approach might be to use the mapped diagnostic context, which is designed to disambiguate between log output from different threads writing to the same logger.