I have written a basic Server that receives data from Client and processes the received messages. Whenever I am receiving I am logging the received messages into a log file. Now the problem is : all messages sent to the Server are logged at the Client side. Suppose a message sent from Client to Server at "18:32:23:345" then at my Server side when I am logging it is showing received at "18:32:23:300". Please observe the Milli-seconds time at the Server side. It is showing that the message is received before the message is sent. I am using Asynchronous logging with log4j2. Can anyone please help me.
This is my XML file of Log4j2 configuration at Server side:
<Configuration status="warn">
<Appenders>
<File name="my_file_appender" fileName="Errors.log" immediateFlush="false" append="false">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} - %msg%n</Pattern>
</PatternLayout>
</File>
<Async name="async_appender">
<AppenderRef ref="my_file_appender" />
</Async>
<!-- file appender -->
<RollingFile name="Error-log" fileName="MESSAGES.log"
filePattern="MESSAGES-%d{yyyy-MM-dd}.log">
<!-- log pattern -->
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} - %msg%n</Pattern>
</PatternLayout>
<!-- set file size policy -->
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="50 MB" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="Error-log" level="info" additivity="false">
<appender-ref ref="Error-log" level="debug"/>
</Logger>
<Root level="info" includeLocation="false">
<AppenderRef ref="async_appender"/>
</Root>
</Loggers>
As per my view the Client side logging is working perfectly. Is there any problem with my configuration? I have tried implementing the same configuration with .properties file. But it is not working. Can anyone also tell me how to change the above configuration to .properties file as loading XML every time makes my application to slow down. Thanks in advance.
Related
I change spring boot to spring MVC, but I can't see any log information in my log file but it populates in the console. Please let me know the changes I need to make in the log4j2.xml file so that log info will be saved to log files.
what is monitorinterval=30 in the below XML file?
Thank you soo much for the response
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
<Properties>
<Property name="LOG_PATTERN">
%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${hostName} --- [%15.15t] %-40.40c{1.} : %m%n%ex
</Property>
</Properties>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="${LOG_PATTERN}"/>
</Console>
<!-- Rolling File Appender -->
<RollingFile name="FileAppender" fileName="logs/prism.log"
filePattern="logs/prism-%d{yyyy-MM-dd}-%i.log.zip">
<PatternLayout>
<Pattern>${LOG_PATTERN}</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="5 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="com.heymath" level="debug"
additivity="false">
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="FileAppender"/>
</Logger>
<Root level="info">
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="FileAppender"/>
</Root>
</Loggers>
</Configuration>
monitorInterval=30 tells Log4j2 to check every 30 seconds to see if the logging configuration has changed and reconfigure if it has.
I see nothing obviously wrong with your configuration. It should be logging all info, warn, error and fatal messages to the file and console. Debug messages from com.heymath loggers should be going there as well.
I would suggest changing the status="WARN" to status="DEBUG" on the configuration element. If you do not see logs from log4j it means that your configuration file was not found and is not being used. Instead, it is using the default configuration which logs errors to the console.
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
My log4j2.xml is exactly the same as the one I've written for another similar server - which works perfectly well. The only differences are the file/server names and paths.
Log4j1 worked fine too, it's just log4j2 that's causing problems. I'm starting to think I might have missed something in the linux config at this point.
Things I've tried:
Including log4j2.xml in the root directory of the project
Including log4j2.xml in the main.resources folder of my project
Using -Dlog4j.configurationFile="PATH" when running the jar (via systemd)
Verified the folder/log file are owned by the server user and server group
Verified that the server has rw permissions for the file/folder
Verified that the server user is a member of the correct group
Also, when I run systemctl status -l on the server, the resulting output shows the log data as I expect to see it in the firmwareserver.log file.
My other server uses the log4j2.xml file from main.resources in the project without any issues.
EDIT: I should add, I'm developing this in eclipse on a windows machine, and when I run it there the log file saves as expected, even using the linux path it still works.
EDIT 2: I found the following error when I ran the jar file directly instead of as a systemd service:
2016-03-11 14:06:39,601 ERROR Unable to locate appender RollingFile for logger
Here's my Log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG" monitorInterval="30">
<Properties>
<Property name="windows-log-path">C:/log4j/</Property>
<Property name="linux-log-path">/var/log/wsfirmwareserver</Property>
</Properties>
<Appenders>
<RollingFile name="RollingFile" fileName="${linux-log-path}/firmwareserver.log"
filePattern="${linux-log-path}/$${date:yyyy-MM}/firmwareserver-%d{yyyy-MM-dd}-%i.log">
<PatternLayout>
<pattern>%d{dd/MMM/yyyy HH:mm:ss,SSS}{GMT+1} [%-5p] [%t] - %c{1}: %m%n</pattern>
</PatternLayout>
<SizeBasedTriggeringPolicy size="5MB" />
<DefaultRolloverStrategy max="30" />
</RollingFile>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] - %m%n" />
</Console>
<SMTP name="SMTPAppender"
smtpProtocol="smtps"
smtpPort="465"
subject="LOC SERVER:Error"
to="me#myjob.com, me#otheremail.com"
from="notifications#myjob.com"
smtpHost="smtp.gmail.com"
smtpUsername="notifications#myjob.com"
smtpPassword="thepassword"
bufferSize="512">
<PatternLayout>
<pattern>%d{dd/MMM/yyyy HH:mm:ss,SSS}{GMT+1} [%-5p] [%t] - %c{1}: %m%n</pattern>
</PatternLayout>
</SMTP>
</Appenders>
<Loggers>
<Logger name="root" level="info" additivity="false">
<appender-ref ref="RollingFile" level="info" />
</Logger>
<Root level="debug" additivity="false">
<AppenderRef ref="Console" level="debug"/>
<AppenderRef ref="RollingFile" level="debug"/>
<AppenderRef ref="SMTPAppender" level="error"/>
</Root>
</Loggers>
</Configuration>
Anybody got any suggestions?
Ideally I'd like to have the config file located in the same folder as the server jar, but at this point I just want it to log to the file properly.
There was an error in the log4j2.xml file itself.
I haven't located it, but replacing it with a copy from another server fixed the issue.
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