Difference between slf4j-log4j12 vs log4j - java

In a project's pom.xml I am seeing a dependency like below
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
Can someone let me know what is the difference between slf4j-log4j12 & log4j ?

Log4j 1.2
slf4j-log4j12 provides a bridge between SLF4J and Log4j 1.2 so that SLF4J knows about how to log using Log4j.
You are using Log4j 1.2. That version's binding it is maintained by the SLF4J project. Here is a summary from the SLF4J docs:
SLF4J supports various logging frameworks. The SLF4J distribution ships with several jar files referred to as "SLF4J bindings", with each binding corresponding to a supported framework.
slf4j-log4j12-1.7.28.jar
Binding for log4j version 1.2, a widely used logging framework. You also need to place log4j.jar on your class path.
Log4j 2
If you are using Log4j 2 or later, you will need a different binding JAR than slf4j-log4j12. That binding is maintained by the Log4j project. According to the Log4j docs:
The Log4j 2 SLF4J Binding allows applications coded to the SLF4J API to use Log4j 2 as the implementation.
You must provide both dependencies if you want SLF4J to route logging to Log4j. Again, from the Log4j 2 docs:
Simply include the Log4j 2 SLF4J Binding jar along with the Log4j 2 jars and SLF4J API jar to cause all SLF4J logging to be handled by Log4j 2.

To summarize:
<dependency> <!--Facade for logging systems-->
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency> <!--Log4j 2 implementation for slf4j-->
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.12.0</version>
</dependency>
In addition make sure that you are using a log4j2 properties file. The mistake of using 'log4j.xml' did cost me quite some time

I'll post some points regarding these logger message.
log4j:
logger.debug("This is log message:" + msg);
log4j string is concatenated every time the line is evaluated even if log level is lower than debug so the string will never be used.
slf4j:
logger.debug("this is log slf4j message",msg);
slf4j string and parameters are passed through to the logger which only substitutes them if the log message is actually to be used.
The only difference is the performance. Where log4j will take more time because of string concatenation compare to slf4j.

Slf4j:
An abstract layer for the logging component.
We can change logging at point of time without much changes in code.
Log4j:
A logging component which provides core functionalities of logging.

Related

Migrating JUL to log4j2, performance is not as expected. What went wrong?

I am a new user of log4j2. Based on Log4j2 performance tests introduction, and it may need to generate a large number of csv files for data processing. I plan to migrate a project from JUL to log4j2. This is a multi-threaded project that uses a lot of loggers. But the test results are not satisfactory . Where did I get it wrong?
the compare results
The dependency configuration is as follows:
<!-- Log4j2 api -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.1</version>
</dependency>
<!-- Log4j2 impl.-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.1</version>
</dependency>
<!-- for Log4j2 asynchronous logging-->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.2</version>
</dependency>
<!-- for Log4j2 csvlayout-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.5</version>
</dependency>
File "log4j2.xml" has multiple similar appenders and loggers, for example:
partial configuration for log4j2.xml
Java related code is as follows:
System.setProperty("log4j2.isThreadContextMapInheritable", "true");
String renameCsvFile = new String( inputDir.getName() + StaticUtils.SEPARATOR +"log"+ StaticUtils.SEPARATOR + "rename");
ThreadContext.put("module3", renameCsvFile);
rename_logger = LogManager.getLogger("myrenamelog");
rename_logger.info("rename logging", "Timestamp","Level", "OrignalPath","RenamedPath","Status", "Message", "Layer#", "Thread#");
rename_logger.info("rename logging...", Instant.now(),"info",file.getAbsolutePath(),newName.getAbsolutePath(),"success"," ","Layer#",Thread.currentThread().getName());
I would suggest you upgrade to the latest release. Specifically, LOG4J2-2644, which was addressed in Log4j 2.12.1, should impact some of your performance times. However, as in LOG4J2-2792, some applications that rely heavily on filters might need to disable eagerly obtaining the location.
If after testing with a newer version you still have problems please create a Jira issue with Log4j. Ideally you should either provide a sample test suite to demonstrate the problem and/or a snapshot created with a profiling tool such as YourKit that can help identify the problem areas.

How can we disable the hibernate logs?

I am working on Hibernate project, But I have to write the logs into a file then both will combined(Hibernate log added in file) How can we disable the hibernate logs.
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.1</version>
</dependency>
Here are two approaches:
Setting the logging level to NONE should turn off all logging.
Since Hibernate uses the slf4j facade, you should be able to use the NOPLogger; see Get a dummy slf4j logger?.
Replace the log4j-core dependency with this:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.30</version>
</dependency>
I've used this but its not working for me:
java.util.logging.Logger.getLogger("org.hibernate")
.setLevel(java.util.logging.Level.OFF);
Yea, that won't work. According the the dependency in your question, you have selected the log4j as the backend. The code snippet above is configuring the java.util.logging logger ...
Look at the javadocs for the log4j classes.
This worked for me..
static {
// Initialized log4j2 Property and disable hibernate log
Configurator.initialize("LOGS", "Projects/log4j.properties");
Configurator.setLevel("org.hibernate", org.apache.logging.log4j.Level.OFF);
}

log4j and log4j-overslf4j both in classpath conflicts in LogManager

we are using log4j-over-slf4j for logging in our application. But one of jar dependency in our application(External to us) needs log4j specific class(org.apache.log4j.spi.RepositorySelector). So, I have added log4j also in our classpath and It was able to find that class,
But, then I start to face new issue, In my code, I am loading RepositorySelectorfrom LogManager,
LogManager.setRepositorySelector(repoSel, guard);
Now, instead of referring to log4j specific LogManager, It is referring to log4j-over-slf4j specific LogManager, due to which , I am getting below error in websphere server console.
Caused by: java.lang.NoSuchMethodError: org/apache/log4j/LogManager.setRepositorySelector(Lorg/apache/log4j/spi/RepositorySelector;Ljava/lang/Object;)V**
Please help me know, how can we remove the conflict, so that, It's able to refer proper log4j1.2.15 specific LogManager.
And, as jar which is using log4j is external to our system, we don't have much control over that.
Below is the complete stack trace.
Caused by: java.lang.NoSuchMethodError: org/apache/log4j/LogManager.setRepositorySelector(Lorg/apache/log4j/spi/RepositorySelector;Ljava/lang/Object;)V
at com.hsbc.es.logging.def.impl.log4j.Log4jLoggingTypeProvider.setContextualRepositorySelector(Log4jLoggingTypeProvider.java:117)
at com.hsbc.es.logging.def.impl.log4j.Log4jLoggingTypeProvider.<clinit>(Log4jLoggingTypeProvider.java:97)
at java.lang.J9VMInternals.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1887)
at com.hsbc.es.logging.LoggingTypeManagerFactory.discoverContextLoggingTypeManagerSPI(LoggingTypeManagerFactory.java:168)
at com.hsbc.es.logging.LoggingTypeManagerFactory.getContextLoggingTypeManagerSPI(LoggingTypeManagerFactory.java:98)
at com.hsbc.es.logging.def.LoggingTypeProviderFactory.getContextLoggingTypeProvider(LoggingTypeProviderFactory.java:49)
at com.hsbc.es.logging.def.LoggingTypeFactory.getDebugger(LoggingTypeFactory.java:58)
You can exclude the transitive log4j dependency from being imported by the dependency that includes it.
In your pom.xml you can tell update your dependency import in order to exclude log4j:
<dependencies>
<dependency>
<groupId>the.group.id</groupId>
<actifactId>the.artifact.id</artifactId>
<version>version-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

adding jXLS to my pom.xml seems to affect hibernate log level

Adding jXLS to my pom seems to affect my app Hibernate log level. The app will log hibernate DEBUG info at every second in the tomcat console (using eclipse).
I add these two dependencies:
<dependency>
<groupId>org.jxls</groupId>
<artifactId>jxls</artifactId>
<version>2.2.5</version>
</dependency>
<dependency>
<groupId>org.jxls</groupId>
<artifactId>jxls-jexcel</artifactId>
<version>1.0.3</version>
</dependency>
When I remove both, then everything will be ok. If I add any of them, then I get the DEBUG info in the console again.
Any idea why is this happening?! Logger is Log4j.
I found an answer in this post:
Disable logging with hibernate from maven
Adding file logback.xml with the described content solved hibernate logging problem.

How to use and configure logback in Adobe CQ5 projects?

I newbie in CQ5. I started my first project in CQ and I want to write any exceptions and debug info of project's components, services and servlets (in bundles) to log files in crx-repo (...\crx-quickstart\logs).
I want to use slf4j with logback implementation in my project.
I tried below steps:
Add dependencies in project's pom.xml
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.3</version>
</dependency>
Add logback.xml with configuration (loggers and appenders) to
project's bundle resource package.
Try to instantiate new logger in service (for example):
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
.....
#Component(metatype = true, label = "Some", description = "Sone service" ,
immediate = true)
#Service(SomeService.class)
public class SomeService {
private final Logger logger = LoggerFactory.getLogger(MyDao.class);
.....
logger.debug("debug");
logger.info("info");
logger.error("error");
......
}
These steps (It isn't work, of course) I gave an example because i don't know how really work with logback in Adobe CQ5. Any suggestions? I would be grateful for any help!
CQ does log to crx-quickstart/logs/error.log with its default configuration, and the underlying Apache Sling framework provides the necessary bridge so you just need to acquire an slf4j Logger and write to that.
The Java code of your SomeService example looks correct to me but in the pom you only need the slf4j-api dependency, with scope provided, as API and implementation packages are provided by the CQ runtime.
You can also have a look at a Sling sample like Slingbucks which will log to that error.log if installed on a default CQ instance.

Categories

Resources