My log doesn't support specials characters like é or è.
I would like to write my log with the encoding UTF-8.
I use log4j and my configuration file is the next one :
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} -
%msg%n"/>
</Console>
<RollingRandomAccessFile name="fileAppender"
fileName="logs/moulinette.log"
filePattern="logs/$${date:yyyy-MM}/moulinette-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<pattern>%-4r [%t] %-5level %logger{35} - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="5 MB"/>
</Policies>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="fileAppender"/>
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Use it as follow:
<PatternLayout charset="UTF-8">
<pattern>%-4r [%t] %-5level %logger{35} - %msg%n</pattern>
</PatternLayout>
Add charset="UTF-8" in the PatternLayout.
See here.
Related
I am trying to write my log into different files depending on the logger name...
is it even possible?
how I can use the logger name in the target file name?
this is the XML file I use:
<Configuration status="info">
<Properties>
<Property name="log-path" value="logs/"/>
<Property name="file-name" value="server"/>
<Property name="file-type" value=".log"/>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
</Console>
<RollingFile name="File" fileName="${log-path}${file-name}${file-type}"
filePattern="${file-name}-%d{yyyy.MM.dd_HH.mm.ss}-%i.log">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
<SizeBasedTriggeringPolicy size="1 MB"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="File"/>
<AppenderRef ref="Console"/>
</Root>
</Loggers>
i have tried to use: <Property name="file-name" value="%logger"/> like in the use in PatternLayout and <Property name="file-name" value="%c{10}"/> witout secssus...
You can't do it like that with the RollingFileAppender. The appender receives log events as configured by your <Loggers> block, if log4j sends it log events with different LoggerNames they will be appended to whatever file is open. A RollingFileAppender writes to one file at a time and rolls when the configured policy tells it to.
You could write to different files by setting up multiple Loggers that target different appenders. Like this:
<Configuration status="info">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
</Console>
<RollingFile name="FileA"
filePattern="/tmp/A-%d{yyyy.MM.dd_HH.mm.ss}-%i.log">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
<SizeBasedTriggeringPolicy size="1 MB"/>
</RollingFile>
<RollingFile name="FileB"
filePattern="/tmp/B-%d{yyyy.MM.dd_HH.mm.ss}-%i.log">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
<SizeBasedTriggeringPolicy size="1 MB"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.example.App" level="info" additivity="false">
<AppenderRef ref="FileA"/>
</Logger>
<Logger name="org.example.App2" level="info" additivity="false">
<AppenderRef ref="FileB"/>
</Logger>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
To route each event to a different RollingFileAppender based on some pattern you can use a RoutingAppender.
The RoutingAppender evaluates LogEvents and then routes them to a subordinate Appender. The target Appender may be an appender previously configured and may be referenced by its name or the Appender can be dynamically created as needed. The RoutingAppender should be configured after any Appenders it references to allow it to shut down properly.
You can also configure a RoutingAppender with scripts: you can run a script when the appender starts and when a route is chosen for an log event.
Here is how you could route based on LoggerName:
<Configuration status="info">
<Properties>
<Property name="log-path" value="logs/"/>
<Property name="file-name" value="server"/>
<Property name="file-type" value=".log"/>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
</Console>
<Routing name="Routing">
<Routes pattern="$${event:Logger}">
<Route>
<RollingFile name="Rolling-${event:Logger}" fileName="${log-path}${file-name}-${event:Logger}${file-type}"
filePattern="${file-name}-%d{yyyy.MM.dd_HH.mm.ss}-%i-${event:Logger}.log">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
<SizeBasedTriggeringPolicy size="1 MB"/>
</RollingFile>
</Route>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Routing"/>
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Also, out of interest, if you really want to you can implement your own Appender that does whatever you want with the LogEvent.
Here's a very rough start. It's an Appender that creates a RollingFileAppender per LoggerName. It only works if you use a SizeBasedTriggeringPolicy. You should be able to drop a class like that into your project and use XML like:
<Configuration status="info">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
</Console>
<FilePerLoggerNameAppender name="File"
filePattern="/tmp/log-%d{yyyy.MM.dd_HH.mm.ss}-%i-$LOGGER$.log">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
<SizeBasedTriggeringPolicy size="1 MB"/>
</FilePerLoggerNameAppender>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="File"/>
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
and see log files created with $LOGGER$ replaced with your logger names.
Below is my log4j2.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="WARN">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<File name="log" fileName="logs/log.txt">
<PatternLayout pattern="%d{yyyy-mm-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</appenders>
<loggers>
<root level="debug">
<appender-ref ref="Console" level="info"/>
<appender-ref ref="log" level="info"/>
</root>
</loggers>
</configuration>
I would like to print whatever I see on the console into my logs.txt file as well.
What am I doing wrong?
I think You are missing the levelrangefilter tag .
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<RollingFile name="log" fileName="logs/log.txt"
filePattern="logs/log.txt.%i" >
<LevelRangeFilter minLevel="FATAL" maxLevel="ALL" onMatch="ACCEPT" onMismatch="DENY"/>
</RollingFile>
</Appenders>
<loggers>
<root level="debug">
<appender-ref ref="Console" level="info"/>
<appender-ref ref="log"/>
</root>
</loggers>
</Configuration>
I'm using the following .xml configuration to log to the console and also to a file.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<Property name="basePath">/logs</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<RollingFile name="File" fileName="${basePath}/log.log" filePattern="${basePath}/log-%d{yyyy-MM-dd}.log" immediateFlush="true">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>
The problem is when I use the following code I get logs on the console but nothing is written to a file.
private static final Logger logger = LogManager.getLogger(App.class);
logger.error("Start App");
Also sometimes I get the following messages when I debug:
Note: when I print out System.getProperty("log4j.configurationFile") I get null
I want to set a directory in Log4j2.xml dynamic.
The Log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console">
<PatternLayout pattern="%d{HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<RollingFile name="MyFile" fileName="${sys:logDirectory}/app.log"
filePattern="${sys:logDirectory}/app-%d{MM-dd-yyyy}-%i.log">
<PatternLayout>
<Pattern>%d %p %c [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="1 MB"/>
</Policies>
<DefaultRolloverStrategy max="2000"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="DEBUG">
<appender-ref ref="Console" level="INFO"/>
<appender-ref ref="MyFile" level="ERROR"/>
</Root>
</Loggers>
</Configuration>
Run:
public static void main(final String[] args)
{
System.setProperty("log4j.logDirectory", "C:\\debug.log");
org.apache.logging.log4j.core.LoggerContext ctx =
(org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
ctx.reconfigure();
log.error("TEST");
}
The Output:
2017-03-15 18:20:27,131 main ERROR
Unable to create file ${sys:logDirectory}/app.log java.io.IOException:
The syntax for the filename, directory name or drive name is wrong.
--- EDIT: the original error message in german was: ---
(Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch.)
...
I tried it and I only found out that if I do this it works for me;
System.setProperty("logDirectory", "C:\debug.log");
So try to remove log4j. in your config statement.
System.setProperty("log4j.logDirectory", "C:\debug.log");
I want to configure my log4j.xml with custom level of verbose - say 350 - in order to print up to some verbose level and including new prints of telemetry that will be at this new level - 350.
What is wrong/missing in my file?
<!--print logs of telemetry, warning and above -->
<CustomLevels>
<CustomLevel name="telemetryLevel" intLevel="350"/>
</CustomLevels>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<RollingFile name="deviceTelemetry" fileName="/home/device/telemetry-${date:yyyy-MM-dd}.log" append="false"
filepattern="/home/device/telemetry-${date:yyyy-MM-dd}-%i.log">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="10M"/>
</Policies>
<DefaultRolloverStrategy max="5"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="deviceTelemetry" level="telemetryLevel">
<AppenderRef ref="deviceTelemetry"/>
</Logger>
<Root>
<AppenderRef ref="Console" level="trace"/>
</Root>
</Loggers>
this way i get the logger in code:
Logger log = LogManager.getLogger("deviceTelemetry");
i don't know yet how to call the logger to append a message. there is a method log(Level level, String message) which gets a level so it might work - i cannot check it yet.