Jump to content

Log4j

From Alfawiki
Apache Log4j
Company typeSoftware framework
IndustrySoftware development, Logging
FounderCeki Gülcü
Area served
Worldwide
ProductsLog4j 1, Log4j 2, Reload4j
ParentApache Software Foundation

Apache Log4j is a logging tool built on the Java platform, initially created by Ceki Gülcü. It belongs to the Apache Logging Services, a division within the Apache Software Foundation. Log4j stands as one of the most prominent Java logging frameworks, extensively implemented in enterprise-level software.

Following this, Gülcü developed additional Java logging solutions such as SLF4J, Reload4j, and Logback, targeting the same domain.

To overcome the shortcomings of Log4j 1.x, java.util.logging, and Logback, the Apache Log4j development team introduced Log4j 2. This version features a flexible plugin system but does not maintain backward compatibility with 1.x releases; however, a compatibility adapter is available to assist with transition. On August 5, 2015, Apache declared the end of life for Log4j 1 and urged users to migrate to Log4j 2 for enhanced security and performance. In January 2022, Gülcü launched Reload4j 1.2.18.0—a fork derived from Log4j 1.2—aimed at resolving critical issues in legacy versions.

A critical zero-day vulnerability named "Log4Shell" was revealed on December 9, 2021, by Alibaba Cloud Security Team within Log4j 2. This security flaw allows remote code execution and has been characterized by Tenable as "the single biggest, most critical vulnerability of the last decade," profoundly affecting cybersecurity risk strategies for organizations utilizing this framework.

Apache Log4j 2

Released as a general availability (GA) product in July 2015, Apache Log4j 2 serves as the modern successor to Log4j 1. It was entirely rewritten, drawing design elements from both Log4j 1 and java.util.logging. Notable enhancements include:

  • Reliable operation with zero message loss during configuration changes
  • A modular plugin architecture supporting custom extensions
  • Simplified setup using XML, JSON, YAML, or properties files
  • Sophisticated filtering and property resolution from configuration files, system properties, environment variables, and ThreadContext Map
  • Support for various APIs including Log4j 2’s own API, Log4j 1.2 API, SLF4J, Commons Logging, and java.util.logging
  • Ability to define custom log levels and utilize Java 8 lambda expressions for deferred logging
  • Integration of markers and user-defined Message objects
  • Minimal or no garbage creation under standard use cases
  • Enhanced performance and improved compatibility with Linux systems

One of its most distinguished capabilities is the "Asynchronous Loggers" feature powered by the LMAX Disruptor framework. This innovation significantly reduces kernel locking contention and increases logging throughput by up to twelvefold—for instance, Log4j 2 can handle over 18 million log entries per second compared to fewer than 2 million for both Logback and Log4j 1.

Log4j log levels

Log4j offers several predefined log levels arranged by descending severity:

Level Description
OFF Disables all logging; highest possible level.
FATAL Critical errors causing premature application termination; prominently displayed on status consoles.
ERROR Runtime errors or unexpected conditions; visible on status consoles.
WARN Indicates deprecated API usage or undesirable runtime scenarios; shown on status consoles.
INFO Significant runtime events such as startup or shutdown; should be minimal and console-visible.
DEBUG Provides detailed information about system flow; generally recorded in logs only.
TRACE Offers the most granular detail; available since version 1.2.12 and logged only.

Tailored log levels

Log4j 2 allows the creation of custom log levels, supported by a source code generation utility that produces Loggers capable of managing these levels as seamlessly as the predefined ones. These personalized levels can either supplement or substitute the standard logging levels.

Configuring Log4j

Configuration in Log4j is handled through configuration files or Java code, compatible with XML, JSON, YAML, and properties files. The primary elements involved are Loggers, Appenders, and Layouts. Utilizing file-based configuration enables toggling logging functionality without modifying the application’s source code, offering enhanced flexibility for runtime management.

Loggers designate the destinations for log messages within an application and can be set to specific logging thresholds such as FATAL or ERROR. Each Logger is capable of directing output to several Appenders simultaneously.

Appenders are responsible for delivering log outputs to various targets. Common types include FileAppender, RollingFileAppender, ConsoleAppender, SocketAppender, SyslogAppender, and SMTPAppender. Log4j 2 has extended this list with Appenders for Apache Flume, Java Persistence API, Apache Kafka, NoSQL stores, memory-mapped files, Random Access files, and ZeroMQ endpoints. This setup allows one Logger to send logs both locally and remotely through multiple Appenders.

Layouts determine the format of log messages. PatternLayout is frequently used for single-line logs using printf-style formatting patterns. Additional available formats include HTMLLayout and XMLLayout. Log4j 2 further supports CSV, Graylog Extended Log Format (GELF), JSON, YAML, and RFC-5424 standards.

Filters offer fine-grained control over which log events are processed by Loggers and Appenders. Beyond filtering by level or regular expressions, Log4j 2 incorporates burst filters, time-based filters, attribute filters such as Markers or Thread Context Map entries, and JSR 223 scripting filters.

For troubleshooting configuration issues:

  • Set the status attribute to TRACE in Log4j 2 to enable internal logging output to standard output; alternatively, use -Dorg.apache.logging.log4j.simplelog.StatusLogger.level=trace before configuration initialization.
  • For Log4j 1.x, enable debugging with -Dlog4j.debug.
  • To verify which log4j2.xml file is loaded, use getClass().getResource("/log4j2.xml").

If no configuration is found, a Log4j application will emit a warning on stdout directing users to the official site and will only record ERROR or FATAL level events by default.

Log4j 2 Configuration Example

<syntaxhighlight lang="xml"> <?xml version="1.0" encoding="UTF-8"?> <Configuration status="trace" monitorInterval="60">

 <Properties>
   <Property name="filename">target/test.log</Property>
 </Properties>
 <Appenders>
   <Console name="STDOUT">
     <PatternLayout pattern="%d %p %c{1.} [%t] %m%n"/>
   </Console>
   <File name="file" fileName="${filename}">
     <PatternLayout>
       <pattern>%d %p %c{1.} [%t] %m%n</pattern>
     </PatternLayout>
   </File>
 </Appenders>
 <Loggers> 
   <Logger name="org.springframework" level="info" additivity="false" />
   <Logger name="com.mycompany.myproduct" level="debug" additivity="true">
     <ThreadContextMapFilter>
       <KeyValuePair key="test" value="123"/>
     </ThreadContextMapFilter>
     <AppenderRef ref="STDOUT"/>
   </Logger>
   <Root level="trace">
     <AppenderRef ref="file"/>
     <AppenderRef ref="STDOUT" level="error"/>
   </Root>
 </Loggers>

</Configuration> </syntaxhighlight>

Log4j 1.2 Configuration Example

<syntaxhighlight lang="xml"> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration PUBLIC "-//LOGGER" "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd"> <log4j:configuration>

   <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
       <layout class="org.apache.log4j.PatternLayout">
           <param name="ConversionPattern"
               value="%d{ABSOLUTE} %5p %c{1}:%L - %m%n" />
       </layout>
   </appender>
   <logger name="org.springframework">
       <level value="info"/>
   </logger>
   <logger name="org.springframework.beans.PropertyEditorRegistrySupport">
       <level value="debug"/>
   </logger>
   <logger name="org.acegisecurity">
       <level value="info"/>
   </logger>
   <root>
       <level value="debug" />
       <appender-ref ref="stdout" />
   </root>

</log4j:configuration> </syntaxhighlight>

TTCC Pattern

TTCC represents a logging message format employed by log4j, standing for Time Thread Category Component. Its layout is expressed as:

 %r [%t] %-5p %c %x - %m%n

The components are defined as follows:

Code Meaning
%r Time in milliseconds since the layout was initialized until the event occurred.
%t The thread's name that produced the logging event.
%p Severity level of the log entry.
%c The category associated with the logging event.
%x Nested diagnostic context (NDC) tied to the thread.
%X{key} Mapped diagnostic context (MDC) value for a given key.
%m Message provided by the application.
%n Newline character(s) appropriate to the platform.

Sample output
467 [main] INFO  org.apache.log4j.examples.Sort - Exiting main method.

Related Ports and Libraries

  • log4c – A logging library written in C, distributed under LGPL via SourceForge. Supports Unix and Windows platforms with build systems like autoconf/automake or MSVC. Configuration is possible through environment variables, code, or XML files. Features appenders for files, streams, and memory-mapped files. Last updated in 2013 and currently not under active development.
  • log4js – A JavaScript adaptation licensed under Apache. Facilitates remote browser event logging to servers using Ajax with XML, JSON, or ASCII formats. Provides appenders such as AjaxAppender, ConsoleAppender, FileAppender, alongside layouts including BasicLayout and JSONLayout. Most recent release is version 2.0 from 2018.
  • log4javascript – Another JavaScript framework inspired by log4j principles. The latest stable version is 1.4.13 released in 2015.
  • JSNLog – Integrates JavaScript client-side logging with server-side .NET frameworks like Log4Net and NLog via a .NET component. Supports capturing exceptions with stack traces and enables correlation of client-server logs using request identifiers. Configuration is managed through web.config; actively maintained with version 3.0.0 as of 2021.
  • Apache Log4net – A .NET Framework port contributed by Neoworks in 2004 that replicates log4j functionality while leveraging .NET features such as NDC and MDC support. The latest version available is 2.0.15 (2022).
  • log4perl – A Perl-based port of log4j with current version 1.57 released in 2022.
  • Apache log4php – PHP logging framework originally derived from log4j but enhanced with PHP-specific capabilities.
  • PL-SQL-Logging-Utility – An adaptation of log4j tailored for PL/SQL environments.
  • Log4db2 – Logging solution designed for DB2 LUW utilizing SQL and SQL PL scripts.
  • Apache Log4cxx – A C++ logging framework modeled after log4j that uses Apache Portable Runtime to ensure cross-platform compatibility; latest release is version 0.13.0 (2022).
  • Log4r – Ruby logging library influenced by Apache log4j offering extensive functionality for Ruby applications.

Log4Shell Vulnerability

The Log4Shell vulnerability (CVE-2021-44228), a severe zero-day remote code execution flaw in Log4j 2, was initially reported to Apache by Alibaba on November 24, 2021, and made public on December 9, 2021. This security gap impacted prominent platforms such as Cloudflare, iCloud, Minecraft: Java Edition, Steam, Tencent QQ, and Twitter. Given the extensive exposure affecting millions of servers, the Apache Software Foundation assigned it the highest possible CVSS score of 10. Cybersecurity organizations like Tenable described it as "the most critical and significant vulnerability of the past decade," while industry specialists characterized it as a devastating architectural defect.

Following the disclosure, Jen Easterly, director of the U.S. Cybersecurity and Infrastructure Security Agency (CISA), emphasized the urgency for vendors to expedite software patching. Germany’s Federal Office for Information Security (BSI) escalated its threat assessment to "extremely critical," and Canada’s Centre for Cyber Security urged organizations to take swift protective measures.

This vulnerability stemmed from a feature in Log4j that could be disabled via configuration—however, this option was removed in version 2.15.0-rc1, released on December 6, 2021. That update introduced limitations on remote lookups to address the problem. Later releases starting with version 2.16.0 disabled all Java Naming and Directory Interface (JNDI) functionality by default and eliminated support for message lookups to further strengthen security.

Further reading


External links