Can't configure logging for executable jar - java

This is similar to this other question, although I already put the logging.properties in the executable jar and doesn't work.
I have a class (ReportGenerator) that has the following:
Logger logger = Logger.getLogger(ReportGenerator.class.getName());
logger.log(Level.INFO, "LOG THIS");
I'm using Netbeans so I put the logging.properties file in the path src/main/resources. It has this (among other things):
# default file output is in user's home directory.
java.util.logging.FileHandler.pattern = /my/folder/reports.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 10
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = OFF
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################
# For example, set the com.xyz.foo logger to only log SEVERE
# messages:
com.mypackage.ReportGenerator.level = ALL
The jar is generated using Maven, when decompressed I can see that the logging.properties is in the main folder of the jar. Along with the folder com where my class is.
-com
-mypackage
-ReportGenerator
logging.properties
...other things
When I run from console:
java - jar MyReportsJar.jar
It shows me the logs through the console. I want to log it to the file I set in the logging.properties.
What am I doing wrong?
How do I do it without setting the JVM java.util.logging.config.file param?

After dealing a few days against this and reading many resources on the Internet I came up with this solution:
I have to change the logging properties of the LogManager in the program. I can use the logging.properties file packaged in the .jar like this:
LogManager.getLogManager().readConfiguration(ReportGenerator.class.getClassLoader().getResourceAsStream("logging.properties"));
And then I can do the same as before to get the logger and log:
Logger logger = Logger.getLogger(ReportGenerator.class.getName());
logger.log(Level.INFO, "LOG THIS");
But I found very useful that you can specify another logging.properties file on runtime so my final code is this:
String logFile = System.getProperty("java.util.logging.config.file");
if(logFile == null){
LogManager.getLogManager().readConfiguration(ReportGenerator.class.getClassLoader().getResourceAsStream("logging.properties"));
}
Logger logger = Logger.getLogger(ReportGenerator.class.getName());
logger.log(Level.INFO, "LOG THIS");
That way, if I execute the jar as this:
java -jar MyReportsJar.jar
It uses the internal logging.properties file.
But if I execute:
java -Djava.util.logging.config.file=<external-logging.properties> -jar MyReportsJar.jar
it uses the external logging.properties file.

Related

Deactivate Geotools INFO logs in JAR

I am using Geotools (version 19.2) to fetch some features. To deactivate the Geotools logging (< SEVERE) I tried 2 things:
As I understood the logging documentation (documentation page):
Logging.getLogger("org.geotools").setLevel(Level.SEVERE);
Loading a custom logging.properties configuration
The configuration (logging.properties) looks like this:
# standard log level
.level = WARNING
handlers = java.util.logging.ConsoleHandler
## limit the messages that are printed on the console to >= WARNING!
java.util.logging.ConsoleHandler.level = WARNING
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.ConsoleHandler.encoding = Cp850
# do not use logging files!
java.util.logging.FileHandler.level = OFF
## just output geotools logs with level SEVERE!
org.geotools.level = SEVERE
Then I am loading the configuration using this code:
LogManager.getLogManager().readConfiguration(MyMainClass.class.getClassLoader().getResourceAsStream("logging.properties"));
Using both approaches I get NO logging output if I run my program in Eclipse. If I run my program as a JAR-file I get the following unwanted logging output:
Nov. 08, 2018 9:48:13 VORM. org.geotools.jdbc.JDBCDataStore
getAggregateExpression INFO: Visitor class
org.geotools.feature.visitor.CountVisitor has no aggregate attribute.
The INFO log resides from private Expression getAggregateExpression(FeatureVisitor visitor) in JDBCDataStore (see GitHub)
Any ideas why the logging configuration does not work for the generated JAR?
Using the JConsole (following answer on Suppress java util logging from 3rd party jar) I figured out that my logging configuration was overwritten by my Java installation's logging.properties file.
I tried to change the logging configuration in my main method which was wrong.
Initializing my custom logging.properties in a separate class and specifying the needed system property solves the problem!
Custom initialization class
public class CustomLoggingPropertiesLoader {
// Initialize the global LogManager
public CustomLoggingPropertiesLoader() {
try {
LogManager.getLogManager().readConfiguration(CustomLoggingPropertiesLoader.class.getClassLoader().getResourceAsStream("logging.properties"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
Use system property ("java.util.logging.config.class")
java
-Djava.util.logging.config.class=de.example.logging.CustomLoggingPropertiesLoader
-classpath [myclasspath]

Application specific log in tomcat 7 using JULI?

I'm using java system logging in tomcat 7, but no logging statements get written to the log. I've added this file to my WEB-INF/classes. The log file "new-xyz-test" gets created (so I have at least some of the config right) but its empty - no log statements get printed to it.
handlers=java.util.logging.ConsoleHandler, org.apache.juli.FileHandler
org.apache.juli.FileHandler.level=ALL
org.apache.juli.FileHandler.directory=${catalina.base}/logs
org.apache.juli.FileHandler.prefix=new-xyz-test-
java.util.logging.ConsoleHandler.level=ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
com.xyz.level=ALL
com.xyz.handlers=org.apache.juli.FileHandler
To configure JULI in the web applications you need have a logging.properties file in the WEB-INF/classes directory. If you use the default handlers, you may lose messages. You need to specify a prefix for the handler in your file.
handlers=1FILE.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
.handlers=java.util.logging.ConsoleHandler
1FILE.org.apache.juli.FileHandler.level=FINEST
1FILE.org.apache.juli.FileHandler.directory=/app-logs
1FILE.org.apache.juli.FileHandler.prefix=file-1
java.util.logging.ConsoleHandler.level=FINE
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
com.xyz.level=INFO
com.xyz.handlers=1FILE.org.apache.juli.FileHandler
com.abc.level=INFO
com.abc.handlers=java.util.logging.ConsoleHandler
A
handler prefix (e.g. 1FILE.) starts with a number, then has an arbitrary string, and ends with a period (.).
See more in Logging in Tomcat
Arguments in the JVM
If you are not running the Tomcat from the startup.sh or startup.bat, you need to specify:
The location of the general logging.properties for Tomcat (in the conf directory of Tomcat)
The manager org.apache.juli.ClassLoaderLogManager. This is important because allows you to configure
for each web application different loggin options. By default, a JVM process can only have a single configuration file.) ,
Similar to the next (I'm using eclipse):
-Djava.util.logging.config.file="C:\Users\Paul\workspaces\utils\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\conf\logging.properties" -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
By default, java.util.logging read the file that is included in the JDK or JRE, e.g.:
"C:\Software\jdk1.7.0_17\jre\lib\logging.properties"
Setting Tomcat Heap Size (JVM Heap) in Eclipse, for how to add arguments in the VM
are you sure that you write to the correct logger , i.e. Logger.getLogger("com.xyz")?
I think that you may got wrong when you wrote in logging.properties:com.xyz.level=ALL com.xyz.handlers=org.apache.juli.FileHandler in the case that you actually write to the logger Logger.getLogger(com.xyz.YourClass.class), that because in the logging properties file you should write the logger name which is in your case com.xyz.YourClass

Initializing log4j for a stand alone application

I'm a newbie to log4j. This is what I have . I have about 20 files in different packages in a STAND ALONE JAVA APPLICATION.
I am trying to use and write log files.
Following is my log4j.properties file which is in my class path:
log4j.appender.R = org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File = /ParentFolder/ChildFolder/application.log
log4j.appender.R.Append = true
log4j.appender.R.DatePattern = '.'yyy-MM-dd
log4j.appender.R.layout = org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %c{1} [%p] %m%n
Following is the code to initialize logging in my main method
final String LOG_FILE = "C:/eclipse_workspace/lib/log4j.properties";
Properties logProp = new Properties();
try
{
logProp.load(new FileInputStream (LOG_FILE));
PropertyConfigurator.configure(logProperties);
logger.info("Logging enabled");
}
catch(IOException e)
{
System.out.println("Logging not enabled");
}
In every java class of the application I have the following code
import org.apache.log4j.*;
private static final Logger logger = Logger.getLogger(TheActualClassName.class);
But I get the following warning messages when I run the app.
log4j:WARN No appenders could be found for logger (com.xxx.myApp.MainProgram.MyFileName).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
What am I doing wrong?? The log file "application.log" is not being generated
May need the following line:
# Set root logger level to INFO and appender to R.
log4j.rootLogger=INFO, R
The root logger is always available and does not have a name.
Since the version 1.2.7, log4j (with the LogManager class) looks for log4j.xml in the classpath first. If the log4j.xml not exists, then log4j (with the LogManager class) looks for log4j.properties in the classpath.
Default Initialization Procedure
LogManager xref
If you are going to use a file named log4j.properties, and it's on your application's classpath, there is no need to even call PropertyConfiguration or DOMConfigurator - log4j will do this automatically when it is first initialized (when you first load a logger).
The error message seems to indicate that your configuration is not being loaded.
Add the VM argument -Dlog4j.debug to your application to have log4j spit out a whole bunch of information when it starts up, which includes which files it tries to load and what values it finds in the configuration.
Raghu ,if you are using stand alone configuration for configuring log4j Properties then use can use BasicConfigurator.configure() method for solving your appenders issue.

Java Logging - where is my log file?

I'm having trouble finding my log files.
I'm using Java Logging - java.util.logging - in Eclipse 3.7.1 on Windows XP. The relevant lines of my logging.properties file are:
handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
.level=INFO
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
As far as I can figure out, after I execute these two lines:
Logger logger = Logger.getLogger("test");
logger.logp(Level.INFO, "myClass", "myMethod", "Alcatraz");
my log file should be in C:\Documents and Settings\[My Windows ID]\javaX.log where X is an integer.
I have 5 different java.log files in that directory, java0.log through java4.log, but none of them contain my log record or even a record with today's date on it. I did some googling and found Tracing and Logging which implies that my logs should be at a different location, c:\Documents and Settings\[My Windows ID]\Application Data\Sun\Java\Deployment\log. There is one file there, named plugin5581819941091650582.log, but it is essentially empty:
<?xml version="1.0" encoding="windows-1252" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
</log>
Its creation date is last week. (I'm not sure what process created it; I certainly didn't create it explicitly.)
So where is my log file then? I can't think of anywhere else to look.
Also, does anyone know when changes to logging.properties take effect? If I changed the log level or the FileHandler.pattern, what would have to happen before my program saw the changes? Simply saving the changes in logging.properties is clearly not enough. Will I need to restart Eclipse? Or reboot the computer? Just curious. That's not nearly as big a deal to me as finding out where my log file actually is.
Where is your logging.properties file located? It should be available in the root of the classpath. As a sanity check, what does the following code print?
System.out.println(getClass().getClassLoader().getResource("logging.properties"));
If the code is in a static context, use
System.out.println(ClassName.class.getClassLoader().getResource("logging.properties"));
Location of log file can be control through logging.properties file. And it can be passed as JVM parameter ex : java -Djava.util.logging.config.file=/scratch/user/config/logging.properties
Details:
https://docs.oracle.com/cd/E23549_01/doc.1111/e14568/handler.htm
Configuring the File handler
To send logs to a file, add FileHandler to the handlers property in the logging.properties file. This will enable file logging globally.
handlers= java.util.logging.FileHandler
Configure the handler by setting the following properties:
java.util.logging.FileHandler.pattern=<home directory>/logs/oaam.log
java.util.logging.FileHandler.limit=50000
java.util.logging.FileHandler.count=1
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.FileHandler.pattern specifies the location and pattern of the output file. The default setting is your home directory.
java.util.logging.FileHandler.limit specifies, in bytes, the maximum amount that the logger writes to any one file.
java.util.logging.FileHandler.count specifies how many output files to cycle through.
java.util.logging.FileHandler.formatter specifies the java.util.logging formatter class that the file handler class uses to format the log messages. SimpleFormatter writes brief "human-readable" summaries of log records.
To instruct java to use this configuration file instead of $JDK_HOME/jre/lib/logging.properties:
java -Djava.util.logging.config.file=/scratch/user/config/logging.properties
The .log file is in your \workspace\.metadata folder. I'm using Eclipse 4.2.
The root cause of the problem the questioner is having is that his logging.properties file is not being read.
The file specified in java.util.logging.config.file is not read from the classpath. Instead it is read from the file system relative the current directory.
For example, running the following command java -Djava.util.logging.config.file=smclient-logging.properties SMMain will read the smclient-logging.properties from the current directory. Once the correct java.util.logging.config.file is read, the logs are generated as specified in the file.
It seems that the default location has changed. To find your logfile open the Java Console with your application. in there press "s". This prints out the System- and Deployment-Properties where you can find something like:
deployment.user.logdir = C:\Users\username\AppData\LocalLow\Sun\Java\Deployment\log
There you will find your logfiles.
If its null, then the file path would be your eclipse home directory. Your logging.properties file is not raken by the system, so point the properties file to the complete path as shown below then your log file will be generated in the place of directlyr where yor prefers it. -Djava.util.logging.config.file=D:\keplereclipse\keplerws\NFCInvoicingProject\WebContent\WEB-INF\logging.properties
Debug the your variable or logger.getHandlers(): just for the instances of FileHandler, and look for its private field: files
Make sure that your logger level including your log.
Make sure that your handler level including your log.
It will be sent to your home directory. If there's no that directory in your operate system, such as windows 95/98/ME, the file should be saved to the default path like C:\Windows\.
Reflect, the same as tip 1
Field[] handlerFiles = handler.getClass().getDeclaredFields();
AccessibleObject.setAccessible(handlerFiles, true);
for (Field field : handlerFiles) {
if (field.getName().equals("files")) {
File[] files = (File[]) field.get(handler);
System.out.println(Arrays.toString(files));
}
}
The log manager will be initialized during JVM startup and completed before the main method. You can also re-initialize it in main method with System.setProperty("java.util.logging.config.file", file), which will call LogManager.readConfiguration().

how to use log4j to write a file inside my project directory?

I have a log4j properties file which is creating a file inside my tomcat>bin folder but instead can it write the log file to my project's root dir? webapps>test>___?
Here is my log4j properties file contents.
#define the console appender
log4j.appender.consoleAppender = org.apache.log4j.ConsoleAppender
# now define the layout for the appender
log4j.appender.consoleAppender.layout = org.apache.log4j.PatternLayout
log4j.appender.consoleAppender.layout.ConversionPattern=%t %-5p %c{3} - %m%n
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.File=/test/a.log
log4j.appender.rollingFile.MaxFileSize=10MB
log4j.appender.rollingFile.MaxBackupIndex=2
log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=%p %t %c - %m%n
# now map our console appender as a root logger, means all log messages will go to this appender
#for console printing
#log4j.rootLogger = DEBUG, consoleAppender
#for file printing
log4j.rootLogger = DEBUG, rollingFile
Try replacing this:
log4j.appender.rollingFile.File=/test/a.log
with this:
log4j.appender.rollingFile.File=../webapps/test/a.log
Note (by Stephen C) - the "../" means this solution depends on whether or not the Tomcat launch mechanism you use makes $CATALINA_HOME the current directory before the JVM that hosts Tomcat. Some do, and some don't.
The log4j configurations understand "${catalina.home}", so ...
log4j.appender.rollingFile.File=${catalina.home}/webapps/test/a.log
However, I don't think it is a good idea to put logs into the webapps tree because they are liable to be blown away if your webapp is redeployed.
Put them in ${catalina.home}/logs instead.
Or better still, put them in the distro-specific conventional place to put application logfiles; e.g. "/var/spool/..." or "/var/log/...".
Putting logfiles in standard places means there are less places for someone else (e.g. the guy who is the backup sysadmin when you are on holiday) to investigate if the file system fills up with old logfiles.

Categories