What is the SLF4J equivalent to Log4j's "-Dlog4j.debug" option? - java

I have a J2EE application running under GF2 and OS X 10.8.4 which has suddenly, and without an y apparent cause stopped logging all of the information my team expects it to.
When deployed under Windows or Linux this issue does not occur. We suspect that it is either an OS update or some issue with the logging subsystem.
The application uses SLF4j and I would like to know what it's doing and where it might be getting its properties from. Under log4j there is an option "-Dlog4j.debug" which writes to STDOUT and tells where it is loading its properties from. Is there an equivalent option in SLF4J?

slf4j is just a facade - an common API - for any of several different logging backends. How to do what you want, depends on which backend you use. E.g. logback has the debug attribute in the configuration file telling it to log verbosely what it is doing.
The best approach for slf4j in a web application is to use the jdk14 bridge, allowing you to directly use the glassfish logging system. As a web application is not allowed to directly use the underlying file system this is the only way you can be fully compliant and still log.

Related

How to control log rotation for Jetty Runner web apps

I'm using jetty-runner.jar version 9.4.28.v20200408. When I run java jar command, I got this output:
Usage: java [-Djetty.home=dir] -jar jetty-runner.jar [--help|--version] [ server opts] [[ context opts] context ...]
and the server opts include this entry
--out file - info/warn/debug log filename (with optional 'yyyy_mm_dd' wildcard
So I have used this expression
yyyy_mm_dd_${API_NAME}-${PORT}-http.log
The logging is working with yyyy_mm_dd but the old entries can't be deleted automatically. Is there a way I can control this?
Note: jetty-runner is deprecated and is being removed.
https://github.com/eclipse/jetty.project/commit/a1b38fadb836f768af6a2cb348d1687715381b25
jetty-runner is for quick testing of your webapp, and is not recommended for production use, purely because it's not setup for customization and configuration just like you are experiencing now.
It's essentially a hardcoded configuration, with a scant few knobs you can tweak.
Logging is hardcoded to use internal Jetty StdErrLog and Jetty RolloverFileOutputStream. Neither of which support what you are attempting to do.
If you move to pure embedded-jetty, where you control things, or use the proper ${jetty.home} and ${jetty.base} split, then you can specify any slf4j based logging implementation you want, along with all of the custom logging behaviors you need (rollover, compression, triggers for rollover, old rollover file behaviors, etc).

What's the best approach in jar/library creation?

I need to create jar/library that does some stuff and writes some logs. For logs I was thinking about java.util.logging.Logger vs Logback. So the question is:
Should I prefer using java out-of-the-box logging or it's totally fine to include some third-party tools?
Or it should be purely the matter of my needs and which one to use doesn't really matter?
Use a facade, like slf4j. Think of it from the point of view of the person using your jar in their application. They will want all the logging going to one place, whether it is logging for your jar or for the rest of the application, they will not want to configure your library's logging separately.
Using a logging facade means your library writes to whatever log the rest of the application uses. The application should be in charge of logging, not your jar.
For which facade to use, slf4j seems like a better choice, commons logging can get in trouble where multiple classloaders are involved. See Difference between Simple Logging Facade for Java and Apache Commons Logging
One can use System.Logger
System.Logger instances log messages that will be routed to the underlying logging framework the LoggerFinder uses. System.Logger instances are typically obtained from the System class, by calling System.getLogger(loggerName) or System.getLogger(loggerName, bundle).
Loggers across libraries always were a pain. Java.util.logging incorporated Logging into the Standard Edition. Since Java 9 there is a Standard Edition way to integrate loggers.
This leaves the choice to the library user. No longer a mix, version blues, etcetera. The exact logger in a straight application could be java util Logger.

Isn't it possible to configure logging INSIDE the application when using jboss AS 7.1.1.Final?

I read a lot but I couldn't figure out how I could specify for example the log level for specific classes.
Only way I could figure out was in the standalone.xml but why should I configure some application specific setting very general in the server? This complicates the deployment process unnecessary.
Isn't it somehow possible to define the specific log level and the output files somewhere inside the war without touching the server?
Btw. it doesn't matter if log4j or commons-logging or slf4j or whatever is used.
Using a logging.properties file or a log4j configuration file in your deployment will work in JBoss EAP 6.x and WildFly (formerly JBoss AS). Note though that a log4j configuration would only work if you use log4j for your logging facade.
That said I agree with Marko that this should probably be done in the server configuration. I would also encourage you to use the CLI or web interface rather than editing the raw XML as well. You can get some more information on the documentation.
I am sorry for not providing a direct answer, but consider this: the application being in charge of logging levels is a bad idea most of the time as this is something an AS admin should be able to change at any time. For example, the point of the DEBUG or TRACE log levels is to be able to place a lot of such statements in the code without hurting the production server's performance. However, once a bug is detected, you want to be able to lower the logging level without rebuilding the application. This should be a purely administrative task.
On the other hand, I do recognize the need to at least have a decent starting point for the logging configuration and I don't know of any architecture which would allow the application to provide defaults which are overridable by the server configuration.

log4j 2 - Change configuration at runtime for J2EE app

Currently we have J2EE applications that run on WebSphere and log4j 1.x is our company's standard for Java logging. We'd like to investigate the ability to change the log4j configuration xml file at runtime so we can change to the DEBUG level, for example, when problems are identified, and return to the ERROR level once those problems are cleared up and DEBUG is no longer needed. We'd like to do all this without having to recycle the application to reread the config file.
I see that DOMConfigurator.configureandWatch() is an available method that would allow the config file to be reread at runtime. However, because it spawns a separate thread that won't be shut down when the application is shut down, it is unsafe to run in a J2EE environment.
http://logging.apache.org/log4j/1.2/faq.html#a3.6
Does anyone know if this was fixed in log4 2? I haven't found anything definitive yet from the documentation and was curious if it is safe to change the config file at runtime in J2EE.
Re-reading the configuration file is not something you want to do in production. It means that you're changing resources which many app servers don't expect to change. Development environments can get away with it on the grounds that blowing up the app server isn't a big deal. It also means that your app might behave differently if it has to be restarted.
You're going to want to change the log levels programmatically. You can do this by using LogManager.getLogger() for the packages you care about. Once you have the logger, change the level to debug, and change it back when you are done.

LOG4J as a singleton, anyway to avoid log4j logging conflicts in web environment

We have a j2ee web environment. The server is configured to share session and possibly classloaders across multiple webapps. Basically, one classloader could server multiple web apps.
This seems to cause issues with log4j. Different webapps could have different log4j configurations but the logging will move to the same file.
Reading online, it looks like log4j uses singletons a lot, in terms of the appenders and other functionality.
Is there a way to completely separate the log4j configurations from one webapp from the other.
Server: websphere6+
Log4j: 1.4.2
Java: 1.5
Example log4j.properties (webapp1):
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=/usr/local/file1.log
log4j.additivity.com.app=false
Example log4j.properties (webapp2):
log4j.appender.Z=org.apache.log4j.RollingFileAppender
log4j.appender.Z.File=/usr/local/file2.log
log4j.additivity.com.app=false
Right now, logging from webapp2 may appear in the webapp1 logs and vice verse. We don't want that.
Possible Solution:
It might be possible to add a custom file appender? Would that fix the issue and what code would I add to the custom appender?
Is it possible to change the log4j initialization. E.g., could I use some startup servlet to load logj4 for each webapp.
You have two ways to solve your problem:
Configure your app. server so it doesn't share classloaders across multiple webapps. When it does do that, because of log4j's nature, only one log4j.properties file will be loaded.
If you leave the app. server so it shares classloaders, then use one "master" log4j.properties file. In it, define appenders for root of every one of your applications (example com.mycompany.webapp1, com.mycompany.webapp2)
No solution is perfect. Particularly, the second one will be problematic if your web apps share some classes that use log4j. In that case, logs from both apps will end up in the same file.
Your problem is a common one. To understand more about this topic, google for "log4j and j2ee".
Edit: since solutions 1 and 2 aren't feasible, you could try something else:
Use log4j.properties file per application. In every one of them, define an appender for their root (as explained in solution 2), and set additivity to false. This also won't be perfect if there is any class sharing between them.
Configure log4j programatically for every application. Since they're legacy applications, this could be tough. One way to do it is to use ServletContextListener for every application and configure log4j on application startup. I haven't personally tried this, so I'm not 100% sure if there will be clashes due to shared classloaders.
Log4j won't be really updated anymore. Ceki Gülcü, who created log4j, stated that he will focus his efforts on slf4j and logback, to correct some mistakes he did during development of log4j.

Categories

Resources