Configure Log4j1.x to log asynchronously through property files - spring

I have a large, Spring-based eCommerce framework as a codebase which makes use of pre configured log4j. I can override property values defined in log4j.properties.
I'd like to configure log4j to log asynchronously to console/file, I've attempted to define new/override appenders but am not seeing any output to console and am unsure why.
Is it possible to wrap current log4j into asynchronous calls?

Related

How to exclude a specific class for a specific logger with SLF4J

My program has an underlaying system that persist every log in elasticsearch.
I have a class that fetches data online and logs it with slf4j log.error(data).
This allow the underlaying system to persist the log in elasticsearch, but it also floods the console with every fetched data.
I wish to disable the consoleAppender just for this specific class.
I've seen other post where people would disable the consoleAppender with logback or would exclude all logging from a specific class, but I couldn't find any information on how to disable one logger in one class.
Is this possible?
It sounds like you just need to set the logging level for that class. Set it to ERROR, WARN or another level, depending on the level of the messages that are flooding the console. Try modifying the application.properties file by adding something like:
logging.level.com.test.MyClass=WARN

Logback with Spring Boot - programatically change configuration at runtime to add Syslog Appender

I am building an application (Spring Boot 1.4.2) where i would like to offer an administrator the option to enable syslog but i want to avoid him/her having to manually edit any config files - in this case logstash-spring.xml.
Therefore i am trying to understand how i can achieve using a logback-spring.xml file as a baseline (e.g. define file based log options, levels etc. - settings i dont want the administrator to change) and on top of that provide a functionality at runtime where an administrator can add or change a syslog appender.
I have listed what i see as requirements:
The changes made to the Logger should be persisted after the Spring Boot application is restarted.
Ideally the syslog server info (name, port) are kept in my persistence layer (H2, hibernate) but i am not sure if that is possible as i guess the logging framework is being injected prior to my persistence layer?
The syslog appender that i want to add should be referenced by root logger so that all the packages i have configured logging for would go to syslog (not sure if this is just "how it works per default")
Also i dont know if i could simply treat logback-spring.xml as a regular XML object and use for example JAXB to manipulate that file and use the autoscan feature of Logback to simply read in the new changes?
I have played around with defining a Logger #Bean:
#Bean
public Logger logger() {
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
// excluded implementation
}
This is being picked up by Spring Boot but that brings me to the 2 items i have listed above that i dont know how or where i would store the syslog server information the administrator would provide.
UPDATE:
I wrote the following which meets the 3 requirements above however i would appreciate any feedback on the actual implementation as i am very new to Spring and Java.
GitHub repository with implementation - spring-boot-logback-syslog
I managed to use the example i posted in my Github repo in my designated application and with that i am answering my own questions based on the implementation in that repo.
Please refer to the README for full details on how it was implemented.
UPDATE: As part of Spring Boot 1.5.1 there is an actuator that can set the logging level during runtime: Production Ready Loggers
Not necessarily 100% related to this topic but this was one of the requirements i had for the implementation as well as changing syslog related settings.

Assign different logger (appender) to different Apache Camel routes?

I was wondering if there is any way already implemented in Apache Camel to be able to log to different loggers depending on the route. I am using Spring DSL to create the routes. My use case is that I want a different log file for each route I am defining.
Is that possible?
You can enabled MDC logging, which then include details about which route is currently being logged from: http://camel.apache.org/mdc-logging.html
Then the logging framework you use, such as log4j, logback, etc. can be configured to log to different appenders based on a MDC key (eg camel.routeId)

How does my spring web app capture errors that I didn't catch and log? Is this a result of apache commons?

I'm confused as to how the errors are logged without me implicitly catching them and logging out the error. All that I've done is put a log4j.xml file in my project defining appenders and now the logs catch and log everything from the frameworks.
If I say, try to query in Hibernate and the query fails, or I try to open a file that doesn't exist, or I get a null pointer exception, if the log4j.xml file defines a log file, and the error level is set correctly, then the error will be captured there?
How does my spring web app capture errors that I didn't catch and log? Is this a result of apache commons logging?
Or is this some magic that log4j knows how to deal with - catch stream to the console etc?
Any info appreciated.
From spring official documentation:
The nice thing about commons-logging is that you don't need anything else to make your application work. It has a runtime discovery algorithm that looks for other logging frameworks in well known places on the classpath and uses one that it thinks is appropriate (or you can tell it which one if you need to). If nothing else is available you get pretty nice looking logs just from the JDK (java.util.logging or JUL for short). You should find that your Spring application works and logs happily to the console out of the box in most situations, and that's important.
To make Log4j work with the default JCL dependency (commons-logging)
all you need to do is put Log4j on the classpath, and provide it with
a configuration file (log4j.properties or log4j.xml in the root of the
classpath).
Take a look for a complete explanation: http://static.springsource.org/spring/docs/3.0.x/reference/overview.html#d0e743

Is log4j thread-safe?

I have a following question. We use log4j in our two projects, that are hosted on the same GlassFish server. Each project has inside log4j.properties file, that points to the files, that are based in different catalogs (let's name them Project1 and Project2).
Now, for some unclear reasons sometimes the info messages of the first project are written to Project2 log files, and the reverse is also true. I checked the log4j.properties files for both of the projects, there is nothing pointing in them to the log of the other project.
The suspicion is that log4j is not actually thread-safe, therefore if two users are working in two systems in the same time, the messages of the loggers can get mixed. Is this suspicion correct?
Yes, log4j is thread safe:
Yes, log4j is thread-safe. Log4j components are designed to be used in
heavily multithreaded systems.
Ref.
What you are describing sounds more like a config mistake, rather than a cross process/threading issue.
Yes, log4j is thread safe. The reason is the method AppenderSkeleton.doAppend() is synchronized. But be carefull configuring programmatically!
For example you can't use the same instance of TTCCLayout in different appenders(read javadoc)! Take a look at PatternLayout method format(). It changes instance field(StringBuffer sbuf), so if you use same PatternLayout instance in different appenders you are to face race conditions. EnhancedPatternLayout is better, cause they modified format method.

Resources