I'd like my application to run at Debug level, except for Spring, which is producing a huge amount of logging statements, which makes it hard to read through the logs. I've currently configured my Log4j2 file like this:
<Configuration status="debug">
<Appenders>
<RollingFile name="systemLog" fileName="C:/test/logs/system.log" includeLocation="true"
filePattern=""C:/test/logs/system-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout pattern="%d{ISO8601} - %-5level [%t] %C %M %m%n" />
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="15 MB"/>
</Policies>
</RollingFile>
<Async name="systemAsyncAppender" includeLocation="true">
<AppenderRef ref="systemLog" />
</Async>
</Appenders>
<Loggers>
<SpringLogger name="org.springframework.*" level="error" additivity="false">
<AppenderRef ref="systemAsyncAppender" />
</SpringLogger>
<Root level="debug" includeLocation="true">
<AppenderRef ref="systemAsyncAppender" />
</Root>
</Loggers>
</Configuration>
I thought that setting up the SpringLogger would set Spring to only run at ERROR level and, and write to the same log as everything else, but I'm still seeing full Spring DEBUG output. I have vague memories of being able to do this very easily with the old log4j.properties files (I think it was as simple as log4j.category.org.springframework=ERROR), but I'm not sure how to do this with Log4J2.
(Using Log4J2 2.0.2, spring 3.2.11)
I don't think log4j2 has any special configuration for Spring, so <SpringLogger> doesn't seem appropriate here.
Instead, just declare a regular logger
<logger name="org.springframework" level="error" additivity="false">
...
</logger>
Also note the logger name. These are hierarchical. You don't need the * (and I think it actually breaks it).
Related
I have an application where there are some custom jars added. One of the jars expects logging to be in a different pattern from the entire application's common logging pattern.
(We are using log4j2.xml way)
Now it is pretty straightforward to do it in Console logs by adding multiple appenders, with different patterns and associating them with the corresponding logger name (base package of the custom jar)
But is there a way to do it in the RollingFile Appenders in the same file ?
Consider the example below
Base application having base log pattern has Logger name = com.legacysystem.base
Custom jar within the application needing custom log pattern has logger name = com.legacysystem.custom
Log pattern for base and custom jar is defined in properties with variable names log-pattern and log-pattern
please ignore the fact that proper pattern value is not added, as i want to keep it hidden (assume log4j2-pattern.xml is present with proper log format)
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="log4j2-pattern.xml">
<xi:fallback >
<Properties>
<Property name="log-pattern">base_log_pattern</Property>
<Property name="custom-log-pattern">custom_log_pattern</Property>
</Properties>
</xi:fallback>
</xi:include>
<Appenders>
<Console name="ConsoleBaseAppender">
<PatternLayout pattern="${log-pattern}"/>
</Console>
<Console name="ConsoleCustomAppender">
<PatternLayout pattern="${custom-log-pattern}"/>
</Console>
<RollingFile name="FILE" fileName="commonFileName.log" filePattern="commonFileName-%d{yyyy-MM-dd-HH}-%i.log.gz">
<PatternLayout pattern="${log-pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="25MB"/>
</Policies>
<DefaultRolloverStrategy max="20"/>
</RollingFile>
<RollingFile name="CUSTOM_FILE" fileName="commonFileName.log" filePattern="commonFileName-%d{yyyy-MM-dd-HH}-%i.log.gz">
<PatternLayout pattern="${custom-log-pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="25MB"/>
</Policies>
<DefaultRolloverStrategy max="20"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name = "com.legacysystem.custom" level="INFO" additivity="false">
<AppenderRef ref="CUSTOM_FILE" />
<AppenderRef ref="ConsoleCustomAppender" />
</Logger>
<Logger name="com.legacysystem.base" level="INFO" additivity="false">
<AppenderRef ref="FILE" />
<AppenderRef ref="ConsoleBaseAppender" />
</Logger>
<Root level="INFO">
<AppenderRef ref="FILE" />
<AppenderRef ref="ConsoleBaseAppender" />
</Root>
</Loggers>
</Configuration>
In the above example, I have succeeded in getting different log patterns in the console, but log files isn't working.
Also, is there a better way to do it without defining two rolling file appenders pointing to same file name ?
I'm using Log4j 2 to log the events of my application. However I'm stuck at the following problem.
Currently all logging messages are being written to two different appenders. One has RollingFile type, while the other has Console type.
What I want is for the RollingFile appender to log messages with an INFO level or higher (ERROR, FATAL), and for the Console appender to log messages with an ERROR level or higher (FATAL).
Inside my log4j2.xml file I seem to be only able to declare the logging level for an entire logger (including all of its appenders). Here is my log4j2.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="30">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout>
<Pattern>%d %level %msg%n</Pattern>
</PatternLayout>
</Console>
<RollingFile name="Log" fileName="log/Log.log" filePattern="log/Log-%d{yyyy-MM-dd}-%i.log" append="false">
<PatternLayout>
<Pattern>%d %level %msg%n</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="1 MB" />
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console" />
<AppenderRef ref="Log" />
</Root>
</Loggers>
</Configuration>
Is there an easy way of doing so? I searched log4j documentation but couldn't find what I was looking for (Maybe I missed it?). If it's possible I would really prefer for the solution to be applicable on any appenders' types; not specific for RollingFile and Console.
EDIT:
I saw many questions where it was asked to write ONLY the messages from a certain level to a file, while writing the messages from a different level to a different file. In my case I need the messages with a certain level of HIGHER to be written to different files. For example in the case I provided messages with level ERROR or FATAL will be written to both the RollingFile and Console, while messages with level INFO will be written to RollingFile only.
To limit logging level on specific appender in log4j2 you should use ThresholdFilter element of an appender.
In your case log4j2.xml file will look like:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="30">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>%d %level %msg%n</Pattern>
</PatternLayout>
</Console>
<RollingFile name="Log" fileName="log/Log.log" filePattern="log/Log-%d{yyyy-MM-dd}-%i.log" append="false">
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>%d %level %msg%n</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="1 MB" />
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console" />
<AppenderRef ref="Log" />
</Root>
</Loggers>
</Configuration>
Here is a simple test:
public class Log4jTest {
private static final Logger logger = LogManager.getLogger(Log4jTest.class);
public static void main(String[] args) {
logger.debug("Debug");
logger.info("Info");
logger.warn("Warning");
logger.error("Error");
logger.fatal("Fatal");
}
}
Console output:
2020-02-25 12:33:50,587 ERROR Error
2020-02-25 12:33:50,589 FATAL Fatal
Log.log contents:
2020-02-25 12:33:50,585 INFO Info
2020-02-25 12:33:50,587 WARN Warning
2020-02-25 12:33:50,587 ERROR Error
2020-02-25 12:33:50,589 FATAL Fatal
In first version of log4j it was Threshold property of appender. On how to solve the same in log4j see the answer on question.
With aid of filters Log4j2 allows to configure the output to a specific appender much more flexible then log4j.
This should do the trick.
<Loggers>
<Root level="debug" additivity="false">
<AppenderRef ref="Console"/>
</Root>
<Logger name="com.project.package" level="info" additivity="false">
<AppenderRef ref="Log" />
</Logger>
</Loggers>
Alternatively, you could do it like this - Different level of logs in different log files
BTW, this is explained very nicely in the Log4j2 documentation. See - https://logging.apache.org/log4j/2.x/manual/configuration.html
I'm trying to push logs to an ActiveMqueue using JMS in log4j2.
I have done this in my log4j2.properites
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="5">
<Appenders>
<RollingFile name="fishLogstash"
fileName="E:/xxx/log/xxx.server/xxxLogstash.log" append="false"
immediateFlush="false" bufferSize="1000"
filePattern="/soft/log/xxx.server/xxxx-%i.log">
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss.SSS} %5p %c{1} - %m%n" />
<Policies>
<SizeBasedTriggeringPolicy size="100M" />
</Policies>
<DefaultRolloverStrategy max="10" />
</RollingFile>
<JMS name="jmsQueue" destinationBindingName="logQueue"
factoryName="org.apache.activemq.jndi.ActiveMQInitialContextFactory"
factoryBindingName="ConnectionFactory"
providerURL="tcp://localhost:61616">
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss.SSS} %5p %c{1} - %m%n" />
</JMS>
</Appenders>
<Loggers>
<Root level="warn">
<AppenderRef ref="fish" />
</Root>
</Loggers>
</Configuration>
After this, I wonder how to use the JMS appender to log in my java code? How to retrieve this specific appender, is there somthing like
Logger log = Logger.getAppender("jmsQueue") ?
Thanks in advance.
1.
In your property file, there are xml content. So I am assuming you are trying to use xml style property file. If so, rename your property file to have .xml extension. E.g. log4j2.xml. Remember to write log4j2 supported xml. Examples can be found here.
2.
Mention name value of your defined appenders as AppenderRef in Loggers section of property file. Based on your Appenders section, Loggers section can be
<Loggers>
<Logger name="jmsLogger" level="warn">
<AppenderRef ref="jmsQueue" />
</Logger>
<Root level="warn">
<AppenderRef ref="fishLogstash" />
</Root>
</Loggers>
3.
In your code, get JMS logger as follows:
Logger log = LogManager.getLogger("jmsLogger");
You can log whatever by using log variable. E.g.
log.info("some message");
Hope, this answer would help you.
Is that possible to use MemoryMappedFile with Policies to break the files until fixed sizes, for example 250MB? My log4j2.xml is like this but I want to break the log files to 250MB and I need to use MemoryMappedFile for IO performance.
<Configuration monitorInterval="30">
<Appenders>
<MemoryMappedFile name="MemoryMap" fileName="output/jscsi-out.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %c{2} - %m%n(%L)" />
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="250 MB" />
</Policies>
</MemoryMappedFile>
</Appenders>
<Loggers>
<Logger name="br.com" level="debug" additivity="false">
<AppenderRef ref="MemoryMap" />
</Logger>
<Logger name="org.jscsi.target.TargetServer" level="debug"
additivity="false">
<AppenderRef ref="MemoryMap" />
</Logger>
<Logger name="org.jscsi.target.storage" level="info"
additivity="false">
<AppenderRef ref="MemoryMap" />
</Logger>
<Logger name="org.jscsi.service" level="debug" additivity="false">
<AppenderRef ref="MemoryMap" />
</Logger>
<Root level="error" includeLocation="true">
<AppenderRef ref="MemoryMap" />
</Root>
</Loggers>
</Configuration>
(Background: I am the author of the MemoryMappedFile appender as well as Async Loggers.)
In some sense the MemoryMappedFile appender is still a work in progress (as of Log4j 2.5). As you mention, there is no Rolling variant. Also, I haven't been able to do any significant performance testing. I made a start some time ago but other issues took priority.
Initial performance testing indicates that synchronous logging, even when using the MemoryMappedFile appender, is unlikely to be faster than asynchronous logging via Async Loggers.
Generally, if you need the rollover behaviour I would suggest you use Async Loggers in combination with the RollingRandomAccessFile appender for now.
I've just updated to Log4. Now i have some small issues configurating my new setup.
The log4j2.xml is quite small and simple, but i'm not sure how i can disable logs (or at least set them to ERROR) for all jersey packages.
Here's my log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
</Console>
<File name="FILE" fileName="/logs/m2m/error.log">
<PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
</File>
<Async name="ASYNC">
<AppenderRef ref="FILE" />
<AppenderRef ref="CONSOLE" />
</Async>
</Appenders>
<Loggers>
<Logger name="org.glassfish.jersey.servlet" level="ERROR" additivity="false">
<AppenderRef ref="ASYNC" />
</Logger>
<Root level="DEBUG">
<AppenderRef ref="ASYNC" />
</Root>
</Loggers>
</Configuration>
And here's the log-output i try to silence:
Jan 24, 2014 8:21:12 AM org.glassfish.jersey.servlet.WebComponent filterFormParameters
WARNING: A servlet request to the URI #### contains form parameters in the request body but the request body has been consumed by the servlet or a servlet filter accessing the request parameters. Only resource methods using #FormParam will work as expected. Resource methods consuming the request body by other means will not work as expected.
Thanks
Based on the format of the output I suspect that the log output shown above is actually produced by JUL (java.util.logging) and not by log4j.
It is possible to route calls made to the java.util.logging API to the log4j2 implementation. Your log4j2 configuration (which looks correct) should then filter out WARN-level log events emitted by any class in the org.glassfish.jersey.servlet package.
This involves adding a few more jars to the classpath: see the FAQ.
If you want to do with Logback, here I explain how to do it:
Excessive warning messages from Jersey 2.x