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

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.

Related

Jetty 11 changed the logging to SLF4J - how to access it?

We understand that Jetty 11 has basically changed logging from version 10 (no internal Jetty classes, moreover Jetty 11 is commited to use SLF4 as a base logging).
The problem
We have a rudimentary knowledge of SLF4J (used it before and we've even read the Jetty 11 SLF4J sources ,too), but currently we don't see any way to "teach" Jetty 11 a new logging (aka there are no "setLogging()" methods in the Jetty 11 source code as there were before).
Global (Jetty) parameters, alas, can't be our solution just yet.
The state (aka our requirements)
We have already solved the "RequestLog" outputs of Jetty, no problems there, we need the "normal" Jetty-log outputs.
We need to control (many) modules/jars etc. via a unified logging.
Our logging is simple but requires that no output happens on the console (stdout / stderr etc). In best case the logging gets an instance of an Exception/Runtime, too.
Therefore, we need to route the Jetty output from the "Jetty server" through our internal logging. Using SLF4? If there is no other way (and we see no other way up to now), gladly.
Switching back to Jetty 10, sadly, is not an option.
Could this be solved in any way we are not aware of (yet)? Any idea would be very appreciated, thank you!
The switch from Jetty logging to Slf4j was actually done in Jetty 10.0.0.
slf4j was designed for unified logging, it can capture into a single logging location implementation all of the logging events generated from libraries that use ...
slf4j API
java.util.logging API
log4j1 API
log4j2 API
commons-logging API
logback API
org.apache.juli.logging API
and if you use slf4j version 2.x series, there's even rudimentary support for capturing java.lang.System.Logger API.
With slf4j, you have 2 categories of jar files to think about.
Bridge API JARs
These are slf4j based JARs that merely capture the above logging events and route them to slf4j. You can choose 0..n of these JARs to use.
There's dozens of options here.
Here's some common ones
jcl-overs-slf4j - captures Jakarta Commons Logging events and sends to slf4j
jul-to-slf4j - captures Java Util Logging events and sends them to slf4j
log4j-over-slf4j - captures Log4j 1.x events and sends them to slf4j
log4j2-overs-slf4j - captures Log4j 2.x events and sends them to slf4j
osgi-over-slf4j - captures osgi logging bundle events and sends them to slf4j
See http://www.slf4j.org/legacy.html
Implementation Binding JAR
These are the implementation of slf4j-api, and is the final binding of all logging events, it is the thing that decides what to do with the logging event (eg: write it to disk, ignore it, send it to a logging database, etc)
You have many choices here as well, here's some common jars to pick from (pick only 1!)
logback-classic - slf4j to Logback (Eclipse Jetty group's favorite logging implementation)
slf4j-jdk14 - slf4j to Java Util Logging
slf4j-log4j12 - slf4j to Log4j 1.2.x
log4j-slf4j-impl - slf4j to Log4j 2.x (see https://logging.apache.org/log4j/2.x/log4j-slf4j-impl/)
slfj-jcl - slf4j to Jakarta Commons Logging
jetty-slf4j-impl - Jetty 10+ implementation of the slf4j api
See: http://www.slf4j.org/manual.html#swapping
Since Jetty 10.0.x, the jetty-slf4j-impl exists, which provides an out of the box implementation that simply writes to System.err (aka STDERR) with some decent logging filtering by level in the usual jetty-logging.properties.
See https://search.maven.org/artifact/org.eclipse.jetty/jetty-slf4j-impl
Important advice
Don't use multiple binding implementations. Narrow it down to 1 binding implementation and purge all other logging implementation jars.
Don't accidentally create a loop with introducing a Bridge API Jar and a Binding Implementation JAR with the same logging technology. (eg: using binding log4j-over-slf4j and slf4j-log4j12 at the same time)
There is no "configuration" to wire up these binding or bridge jars, their mere existence in the classloader is enough to make them work. See the slf4j manual on how that works.
We have already solved the "RequestLog" outputs of Jetty, no problems there, we need the "normal" Jetty-log outputs.
Interesting, this is "solved" by actually using slf4j, as that's the only non-deprecated implementation of RequestLog.Writer in Jetty 10 and Jetty 11.
The way this works, is the Slf4jRequestLogWriter will emit events to a single named logger (the name of which you can configure in Slf4jRequestLogWriter.setLoggerName(String)) using the slf4j-api. Then it reaches the logging implementation and is routed wherever that logging configuration decides based on that logger name (file, with rolling, syslog, sent to a different system for aggregation, logstash, etc)
Did you really implement your own RequestLog.Writer instead of just using your preferred logging logging library? (libraries like logback, log4j2, log4j1, and even java.util.logging can easily create separate log files for RequestLog events).
⚠️ Note: do not use logback-access for RequestLog at this time (It does not fully support jakarta.servlets yet, and has many bugs that result in bad request log data. See open PR at https://github.com/qos-ch/logback/pull/532)

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.

What happens when dependency uses different logging?

Suppose I have a web project (war) which is using logback logging but this project has a dependency of a jar which internally uses log4j logging. What will happen in this case? Will dependency logs appear in my logback log file or they just disappear (means I wont be able to see them anywhere) or some exception?
The logs coming from your dependency won't appear in your log file unless you use a bridge to redirect calls made to log4j by calls made to your logger.
If you use logback with slf4j, you can refer to this link to have more explanation on how to do that : http://www.slf4j.org/legacy.html

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.

SLF4J Message Format In WebSphere App Server

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

Categories