Download - Log4j2
![Page 1: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/1.jpg)
![Page 2: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/2.jpg)
Trac
ing
use cases
Execution time
system statuscurrent environment
parameters
issue recognition
progress
![Page 3: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/3.jpg)
stackholders
developers
production timesystem engineers
managers
users
testers
lawyers DevOps
![Page 4: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/4.jpg)
requirements
easy to use APIstackholder specific logs
readable logs
completenessperformance
client specific logging (UI, console, build job)
reliablecorrectness
use case specific logging (production,testing, debugging)
historic data
relevant logs
![Page 5: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/5.jpg)
What to log
• reporter (who discovered)
• affected element
• severity
• message
• issue code
• additional data (e.g. exception object)
![Page 6: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/6.jpg)
Log levels
• built-in: OFF, TRACE, DEBUG, INFO, WARN, ERROR, FATAL• Custom log levels• no level inheritance (as in log4j 1.x and logback), because
separation of logger configuration and logger
![Page 7: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/7.jpg)
Log levels (2)<Configuration … status="INFO">
<Loggers>
<Root level="INFO">
<AppenderRef ref="SYSERROUT" />
</Root>
<Logger name="org.apache.logging.log4j2" level="INFO" />
<Logger name="my.package.MyIgnoreClass" level="OFF" />
</Loggers>
</Configuration>
![Page 8: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/8.jpg)
Appenders<?xml version="1.0" encoding="UTF-8"?> <Configuration …>
<Appenders> <Console name="STDOUT" target="SYSTEM_OUT"> …</Console>
…</Appenders><Loggers>
<Logger name="my.package"> <appender-ref ref="STDOUT" /> </Logger>
</Loggers></Configuration>
![Page 9: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/9.jpg)
Appenders
• ConsoleAppender• FileAppender
– RollingFileAppender– RandomAccessFileAppender
• Messaging– JMSAppender– SMTPAppender
• DB– JDBCAppender– JPAAppender– NoSQLAppender
• Remote– SocketAppender– SyslogAppender
![Page 10: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/10.jpg)
Appenders
• Wrapper– FailoverAppender– AsyncAppender
<Async name="Async">
<AppenderRef ref="MyFile"/>
</Async>– RoutingAppender .. explained later with MDC– RewriteAppender .. explained later with Message API
![Page 11: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/11.jpg)
FailoverAppender<Failover name="Failover" primary="RollingFile">
<Failovers>
<AppenderRef ref="Console"/>
</Failovers>
</Failover>
![Page 12: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/12.jpg)
Layout
• PatternLayout
• HTMLLayout
• XMLLayout
• JSONLayout
• SerializedLayout
![Page 13: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/13.jpg)
Pattern Layout<PatternLayout
pattern= " %date{dd.MM.yyyy HH:mm:ss,SSS} %5p %logger %m%n" />
%5p (oder %level) .. log level, maximal 5 Buchstaben, rechtbündig%logger .. logger name%c .. class name
%m .. log message%n .. platform dependent line break%M .. class method
![Page 14: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/14.jpg)
Pattern Layout (2)
• %t .. Name of the thread• xException["none"|"short"|"full"|depth],[filters(packages)}• xThrowable["none"|"short"|"full"|depth],[filters(packages)}• xEx{"none"|"short"|"full"|depth],[filters(packages)}
– %xEx{short} .. Nur erste Zeile des Throwable– %xEx{n} .. n Zeilen
– %xEx{none} oder %xEx{0} .. unterdrücken • MDC{key} später erklärt
![Page 15: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/15.jpg)
Properties<?xml version="1.0" encoding="UTF-8"?><Configuration …>
<Properties><Property name="defaultDatePattern">
%date{dd.MM.yyyy HH:mm:ss,SSS} </Property>
<Property name="defaultLoggerPattern"> %5p %logger %marker %m%n </Property>
<Property name="defaultLogPattern"> ${defaultDatePattern} ${defaultLoggerPattern} </Property>
</Properties> … </Configuration>
![Page 16: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/16.jpg)
Nested Diagnostic Context (NDC)
• stack• context is stored per thread• use push and pop to add and remove information
NDC.push("processingLevel2");
log.info("success");
log4j.appender.CA.layout.ConversionPattern
=%d{yyyy-MM-dd HH:mm:ss.SSSS} %p %C %x = %m%n
%x .. Accessing information
![Page 17: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/17.jpg)
Mapped Diagnostic Context (MDC)
• context is stored per thread• MDC.put(), MDC.get(), and MDC.remove()
MDC.put("userIP", req.getRemoteAddr());
MDC.put("userName", foo.getName());
log.info("success");
log4j.appender.CA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSSS} %p %X{userIP} %C %X{userName} = %m%n
%X{userName} .. retrieves value for key "userName"
![Page 18: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/18.jpg)
Routing Appender<Console name="SYSERR"> … </Console>
<Routing name="ConsoleAppenderRouteIssueCode">
<Routes pattern="${ctx:issueCode}">
<Route>
<Console name="ConsoleAppenderWithIssueCode">
<PatternLayout pattern="${ctx:issueCode} -
${defaultLoggerPattern}"/>
</Console>
</Route>
<Route ref="SYSERR" key="${ctx:issueCode}" />
</Routes>
</Routing>
…
<AppenderRef ref="ConsoleAppenderRoute">
![Page 19: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/19.jpg)
Lookup● $${ctx:myThreadContextPropertyKey}● ${ctx:myThreadMapContextPropertyKey}● ${sys:mySystemPropertyKey}● ${map:myMapMessageKey}● $${date:MM-dd-yyyy}● $${env:USER}● ${java:runtime}● $${jndi:logging/context-name}● define custom lookup plugins
![Page 20: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/20.jpg)
Markersprivate static final Marker SQL_MARKER =
MarkerManager.getMarker("SQL");
private static final Marker UPDATE_MARKER = MarkerManager.getMarker("SQL_UPDATE", SQL_MARKER);
private static final Marker QUERY_MARKER = MarkerManager.getMarker("SQL_QUERY", SQL_MARKER);
…
logger.debug(QUERY_MARKER, "SELECT * FROM {}", table);
![Page 21: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/21.jpg)
Filters
BurstFilter .. throttle logging when too many logs produced
ThresholdFilter .. filters by log level ranges
RegexFilter .. messages have to match regex
MarkerFilter .. log event filter by marker resp. its sub type
TimeFilter .. log only at certain times of day
MapFilter .. filters by entries in MapMessage
StructuredDataFilter .. special MapFilter
DynamicThresholdFilter .. z.B. debug only for user id X
ThreadContextMapFilter .. ThreadContext Map entries
CompositeFilter .. apply multiple filters
![Page 22: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/22.jpg)
Regex Filter<?xml version="1.0" encoding="ASCII"?>
<Configuration name=„MyLogger" …>
…
<Filters>
<RegexFilter regex=".*stringToMatch.*" onMatch="DENY"
onMismatch="NEUTRAL"/>
</Filters>
…
</Configuration>
![Page 23: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/23.jpg)
Thread Context Map Filter<Loggers>
…
<Root level="error">
<AppenderRef ref="RollingFile"/>
<ThreadContextMapFilter onMatch="ACCEPT"
onMismatch="NEUTRAL" operator="or">
<KeyValuePair key="foo" value="bar"/>
<KeyValuePair key="User2" value="WARN"/> </ThreadContextMapFilter>
</Root>
</Loggers>
![Page 24: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/24.jpg)
Message API
• pass built-in or custom message objects• org.apache.logging.log4j.message
– ParameterizedMessage– MapMessage– SimpleMessage– ObjectMessage– Message
logger.info(new LoggedInMessage(map, user));
![Page 25: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/25.jpg)
RewriteLogger logger = LogManager.getLogger(MyClass.class);
Map<String, String> msg = new HashMap<String, String>();
msg.put("creditcard", "123456789");
logger.info(new MapMessage(msg));
![Page 26: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/26.jpg)
Rewrite (2)<Rewrite name="rewrite">
<AppenderRef ref="myweb"/>
<MapRewritePolicy mode="Update">
<KeyValuePair key="creditcard" value="XXXXXXXXXX"/>
</MapRewritePolicy>
</Rewrite>
<Logger …>
<Appender-Ref ref="rewrite" />
</Logger>
source: https://gomtiprabha.wordpress.com/2014/03/11/rewrite-appender-in-log4j2/
![Page 27: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/27.jpg)
Flow tracingpublic String method(String input) {
logger.entry(input);
…
return logger.exit();
}
![Page 28: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/28.jpg)
package my.custom.log4j2.plugins;
@Plugin(name = "Sandbox", type = "Core", elementType = "appender")
public class SandboxAppender extends AppenderBase {
private SandboxAppender(String name, Filter filter) {
super(name, filter, null);
}
public void append(LogEvent event) {
System.out.println(event.getMessage().getFormattedMessage());
}
@PluginFactory
public static SandboxAppender createAppender(
@PluginAttr("name") String name,
@PluginElement("filters") Filter filter) {
return new SandboxAppender(name, filter);
}
}
Plug-in infrastructure
![Page 29: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/29.jpg)
Plug-in infrastructure (2)<configuration … packages="my.custom.log4j2.plugins">
…
<appenders>
<Sandbox />
</appender>
…
</configuration>
![Page 30: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/30.jpg)
Reconfigure <?xml version="1.0" encoding="UTF-8"?>
<configuration monitorInterval="30">
...
</configuration>
• monitoring interval is a value in seconds• log4j 2 would reconfigure logging in case something has
changed in your configuration• log4j 2.0 does not lose logging events at the time of
reconfiguration
![Page 31: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/31.jpg)
XInclude<?xml version="1.0" encoding="UTF-8"?>
<configuration …>
<ThresholdFilter level="debug"/>
<xi:include href="log4j-xinclude-appenders.xml" />
<xi:include href="log4j-xinclude-loggers.xml" />
</configuration>
![Page 32: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/32.jpg)
Performance
source: https://logging.apache.org/log4j/2.x/manual/async.html
![Page 33: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/33.jpg)
Logger configuration
• Centralize
• different context selectors– ThreadLocal– Classloader– JNDI– AsyncLogger
• Make all loggers async– Bundle
![Page 34: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/34.jpg)
OSGi
• Configure BundleContextSelector– associates LoggerContexts with the ClassLoader of the
bundle that created the caller of the getLogger call
• Own logger API and central logger config– Derive Eclipse plug-in project from log4j2 jars– Define fragment project to define your own logger API
• In MANIFEST set – Eclipse-ExtensibleAPI: true
![Page 35: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/35.jpg)
Programmatic access-Dlog4j.configurationFile= ...
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
LoggerConfig loggerConfig =
config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
loggerConfig.setLevel(level);
ctx.updateLoggers(); // loggers refetch information from their LoggerConfig
![Page 36: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/36.jpg)
Bad practice
• logging errors that has been already handled by application code (e.g. failed login)
• log messages with line breaks
• non unified formatted log messages (no tabs)
• long log messages (can be avoid by shorten the package name)
• in tests use logging where assertions would have been a better choice (as they really enforce expected behavior where logs can be ignored)
• not logging exception objects
• using custom appenders holding state
![Page 37: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/37.jpg)
System.out.println(...)
System.err.println(...)
exception.printStackTrace()
FileWriter writer = ...;writer.write(...);writer.close();
LOGGER.error(...)
Bad practice (2)
![Page 38: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/38.jpg)
Bad practice (3)
![Page 39: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/39.jpg)
• use timestamps for every event
• log thread name
• log source of event (e.g. class name and message)
• log ids from domain (e.g. transaction id)
• concise and descriptive messages
• use rolling file appender (to restrict single log file size)
• log method inputs and output at debug resp. trace level
• log full exception objects
• log no more than necessary in production
Good practice
![Page 40: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/40.jpg)
Good practice (2)
![Page 41: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/41.jpg)
Log4J2 + Xtend Active Annotations
@Delegate (built-in)to derive custom loggers with a few customized methods
@Logto initialize instance log field with correct class as parameter
@TraceableTo annotate methods, so that logger.entry and logger.exit with input and output parameters are generated
![Page 42: Log4j2](https://reader033.vdocument.in/reader033/viewer/2022042600/5880f0561a28abc3368b461f/html5/thumbnails/42.jpg)
Links
• Log4j2
• Apache Log4j 2.0 - Worth the Upgrade?
• The new log4j 2.0
• The Logging Olympics – A Race Between Today’s Top 5 Java Logging Frameworks