ThreadLocal guard in Logback appender base classes - java

ThreadLocal guard is utilized in doAppend method of Logback base appenders to prevent calling back on itself.
Under what circumstances would doAppend call back on itself?

Under what circumstances would doAppend call back on itself?
Anytime the Appender::append creates logging events that feedback into the appender itself. This is any Appender makes method calls against a 3rd party library which in itself uses a logging framework that uses slf4j or can be bridged to logback/slf4j.
Take the SMTPAppender as an example. Per the docs:
The SMTPAppender relies on the JavaMail API.
If the following statements are true then you have a feedback loop:
An ancestor of the JavaMail logger namespace has an attached SMTPAppender, say the root logger for example.
JavaMail session debugging has been enabled which will generate JUL log records on SMTP send.
The sl4fj JUL bridge handler is installed and is redirecting the JUL log records to the already attached SMTPAppender in point 1.
There is a running thread that tries to generate the first log message.
The SMTPAppender attempts to send email message. This action will generate more messages that feedback into logger in point 1.
When all of this is true, your application log message that you wanted to send via email ended up creating X number of log message debug statements from JavaMail. Those X number of message now end up calling SMTPAppender::append and so on.
This same type of example could be applied to the DBAppender which requires a JDBC driver that could be directly logging to slf4j. Same rules for any custom appenders applies here too.
In general, you don't what your application logs to be mixed with this appender generated log information or create some sort of feedback loop that takes down your server.

Related

How to disable logging in imported libraries?

In my application, I am using SLF4J's Logger for logging. When an error is logged, I am sending a message to another application. The problem is that one of the libraries I use (Slack API) uses the same logger (in class com.slack.api.methods.impl.TeamIdCache), so when it logs an error, my application sends a message that I didn't intend it to send.
How can I disable that library's logger?
You can disable specific logger in your application properties:
logging.level.com.slack.api.methods.impl.TeamIdCache=OFF
See Spring documentation for more information regarding other configuration options and log levels.

What is the difference between Java Logger and System.out.println

I looked up the api about the logger class(here) and I was looking at the Logger.info method. I was confused when I saw its perimeter as a message displayed as a string public void info(String msg) which is same as System.out.println(). I am wondering what is the different between these two, and why do we use Logger instead of System.out.println when they can print out the same thing.
In Logger.
Logger.info("Hello")
Output:
[INFO ] 2015-08-07 11:18:46.140 [main] ClassName Hello
In System.out.println
`System.out.println("Hello")
Output:
Hello
Usually, because a Logger can be configured to write to a file (and the console). It might also be configured at higher (or lower) granularity as to messaging. For example, you might configure (at runtime) for level of warn. In which case, that logger would not display debug or info messages. It can include information such as the class that is writing, a line number, and a date and time (of the message).
Using a logger allows you to abstract out a lot of details and do a lot more than you could writing to stdout.
You can specify different destinations to write to. Different appenders write to a file, roll the file for given time periods, write to a queue or database, etc.
You can specify a consistent format for log messages instead of having to add it to every line you write to stdout.
You can choose an appender that buffers the output so that multiple threads can log without having the threads contend for the lock on the console object.
You can do a lot with filtering by category (typically package and classname) and log level (trace, debug, info, error, fatal), to make it easy to configure what log messages you want to see and which you want to ignore. With logging you can change the configuration in the logger properties or include a page in your application to change what gets filtered on the fly.
You can mix and match this stuff, for instance, setting up a specific smtp appender to email log messages for logging level of error or higher, in addition to writing the messages to a rolling file or whatever.
The main difference between a Logger and System.out.println is Logger: Prints the text in a file(text file)System.out.println: Prints the output in console
Logger is useful when you are going for any LIVE projects. Because if any project is developed and deployed, then you cannot check the console. At that time Logger will be useful to track the flow of your project also you can find the Error or Exception if you have given the logger in catch{...} block.
Also go through this Logger vs. System.out.println
But when we use any logging mechanism(log4j, slf4j, logback etc) we
configure appenders and corresponding target log files for each
package. By default console appender is turned off unless you
explicitly configure it to log to a destination.
The System.out.println always logs the message to a console appender.
So, it should be used only when we are sure that the console appender
is configured in the logger configuration file. Otherwise we end up
having logs logged on server console which is incorrect. Any log from
inside the application should go to the corresponding application log
and not the server log.
Let me explain with an example.
If we are building an application called Tracker using a logging mechanism to run in a tomcat container, and we configured appenders for application logging with destination log file as tracker-application.log and we did not configure the console appender.
Then if the System.out.println is encountered by the JVM then the log will go to server log of the tomcat server which is wrong because server log should only have information about the server and not the application.
But if we created a console appender with a target log file then it will be logged properly.
Hope I was clear. ;)
For best practices refer Do not use System.out.println in server side code or http://www.vipan.com/htdocs/log4jhelp.html
For differences between both of them please refer
Logger vs. System.out.println

Is it possible to get the root log level of Jboss Server, if custom loggers are used instead of logging service provided by the Server?

Following are the requirements,
multiple modules deployed on JBoss AS 7 with individual logging configuration using logback.xml.
all of them request exclusion of default logging-service provided by the Server, using jboss-deployment-structure.xml.
Following are observation,
log.debug statements get printed as INFO on Server log(server.log)
it's because root level of custom-logger(logback.xml) is set to DEBUG
Now questions,
How can I make, DEBUG statements generated by custom logging statement gets printed with appropriate log level?
Conversely, is it possible to get log level of Server without using it's logging service?
In other words, is it possible to achieve uniform log-level configuration across multiple modules that use custom-loggers?

Websphere with Logback logging to system out - formatting issue

I am using Logback in my application hosted on Websphere App Server. Logback is configured to log to System Out (and others are hesitant to change to a different file). The issue is that Websphere uses its own format for logging to System Out. Executing logger.debug("test") in my app yields:
[8/7/12 12:27:55:629 CDT] 0000003a SystemOut O DEBUG com.myapp... test
where everything up to the "O" is added by Websphere. The rest is from Logback
I have set up Logback to use the following pattern: %-5level %logger{36} - %msg%n so that I don't repeat timestamp and thread info which Websphere does on its own, but I am still annoyed that I can't fully customize the logging to System Out from within Logback.
I don't know a whole lot about logging best practices. Before, I have logged to separate files by web app, but for this project, I was told the System Out files are monitored by a third party and I should not change from using System Out. Is there any way to get around my issue given these requirements and tell Websphere not to mess with my System Out logging, or is the only solution to start logging to a different file? Thanks!
Your logback is configured to write messages to System.out. However, everything that is written to System.out is redirected by WebSphere and written to the SystemOut.log file with the same format as log messages produced by WebSphere, but with a severity indicator "O". It is not possible to change that.
Note that it is likely that the people who told you to use SystemOut.log actually meant that you should ensure that logging is done using WebSphere's log system so that messages are written with the correct category and severity and that log levels can be changed at runtime. Since WebSphere's log system is build on java.util.logging you should probably just replace logback by slf4j-jdk14 to satisfy their requirement.
I don't think you're going to be able to change the format. And if you could, it might break the current monitoring anyway.
I wonder if anyone would mind if you log to two loggers at the same time, SystemOut for the existing monitoring, and your own for a more readable format.
The problem is that Logback redirects the messages to console output instead of java.util.logging. Console output has no log levels and that's why WebSphere just writes "O".
We solved this by implementing a Logback appender that redirects logs to JUL (java.util.logging) instead. We convert Logback log levels to JUL levels (e.g. Logback "ERROR" is JUL "SEVERE").
We also wanted to use Websphere's trace options. If trace is enabled for a class/package pattern, you will see Logback DEBUG and TRACE messages in Websphere's trace.log. You can also check if the trace is enabled by calling Logback's isDebugEnabled() / isTraceEnabled().
See this answer with a full implementation:
https://stackoverflow.com/a/74386323/395879

Google App Engine - Can not find my logging messages

I can not find the results of my logging calls.
To log messages I tried both:
System.out.println("some message");
and
Logger logger = Logger.getLogger("MyLogger"); // Logger is java.util.logging.Logger
// ...
logger.info("some message");
I have deployed my app and after few tests I decided check out some
log messages. But there were no messages. I changed minimum severity
level to "Info" from default "Error", and only messages i've seen were
service messages like this:
http://dl.dropbox.com/u/1678938/logs.png
I would also be grateful if someone show a little snippet with logging some data (if it's works) - I suspect my problem may be the one of that stupid problems when somewhat incorrectly located comma can be the cause of situation.
Could it be that your logging.properties is setting the default value to WARNING?
Ours has this in our war/WEB-INF/logging.properties file:
# Set the default logging level for all loggers to WARNING
.level = WARNING
# Default level for subpackages of 'server' will be INFO
com.company.whatever.server.level=INFO
Problem has shrunk into more concrete form - App Engine "eats" info-messages, but shows others, such as error and warning messages.
After this call I have eventually seen my info messages:
log.setLevel(Level.INFO);
But it is still not clearly - why info-messages weren't being shown. Google's manual states:
Everything the servlet writes to the
standard output stream (System.out)
and standard error stream (System.err)
is captured by App Engine and recorded
in the application logs. Lines written
to the standard output stream are
logged at the "INFO" level, and lines
written to the standard error stream
are logged at the "WARNING" level.
Had exactly the same problem and after changing the value in logging.properties from
.level = WARNING
to
.level = INFO
The problem was definitively fixed. Google needs to update their documentation and/or change the value of the supplied default so that "INFO" log messages don't get swallowed.
I used to set LEVEL to SEVERE for testing
logger.log(Level.SEVERE, "test message");
It does not need changing any value in logging.properties

Categories

Resources