I just start working on maintaining a Spring application which is deployed on WebSphere enterprise (version 8.5). It is my first time using the container. I need to have log messages in the debug level for tracing down a bug. The bug error log message shows up in the trace.log. After the system admin configures the container log level to debug, we don't see any debug level log messages. The application didn't have a log property file although log4j and Slf4j are its dependencies. I add a log4j.properties file which configures both a log file output and the console output. I, however, don't see the log file nor any log messages on console according to the system admin. It seems to me that the debug log level configuration is special in Websphere. How to solve this log level configuration problem?
The followings are Java code segment
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class MyClass {
private static final Logger log = LoggerFactory.getLogger(MyClass.class);
public void method01(){
log.debug("....");
}
and the property file:
# Root logger option
log4j.rootLogger=DEBUG, file, stdout
# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=${SERVER_LOG_ROOT}/portal-server.log
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %C:%M:%L - %m%n
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %C:%M:%L - %m%n
Notes: ${SERVER_LOG_ROOT} is replaced by a real path on the container box without a luck either.
Your application is using log4j logger trough the slf4j logging interface. This is a pretty standard setup. WebSphere doesn't interfere with this kind of logging configuration.
These are steps for proper setup of this configuration:
First exclude commons-logging dependency from your project. It is a popular logging interface required by Spring and various different projects. Instead, we will use slf4j.
Add dependencies to:
slf4j-api - our logging interface
jcl-over-slf4j - commons-logging implementation
slf4j-log4j12 - sl4j log4j bridge
log4j - logging api
Create log4j.properties in /WEB-INF/log4j.properties location.
Bootstrap log4j. Simplest way to bootstrap in spring web app is by using Log4jConfigListener utility class. Add following entries to web.xml. You should add this at the very top of web.xml in order to bootstrap logging before anything other happens.
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
That's it. This should work.
Now that logging is working you should probably make more detailed configuration with console logging during development; and more concise logging in deployment.The simplest way to do it is by using parameterized configuration log4j.properties:
log4j.rootLogger=${LOG4J_SERVER_LOGLEVEL}, fileAppender
log4j.appender.console=org.apache.log4j.ConsoleAppender
... console appender configuration ...
log4j.appender.fileAppender=org.apache.log4j.DailyRollingFileAppender
... file appender configuration ..
In a production LOG4J_SERVER_LOGLEVEL environment variable is set to "INFO". On my development machine, it is set to "DEBUG, console". This way servers log only to fileAppender, and development machine logs to console and fileAppender.
You can always add more environment variables to fine tune specific loggers or even make log4j.properties external and provide "file:" location as param-value. In case of external log4j.properties Log4jConfigListener can be setup to monitor changes in log4j properties and change the logging configuration in real time.
Nothing of this is WebSphere specific and these steps are the same in any Java web container. Now if you need logging which is configurable from WebSphere console you can accomplish this by replacing log4j with jul logger. WebSphere provides admin interface for jul logging under "Logs and trace" section.
Related
I want to define high-level file logging in application.properties as a convenience to leverage my log4j2.xml file configuration. By itself my log4j2 config is working fine, however I was hoping to control logging levels and log file and path info from the application.properties file. I have the spring-boot-starter-log4j2 dependency in the application's pom file.
In log4j2.xml I have as one of the properties
<Property name="LOG_FILE">${LOG-DIR}/test.log</Property>
, where LOG-DIR is defined in another (previous) property in the same file. In my application.properties file, I have
logging.file=LOG_FILE
as a property, plus several level properties such as
logging.level.org.springframework.web=DEBUG
none of these log-related properties as defined in my application.properties file are working to build the corresponding log file. Again, when I simply use log4j2.xml by itself it works fine, but wanted to take advantage of the convenience of application.properties for logging configuration.
Any insights into what I am doing wrong are greatly appreciated. thank you
If I understood your question right, you are looking at Property Substitution feature of log4j2.
You can define logging property in application.properties file like below:
log.file.path=/myDir/logpath
And then the property(s) lookup defined as Property in log4j2.xml:
<Configuration>
<Properties>
<property name="LOG_FILE">${bundle:application:log.file.path}</property>
</Properties>
Now all the property can be referred in same log4j2.xml with ${propertyName} notation, which eventually points to values from application.properties file.
I have a Spring Boot 2.0.5 command-line application with mostly default configurations.
How can I enable HTTPClient wire-logging?
I tried throwing this into a log4j.properties file:
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%c] %m%n
log4j.logger.org.apache.http=DEBUG
I tried adding spring-boot-starter-logging to the pom.xml.
I also tried adding JVM parameters to the app launch:
-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
-Dorg.apache.commons.logging.simplelog.showdatetime=true
-Dorg.apache.commons.logging.simplelog.log.org.apache.http=DEBUG
But nothing works. No httpclient logs at all.
How can I get some httpclient logs?
Solution was counter-intuitive. Add this line to application.properties:
logging.level.org.apache.http=DEBUG
I am using Log4j2 and Spring Boot (1.2.4). Following the documentation (and the log4j2-file.xml as example in spring-boot.jar), here is my configuration
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<File name="Logs" fileName="${sys:LOG_FILE}" append="false">
...
<Logger level="warn">
<AppenderRef ref="Logs"/>
</Logger>
In application.properties file :
logging.file: /var/tmp/logs/mylog.log
As a result, 2 files are generated :
One file named ${sys:LOG_FILE} which remains empty
One file /var/tmp/logs/mylog.log properly filled
I do not understand why the file ${sys:LOG_FILE} is generated.
Any idea ?
Thanks a lot.
I'm using version 1.2.5.RELEASE of Spring Boot (including the starter parent) and I'm seeing the same issue.
My assumption is that Log4j2 tries to initalize the file before Spring Boot loaded the configuration, resulting in an empty file called ${sys:LOG_FILE} or ${sys (on Windows).
One way of avoiding this is to just set the system property (-DLOG_FILE=/var/tmp/logs/mylog.log) and remove logger.file from your configuration.
It seem log4j2.xml is loaded and log file is created before application.properties being loaded. One way to fix this is to change the name of log4j2.xml to something else, for example log4j2-example.xml to present auto loading and then add the following line into application.properties:
logging.config=classpath:log4j2-example.xml
This will ensure the LOG_PATH are loaded before creating logger.
logging.file is just used for default logger configured by spring only.
In this case, your LOG_FILE must be passed into system variable before execute the jar by -DLOG_FILE=/location/of/log.file
I am using spring mvc 3. Today I discovered spring profiles and how you can set them in your web.xml. I am loading my profile from an application properties file but cannot achieve the same thing with log4j in order to load a different log4j file based on whether or not I am building for dev or building for prod.
Here is what I have for spring.profiles.active.
A properties file named env.properties..
spring.profiles.active=dev
An AppInitializer class which implements ApplicationContextInitializer.
public void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
try {
ResourcePropertySource env = new ResourcePropertySource("classpath:env.properties");
String profile = (String)env.getProperty("spring.profiles.active");
environment.getPropertySources().addFirst(env);
...
}
The following in my web.xml
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>${spring.profiles.active}</param-value>
</context-param>
Problem : Now I try and load a different log file based on env like so...
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:/log4j-${spring.profiles.active}.xml</param-value>
</context-param>
Where the aim is to load log4j-dev.xml but this does not work.
Can anyone help me with this please?
thanks
Log4j supports variable substitution inside the log4j.xml file. You could substitute the log directory based on an environment specific system property. That would mean that you could keep the file name as:
<param-value>classpath:/log4j.xml</param-value>
Then you could parameterize the directory inside the file:
<param name="File" value="${log4j_dir}/filename.log" />
And then for each app server in each environment, you could set the appropriate folder path. Eg. for dev:
-Dlog4j_dir=/path/on/dev
It does mean that you'd be using a system property rather than a property in a properties file but it may be one way of achieving what you're after.
I use filterpane plugin for grails and need to debug it's flow. In Config.groovy i put in log4j clause debug 'org.grails.plugin.filterpane'. It started logging to console from FilterPaneUtils but not from FilterPaneService, even thought both classes are from org.grails.plugin.filterpane package. I debugged code in FilterPaneService and it run through log.debug line but nothing appears on console.
What should I do to start logging from class FilterPaneService?
using Grails 2.1.1
and filterpane plugin 2.2.2
Try with
debug grails.app.services.org.grails.plugin.filterpane.FilterPaneService
I added
private static final Log log = LogFactory.getLog(this)
to the FilterPaneService class and it started logging. I'm not sure why the author of this plugin didn't put this declaration but without it it's not working.