Add exception in log4j patterlayout in JSON format - java

I want to log in JSON. I have the following log4j.properties:
log4j.rootCategory=ALL,console
log4j.logger.com.demo.package=ALL,console
log4j.additivity.com.demo.package=false
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.out
log4j.appender.console.immediateFlush=true
log4j.appender.console.encoding=UTF-8
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern={"debug_level":"%p","debug_timestamp":"%d{ISO8601}","debug_thread":"%t","debug_file":"%F","debug_line":"%L","debug_message":"%m"}%n
My log statements are like this:
log.error("SocketTimeoutException while fetching log:", e);
But this only logs the message in debug_message key i.e. SocketTimeoutException while fetching log: and the exception stacktrace is logged in a separate line outside the json.
How can I make the exception part of the Pattern.

Related

multiple log levels in same log file in log4j

How can multiple log levels added to the same log file in log4j?
For example:
log4j.rootLogger=INFO,WARN,stdout,file
It gives the log4j error when application start as:
Could not instantiate appender named WARN.
The purpose of the threshold is to tell log4j to ignore all logging requests with a priority lower than what you specify. Specifying a given threshold does not limit you to logging with that threshold.
FileAppender fa = new FileAppender();
fa.setThreshold(Level.INFO);
fa.setAppend(true);
Logger.getRootLogger().addAppender(fa);
In the above code, the appender has been configured to operate with a threshold of INFO. This means that the following code will not log, because DEBUG is a lower priority than INFO:
Logger logger = Logger.getLogger(SomeClass.class);
logger.debug("This will not log");
But this code will log:
logger.warn("This debug message will log.");
logger.error("And this error message will also log.");
In this case, both WARN and ERROR have a higher priority than INFO.

REST JAX-RS Logging

I have followed the HelloWorld example and got my fist REST done successfully. Now, I would like to add the logging capability the code. For example, I would like to have any logging frameworks (Log4j, JUL) and be able to log in the code, and have output to a file. How do I implement the logging to my REST code?
#Path("/hello")
public class HelloWorldService {
Logger log = Logger.getLogger("className");
#GET
#Path("/{param}")
public Response getMsg(#PathParam("param") String msg) {
String output = "Jersey say : " + msg;
//for example, here. hopefully to a file
log.info("Log Jersey say : " + msg);
return Response.status(200).entity(output).build();
}
}
I am using Jersey 1.19, Tomcat 8
You can use open source Apache Log4j library. Add below dependency in your pom or download it from here.
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
log4j.properties
# Root logger option
log4j.rootLogger=INFO, file
# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
#Redirect to Tomcat logs folder
#log4j.appender.file.File=${catalina.home}/logs/logging.log
log4j.appender.file.File=C:\\logigng.log
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
With this configuration, all logging will be redirected to your specified log file.
Source : http://www.mkyong.com/logging/log4j-log4j-properties-examples/
How to log a message using Log4j?
private static final Logger logger = Logger.getLogger(HelloWorldService.class);
Logs messages with different priorities, for example, debug, info, warn, error and fatal. Normally, you just need to use debug or error.
//logs a debug message
if(logger.isDebugEnabled()){
logger.debug("This is debug");
}
//logs an error message with parameter
logger.error("This is error : " + parameter);
//logs an exception thrown from somewhere
logger.error("This is error", exception);
To set logger in debug mode, change this in your property file
log4j.rootLogger=DEBUG, file

How to know in log4j , that ERROR level is triggered?

How to know in log4j , that ERROR level is triggered. In my code I have written like If an exception occurs i.e if an ERROR level is triggered then I will show log file path in console and wont show any message for other levels.
In Log4j you can configure different levels in the log4j.properties or xml file which ever you choose to use.
There is some predefined pattern with the error levels and runs from lower to upper.
Lowest id Debug its in this sequence.
1.Debug
2. Warn
3. Error etc
So if you want only Error messages then configure the Error level to Error. you wot get Debug and Warn
If you configure Debug you get everything
Ex.
<logger name="org.springframework...">
<level value="error" />
</logger>
This is the point of separating the code from the configuration.
E.g., your code could look like this:
try {
someMethod();
} catch (SomeException e) {
log.error("Error!!! " + e.getMessage());
}
And in your log4j configuration, your configure your log to output only ERROR level messages:
log4j.rootLogger=error, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# Just an example of a pattern layout
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

how to disable a log4j timestamp for only particular lines

i have logging configured in log4j.properties file , i am getting a output something like this
2013-11-12 19:33:17,897 - INFO Starting queue dispatching for DaphneStore Queue: om.fi
2013-11-12 19:33:17,897 - INFO Starting CBR queue dispatching for DaphneStore
2013-11-12 19:33:17,897 - INFO Starting server shutdown
is there any possibility that i do not get timestamp information on the left hand side for some of the lines, something like this
2013-11-12 19:33:17,897 - INFO Starting queue dispatching for DaphneStore Queue:
Starting CBR queue dispatching for DaphneStore
Starting server shutdown
here is my log4j configuration
# Set root logger to output only ERROR and FATAL events to R appender
log4j.rootLogger=ERROR, R
# Define R appender to output to local log
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.file=D:/logs/abc.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d %-5p %c - %m%n
Couple of quick solutions:
Create a different appender with ConversionPattern=%m%n (This will just print the logger text without timestamps I suppose).
Modify the exisitng appender with ConversionPattern=%m%n. Here you can manually add timestamps (using DateFormat like SimpleDateFormat) to the logger text wherever needed. In rest of the cases, plain text will be added to the logger file without timestamp.
You are probably not using log4j correctly. Every call to log.info/error/...() is considered a separate log message.
What you are probably trying to do is something like this:
final StringBuilder logmsg = new StringBuilder();
logmsg.append("Starting queue dispatching for DaphneStore Queue: \n");
logmsg.append("Starting CBR queue dispatching for DaphneStore\n");
logmsg.append("Starting server shutdown\n");
log.info(logmsg);
UPDATE
What I mean is that the timestamp is an important part of a log message, it says when something happened. If you don't need this information all the time you should probably lose the timestamp all-together and put a single logging call to mark when your application was started:
String moment = (new SimpleDateFormat("yyyy-MM-dd ...")).format(new Date());
log.info(moment + " Application started");

Log Level per appender for a single Logger

Is it possible to configure different log levels for a single Logger based on the appender?
I realize this is similar to this question, and this is as far as I had already got myself, but the problem with this is that the threshold applies to all loggers that log to that appender, whereas I only want the threshold to apply to a single logger.
i.e. So far I have something like this:
log4j.rootLogger=WARN, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Threshold=WARN
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
log4j.logger.mylogger=DEBUG,logfile
log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logfile.DatePattern=${roll.pattern.daily}
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{${datestamp}} [%t] %-5p %C{2} - %m%n
log4j.appender.logfile.File=mylogfile.log
I want mylogger DEBUG messages to be send to the logfile appender, but I also want mylogger INFO messages to be sent to the stdout appender (but for all other loggers only WARN ings). Using the Threshold to limit stdout to WARN restricts the output of mylogger.
Aha, I fixed it by changing
log4j.appender.stdout.Threshold=WARN
to
log4j.appender.stdout.Threshold=INFO
Should have been more careful first time round.

Categories