I am trying to get DropWizard to log to an output file. The file is being created but nothing written to it.
In fact it would appear that the configuration in the provided .yml file is not being used.
I am also getting the following warnings during startup, not sure if they are related:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/conor/.m2/repository/ch/qos/logback/logback-classic/1.1.3/logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/conor/.m2/repository/com/conor/project/project-common/0.1-SNAPSHOT/project-common-0.1-SNAPSHOT.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
How can I get dropwizard to pickup the logging config in the yml provided at startup and how can I figure out where the current config is coming from? Thanks.
UPDATE::
I am running DropWizard v0.9.1 and my logging configuration is as follows:
# Logging settings.
logging:
# The default level of all loggers. Can be OFF, ERROR, WARN, INFO, DEBUG, TRACE, or ALL.
level: TRACE
# Logger-specific levels.
loggers:
# Sets the level for 'com.example.app' to DEBUG.
io.dropwizard: INFO
# Redirects SQL logs to a separate file
org.hibernate.SQL:
level: DEBUG
# Logback's Time Based Rolling Policy - archivedLogFilenamePattern: /tmp/application-%d{yyyy-MM-dd}.log.gz
# Logback's Size and Time Based Rolling Policy - archivedLogFilenamePattern: /tmp/application-%d{yyyy-MM-dd}-%i.log.gz
# Logback's Fixed Window Rolling Policy - archivedLogFilenamePattern: /tmp/application-%i.log.gz
appenders:
- type: console
- type: file
threshold: DEBUG
logFormat: "%-6level [%d{HH:mm:ss.SSS}] [%t] %logger{5} - %X{code} %msg %n"
currentLogFilename: output/logs/dropwizard.txt
archivedLogFilenamePattern: output/logs/dropwizard-%d{yyyy-MM-dd}-%i.txt.gz
archivedFileCount: 10
timeZone: UTC
maxFileSize: 10MB
This looks like a typical SLF4J binding issue and is solved easily. First take a look at the relevant section in the URL provided with the warning for an explanation.:
The warning emitted by SLF4J is just that, a warning. Even when multiple bindings are present, SLF4J will pick one logging framework/implementation and bind with it. The way SLF4J picks a binding is determined by the JVM and for all practical purposes should be considered random. As of version 1.6.6, SLF4J will name the framework/implementation class it is actually bound to.
Embedded components such as libraries or frameworks should not declare a dependency on any SLF4J binding but only depend on slf4j-api. When a library declares a compile-time dependency on a SLF4J binding, it imposes that binding on the end-user, thus negating SLF4J's purpose. When you come across an embedded component declaring a compile-time dependency on any SLF4J binding, please take the time to contact the authors of said component/library and kindly ask them to mend their ways.
Since the binding choice is random, my guess is that the project-common SLF4J dependency is being bound and not the intended one from logback-classic, a transitive dependency of dropwizard. You should either exclude the one in the project-common in your Maven pom file or better yet, if you have access to the code to project-common, remove it from the pom file as the linked-to web page suggests (i.e. "mend their ways").
From the Exception, I think you are using the two different version of logback classic both in class path which arise the conflicts. Try to find out the jar which are included two times but different version and remove one of them. If you are using the Maven to manage the dependency exclude the jar using the tag
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>the version you want to remove</version>
</exclusion>
</exclusions>
Related
Is there OWSAP ESAPI logging supported in logback for spring boot application? I did a lot of research but could not find much on this. I found out that org.owasp.esapi now supports this after this PR . But this means that I will have to do away with logback. Is there a way that I can implement OWSAP ESAPI logging using logback? We are using slf4j logger that logback provides.
I looked at logback's maven page and there has not been any major release since 2017. So I am guessing that logback does not supports OWSAP ESAPI logging. Please correct me if I am wrong. If that is the case are there any alternatives I can use?
Also according to this spring-boot does not support slf4j 1.8 and above.If that is the case are there any alternatives I can use?
I found out that org.owasp.esap actually delegates the actual logging to our existing infrastructure. So all I had to do is add the correct package and it automatically takes care of the logging via whatever config I have in logback.
Add the esapi dependency to pom.xml
<dependency>
<groupId>org.owasp.esapi</groupId>
<artifactId>esapi</artifactId>
<version>2.2.0.0</version>
</dependency>
Add the ESAPI.properties file to src/main/resources/. This file contains the config properties for the ESAPI logger. Since I was using Slf4j looger, I set ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory in the file.
Now we can use the ESAPI logger for logging which internally will use the Slf4j logger. As the function definition of the ESAPI logger has an extra argument I had to update all the logger functions accordingly.
For me, the solution was:
Add the next code to my pom.xml
<dependency>
<groupId>org.owasp.esapi</groupId>
<artifactId>esapi</artifactId>
<version>2.2.0.0</version>
</dependency>
Add ESAPI.properties and validation.properties files to src/main/resources/, I took them from this post, of Vaquar Khan answer.
Update the property ESAPI.Logger in the file ESAPI.properties with this code of AshwinSreekumar:
ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory
I hope it will help you, because in my case, I had to do some extra steps to make it work.
Eclipse, Selenium, Windows
The import org.apache.log4j cannot be resolved
I have followed all the documented steps I can find, i.e.:
1) the following two jar files are in the project build-path:
log4j-core-2.6.2.jar and log4j-api-2.6.2.jar
2) the above two jar files are located in the following folder:
C:\eclipse\apache-log4j-2.6.2-bin
3) The above folder is in my system CLASSPATH environment variable C:\eclipse\apache-log4j-2.6.2-bin
4) The project contains the following log4j.properties file in the project root
# This sets the global logging level and specifies the appenders
log4j.rootLogger=INFO, theConsoleAppender
# settings for the console appender
log4j.appender.theConsoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.theConsoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.theConsoleAppender.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
5) I have cleaned the project
6) failing import is: import org.apache.log4j.Logger;
Intermittently I am also getting this error message
"The type org.apache.log4j.Logger cannot be resolved. It is indirectly referenced from required .class files" at the first line:
package com.example;
This error disappears when I do a project -> Clean
but the error on import of log4j persists.
Any thoughts would be greatly appreciated.
If you are getting this error it means your application or one of its dependencies uses the Log4j 1.2 API.
The org.apache.log4j package is the Log4j 1.2 namespace. Log4j 2 uses the org.apache.logging.log4j namespace. Log4j 1.2 became End of Life in 2015 and users are recommended to upgrade to Log4j 2.
You already have the correct log4j-api-2.x.jar and log4j-core-2.x.jar in your classpath, the only thing missing is the log4j-1.2-api-2.x.jar. log4j-1.2-api is an adapter module that ensures your application's calls to the Log4j 1.2 API are delegated to the Log4j 2 implementation.
Please ensure the old log4j-1.2.x.jar is removed from the classpath.
Finally, the configuration you showed seems to be for Log4j 1.2 and will not work with Log4j 2. The Log4j 2 manual has many example configurations. (The documentation alone is reason to upgrade, it is so much better in Log4j 2.) See for example the section on the Console appender or the File appender.
Log4j 2 also supports a properties configuration format (but the syntax differs from the log4j 1.2 properties format).
Check your Eclipse version and log4j dependency version. If 1.2.17 is not working then check using 1.2.16.
Can anyone tell me the difference between slf4j-log4j and log4j-over-slf4j? Which is more standard to use in a Java web application? I currently have both on the classpath and that is causing a runtime exception as the web server is trying to prevent a StackOverFlowException from happening.
Exception:
java.lang.IllegalStateException:
Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path
slf4j-log4j is using log4j as an implementation of slf4j.
log4j-over-slf4j causes calls to the log4j API to be 'routed' to slf4j.
You cannot use both of these JAR's at the same time.
Both are valid libraries to use and are equally 'standard', it depends on the project.
In general, if your project is using log4j already and you don't have the ability to update all of your log4j Loggers to slf4j Loggers; log4j-over-slf4j is a quick fix to be able to start using slf4j immediately.
However, if your project is new or does not have an existing logging mechanism and you choose to use slf4j, slf4j-log4j would be the way to go as it is just specifying slf4j should be bound to log4j.
That being said, I agree with c12's comment. Stop using log4j and instead use slf4j and logback.
in my project , org.slf4j.impl.Log4jLoggerFactory is in
activemq-all-5.7.0.jar
not in slf4j-log4j12.jar
the exception message mislead me
I just picked up an existing web application at work that is supposed to log its activity using Log4J. I've configured my workspace exactly as I was told to and everything else (db connection, authentication, etc...) works fine except that the nothing is being written to the log file. Other similar applications have no problem logging.
I've looked at the WebSphere console when the application starts up and there are no errors there that might indicate why Log4J isn't logging.
I mentioned this to another dev (who once worked on this application, but not for a while and is more out of date than I am on it) who remarked that it was very strange behaviour, but had no idea why it might fail to log and not report any errors.
I've gone over the config file and properties file and everything looks OK. I suspect that Log4J is never even reading the log4j.xml but I'm not certain of that. It's been a while since I've worked with Log4J - does anyone have some good tips on trouble-shooting this type of problem?
PS: There are instances of this application that are deployed to various test/QA/prod servers and these instances all log fine. It's only on local workstations that logging seems to silently fail.
Update: So it does seem to be a problem with the way the application is being deployed.
I changed the classloader mode to "Parent Last" and I can see that the Log4J file is at least being read now. And the first action I attempt triggers a ClassNotFoundException saying that org.apache.commons.logging.impl.Log4jFactory cannot be found.
2nd Update:
I've noticed something stranger... The application has two WAR projects - one of them is for the UI and the other is for some web services. The project that is for the UI is successfully logging its operations to the log file. The web service project is the one that fails with the ClassNotFoundException. Both of them have commons-logging.jar listed as a JavaEE module dependency, and neither of them have a project-specific logging configuration (all config files are in a Resources project).
A major difference is that that UI project includes some other in-house frameworks (pre-compiled as JARs) that might already include necessary logging configurations and maybe that's where the difference is.
I also tried to use the answer (a file named org.apache.commons.logging.LogFactory in the META-INF/services with one line containing: "org.apache.commons.logging.impl.Log4jFactory") from this question: Websphere all logs are going to SystemOut.log but it did not seem to help.
See this answer:
How to initialize log4j properly?
-Dlog4j.debug is very useful for problems like this
The most recent thing I changed that finally got logging working properly was changing the classloader mode to "PARENT_FIRST" and WAR classloader policy to "Application". The initial default configuration was "PARENT_FIRST"/"Module". I changed it to "PARENT_LAST"/"Application" on the advice of a co-worker who says logging works fine for them and this is the only change they have to make when they create a new sandbox for this application. I'm not sure why I had to go with "PARENT_FIRST"/"Application", but at least it works now.
UPDATE:
I tried setting up a new workspace and I had the same problem. It turns out you need "PARENT_FIRST"/"Application" AND a file named org.apache.commons.logging.LogFactory in the META-INF/services with one line containing: "org.apache.commons.logging.impl.Log4jFactory". Not having the file causes logging to fail (typically with a message saying that a Log4J cannot be found).
just my two cents - i had something like this happening - but in my case i could see some output from my logging calls. it was just apparent that the configuration was picked up from somewhere else, and the one i was changing didn't have any impact.
after turning on -Dlog4j.debug=true as suggested here, it was evident that log4j was picking up a file named log4j.xml situated inside my tomcat's work directory. either it was a leftover from other stuff i was doing, or it was generated somehow from some log4j configuration in one of my misconfigured libraries.
i haven't thought of erasing the contents of work directory (could have tried.. [edit: i tried and it didn't work]) - the only thing i though of was to pass hardcoded reference to my properties file through -Dlog4j.configuration=log4j.properties (didn't want to use absolute path) (it happened that i was using a properties file and not an xml) - and it worked.
[edit: well, it didn't work for the server configuration. I finally found what was wrong - some home-cooked libraries that I was including as JARs into my project, had their own log4j.xml and log4j.properties files, which were apparently read/found earlier than my own properties file - the rightest thing was to delete these redundant property files from JARs]
I realize this isn't your exact same symptom, but there are known issues with log4j if your application (or anything it uses) uses Commons Logging. See if this question/answer is relevant.
I had a problem where log4j was not showing anything in one of my projects. Turned out I had added a leading space in the classname in the log4j2.xml file. Log4j does a dictionary lookup by classname. So any leading or trailing space in the classname would render that particular entry invalid.
not able to create log file, i have used logback.xml file in spring webservice application and deployed into websphere server...But when i have used log4j.properties file it is creating log file . i have given proper dependency proper for log4j and slf4j.. logback.xml file
<file>C:/abc/myLogFile.log</file>
<append>true</append>
<encoder>
<pattern>%d [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder></appender>
`
dependency:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
Specifically, I use spring only for configuring my project through ApplicationContext. In my spring xml I load some bean properties through PropertyPlaceholderConfigurer. Whenever in the dependencies I swap commons-logging-x.x with jcl-slf4j.jar the loading of the context fails with ClassNotFoundExceptions on the placeholder substitutions. Example:
In my spring.xml there is:
<bean id="testbean" class="${testbean.implementingClass}"/>
where testbean.implementingClass is defined in spring.properties:
testbean.implementingClass=my.implementation.TestClass
If I run the project using commons-logging jar all works perfectly. If I change it to jcl-slf4j then I get ClassNotFoundException that the class [${testbean.implementingClass}] was not found, i.e. it does not do the placeholder substituion. Has anyone observed this?
EDIT: My problem doesnt have to do with the jars because:
From http://www.slf4j.org/legacy.html :
Our JCL over SLF4J implementation will allow you to migrate to SLF4J gradually, especially if some of the libraries your software depends on continue to use JCL for the foreseeable future. You can immediately enjoy the benefits of SLF4J's reliability and preserve backward compatibility at the same time. Just replace commons-logging.jar with jcl-over-slf4j.jar. Subsequently, the selection of the underlying logging framework will be done by SLF4J instead of JCL but without the class loader headaches plaguing JCL. The underlying logging framework can be any of the frameworks supported by SLF4J. Often times, replacing commons-logging.jar with jcl-over-slf4j.jar will immediately and permanently solve class loader issues related to commons logging.
When you use jcl-slf4j, you have to make sure you have excluded all commons-logging dependencies from your project. Make sure there is no commons-logging jar anywhere in the classpath.