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.
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
In log4j I can specify file like this:
log4j.additivity.org.springframework.ws.server.MessageTracing=false
log4j.logger.org.springframework.ws.server.MessageTracing=TRACE, AUDIT
log4j.additivity.org.springframework.ws.client.MessageTracing=false
log4j.logger.org.springframework.ws.client.MessageTracing=TRACE, AUDIT
when I want to log into appender named AUDIT.
How should I rewrite this into log4j2 xml configuration?
UPDATE
I have defined root logger like:
<Root level="error">
<AppenderRef ref="console" />
<AppenderRef ref="syslog" />
</Root>
and some of class I want to log into app file. In log4j:
log4j.logger.org.springframework=WARN, APP
log4j.logger.org.my.project=DEBUG, APP
but in log4j2 I have no idea how to rewrite in in one sentence
Have you tried something like the following (you need to first define your "app" appender):
<Appenders>
<File name="app" fileName="logs/app.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
</File>
</Appenders>
Then define your logger's appender:
<logger name="org.my.project" level="debug">
<appender-ref ref="app" />
</logger>
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).
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