I have a web service (Jenkins) that handles user requests, and I want to be able to dynamically append the request session id to each log line without having to actually add that variable to each and every log action.
I'm using log4j2 with slf4j implementation, I initialize the logger using an external configuration file with org.apache.logging.log4j.core.config.Configurator, I create an instance of the logger per every session using
final Logger logger = LoggerFactory.getLogger(MyClass.class);
I have for example:
logger.debug("received new request");
...
logger.debug("added something");
And I want the user session id to be added to each line without having to add it myself like:
logger.debug("{} received new request",session.getId());
...
logger.debug("{} added something",session.getId());
My log4j2.xml file is:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<Configuration status="INFO">
<Properties>
<Property name="logPath">...</Property>
<Property name="rollingFileName">...</Property>
</Properties>
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="[%highlight{%-5level}] %d{DEFAULT} %c{1}.%M() - %msg%n%throwable{short.lineNumber}" />
</Console>
<RollingFile name="rollingFile" fileName="${logPath}/${rollingFileName}.log" filePattern="${logPath}/${rollingFileName}_%d{yyyy-MM-dd}.log">
<PatternLayout pattern="[%highlight{%-5level}] %d{DEFAULT} %c{1}.%M() - %msg%n%throwable{short.lineNumber}" />
<Policies>
<!-- Causes a rollover if the log file is older than the current JVM's start time -->
<OnStartupTriggeringPolicy />
<!-- Causes a rollover once the date/time pattern no longer applies to the active file -->
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="com.project" level="debug" additivity="false">
<AppenderRef ref="console"/>
<AppenderRef ref="rollingFile"/>
</Logger>
</Loggers>
</Configuration>
Actual results from current log file:
[[36mDEBUG[m] 2019-02-05 16:42:09,794 SpellCheck.getResult() - start
[[36mDEBUG[m] 2019-02-05 16:42:10,420 SpellCheck.getResult() - Spelling correction returned no results.
[[36mDEBUG[m] 2019-02-05 16:42:10,420 SpellCheck.getResult() - end
What I want to achieve:
[[36mDEBUG[m] 2019-02-05 16:42:09,794 SpellCheck.getResult() - 1234 - start
[[36mDEBUG[m] 2019-02-05 16:42:10,420 SpellCheck.getResult() - 1234 - Spelling correction returned no results.
[[36mDEBUG[m] 2019-02-05 16:42:10,420 SpellCheck.getResult() - 1234 - end
Where 1234 is for example the session id.
Thanks.
I figured it out, was a lot easier than I thought.
Basically added %X{userSessionId} to the
<PatternLayout pattern= ... />
row in log4j2.xml.
And in the code added
HttpSession session = request.getSession();
org.apache.logging.log4j.ThreadContext.put("userSessionId", session.getId());
Related
We have an issue where whenever our Gatling performance tests are run the .log file that should generate at the root of the folder is not there.
This is my whole logback file if anyone able to help please.
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter> -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
<immediateFlush>true</immediateFlush>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile.log</file>
<append>false</append>
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
</encoder>
</appender>
<!-- uncomment and set to DEBUG to log all failing HTTP requests -->
<!-- uncomment and set to TRACE to log all HTTP requests -->
<logger name="io.gatling.http.engine.response" level="TRACE" />
<root level="WARN">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
Thank you very much.
Update
It seems the issue may be with IntelliJ itself as noticed we can see the file when going directly to the finder.
Disabling custom plugins should help. Seems one of configuration was corrupted.
There's a good chance the file is simply not generated where you expect it. Try setting an absolute path instead to verify.
I have mule 3.8.1. I can see logs for each app I have in %MULE_BASE%/logs/%MULE_APP%.log just like defined in wrapper.conf file. Example log files I have are:
mule-app-APP1.log.2020-04-07
mule-app-APP1.log
mule-app-APP2.log.2020-04-07
mule-app-APP2.log
I understand that by default logs are created in the format %MULE_APP%.log where MULE_APP is mule-app-<app_name>.
My question is about "rolling" files. I mean, creating a new log file each day. There is log4j2.xml in the project but there is only AsyncRoot appender pointing out to Console appender. My question: is the "rolling" log files behavior default in mule ? or there must be a configuration set in the project by someone else, that I'm missing ?
This is not Mule behaviour. This is log4j2 behaviour which is defined in the log4j2.xml file. If you have definition like this
<RollingFile name="file" fileName="${sys:mule.home}${sys:file.separator}logs${sys:file.separator}myApp.log"
filePattern="${sys:mule.home}${sys:file.separator}logs${sys:file.separator}myApp-%i.log">
<PatternLayout pattern="%-5p %d [%t] [event: %X{correlationId}] %c: %m%n" />
<SizeBasedTriggeringPolicy size="10 MB" />
<DefaultRolloverStrategy max="10"/>
</RollingFile>
which is generate automatically when you create myApp mule Application then you will alwyas have only 10 latest rolling logs.
If you elimate fileName like this
<RollingFile name="file"
filePattern="${sys:mule.home}${sys:file.separator}logs${sys:file.separator}myApp-%i.log">
<PatternLayout pattern="%-5p %d [%t] [event: %X{correlationId}] %c: %m%n" />
<SizeBasedTriggeringPolicy size="10 MB" />
<DefaultRolloverStrategy max="10"/>
</RollingFile>
then you will have behaviour like you described with infinite rolling logs.
See more about this here https://simpleflatservice.com/mule4/RollingLogFiles.html
I am using third party code that uses:
if (logger.isDebugEnabled()) {
logger.debug("Message");
}
I'm getting these messages in my output even though I'm using the standard run configuration, and it's only happening on my instance of this particular project so I'm not sure what I'm missing.
I've tried deleting the run configuration and starting it again but I keep getting it in my output.
How do I stop this?
[SOLVED]
I found this in another project, copied it across and it's behaving as I would expect now:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
This was in logback.xml in src>main>resources
Thanks to those that commented!
I would like to change some properties from the log4j2.xml file depending on the my application.properties, for example define some properties and then substitute in the log4j2 those properties that are parameters.
I ran different approaches but I still did not get the right thing. I would like to have different configs depending on the environment (DEV, QA or PROD). How to accomplish this?
I'm trying to have this in my properties
#Place holders for log4j2.xml file
log.file.path=/opt/tomcat/logs
log.file.name=dummydummy
log.file.size=100 MB
log.level=DEBUG
My log4j2 below.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
<Properties>
<Property name="PID">????</Property>
<property name="name">my-log</property>
</Properties>
<Appenders>
<RollingFile name="file" fileName="${log.file.path}${log.file}.log"
filePattern="${log.file.path}${log.file}-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout
pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${sys:PID} --- [%t] %c{1}(%M:%L) : %m%n%wEx" />
<Policies>
<TimeBasedTriggeringPolicy /><!-- Rotated everyday -->
<SizeBasedTriggeringPolicy size="${log.file.size}" /> <!-- Or every 100 MB -->
</Policies>
</RollingFile>
<Console name="Console" target="SYSTEM_OUT" follow="true">
<PatternLayout
pattern="%clr{%d{yyyy-MM-dd HH:mm:ss.SSS}}{faint} %clr{%5p} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%t]}{faint} %clr{%c{1}(%M:%L)}{cyan} %clr{:}{faint} %m%n%wEx" />
</Console>
</Appenders>
<Loggers>
<Logger name="org.hibernate.validator.internal.util.Version"
level="warn" />
<Logger name="org.apache.coyote.http11.Http11NioProtocol" level="warn" />
<Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="warn" />
<Logger name="org.apache.catalina.startup.DigesterFactory" level="error" />
<Logger name="org.springframework.web" level="error" />
<Root level="${log.level}">
<AppenderRef ref="Console" />
<AppenderRef ref="file" />
</Root>
</Loggers>
</Configuration>
The properties lookup element allows to refer properties from an external properties file in the log4j configuration.
For your example it should be something like this:
A file env.properties contains the following properties:
log.file.path=/opt/tomcat/logs
log.file.name=dummydummy
log.file.size=100 MB
log.level=DEBUG
The properties lookup should be defined as properties of the log4j2.xml:
<Configuration>
<Properties>
<property name="log.file.path">${bundle:env:log.file.path}</property>
<property name="log.file.name">${bundle:env:log.file.name}</property>
<property name="log.file.size">${bundle:env:log.file.size}</property>
<property name="log.level">${bundle:env:log.level}</property>
</Properties>
Now the properties may be referred in appenders with ${property_name} notation. Each property reference will be interpolated with the real value from the env.properties.
You can find another example of properties lookup here.
As of Log4j 2.13.0 Log4j 2 now provides a Spring Lookup as part of its Spring Cloud Config support. It will allow you to reference properties defined in your application.properties or application.yml file of your Spring Boot application in the log4j2.xml.
Since log4j 2.14.0, you can now use Spring Boot environment variables without Spring Cloud and without doing direct reference to the properties file. You'll need at least Spring Boot 2.0.3
<property name="applicationName">${spring:spring.application.name}</property>
Documentation: https://logging.apache.org/log4j/2.x/log4j-spring-boot/index.html
Maven repository: https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-spring-boot
Ensure that log4j2 starter is added in the classpath and then remove logging related properties in application.properties then spring will load your log4j2.xml from resources folder.
This way you can have full control over logging. If you want to substitute values then refer this link
Note:: If you have actuator in your project then remove spring boot logger starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
Workaround in case you need just different property values in log4j2.xml config for different spring profiles (dev, test, prod, etc.).
You could access spring profile files like: ${bundle:application-${sys:spring.profiles.active}:log.file.name}
application-dev.properties file:
log.file.name=dev_log
application-prod.properties file:
log.file.name=app_name
log4j2.xml config:
<Configuration>
<Properties>
<Property name="file_name">${bundle:application-${sys:spring.profiles.active}:log.file.name}</Property>
</Properties>
<Appenders>
<RollingFile name="RollingFile"
fileName="/logs/${file_name}.log"
...
NOTE: You have to add log.file.name property to each spring profile, log4j2 sees it just as separate text files and will not resolve default values from application.properties file and etc.
I have two log4j2 generated log files. I am generating these log files using FileAppender and now I want to send those log files to AWS cloudwatch and S3 bucket as a log4j2 destination.
I am new to log4j2 and this cloud API. I have searched a lot but not able to find something useful. Though I have found these two links:
http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-configuration-cwl.html and http://docs.aws.amazon.com/AWSSdkDocsJava/latest/DeveloperGuide/java-dg-logging.html
But I am not sure how it will work and whether Is this the only way to send log files to AWS cloudwatch and S3 bucket. And What other settings do I need to do in my log4j2.xml file.
So, how to send log4j2 generated log files to cloud API? I have to use log4j2 and J2EE.
Here is my log4j2.xml file:
<Configuration monitorInterval="30" status="warn" name= "MyApp" packages="" xmlns="http://logging.apache.org/log4j/2.0/config">
<Properties>
<Property name="filename-server1-all">${sys:catalina.home}/logs/server1-all.log</Property>
<Property name="filename-server1-err">${sys:catalina.home}/logs/app.log</Property>
<Property name="pattern_layout">%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property>
</Properties>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
<File name="appender-server-1-all" fileName="${filename-server1-all}">
<PatternLayout pattern="${pattern_layout}" />
</File>
<File name="appender-server1-err" fileName="${filename-server1-err}">
<PatternLayout pattern="${pattern_layout}" />
</File>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="appender-server-1-all" level="all"/>
<AppenderRef ref="appender-server1-err" level="error"/>
</Root>
</Loggers>
</Configuration>