Package org.apache.sis.util.logging
Class MonolineFormatter
java.lang.Object
java.util.logging.Formatter
org.apache.sis.util.logging.MonolineFormatter
A formatter writing log messages on a single line. Compared to the JDK Configuration from
The format can also be set from a
SimpleFormatter
,
this formatter uses only one line per message instead of two. For example, messages formatted by
MonolineFormatter
may look like:
By default,
Logging example 00:01
CONFIG
[MyApplication] Read configuration from “my-application/setup.xml”.
00:03
INFO
[EPSGFactory] Connected to the EPSG database version 9.1 on Derby 10.14.
00:12
WARNING
[NetcdfStore] Read “foo.nc” in 0.2 second.
MonolineFormatter
shows only the level and the message. One or two additional
fields can be inserted between the level and the message if the setTimeFormat(String)
or
setSourceFormat(String)
methods are invoked with o non-null argument. Examples:
setTimeFormat("HH:mm:ss")
for formatting the time like00:00:04"
, as time elapsed since theMonolineFormatter
creation time.setSourceFormat("logger:long")
for formatting the full logger name (e.g."org.apache.sis.storage.netcdf"
).setSourceFormat("class:short")
for formatting the short class name, without package (e.g."NetcdfStore"
).
Configuration from logging.properties
The format can also be set from a logging.properties
file.
For example, user can cut and paste the following properties into logging.properties
:
See setTimeFormat(String)
and setSourceFormat(String)
for more information about the
above time
and source
properties. Encoding and logging level are configured separately,
typically on the JDK ConsoleHandler
like below:
Thread safety
The sameMonolineFormatter
instance can be safely used by many threads without synchronization
on the part of the caller. Subclasses should make sure that any overridden methods remain safe to call
from multiple threads.- Since:
- 0.3
- Version:
- 1.0
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final StringBuffer
Buffer for formatting messages.private static final int
Format the fully qualified class name.private static final int
Format the class name without package.private int[]
Numerical values of levels for which to apply colors in increasing order.The colors to apply, ornull
if none.private String[]
X3.64 sequences of colors matching the levels declared incolorLevels
.private static final Comparator
<Level> A comparator for logging level.private static final int
Minimal number of stack trace elements to print before and after the "interesting" elements.private static final int
Number of characters or spaces to colorize at the beginning of lines that are continuation of a single log record.private final boolean
true
if the faint X.364 code is supported.private static final String[]
The label to use in thelogging.properties
for setting the source format.private String
The string to write on the left side of the first line of every log records.private static final Level
Log records at level below this threshold will be printed in faint color.private final int
The minimum amount of characters to use for writing logging level before the message.private static final int
Format the source logger only.private static final int
Format the source logger without base.private static final int
Maximal amount of causes to print in stack traces.private AutoMessageFormat
The message format, ornull
if not yet created.private String
Value of the last call toMessageFormat.applyPattern(String)
.private static final int
Format the class name and method name.private static final int
Do not format source class name.private final PrintWriter
The printer wrapping thewriter
.private static final boolean
Whether the logging level should be visible or not.private int
One of the following constants:NO_SOURCE
,LOGGER_SHORT
,LOGGER_LONG
,CLASS_SHORT
,CLASS_LONG
orMETHOD
.private final long
Time ofMonolineFormatter
creation, in milliseconds elapsed since January 1, 1970.private SimpleDateFormat
The format to use for formatting elapsed time, ornull
if there is none.private final LineAppender
The line writer. -
Constructor Summary
ConstructorsConstructorDescriptionConstructs a defaultMonolineFormatter
.MonolineFormatter
(Handler handler) Constructs aMonolineFormatter
configured for the given handler. -
Method Summary
Modifier and TypeMethodDescriptionprivate String
Gets the color for the given level.colors()
Returns thecolors
map, creating it if needed.Formats the given log record and returns the formatted string.formatMessage
(LogRecord record) Returns the localized message from the given log record.Returns the string to write on the left side of the first line of every log records, ornull
if none.getLevelColor
(Level level) Returns the color used for the given level, ornull
if none.Returns the format for the source, ornull
is the source is not shown.Returns the format for elapsed time, ornull
if the time is not shown.static MonolineFormatter
install()
Installs aMonolineFormatter
for the root logger, or returns the existing instance if any.static MonolineFormatter
Installs aMonolineFormatter
for the specified logger, or returns the existing instance if any.(package private) static int
levelWidth
(Level threshold) Returns the length of the widest level name, taking in account only the standard levels equals or greater than the given threshold.private static void
more
(Appendable writer, int numToSkip, boolean con) Formats the number of stack trace elements that where skipped.private static void
printAbridged
(Throwable exception, Appendable writer, String loggerName, String sourceClassName, String sourceMethodName) Prints an abridged stack trace.private void
Resets the colors to the default values.void
resetLevelColors
(boolean enabled) Resets the colors setting to its default value.void
Sets the string to write on the left side of the first line of every log records.void
setLevelColor
(Level level, String color) Sets the color to use for the given level, ornull
for removing colorization.void
setSourceFormat
(String format) Sets the format for displaying the source, or hides the source field.void
setTimeFormat
(String pattern) Sets the format for elapsed time, or hides the time field.private void
sourceFormat
(String format) Implementation ofsetSourceFormat(String)
, to be invoked also by the constructor.private void
timeFormat
(String pattern) Implementation ofsetTimeFormat(String)
, to be invoked also by the constructor.
-
Field Details
-
NO_SOURCE
private static final int NO_SOURCEDo not format source class name.- See Also:
-
LOGGER_SHORT
private static final int LOGGER_SHORTFormat the source logger without base.- See Also:
-
LOGGER_LONG
private static final int LOGGER_LONGFormat the source logger only.- See Also:
-
CLASS_SHORT
private static final int CLASS_SHORTFormat the class name without package.- See Also:
-
CLASS_LONG
private static final int CLASS_LONGFormat the fully qualified class name.- See Also:
-
METHOD
private static final int METHODFormat the class name and method name.- See Also:
-
FORMAT_LABELS
The label to use in thelogging.properties
for setting the source format. -
LEVEL_THRESHOLD
Log records at level below this threshold will be printed in faint color. Logs records at this level or above will be printed in normal color. This threshold is set to the default level of console handlers. -
COMPARATOR
A comparator for logging level. This comparator sorts finest levels first and severe levels last. -
SHOW_LEVEL
private static final boolean SHOW_LEVELWhether the logging level should be visible or not. We do not provide the option to hide the levels for now.- See Also:
-
CONTINUATION_MARGIN
private static final int CONTINUATION_MARGINNumber of characters or spaces to colorize at the beginning of lines that are continuation of a single log record. This count includes theStrings.CONTINUATION_MARK
character. Should not be smaller than 2 since algorithm in this class needs one white space afterStrings.CONTINUATION_MARK
.- See Also:
-
CONTEXT_STACK_TRACE_ELEMENTS
private static final int CONTEXT_STACK_TRACE_ELEMENTSMinimal number of stack trace elements to print before and after the "interesting" elements. The "interesting" elements are the first stack trace elements, and the element which point to the method that produced the log record.- See Also:
-
MAX_CAUSES
private static final int MAX_CAUSESMaximal amount of causes to print in stack traces. This is an arbitrary limit.- See Also:
-
header
The string to write on the left side of the first line of every log records. The default value is an empty string. This field cannot be null.- See Also:
-
colors
The colors to apply, ornull
if none.- See Also:
-
faintSupported
private final boolean faintSupportedtrue
if the faint X.364 code is supported. On MacOS, faint colors produce bad output. -
colorLevels
private transient int[] colorLevelsNumerical values of levels for which to apply colors in increasing order. Computed fromcolors
when first needed or when the color map changes. -
colorSequences
X3.64 sequences of colors matching the levels declared incolorLevels
. Computed fromcolors
when first needed or when the color map changes. -
levelWidth
private final int levelWidthThe minimum amount of characters to use for writing logging level before the message. If the logging level is shorter, remaining characters will be padded with spaces. This is used in order to align the messages.- See Also:
-
startMillis
private final long startMillisTime ofMonolineFormatter
creation, in milliseconds elapsed since January 1, 1970. -
timeFormat
The format to use for formatting elapsed time, ornull
if there is none. -
messageFormat
The message format, ornull
if not yet created. -
messagePattern
Value of the last call toMessageFormat.applyPattern(String)
. Saved in order to avoid callingapplyPattern(String)
in the common case where the same message is logged many times with different arguments. -
sourceFormat
private int sourceFormatOne of the following constants:NO_SOURCE
,LOGGER_SHORT
,LOGGER_LONG
,CLASS_SHORT
,CLASS_LONG
orMETHOD
. -
buffer
Buffer for formatting messages. We will reuse this buffer in order to reduce memory allocations. This is the buffer used internally bywriter
.This buffer is also arbitrarily chosen as our synchronization lock. The rational is that all operations on
StringBuffer
are synchronized anyway. So by reusing it for our lock, we will take only one monitor instead of two. -
writer
The line writer. This object transforms all"\r"
,"\n"
or"\r\n"
occurrences into a single line separator. This line separator will include space for the left margin, if needed. -
printer
The printer wrapping thewriter
. This is used forThrowable.printStackTrace(PrintWriter)
calls. We don't use the printer for other usage in order to avoid unnecessary indirections and synchronizations.
-
-
Constructor Details
-
MonolineFormatter
public MonolineFormatter()Constructs a defaultMonolineFormatter
. This no-argument constructor is invoked by the logging system if thelogging.properties
file contains the following line:- Since:
- 1.0
-
MonolineFormatter
Constructs aMonolineFormatter
configured for the given handler.Auto-configuration from the handler
Formatters are often associated to a particular handler. If this handler is known, giving it at construction time can help this formatter to configure itself. This handler is only a hint - it will not be modified, and no reference to that handler will be kept by this constructor.- Parameters:
handler
- The handler to be used with this formatter, ornull
if unknown.- See Also:
-
-
Method Details
-
levelWidth
Returns the length of the widest level name, taking in account only the standard levels equals or greater than the given threshold. -
getHeader
Returns the string to write on the left side of the first line of every log records, ornull
if none. This is a string to be shown just before the level.- Returns:
- the string to write on the left side of the first line of every log records, or
null
if none.
-
setHeader
Sets the string to write on the left side of the first line of every log records.- Parameters:
header
- The string to write on the left side of the first line of every log records, ornull
if none.
-
getTimeFormat
Returns the format for elapsed time, ornull
if the time is not shown. This method returns the pattern specified by the last call to thesetTimeFormat(String)
method, or the patten specified by theorg.apache.sis.util.logging.MonolineFormatter.time
property in thejre/lib/logging.properties
file.- Returns:
- the time pattern, or
null
if elapsed time is not formatted.
-
setTimeFormat
Sets the format for elapsed time, or hides the time field. The pattern must matches the format specified inSimpleDateFormat
, but for the time part only (no date).Example: The"HH:mm:ss.SSS"
pattern will display the elapsed time in hours, minutes, seconds and milliseconds.- Parameters:
pattern
- the time pattern, ornull
to disable time formatting.- Throws:
IllegalArgumentException
- if the given pattern is invalid.
-
timeFormat
Implementation ofsetTimeFormat(String)
, to be invoked also by the constructor.- Throws:
IllegalArgumentException
-
getSourceFormat
Returns the format for the source, ornull
is the source is not shown. This method returns the source format specified by the last call to thesetSourceFormat(String)
method, or the format specified by theorg.apache.sis.util.logging.MonolineFormatter.source
property in thejre/lib/logging.properties
file.- Returns:
- the source format, or
null
if source is not formatted.
-
setSourceFormat
Sets the format for displaying the source, or hides the source field. The given format can be any of the following values, from more verbose to less verbose:null
for hiding the source field."class:long"
for the source class name"logger:long"
for the logger name"class:short"
for the source class name without the package part."logger:short"
for the logger name without the package part."class.method"
for the short class name followed by the source method name
- Parameters:
format
- the format for displaying the source, ornull
if the source shall not be formatted.- Throws:
IllegalArgumentException
- if the given argument is not one of the recognized format names.
-
sourceFormat
Implementation ofsetSourceFormat(String)
, to be invoked also by the constructor.- Throws:
IllegalArgumentException
-
getLevelColor
Returns the color used for the given level, ornull
if none. The current set of supported colors are"red"
,"green"
,"yellow"
,"blue"
,"magenta"
,"cyan"
and"gray"
. This set may be extended in any future SIS version.- Parameters:
level
- the level for which to get the color.- Returns:
- the color for the given level, or
null
if none.
-
setLevelColor
Sets the color to use for the given level, ornull
for removing colorization. This method should be invoked only if this formatter is associated to aHandler
writing to a terminal supporting ANSI escape codes (a.k.a. ECMA-48, ISO/IEC 6429 and X3.64 standards).The given
color
argument shall be one of the values documented in thegetLevelColor(Level)
method.- Parameters:
level
- the level for which to set a new color.color
- the case-insensitive new color, ornull
if none.- Throws:
IllegalArgumentException
- if the given color is not one of the recognized values.
-
colors
Returns thecolors
map, creating it if needed. -
resetLevelColors
private void resetLevelColors()Resets the colors to the default values. This method does not check if ANSI escape codes are supported or not - this check must be done by the caller. -
resetLevelColors
public void resetLevelColors(boolean enabled) Resets the colors setting to its default value.- If
enabled
istrue
, then this method defines a default set of colors. - If
enabled
isfalse
, then this method resets the formatting to plain text.
- Parameters:
enabled
-true
for defining a default set of colors, orfalse
for removing all colors.
- If
-
colorAt
Gets the color for the given level. If there is no explicit color for the given level, returns the color of the first level below the given one for which a color is specified. -
format
Formats the given log record and returns the formatted string. See the class javadoc for information on the log format. -
formatMessage
Returns the localized message from the given log record. First this method gets the raw message from the given record. Then there is choices:- If the given record specifies a resource bundle, then the message is used as a key for fetching the localized resources in the given bundle.
- If the given record specifies one or more parameters
and if the message seems to use the
MessageFormat
syntax, then the message is formatted byMessageFormat
.
- Overrides:
formatMessage
in classFormatter
- Parameters:
record
- The log record from which to get a localized message.- Returns:
- the localized message.
-
printAbridged
private static void printAbridged(Throwable exception, Appendable writer, String loggerName, String sourceClassName, String sourceMethodName) throws IOException Prints an abridged stack trace. This method is invoked when the record is logged at at low logging level (typically less thanLevel.INFO
).- Parameters:
exception
- the exception to be logged.writer
- where to print the stack trace.loggerName
- the name of the logger when the log will be sent.sourceClassName
- the name of the class that emitted the log.sourceMethodName
- the name of the method that emitted the log.- Throws:
IOException
-
more
Formats the number of stack trace elements that where skipped.- Throws:
IOException
-
install
Installs aMonolineFormatter
for the root logger, or returns the existing instance if any. This method performs the following choices:- If a
ConsoleHandler
is associated to the root logger, then:- If that handler already uses a
MonolineFormatter
, then the existing formatter is returned. - Otherwise the
ConsoleHandler
formatter is replaced by a newMonolineFormatter
instance, and that new instance is returned. We perform this replacement in order to avoid sending twice the same records to the console.
- If that handler already uses a
- Otherwise a new
ConsoleHandler
using a newMonolineFormatter
is created and added to the root logger.
Implementation note: The current implementation does not check for duplicatedConsoleHandler
instances, and does not check if any child logger has aConsoleHandler
.- Returns:
- the new or existing
MonolineFormatter
. The formatter output can be configured using thesetTimeFormat(String)
andsetSourceFormat(String)
methods. - Throws:
SecurityException
- if this method does not have the permission to install the formatter.
- If a
-
install
@Debug @Configuration public static MonolineFormatter install(Logger logger, Level level) throws SecurityException Installs aMonolineFormatter
for the specified logger, or returns the existing instance if any. This method performs the following steps:- If a
ConsoleHandler
is associated to the given logger, then:- If that handler already uses a
MonolineFormatter
, then the existing formatter is returned. - Otherwise the
ConsoleHandler
formatter is replaced by a newMonolineFormatter
instance, and that new instance is returned. We perform this replacement in order to avoid sending twice the same records to the console.
- If that handler already uses a
- Otherwise:
- The
Logger.setUseParentHandlers(boolean)
flag is set tofalse
for avoiding duplicated loggings if aConsoleHandler
instance exists in the parent handlers. - Parent handlers that are not
ConsoleHandler
instances are added to the given logger in order to preserve similar behavior as before the call tosetUseParentHandlers(false)
. - A new
ConsoleHandler
using a newMonolineFormatter
is created and added to the given logger.
- The
Implementation note: The current implementation does not check for duplicatedConsoleHandler
instances, and does not check if any child logger has aConsoleHandler
.Specifying a log level
This method can opportunistically set the handler level. If the given level is non-null, then theConsoleHandler
using theMonolineFormatter
will be set to that level. This is mostly a convenience for temporary increase of logging verbosity for debugging purpose. This functionality should not be used in production environment, since it overwrite user's level setting.- Parameters:
logger
- the base logger to apply the change on.level
- the desired level, ornull
if no level should be set.- Returns:
- the new or existing
MonolineFormatter
. The formatter output can be configured using thesetTimeFormat(String)
andsetSourceFormat(String)
methods. - Throws:
SecurityException
- if this method does not have the permission to install the formatter.
- If a
-