SLF4J Message Format In WebSphere App Server - java

So, I'm beating my head against the wall with logging again. I know, how complex can it be? Well, let's see...
I'm starting a new project to be run on WebSphere Application Server 6.1 (actually Portal Server 6.1, but it's WAS 6.1 under the hood - whatever). I usually use java.util.logging for my WAS projects and everything is fine. This customer is a SLF4J fan and wants to use that. Fair enough, sounds easy.
So, I deploy slf4j-api-1.5.8.jar and slf4j-jdk14-1.5.8.jar in my WEB-INF/lib directory. In my code I do a --
// These classes are coming from org.slf4j.*
private static Logger log = LoggerFactory.getLogger(MyClass.class);
...
log.debug("This is a log message");
As expected I get an entry in the SystemOut.log. However, it's the format of that message that I can't figure out. A sample would be --
[12/15/09 15:43:15:071 EST] 00000042 MyClass D com.example.MyClass This is a log message
Let me explain what's in that sample log entry. I assume everything to the left of com.example.MyClass is coming from the j.u.l formatter. Everything to the right of it is what I included in my log.debug(). So, who's adding the com.example.MyClass? Only thing I can think is that SLF4J is adding it before it passes the message through to the underlying j.u.l.
It's the com.example.MyClass part that's irritating me. I don't want that included in the SLF4J-generated log message. The class name is already included, so it's extra fluff that's not needed. Plus, the real package names are quite long and their inclusion just pushes the real meat of the log entry too far off to the right.
When I use just plain java.util.loggging, the log entry is exactly the same except that the "com.example.MyClass" piece is not included. Exactly as I want!
So, the question is - how can I get rid of this extra class name entry in the log messages generated via SLF4J under WAS?
Thanks!

You bind slf4j to java.util.logging which most likely is configured inside WebSphere as it doesn't look like the standard message format.
I do not know WebSphere, but you may get a better result by telling slf4j to bind to something else. Would the slf4j-simple backend do? It just prints out info-or-higher messages instead of invoking java.util.logging.

Basically you want to configure the layout of the logging messages produced by the underlying logging mechanism.
SLF4J does not actually perform the logging, but delegates to other logging systems (log4j, JUL, etc) based on how you set it up.
So if you are binding SLF4J with JUL, then I think the real question you are asking is either one of
Setting the Formatter of a Logger Handler
Creating a Custom Formatter for a Logger Handler

Related

log4j.logger.org.jasig.cas not got emitted into application logs

We are using cas-client-core-3.3.3.jar for providing single sign on functionality in our application and we are trying to emit this jar library logs into our appliation logs.
Our application is a weblogic based application and we are using log4j for logging.
So to get cas-client-core-3.3.3.jar logs in our application log we have added this property in our log4j.properties
log4j.logger.org.jasig.cas=DEBUG
but we are not getting the logs which are expected from org.jasig.cas classes. I am attaching sample log here which is expected
2015-05-13 10:00:17,798 DEBUG [org.jasig.cas.client.validation.Saml11TicketValidator.<constructValidationUrl>] - Placing URL parameters in map.
2015-05-13 10:00:17,801 DEBUG [org.jasig.cas.client.validation.Saml11TicketValidator.<constructValidationUrl>] - Calling template URL attribute map.
2015-05-13 10:00:17,802 DEBUG [org.jasig.cas.client.validation.Saml11TicketValidator.<constructValidationUrl>] - Loading custom parameters from configuration.
2015-05-13 10:00:17,803 DEBUG [org.jasig.cas.client.validation.Saml11TicketValidator.<validate>] - Constructing validation url:
Disclaimer: I've never worked with Web Sphere but worked a lot with different logging systems, so my answer is based on my experience in this area.
First off, cas uses slf4j under the hood which is great.
Slf4j is only an interface (slf4j-api jar), and if you want to use it with log4j which is a concrete implementation of logging system that knows nothing about slf4j apis you should provide an implementation of sfl4j interfaces that will delegate the calls to log4j loggers.
So you should also include such an adapter in classpath as well Here is the link.
Now if this doesn't work, then probably the log4j.properties are not configured correctly, for example, the logger doesn't have any associated appenders/wrong appenders.
I've found the best way to check this is just to place a breakpoint on the logger's call (inside cas library) and see the following:
Which implementation of slf4j interface is actually used (as I've said before org.sl4j.Logger is just an interface and it has to be instantiated with real implementation object somehow, you know)
See the associated appenders to the underlying implementation.
Regarding the second item, depending on technology/frameworks you have, you might be able to get this information via JMX or some kind of web admin interface. Debugging is a "hardcore" general way to figure this out.

Intercepting or wrapping log4j root logger or appender

I would like to inject a piece of information into all messages logged by anything, including third-party code. The reason is that, in our web-services-oriented application, requests come in with unique IDs and I want those unique IDs to be attached to all log messages that occur while processing a request, to assist in later analysis. I am already tracking the "current request" using ThreadLocal<> techniques, so I have the ability to fetch the "current request" from anywhere.
To that end, I would like to configure log4j such that I can inject the requestID into messages before they reach the root logger (or appender?). I know that I can just make a whole new Appender that implements append() and does whatever it wants with the output, but that's not what I'm asking for. I want output to ultimately go to whatever appender is configured at startup, but with the additional information attached.
I am using log4j 1.x, but if a move to log4j 2.x or using slf4j makes this significantly easier, I would consider it.

How to disable capture of std-out in JBoss?

Using JBoss EAP 6.4 (AS 7.x I guess).
By default, JBoss' logging service is capturing all application output to stdout (and presumably stderr) and wrapping it in its own log4j-based logs. When running locally I want to totally disable this (annoying) feature1, but the references I've found on the Interwebs all either don't work or are for older versions of JBoss. I've tried excluding every possible logging framework in the jboss-deployment-structure configuration, passing -Dorg.jboss.logging.per-deployment=false as a system property, but still JBoss captures stdout.
How can I disable it in this version of JBoss?
[1] If you must know the reason, it's because we have detailed logging configuration via logback and when running locally in an IDE want to be able to see and control that log output in the console without JBoss' logging service getting in the way.
It's hard-coded in the entry points to capture stdout and stderr. This is done so both streams are written to the defined log handlers. Because of this there is no real clean way around it. However there are ways to make it at least look a little better.
You can create a new console-handler and define a stdout logger to ensure only the simple message is written though.
Here are some CLI commands to configure a logger named stdout to just print the message it receives.
/subsystem=logging/pattern-formatter=plain-formatter:add(pattern="%s")
/subsystem=logging/console-handler=plain-console:add(autoflush=true, target=System.out, named-formatter=plain-formatter)
/subsystem=logging/logger=stdout:add(use-parent-handlers=false, handlers=[plain-console])
Note: It could be my test logback.xml configuration, but I had to use a pattern of %s%n for the plain-formatter.
The only other option I can think of would be to write your own logback ConsoleAppender that creates an output stream based on java.io.FileOutputStream.out rather than using System.out.

gwt-log Configurations

I just read the gwt-log Getting Started guide and found it very helpful, however I have a few questions surrounding the Loggers:
The SystemLogger sends output to System.err and System.out - in the context of a client-side web app running inside a browser, where will this output eventually go? Browser logs?
Does RemoteLogger depend on JUL or log4j? I have a homegrown slf4j binding that I like to use for all my Java backends, and would like to use it, but not sure if RemoteLogger will be incompatible with it?
Is it possible to have RemoteLogger hit my own LoggingServiceServlet, which could then translate the log messages coming in on the HttpServletRequest into logging statements that are compatible with my custom slf4j binding? If so, what might this config look like?
Thanks in advance!
In this link, you have a most updated documentation about the GWT logging framework
Answers to your questions:
#1 Yes it works in client side, but only when running the app in DevMode (not in production nor superdev mode). Look for the log lines in the DevMode window, or in your terminal output if you run dev-mode from the command-line.
#2 It depends on java.util.logging, you can change it though (see #3)
#3 Yes you can change the logging framework extending the RemoteLoggingServiceImpl and overriding the logOnServer(LogRecord lr) method.

Component-based logging with logback (or: intercept foreign log messages)

I'm looking for a way to define transitive log message routing. Let's say we have an application called poly with these packages:
com.mycompany.server-common
com.mycompany.communication
com.mycompany.webservice
server-common is used by both of the 2 others. All 3 use org.hibernate as well.
Now, I like to have 1 logfile for the webservice component with all messages from com.mycompany.webservice and with those messages from com.mycompany.server-common and org.hibernate that were initiated by the webservice. And then, another coresponding file for the communication package.
My application is a war file running in tomcat, where all components run in 1 context (it comes in 1 war file). I already defined the multiple log files, but they naturally only log that what i defined statically, there is no transitive inclusion.
I would be very interested in ideas how I could achieve the desired behaviour. I already thought about using the MDC for that, but I'm not sure if that's a good idea.
Another idea was to separate the contexts, but I think in the current project state this will be hard and it does not offer the flexibility I hope for.
Any hints or discussions are appreciated.
If you set an MDC key when webservice starts serving a request and clear the MDC key at the end of the request, SiftingAppender will do what you are asking. Shout on the logback-user mailing list if you run into difficulties.

Categories