There is so much to tell about the Western country in that day that it is hard to know where to start. One thing sets off a hundred others. The problem is to decide which one to tell first.
—JOHN STEINBECK, East of Eden
Manual · Appenders · Appenders: Console and File
Appenders: Console and File
This page continues the
Appenders chapter. The overview
introduces the Appender interface,
AppenderBase,
and
OutputStreamAppender
(including its encoder and
immediateFlush properties and the class diagram of
its subclasses).
Here we turn to the concrete stream-oriented appenders that
most applications configure first:
ConsoleAppender,
JansiConsoleAppender, and
FileAppender. All three build on
OutputStreamAppender. Rolling files are covered
separately under
Rolling file.
ConsoleAppender
The
ConsoleAppender, as the name indicates,
appends on the console, or more precisely on
System.out or System.err, the former being
the default target. ConsoleAppender formats
events with the help of an encoder specified by the
user. Encoders will be discussed in a subsequent chapter. Both
System.out and System.err are of type
java.io.PrintStream. Consequently, they are
wrapped inside an OutputStreamWriter which
buffers I/O operations.
WARNING Please note the console is comparatively slow, even very slow. You should avoid logging to the console in production, especially in high volume systems.
| Property Name | Type | Description |
|---|---|---|
| encoder |
Encoder
|
See OutputStreamAppender properties. |
| target | String |
One of the String values System.out or System.err. The default target is System.out. |
| withJansi | boolean |
since 1.6.3
Deprecated. Prefer
By default withJansi
is |
Here is a sample configuration that uses ConsoleAppender.
Example: ConsoleAppender configuration (logback-examples/src/main/resources/chapters/appenders/conf/logback-Console.xml)
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} -%kvp- %msg %n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
Requires a server call.
Requires a server call.
After you have set your current path to the logback-examples directory and set up your class path, you can give the above configuration file a whirl by issuing the following command:
java chapters.appenders.ConfigurationTester src/main/java/chapters/appenders/conf/logback-Console.xml
JansiConsoleAppender
since 1.6.3 The JansiConsoleAppender
is a ConsoleAppender that always writes through
JLine's org.jline.jansi.AnsiConsole. It is the
recommended way to enable ANSI sequences on platforms that need
Jansi (notably Windows). Unlike the deprecated
withJansi path on
ConsoleAppender, this class talks to
AnsiConsole directly and does not use reflection.
You must place org.jline:jansi-core on the class
path. On start, the appender calls
AnsiConsole.systemInstall() and routes output to
AnsiConsole.out() or AnsiConsole.err()
according to the target property. On
stop, if this appender performed the install, it pairs that call
with AnsiConsole.systemUninstall(). As with
ConsoleAppender, stop flushes the console stream but
does not close process-wide stdout or stderr.
JansiConsoleAppender admits the same
encoder and
target properties as
ConsoleAppender. You do not set
withJansi; Jansi wrapping is always
applied.
Here is a sample configuration that uses
JansiConsoleAppender instead of a plain
ConsoleAppender with
<withJansi>true</withJansi>:
DEPRECATED
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<withJansi>true</withJansi>
<encoder>
<pattern>%highlight(%-5level) %logger{35} - %msg%n</pattern>
</encoder>
</appender>
RECOMMENDED
<appender name="STDOUT" class="ch.qos.logback.core.JansiConsoleAppender">
<encoder>
<pattern>%highlight(%-5level) %logger{35} - %msg%n</pattern>
</encoder>
</appender>
FileAppender
The FileAppender,
a subclass of OutputStreamAppender, appends log events into
a file. The target file is specified by the File option. If the file already exists, it
is either appended to, or truncated depending on the value of the
append property.
| Property Name | Type | Description |
|---|---|---|
| append | boolean |
If true, events are appended at the end of an existing file. Otherwise, if append is false, any existing file is truncated. The append option is set to true by default. |
| encoder |
Encoder
|
See OutputStreamAppender properties. |
| file | String |
The name of the file to write to. If the file does not
exist, it is created. On the MS Windows platform users
frequently forget to escape backslashes. For example, the
value c:\temp\test.log is not likely to be interpreted
properly as '\t' is an escape sequence interpreted as
a single tab character (\u0009). Correct values can
be specified as c:/temp/test.log or alternatively as
c:\\temp\\test.log. The File option has no default value.
If the parent directory of the file does not exist,
|
| bufferSize | FileSize |
The bufferSize option set the size of the output buffer in case immediateFlush option is set to false. Default value for bufferSize is 8192. The value 256 KB seems to sufficient even in cases of very heavy and persistent loads. Options in defined in units of "FileSize" can be specified in bytes, kilobytes, megabytes or gigabytes by suffixing a numeric value with KB, MB and respectively GB. For example, 5242880, 5120KB, 5120 KB, 5MB, 5 MB, 2 GB and 2GB are all valid values, with the first five being equivalent. A numerical value with no suffix is taken to be in units of bytes. |
| prudent | boolean |
In prudent mode, FileAppender will safely
write to the specified file, even in the presence of other
FileAppender instances running in different
JVMs, potentially running on different hosts. The default
value for prudent mode is false.
Prudent mode can be used in conjunction with
Prudent mode implies that append property is automatically set to true. Prudent more relies on exclusive file locks. Experiments show that file locks approximately triple (x3) the cost of writing a logging event. On an "average" PC writing to a file located on a local hard disk, when prudent mode is off, it takes about 10 microseconds to write a single logging event. When prudent mode is on, it takes approximately 30 microseconds to output a single logging event. This translates to logging throughput of 100'000 events per second when prudent mode is off and approximately 33'000 events per second in prudent mode. Prudent mode effectively serializes I/O operations between all JVMs writing to the same file. Thus, as the number of JVMs competing to access a file increases so will the delay incurred by each I/O operation. As long as the total number of I/O operations is in the order of 20 log requests per second, the impact on performance should be negligible. Applications generating 100 or more I/O operations per second can see an impact on performance and should avoid using prudent mode. Networked file locks When the log file is located on a networked file system, the cost of prudent mode is even greater. Just as importantly, file locks over a networked file system can be sometimes strongly biased such that the process currently owning the lock immediately re-obtains the lock upon its release. Thus, while one process hogs the lock for the log file, other processes starve waiting for the lock to the point of appearing deadlocked. The impact of prudent mode is highly dependent on network speed as well as the OS implementation details. We provide a very small application called FileLockSimulator which can help you simulate the behavior of prudent mode in your environment. |
Immediate Flush By default,
each log event is immediately flushed to the underlying output
stream. This default approach is safer in the sense that logging
events are not lost in case your application exits without properly
closing appenders. However, for significantly increased logging
throughput, you may want to set the immediateFlush property to
false.
Below is an example of a configuration file for
FileAppender:
Example: FileAppender configuration (logback-examples/src/main/resources/chapters/appenders/conf/logback-fileAppender.xml)
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile.log</file>
<append>true</append>
<!-- set immediateFlush to false for much higher logging throughput -->
<immediateFlush>true</immediateFlush>
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} -%kvp- %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
Requires a server call.
Requires a server call.
After changing the current directory to logback-examples, run this example by launching the following command:
java chapters.appenders.ConfigurationTester src/main/java/chapters/appenders/conf/logback-fileAppender.xml
Uniquely named files (by timestamp)
During the application development phase or in the case of
short-lived applications, e.g. batch applications, it is desirable
to create a new log file at each new application launch. This is
fairly easy to do with the help of the <timestamp>
element. Here's an example.
Example: Uniquely named FileAppender configuration by timestamp (logback-examples/src/main/resources/chapters/appenders/conf/logback-timestamp.xml)
<configuration>
<!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
the key "bySecond" into the logger context. This value will be
available to all subsequent configuration elements. -->
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<!-- use the previously created timestamp to create a uniquely
named log file -->
<file>log-${bySecond}.txt</file>
<encoder>
<pattern>%logger{35} -%kvp- %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
Requires a server call.
Requires a server call.
The timestamp element takes two mandatory attributes key and datePattern
and an optional timeReference
attribute. The key attribute is the name
of the key under which the timestamp will be available to
subsequent configuration elements as a
variable. The datePattern attribute
denotes the date pattern used to convert the current time (at which
the configuration file is parsed) into a string. The date pattern
should follow the conventions defined in SimpleDateFormat. The
timeReference attribute denotes the time
reference for the time stamp. The default is the
interpretation/parsing time of the configuration file, i.e. the
current time. However, under certain circumstances it might be
useful to use the context birth time as time reference. This can be
accomplished by setting the timeReference
attribute to "contextBirth".
Experiment with the <timestamp> element by
running the command:
java chapters.appenders.ConfigurationTester src/main/resources/chapters/appenders/conf/logback-timestamp.xml
To use the logger context birthdate as time reference, you would set the timeReference attribute to "contextBirth" as shown below.
Example: Timestamp using context birthdate as time reference (logback-examples/src/main/resources/chapters/appenders/conf/logback-timestamp-contextBirth.xml)
<configuration>
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"
timeReference="contextBirth"/>
...
</configuration>