I have a 3rd-party developed big complex application full of java.util.logging.Logger#finer() calls.
Normally I use log4j and sl4j for logging, and I don't know very much of java.util.logging, even less about all the configuration details and possibilities.
Every single google about "java.util.logging" points to a full explanation about streams handlers, formatters, levels. Everyone assumes I really care about all this stuff (it is a reasonable assumption actually). But I couldn't care less.
I'm not really interested in separating logs per file, or file rotation, zipping, email, remote log etc. I'm also not concerned about log level and message formatting thrills.
All I want to do is to run this application with all available log messages spitting to stdout.
Is there an easy simple direct way to do this?
Something like jvmargs -Djava.util.logging.level=FINEST -Djava.util.logging.to=stdout.
Or maybe some simple file dropped into some location in the classpath?
All I want to do is to run this application with all available log messages spitting to stdout
Don't do this in production but it is the fast, easy, hacky way:
Edit the logging.properties file located in java/conf. E.G. /usr/lib/jvm/default-java/conf/logging.properties
That file is setup to attach a ConsoleHandler to the root logger which is what you want to do this. You just need to adjust the levels to see the output. This is a global change so be aware.
Edit that file and:
Change .level= INFO -> .level=ALL
Change java.util.logging.ConsoleHandler.level = INFO to java.util.logging.ConsoleHandler.level = ALL
Save the changes and restart your app.
The recommended way:
Most JVMs are not in your control (production/dev server) so you can instead copy that file to a location you own and use the java.util.logging.config.file system property.
E.G. -Djava.util.logging.config.file=/home/myuser/myapp/logging.properties
That way you are free to make changes that are local to your program and not global to the machine.
Related
I have an existing application that logs messages using the java.util.logging API. As far as I can see, there are no configuration files for it in the framework, though there is some code to create a file appender. When I run the application, I get log messages to the console and to a file.
Now, I need to incorporate a library that uses Log4j 2. When I do so, I lose the console logging from the main application (though log messages still get written to the file appender that is created programmatically).
I imagine that, since the file appender is working in the original application, that I can solve my problem by also programmatically creating a console appender in the main application. However, I don't know if that's right or a kludge.
So, my question: is there anything general that I need to know about making java.util.logging and Log4j 2 interoperate? If the original application is not coded properly or according to best practices, I can change it.
Now, I need to incorporate a library that uses Log4j 2. When I do so, I lose the console logging from the main application (though log messages still get written to the file appender that is created programmatically).
The
Log4jBridgeHandler will remove handlers if the install method is called from code. You can always print the log tree to see what handlers are attached or attach a tool like JConsole to inspect the logger tree with and without the 3rd party lib.
I imagine that, since the file appender is working in the original application, that I can solve my problem by also programmatically creating a console appender in the main application. However, I don't know if that's right or a kludge.
Programmatic configuration of the logger tree should be done with the LogManager config option:
A property "config". This property is intended to allow arbitrary configuration code to be run. The property defines a whitespace or comma separated list of class names. A new instance will be created for each named class. The default constructor of each class may execute arbitrary code to update the logging configuration, such as setting logger levels, adding handlers, adding filters, etc.
Create a stand alone named class that just installs the handlers in the constructor.
Set the java.util.logging.config.class system parameter to the name of your class.
Otherwise if you have a logging.properties you set config to your class name.
So, my question: is there anything general that I need to know about making java.util.logging and Log4j 2 interoperate? If the original application is not coded properly or according to best practices, I can change it.
The java.util.logging.LogManager can only see classes on the system class loader. In that case log configuration in code is required to gain access to the correct classloader.
It might be easier to remove all JUL configuration and bridge to Log4j2. You can then leverage the configuration needed through that framework.
I'm trying to write logs of multiple services to same file, but my rolling policy given is not working, tried with both time based and size based rollings. Thing is my services are running simultanously and writting there logs to same file in my local directory. When tried to write logs by single service it is working as expected.
Please help me to solve this issue tried with different rolling policies.
Appender to log to file
${LOG_FILE}
Minimum logging level to be presented in the console logs
INFO
${LOG_PATH}/archived/log_%d{dd-MM-yyyy}_%i.log
10KB
I had an experience similar to yours with Log4j 1.x then I debugged an appender back then (~5-6 years ago) and came to the following conclusions:
I don't think you can write data from multiple services into the same file. In other words,
Logging framework usually assumes that only it can change the file. In some Operating Systems (windows) it will even stop writing into file if some other process will rename / change the current file.
Of course its just a code and you could create a more sophisticated appeneder that will probable make it work, but frankly I don't think it worth the effort.
So I suggest writing into different files, where file name can be generated in a way that it will contain a pid of the resource. The downside of this method is that if the process dies and then re-runs, on-one will take care of the old resources.
Another approach (somewhat similar) - is to create a folder with logs for each service so that they'll get different logs based on folder (even if files in these folders will be with the same name).
I am writing a small xml transformation layer in Java. I receive xml via web service, modify it, and then send the modified xml to another system. I then wait for a response and return the response to the original caller.
System A -> Me -> System B -> Me -> System A
I want to log the request I receive, the request I send, the response I receive, and the request I send. Basically I want to log the xml where each arrow is in my diagram.
My problem is with the RollingFileAppender. I try to roll at 10MB, sometimes it does and sometimes it doesn't roll. If it rolls a couple times, and then stops, it will continue to rename the rolled files from 3 to 4 and 4 to 5 and so on.
My best guess is that when the 10MB mark is crossed, there are multiple threads writing to the log file so the file cannot me renamed. I am hoping that Log4J has an easy solution for this, but if necessary, I am open to switching to a new logging framework. Thank you in advance for any help.
EDIT
Here is my properties file.
log4j.rootLogger=DEBUG, fileOut
log4j.appender.fileOut=org.apache.log4j.RollingFileAppender
log4j.appender.fileOut.File=/logs/log.log
log4j.appender.fileOut.layout=org.apache.log4j.PatternLayout
log4j.appender.fileOut.layout.ConversionPattern=%d %-5p %c - %m%n
log4j.appender.fileOut.MaxFileSize=10MB
log4j.appender.fileOut.MaxBackupIndex=10
log4j.appender.fileOut.append=true
EDIT 2 This is essentially a bump, as this post has a low number of views. I feel like this cannot be a unique problem. Any help is much appreciated. Thanks!
Log4J initializes itself at the classloader level. Within a certain classloader and its ancestors, Log4J can only be initialized once and the same Log4J configuration applies to all Log4J calls within the classloader.
As long as all of your logging calls are performed within the same Log4J configuration "realm", Log4J knows how to synchronize access to the physical file pointed at by the rolling appender configuration; when the time comes to roll, rolling is performed with no problem.
Things become problematic once you have two (or more) Log4J "configuration realms" using the same physical file for the rolling appender configuration. That could be:
Two different web applications on the same physical JVM
Two different web applications on two distinct JVMs
Same web application horizontally clustered on two distinct JVMs
(etc)
Log4J simply has no way of knowing who else, other than itself within the same Log4J configuration realm, uses that file. So, what ends up happening is that Log4J on System A attempts to roll the file (because it thinks that no other processes are accessing that file), and fails because someone on System B is using the file at the same time.
This is a known limitation of using file appenders, and you can't really blame Log4J for this: Log4J simply doesn't have the means of monitoring who else, other than Log4J in the same "configuration realm", is using that file.
For such usage scenario, you can use the Log4J socket appender.
If your scenario doesn't involve multiple Log4J "configuration realms", then try adding -Dlog4j.debug=true to the JVM parameters and see what exactly is going on during the file rolling operation.
For others that arrive here, check you are using RollingFileAppender NOT FileAppender!
Cut and paste errors are too easy, for me at least.
I also faced the same issue in my application.
Thanks to #Isaac found that I was doing DOMConfigurator.configure for the same log configuration in 2 web applications deployed in the application server.
I commented one of them and rolling over happened as expected.
While creating an example using Java and the com.alvazan.orm.api library, the use of "System.out.println" is prohibited.
One of the first and most simple Java exercises learned is "Hello World", also using the
"System.out.println" (...also known as logging, or returned requested data found in the console?)
When using Eclipse, logging is turned off by modifying the logback.xml file (ctrl-shift-R and typing in logback.xml)
From there;
<logger name="com.alvazan.orm" level="WARN"/>
is the line to add to the logback.xml file so that only startup logs appear.
In addition, two more logs such as....
2012-09-14 22:05:08,067 com.alvazan.test.FactorySingleton createFactory
INFO: CREATING FACTORY FOR TESTS
2012-09-14 22:05:08,809 com.impetus.annovention.ClasspathDiscoverer processFile
INFO: adding folder to scan=file:/C:/AAROOT/workareas/area1/playorm/eclipsegen/
are used.
Just clarifying that all information is typed into the logback.xml file?
Is there a diffrent file to use(other than logback.xml)?
Or is the end-user to use, for instance, "com.alvazan.test.FactorySingleton createFactory"; and "com.impetus.annovention.ClasspathDiscoverer processFile"?
Finalizing this question, is the file path for the preceeding necessary?
Thanks for your time,
Ryan
In response to Brett, and additional information/questions,
How is your root logger configured? You are only setting WARN for com.alvazan.orm, so if your root logger is INFO, then com.alvazan.test INFO's will be logged.
Hey Brett, thanks for the reply...
As for the root logger configuration, I believe the value is set at "INFO".
That being said, I would want to set "INFO" to "WARN", to prevent the use of
"System.out.println"
Also in the previous question, I mentioned:
2012-09-14 22:05:08,067 com.alvazan.test.FactorySingleton createFactory
INFO: CREATING FACTORY FOR TESTS
2012-09-14 22:05:08,809 com.impetus.annovention.ClasspathDiscoverer processFile
INFO: adding folder to scan=file:/C:/AAROOT/workareas/area1/playorm/eclipsegen/
com.alvazan.test.FactorySingleton
and
com.impetus.annovention.ClasspathDiscoverer (diffrent package within same library)
Different locations found within the same library...
Do i need to do the logback process for the other files, or *package, or doing it one time within the same library, should suffice for all? Or do I adjust additional values?
Your first statement....
"While creating an example using Java and the com.alvazan.orm.api
library, the use of "System.out.println" is prohibited."
In general, no one uses in System.out.println. Hibernate does not, JBoss does not, tomcat does not. They all use a logging framework so you can configure each and every log in production and each company using tomcat or jboss or hibernate can configure it differently. If these programs use System.out.println, customers would have no control and your server would ALWAYS run slow as you NEVER want "all" logging and there is no way to turn System.out.println's off!!!!! they are always on. log.info can be turned off and on.
The most complete answer on configuring logback can be found in their documentation
http://logback.qos.ch/manual/configuration.html
Just clarifying that all information is typed into the logback.xml
file?
I am not sure what you mean by this question. logback.xml is the configuration for a logging library called logback which you can find at the link above.
Is there a diffrent file to use(other than logback.xml)?
logback has other options like a groovy file to configure it, but playOrm is using only logback.xml though any client can decide what configuration file they use since playOrm discards the logback.xml file that is checked in when delivering to other projects.
Or is the end-user to use, for instance, "com.alvazan.test.FactorySingleton createFactory";
and "com.impetus.annovention.ClasspathDiscoverer processFile"?
I am very confused by this question. The end user should not be using FactorySingleton(neither directly nor indirectly AND that class is not even in the jar because it's in the test package). The end-user will be using ClasspathDiscoverer only indirectly...in fact, end-user won't even know about these classes.
Finalizing this question, is the file path for the preceeding necessary?
Are you trying to ask is the file path in logback.xml necessary? If you want to know more about how logback works, you need to read alot of the documentation. Basically, you can do stuff like com.alvazan level=WARN to turn any classes in com.alvazan.** to warn level(This is recursive and applies to children, grandchildren, etc. etc.). The ROOT logger is always defined as well in logback.xml and is the level for ALL classes in a all packages unless overridden.
yes, the root logger in playorm is set to warn.
At the bottom of the picture you show(your picture is cut off so not in that picture), there is a "source" tab and you may want to click that to view the xml better and it would match up with logback's documentation better as well. Here is a link to the file I bet you are looking at..
https://github.com/deanhiller/playorm/blob/486079cfefbd2b4b79e99652b24c146572663dda/input/javasrc/logback.xml
root logger is clearly set to info and could be set to warn if you want.
So, what do you want. Do you want those two log statements to go away and be turned off? Do you want ALL log statements to be turned off except WARN?
If you want all to be turned off in ALL software libraries, just change the root logger to "WARN". If you want to turn just FactorySingleton off you can add this line
<logger name="com.alvazan.test.FactorySingleton" level=""WARN"/>
If you want all of com.alvazan logging turned off instead of just everything in com.alvazan.orm as you also want com.alvazan.test off as well, BUT you want all other libraries to still be on(BUT always want WARN on which you generally should want), then you could change this
<logger name="com.alvazan.orm" level=""WARN"/>
to the following instead
<logger name="com.alvazan" level=""WARN"/>
Your best bet to understand logback though is to read logback documentation.
How is your root logger configured? You are only setting WARN for com.alvazan.orm, so if your root logger is INFO, then com.alvazan.test INFO's will be logged.
hiho guys i want to ask you for the best practice (according to you) for writing a log in different files, for example i want info severity to be logged in info.log, debug severity in debug.log and so on... and no i dont want to use different Logger for each severity
We had an application that used to do this (separate log files per severity), and it ended up providing us no value.
All it ends up doing is A) complicating your debugging efforts, and B) taking up disk space.
Logging all severities to the same file is more convenient and easier to work with.