SLF4J and LogBack configuration in GWT (Eclipse and Jetty) - java

I've made an app init function that I'm using both in Java and GWT applications. I have external logback.xml file that I'm setting the path to the "logback.configurationFile" System property. In pure Java projects, all works as expected, but not in GWT projects.
I've implemented my ServletContextListener and in method contextInitialized I'm setting the System property. Logback does not read it, but falls back to basic (red letters in console).
So, I tried to follow instructions from logback configuration
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
to reconfigure Logback, but that throws
java.lang.ClassCastException: org.slf4j.impl.SimpleLoggerFactory cannot be cast to ch.qos.logback.classic.LoggerContext
I also tried to put logback.xml in folders: src, war, war/WEB_INF, but it doesn't read it.
I'm switching to slf4j because previous log4j started to throw many "class not found" exceptions (something with commons-logging)
The question is:
What is wrong?
or
How can I get sfl4j (logback) to read the external configuration XML file?
or
How can I get sfl4j (logback) to read any configuration XML file?
Help appreciated
EDIT: Tried to use log4j adapter with slf4j, and it doesn't work either.
EDIT2: I reverted back to pure log4j that didn't work before. However, I added log4j.jar directly in "Installed JRE" in Eclipse in the main system JRE and now the pure log4j works. What seems to me is that there is quite a difference between the OpenJDK and the Sun's JDK, and that is causing problems. I'll try to fix this slf4j issue in a few days. Maybe there is also a need for some jar on some weird place.
EDIT3: slf4j now works with log4j, but I have to manually configure it. Doesn't matter where I put log4j.xml, it doesn't read it. Looks like classloader problem with Sun's JDK. I'll try with Logback soon. It might be similar problem.

I have logback working in my gwt,eclipse, jetty projects. works quite well. Kind of worked out of the box. I am using maven. What I did is:
add slf4j-api and logback as a dependencies.
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.0</version>
</dependency>
in my code I get a logger by using:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
protected Logger log = LoggerFactory.getLogger(this.getClass());
The logback.xml is in my src/main/resources folder. This way it will be placed in target/myproject/WEB-INF/classes after beeing compiled.
Hope this will help you.

There are a number of possible configurations with jetty, slf4j, and logback.
It really depends on what you are trying to accomplish.
1) Having the webapp itself do its own logging to logback.
2) Having a global log at the server level that logs the server events and webapp events to logback.
3) Having a global logback configuration at the server level that creates a log file for the server and individual log files for each webapp.
To accomplish #1, you just have to put the slf4j and logback files in your webapp's WEB-INF/lib directory and deploy the webapp. (be sure you put the configuration files in the webapps WEB-INF/classes or WEB-INF/ directory)
To accomplish #2 and #3 you need to let jetty know that slf4j and logback should be exposed to all webapps, and that all webapps, regardless of the existence of their own (potential) slf4j and logback jars, they are to always use the jar files from the server.
This is done by manipulating the WebAppContext's list of systemClasses and serverClasses via the default web
Slf4j is permitted through the webapp classloader barrier on Jetty, but logback is not.
This can be defined statically in the context/*.xml deployable, or dynamically via a DeploymentManager binding. see the jetty-webapp-logging module on jetty.codehaus.org for details on how to accomplish this (I would link you do this, but codehaus is undergoing a server migration ATM)
So, i gist'd the relevant file here - https://gist.github.com/1409147
package org.mortbay.jetty.webapp.logging;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppLifeCycle;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.webapp.WebAppContext;
public class CentralizedWebAppLoggingBinding implements AppLifeCycle.Binding
{
#Override
public String[] getBindingTargets()
{
return new String[]
{ "deploying" };
}
#Override
public void processBinding(Node node, App app) throws Exception
{
ContextHandler handler = app.getContextHandler();
if (handler == null)
{
throw new NullPointerException("No Handler created for App: " + app);
}
if (handler instanceof WebAppContext)
{
WebAppContext webapp = (WebAppContext)handler;
webapp.addSystemClass("org.apache.log4j.");
webapp.addSystemClass("org.slf4j.");
webapp.addSystemClass("org.apache.commons.logging.");
}
}
}
To accomplish #3 you'll need to setup a slf4j MDC handler and sift logging in logback that uses the MDC information to route the appropriate logging event to the logfile of your choice.
I blogged about this at http://webtide.intalio.com/2011/08/sifting-logs-in-jetty-with-logback/ and have example projects for basic logback, sifted logback, and even how to use the logback-access module for NCSA access logging at https://github.com/jetty-project/jetty-and-logback-example

Logback looks for its configuration files in the classpath, not in the file system.
To get to a configuration file in the file system, use file inclusion as described at http://logback.qos.ch/manual/joran.html#fileInclusion. Note that the filename can refer to an environment variable if it makes it easier to point to the file system location of the file.

I am also faced the same problem, found slf4j-simple.jar in the pom/class path. Once it was removed, working fine.

Related

OWSAP ESAPI logging support in logback in spring boot

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.

Ignore dependency log4j.properties

I have a web application deployed on WildFly 10. After adding a new Maven dependency to my application, logging stopped working. Investigating, I've found that the new dependency includes a log4j.properties in its JAR, and I guess this is causing the logging to screw up.
I cannot delete the file from the JAR, since every time my project compiles it would come back. I need WildFly to manage the logging properties, so adding an additional log4j.properties isn't an option (it would be if it can be configured to fallback to WildFly defaults, but I don't know if this is possibile).
How can I ignore a dependency's log4j.properties or override it with WildFly's settings?
If your app does not use is own log4j properties file or xml, you are best just disabling the per-deployment logging configuration option on wildfly, then any will be ignored
You can exclude Logging module from you jar.
dependencies {
compile group : 'com.chapter1' name: 'common.all', version: '1.0.001'{
exclude( // here u can exclude that module... )
}
In WildFly 10 you can set the use-deployment-logging-config on the logging subsystem to false which will skip processing any logging configuration files. Do note this will skip processing on all deployments.

Log4J does not log anything

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>

removing commons-logging and using slf4j causes errors in spring

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.

Disabling logging for jetty run from maven

I downloaded a big framework which I need to built from source. The project uses a maven build structure, and includes a demo application which can be viewed with an embedded jetty. Maven plugins handle all this stuff.
However when I run the demo application (with mvn jetty:run), I can't really use it because for some reason logging on the DEBUG level is turned on and the application spends most of its time logging a lot of statements. Responsiveness is reduced to almost nothing.
The framework (geomajas 1.5.0) seems to use SLF4J, but I can't figure out where it is configured or where it can be turned off.
Any ideas welcome... thanks!
Update:
Apparently they use logback. I found the configuration file (logback.xml), in which I edited out the DEBUG levels and replaced them with ERROR
To make sure the changes would propagate, I cleaned the project and rebuilt it. But the issue remains!
I manually looked at the logback.xml files in the target folder, and they've updated. But I still see the log records!
Update 2
I'm on Windows 7 btw.
The simplest and most straight forward way to disable logging would be indeed to use the NOP binding. To do so, edit geomajas/geomajas-dojo-example/pom.xml and change the logging dependencies into:
<!-- logging dependencies, delegate all to slf4j and use logback -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.5.8</version>
</dependency>
And run mvn jetty:run.
looking at this slf4j manual/overview http://www.slf4j.org/manual.html it looks like you could turn off all logging by using the slf4j NOP jar (slf4j-nop-1.5.10.jar). So you'd probably need to find and replace the current slf4j implementation jar in your projects WEB-INF/lib folder with the NOP jar.
Though most likely it's using a log4j implementation, if that's the case you'd need to find the log4j.xml or log4j.properties and edit/remove them. They could be tricky to find though - first look in WEB-INF/classes and then in some sort of config directory would be a good start.
EDIT {
A bit ugly but if you just want to get it up and running as fast as possible you could redirect stdout and stderr to /dev/null which should make it a bit faster as it won't be writing to disk or console:
mvn jetty:run > dev/null 2>&1
}
HTH
Try to find out a log4j configuration (if it is used for logging) - that might be log4j.xml (or log4j.properties) file. If you remove this file from classpath there will be no logging at all. If you want to reduce level of logs try to comment out some logger sections in this file, like e.g.
<!--<logger name="org.hibernate">
<level value="debug"/>
<appender-ref ref="hibernate-file"/>
</logger>-->
For this example there will be no logs for classes from org.hibernate package.
Geomajas uses logback for the sample applications. You can configure the logging using the logback.xml file in src/main/resources.
Switching everything off can be done using a config file like:
<configuration>
<root>
<level value="OFF"/>
</root>
</configuration>
Kind regards,
Joachim

Categories

Resources