Log4j is a debugging logger.
version:
dependencies {
compile 'org.apache.logging.log4j:log4j-api:2.13.0'
compile 'org.apache.logging.log4j:log4j-core:2.13.0'
}
Get a logger
protected static final Logger parentLogger = LogManager.getLogger();
markers (log4j.Marker class) are objects that are used to add easily filterable information to log messages. Markers can be hierarchical - each Marker may have a parent. This allows for broad categories being subdivided into more specific categories. An example might be a Marker named “Error” with children named “SystemError” and “ApplicationError”.
Markers must be unique.
// A parent
Marker SQL_MARKER = MarkerManager.getMarker("SQL");
// A query marker
Marker QUERY_MARKER = MarkerManager.getMarker("SQL_QUERY").setParents(SQL_MARKER);
// A debug message with a marker
logger.debug(QUERY_MARKER, "SELECT * FROM {}", table);
By default, Log4j looks for a configuration file named log4j2.xml (not log4j.xml) in the classpath.
The order on how log4j search the configuration can be found in the AutomaticConfiguration section
-Dlog4j.configuration=file:/etc/schema-registry/log4j.properties
Format supported:
The default configuration xml would look like that.
<?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>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
public class Main
{
private final static Logger logger = Logger.getLogger(Main.class);
public static void main(final String[] args) throws Exception
{
// Minimal Configuration
System.setProperty("log4j.debug","true");
org.apache.log4j.BasicConfigurator.configure();
if (args.length != 1)
{
logger.error("Please provide an argument");
return;
}
...
see Log4j - How to route message to log file created dynamically
A constructor code where the logger is declared as class variable private Logger threadLogger
// Logger Name is normally hierarchic "com.foo.bar"
// We add the thread name
String loggerName = QueryExecutor.class.getCanonicalName()+"."+threadName;
LOGGER = Logger.getLogger(loggerName);
// Log4j properties
Properties log4jProp = new Properties();
// Once a message is accepted by the logger,
// it's sent to one or several appenders (to a file, to the console, to a mail server, etc.).
final String appenderName = "FileAppender";
// Set logger level to DEBUG and its only appender.
log4jProp.setProperty("log4j.logger."+loggerName, "DEBUG, " + appenderName);
// File Appender
log4jProp.setProperty("log4j.appender." + appenderName,"org.apache.log4j.FileAppender");
// Properties are the set method (File equivalent to setFile)
String timeStamp = new SimpleDateFormat("yyyy.MM.dd_HH.mm.ss").format(new Date());
String logFileName = loggerName+"_"+timeStamp+".log";
log4jProp.setProperty("log4j.appender." + appenderName + ".File", logFileName);
// Above Warning
// The levels of logging are TRACE, DEBUG, INFO, WARN, ERROR and FATAL.
// See org.apache.log4j.Level
log4jProp.setProperty("log4j.appender." + appenderName + ".Threshold","WARN");
// Layout is org.apache.log4j.PatternLayout
log4jProp.setProperty("log4j.appender." + appenderName + ".layout","org.apache.log4j.PatternLayout");
// See org.apache.log4j.PatternLayout#setConversionPattern date in ISO 8601 format, thread name, level, logger, message
log4jProp.setProperty("log4j.appender." + appenderName + ".layout.ConversionPattern","%d [%t] %-5p %c - %m%n");
PropertyConfigurator.configure(log4jProp);
Note that a rolling file appender added this way cannot use lookup value
RollingFileAppender rollingFileAppender = RollingFileAppender.newBuilder()
.withCreateOnDemand(true)
.setName("analytics-" + contextEventFileNameExpression)
.withFileName("logs/analytics.jsonl")
.withFilePattern("logs/analytics/$${date:yyyy-MM}/analytics-%d{yyyy-dd-MM}-%i.jsonl")
.setIgnoreExceptions(false)
.setFilter(
ThresholdFilter.createFilter(
Level.INFO,
Filter.Result.ACCEPT,
Filter.Result.DENY)
)
.setLayout(
PatternLayout
.newBuilder()
.withPattern("%m%n")
.build()
)
.withPolicy(
/**
* It causes a rollover once the date/time pattern no longer applies to the active file.
* https://logging.apache.org/log4j/2.x/manual/appenders.html#timebased-triggering-policy
*/
TimeBasedTriggeringPolicy
.newBuilder()
.build()
)
.setConfiguration(config)
.build();
config.addAppender(rollingFileAppender);