After a lot of attempts, I have am finally able to formulate a question. I hope it makes some sense and is easy to understand. Working on a web-application that uses Spring and Jersey. I am required to implement an application-wide logger that should log all the activities performed on the application into a database. For the time being I have used the HAS-A implementation and called the logging method everywhere a CRUD operation is performed. Something like this:
LogBean lBean=new LogBean("rickesh#email.com","update","address","127.0.0.1");
logToDatabase(lBean);
But this causes a lot of repeated lines of code and I have to repeatedly keep instantiating and calling the log method every section the CRUD operation in performed. Is there any way I can pull out the logging from the controller layer, the REST layer? Are there any specific functionality in Spring or Jersey with which I can perform logging on a separate layer and I don't have to keep repeating the same lines of code everywhere. Please advice.
If you are getting messy with writing your logs you should look into AOP. If you are already using spring you should read about Spring AOP, and for logging per se, read using Spring AOP for logging
AOP is a better way but if getting to learn it to resolve this issue is going to take longer then here is a simple alternative.
Add log4j JAR to your WebApp. Make sure, log4j version bundled in your WebApp doesn't conflict with the version already with your Application Server
Place a log4j.xml for FILE and CONSOLE appendars in your class path (src/main/resources)
There is a Log4JConfigureListener provided by Spring which you can declare under section in your web.xml
Additionally, if too much log is generated, you can limit the output of the loggers via either log4j.xml in your application to certain packages only or via using Root logger configuration for your project specific packages. For example, in JBoss you can add a "category" for a package at a specific LOG level
Your specific "separate layer" should have a separate and distinct package name to target the log appendars for that layer
Hope this helps!
Related
I want to put the configuration file of the log4j2 (v2.17.0) outside of the war file. Therefore, I can change the logging configuration without redeploying the war file. The log4j2-web.jar provides mechanism to configure the configuration file outside of the war file along with other features.
Unfortunately, I am not allowed to use the log4j-web.jar file in web application.
According to the log4j2 FAQ, it is not recommended to use LoggerContext to load configuration file because it is not part of the public API.
Question:
Is there any valid way to use log4j2 in the web application without log4j-web.jar file?
Question: Is there any valid way to use log4j2 in the web application without log4j-web.jar file?
There are two potential ways that you could dynamically update the logging configs without using log4j2-web.jar .
Ignore the FAQ's recommendation1 and use LoggerContext.reload to reload the configuration.
It is possible that the Log4j2 team could change something in a future version so that this approach no longer works. But this is unlikely (IMO) ... and you can deal with that problem if / when it happens.
Use Log4j2's automatic reconfiguration mechanism. Basically, you tell Log4j2 to regularly check the config file to see if it has changed.
However ...
If I was you, I would want to understand why you are "not allowed" to use "log4j-web.jar". Is it for security reasons? If it is, you may need to talk to the security people so that you fully understand the security reasons.
Q: Why?
A: Because you appear to be wanting to duplicate some of the functionality of "log4j-web.jar". It may be that it is the functionality you are trying to duplicate that is the root of your security team's concerns. And if that is the case, then implementing the functionality by hand (i.e. without using "log4j-web.jar") could potentially be worse ... from a security perspective!
So ... find out! This is NOT a case where "asking for forgiveness rather than for permission" is a sound strategy.
1 - Actually, I don't read this as a "recommendation". Rather, I read it as a "warning of potential consequences". If they really thought that using LoggerContext.reload this was a bad idea, I think they would have used more explicit language.
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.
I've been experimenting with different logging frameworks for use in a Java library I've been developing. I'd like to separate the logging configuration of the library from logging done by users implementing the library. I want users of my library to be able to specify their own LOG2J2 configuration and log their own information without it having ANY effect on the logging configuration of the library. The best way I can see to accomplish this is to have the library create and use it's own LoggerContext. I have two questions: Is it possible to create and use a special LoggerContext specifically for my library or is there perhaps an easier way to accomplish what I'm trying to do? Once I've created a LoggerContext and applied its configuration is it possible to somehow tie it back to the LogManager so that when I call LogManager.getLogger() from my library it will use my custom LoggerContext?
To try and put it simply, I want to separate the framework logging from the implementation logging. Similar to what is being described here. Unfortunately, that link seems to focus more on Web logging separation rather than application/framework logging separation.
Spring Boot's logging location can be set using the logging.file property in application.properties. However I want to set the location programmatically. My logic is not based on any Spring beans, only on trial-and-error because the same code has to run across different environments which may have different security configurations.
According to the documentation:
Since logging is initialized before the ApplicationContext is created, it isn’t possible to control logging from #PropertySources in Spring #Configuration files. System properties and the conventional Spring Boot external configuration files work just fine.) [sic]
So I know I can't use #Configuration files, but can I use some other way like a static initialiser and still manage to set the logging location programmatically?
(NOTE: I'm personally using SLF4J with Logback, but Spring Boot's logging framework is meant to cope with different logging facades/implementations and in fact uses Commons Logging internally.)
(NOTE 2: Some people have noted this as a duplicate of another question...but that question seems to be talking more about configuring the actual logging implementation, whereas this question is about Spring Boot's own configuration. In fact, I cannot immediately determine from those answers how to solve my specific question, as noted in a comment underneath the relevant answer. The answer to that other question focusses mainly on how to get the code to load at the correct point of context initialization, whereas my question is about how to set the logging location.)
There's another answer: Spring Boot programmatic logging configuration
Basically, it's possible to do that via the SpringApplicationInitializer (implementing ApplicationContextInitializer)
SpringApplication application = new SpringApplication(MySources.class);
application.addInitializers(new LoggingInitializer());
application.run(args);
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.