Setting configuration file with Log4j using slf4j-log4j12 - java

I know there is several answers for how to set the file. Non have worked with me.
I'm trying to unifying several conf files for that I need to set the conf of log4j provided in slf4j-log4j12 into the configuration file provided as parameter of the program. Till now I tried by setting as parameter of the jvm like:
java '-Dlog4j.configuration=conf.cfg' -jar my.jar
I'm getting back:
log4j:WARN No appenders could be found for logger (org.apache.commons.beanutils.converters.BooleanConverter).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
log4j:ERROR Could not parse file [].
Setting programatically by:
System.setProperty("log4j.configuration",(new File( Configurator.getDefaultConfig().getString(Const.LoggingDefaultLoggingFile))).toURL().toString());
and
System.setProperty("log4j.configurationFile",(new File( Configurator.getDefaultConfig().getString(Const.LoggingDefaultLoggingFile))).toURL().toString());
Same result.
I tried using DOMConfigurator but is for xml I'm using properties so no success.
I was searching how to reload the log4j but the give complex solution for making subscription for monitoring change and constant loading of changes.
I just want programatically change the configuration file once.
Till now, I was able to set the file just if I put it directly into the jar. But this by using a separated file with the default name.
Is there a way of loading the file directly int the Log4j (no shity system properties)? o there is a simple way of doing this better?

log4j looking for log4j.properties under WEB-INF\classes
PropertyConfigurator class,
example of usage:
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
// ...
public static final Logger log=Logger.getLogger(App.class);
// ...
PropertyConfigurator.configure("log4j.properties");

Related

Not able to print logs to Tomcat's CATALINA_BASE by using log4j2

I have update our code from log4j to log4j 2.17.1 And I want to stored the log file to servers under the Apache tomcat. I am using the log4j2.properties mentioned below.
When I run the code, then the logs file is printed in under code structure(see in below attached screenshot)but I want to print the logs file in QA-Servers under apache tomcat.
Please help me to solve the issue.
TL;DR: use ${sys:catalina.base}.
The property substitution in Log4j 2.x differs from Log4j 1.x (cf. documentation). The most prominent change is that:
in Log4j 1.x ${catalina.base} is looked up in Java system properties and, if the system property does not exist, in the configuration file,
in Log4j 2.x ${catalina.base} is looked up only in the configuration file.
In both cases if the property can not be resolved the placeholder is left unchanged.
In Log4j 2.x all external property lookups must be prefixed using an appropriate prefix. The exact equivalent of Log4j 1.x behavior is ${sys:catalina.base}. Therefore you can use:
# Fallback
property.catalina.base=.
appender.rolling.fileName=${sys:catalina.base}/logs/aseq_wiptmobile_qa-1.applog

How generate log files separated by apps running over websphere 9 ? I use java.util.logging to generate logs

I use websphere 9 application server to deploy war's and ear's, and use java.util.logging to generate logs into applications. I try to use properties file to configure the FileHandler of the LogManager, but websphere write ALL other logs on my file.
I not use log4j because i can't set log levels at runtime.
Is possible make differents file logs by application over websphere with java.util.logging ?
This is my properties file Logger.properties
handlers= java.util.logging.FileHandler
#java.util.logging.ConsoleHandler.level = INFO
#java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
# Set the default formatter to be the simple formatter
java.util.logging.FileHandler.formatter =java.util.logging.SimpleFormatter
# Use UTF-8 encoding
java.util.logging.FileHandler.encoding = UTF-8
# Write the log files to some file pattern
java.util.logging.FileHandler.pattern = C:/Users/pmendez/Documents/Log/testLogs.log
# Limit log file size to 5 Kb
java.util.logging.FileHandler.limit = 5000
# Keep 10 log files
java.util.logging.FileHandler.count = 10
#Customize the SimpleFormatter output format
java.util.logging.SimpleFormatter.format = %d [%t] %-5p (%F:%L) - %m%n
I try to use properties file to configure the FileHandler of the LogManager, but websphere write ALL other logs on my file.
Per your logging.properties you are attaching the FileHandler to the root logger. It would be expected to see log records from WebSphere because by default Logger::setUseParentHandlers is set to true.
Is possible make differents file logs by application over websphere with java.util.logging ?
You have to do one of the following:
Attach your FileHandler to the root logger of your application so the FileHandler is not attached to parent of the WebSphere application. Say application package is com.my.app.rules you can add entry of tocom.my.app.rules.handlers=java.util.logging.FileHandler and remove the attachment to the root logger. Next you demand the logger from code and pin it to memory so this package becomes the new root logger of your application code.
Create java.util.logging.Filter and install it on the FileHandler.
Turn off the logging for WebSphere. You can do this by setting the root logger to off and forcing all of your loggers to say info.
.level=OFF
com.my.app.rules.class1.level=INFO
com.my.app.rules.class2.level=INFO
com.my.app.rules.class3.level=INFO
It's possible set one FileHandler by app ?
The default java.util.logging.LogManager only supports one set of FileHandler settings. You can attach instances to various loggers but it doesn't allow for instances with different settings via the logging.properties. However, the LogManager does support per the documentation:
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.
So what you need to do is bundle a configuration class with your application that performs the needed FileHandler and logger configuration and modify your logging.properties to load it. One issue with this approach is that the LogManager can only see classes from the system class loader.
From jmehrens answer you can see it might be a bit difficult. Maybe you should consider switching logging to High Performance Extensible Logging (HPEL). It is just setting in the application server, so no changes in the applications code.
Then you could query logs for the given application using command line tool:
logViewer.sh -includeExtensions appName=PlantsByWebSphere
This would be much easier, if it fits your purpose. Moreover, generating separate log files is now not recommended, if you plan to move your apps in the future into containers/cloud or refactor them into microservices.
My solution to this isue was create a PersonalFileHandler to use on all Logger's. Properties are read from properties file called "Logger.properties", and invoque read this programmatically, same like this:
//Read config file
LogManager.getLogManager().readConfiguration(LoggerJUL.class.getResourceAsStream("/Logger.properties"));
//Add handler to logger
Logger.getLogger(clazz)).addHandler(new PersonalFileHandler());
PersonalFileHandler extends FileHandler, and properties are set by configure method on FileHandler class on runtime.

hadoop container stdout is always empty

Why is stdout file of a job container in hadoop is always of size 0.
On java
import org.apache.log4j.Logger;
static final Logger MAPLOGGER= Logger.getLogger(MyMap.class.getName());
MAPLOGGER.warn("key is :"+key);
after running jar, 3 files are generated
stderr, stdout,syslog
stderr contains
log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.impl.MetricsSystemImpl).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
where exactly MAPLOGGER.warn("key is :"+key); writes the log?.
It doesn't write it anywhere right now, because you have not set up log4j.
From the link in the WARN message:
"Why do I see a warning about "No appenders found for logger" and "Please configure log4j properly"?
This occurs when the default configuration files log4j.properties and log4j.xml can not be found and the application performs no explicit configuration. log4j uses Thread.getContextClassLoader().getResource() to locate the default configuration files and does not directly check the file system. Knowing the appropriate location to place log4j.properties or log4j.xml requires understanding the search strategy of the class loader in use. log4j does not provide a default configuration since output to the console or to the file system may be prohibited in some environments."
So you need to set up the log4j engine, and give it to Java overall, or explicitly declare their location in the application.

How can I determine what log configuration source Logback actually used?

log4j has a property, log4j.debug, which will helpfully provide the user with an indication of which configuration file was actually used to configure the logging system.
I haven't been able to find anything equivalent with the (otherwise superior) Logback logging framework. Is there any way to print (for diagnostic purposes) at runtime, which configuration file Logback used to bootstrap itself?
[edit]
To clarify, I'd ideally like a solution that doesn't require me to modify the configuration file itself (since a badly assembled third-party JAR, for example, may be picked up incorrectly, and prior to my logback configuration XML).
You can set a Java system property to output Logback debugging info:
java -Dlogback.statusListenerClass=ch.qos.logback.core.status.OnConsoleStatusListener
This is further explained by the Logback documentation for automatic status printing (very bottom mentions forcing status output) and the logback.statusListenerClass property:
In the absence of status messages, tracking down a rogue logback.xml configuration file can be difficult, especially in production where the application source cannot be easily modified. To help identify the location of a rogue configuration file, you can set a StatusListener via the "logback.statusListenerClass" system property (defined below) to force output of status messages. The "logback.statusListenerClass" system property can also be used to silence output automatically generated in case of errors.
If you want to go deep into Logback, you can do the following
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) throws Exception {
LoggerContext loggerContext = ((ch.qos.logback.classic.Logger)logger).getLoggerContext();
URL mainURL = ConfigurationWatchListUtil.getMainWatchURL(loggerContext);
System.out.println(mainURL);
// or even
logger.info("Logback used '{}' as the configuration file.", mainURL);
}
}
It will print the URL of the loaded configuration file.
you can set debug="true" in a logback.xml file that you control like this:
<configuration debug="true">
(...)
</configuration
and tho make sure that file is going to be used by logback add following VM argument when you start your program:
-Dlogback.configurationFile=/path/to/yourlogback.xml
This does not really answer to your question but gives you a work around solution.
Not very scientific, but it works if you just want a quick confirmation.
I simply changed the log entry pattern and observed whether or not it changed in my console/log file.

How to handle log4j no appenders error

Whenever I debug my code in Netbeans this appears:
log4j:WARN No appenders could be found for logger (org.apache.pdfbox.pdfparser.PDFObjectStreamParser).
log4j:WARN Please initialize the log4j system properly.
Why is this? Is this important?
Why is this?
The reason why you see this message is that your log4j configuration file(i.e. log4j.xml or log4j.properties) is NOT found in the classpath. Placing the log4j configuration file in the applications classpath should solve the issue.
is this important?
Depends on requirement, if you want messages logged to a file with defined levels, then yes you need to fix this warning. Otherwise you may ignore.
For setting Log4j in runtime, do this:
java -Dlog4j.configuration=file:///D:/crawler4j-3.5/log4j.properties -jar newCrawlerV0.1.jar

Categories