|
GreyLog
is a fully configurable, high performance logging framework, which contains particular optimisations to support 8-bit charsets (ie. the vast majority) and single-threaded mode.
It consists of the
com.grey.logging
Java package.
GreyLog differs from
Log4j12, JUL (java.util.logging
)
and other logging frameworks, in that its loggers really are logfile streams, and not merely formatting handlers which cascade into a single actual logger.
This means that care has to be taken when instantiating GreyLog loggers via
SLF4J.
SLF4J and JCL (Apache Commons Logging)
are biased towards Log4j12 and JUL, and developers typically expect to call
org.slf4j.LoggerFactory.getLogger(name)
(or the JCL equivalent) in every module, using a different name each time, without actually creating multiple I/O streams.
In the case of GreyLog, this would result in multiple logfile streams which is probably not what you intended, so the required loggers need to be created in one place and then made available.
GreyLog is part of the
NAF
suite, but it has no dependency on NAF's reactor core and is suitable for use by non-NAF applications - whether invoked directly or via its SLF4J adapter.
GreyLog loggers are created by the
com.grey.logging.Factory
class, which provides a number of
getLogger()
factory methods.
All of them are based on a config file which is generically termed the
logging.xml
file (though it's not necessarily called that) and contains named entries, each of which specifies and defines a particular logger.
If you call a getLogger()
variant that doesn't specify a config file, then the global default logging.xml file is used.
If you call a getLogger()
variant that doesn't specify a named logger (or you specify a blank or null name), then a special logging.xml entry called the
default
logger is used.
The default entry need not exist (though it is recommended that you do define it) and if it doesn't GreyLog will create a logger with default settings, which can be influenced by system properties (see the default constructor in the
com.grey.logging.Parameters
source code), but is typically the standard-output stream.
If you specify a named logger other than default, and it doesn't exist in the logging.xml file, then a
SinkLogger
instance is returned, which silently discards all messages written to it.
The first time the GreyLog framework tries to access the default logging.xml config file, it looks for it on the following search path:
• If the grey.logger.configfile system property is set, then it specifies the pathname.
• ./logging.xml (ie. look in current directory)
• ./conf/logging.xml
• $HOME/logging.xml
• Looks for it on the classpath as ./logging.xml.
If still not found, then getLogger()
calls will treat all requested loggers as non-existent, so as described above, any logger other than default will get mapped to the SinkLogger
.
The example below illustrates the structure of the logging.xml config file, and the logger name specified in the
getLogger()
call is used to select the matching
logger
block.
<loggers> <logger name="default"> <file class="com.grey.logging.MTLatinLogger">%stdout%</file> </logger> <logger name="mylogger1"> <file level="trc" rot="daily">%DIRLOG%/app.log</file> </logger> <logger name="mylogger2"> <file maxfile="10M">app2.log</file> </logger> </loggers> |
The value of the
file
element specifies the pathname of the output file, which is actually a template name in which the timestamp gets embedded.
It can also take the special values
%stdout% and
%stderr%,
which will direct logging output to the process's standard-output or standard-error instead.
If it contains the special token
%DIRLOG%, that will be replaced by the value of the
grey.logger.dir system property.
If it contains the special token
%DIRTMP%, that will be replaced by the value of
com.grey.base.config.SysProps.TMPDIR
.
If it contains the special token
%TID%, that will be replaced by the Java thread ID
(Thread.currentThread().getId()
).
The attributes of the
file
elements are shown below.
The default values for all these config attributes are determined via system properties. See the
com.grey.logging.Parameters
source code.
com.grey.logging.LatinLogger
,
which is a logger that may outperform others by avoiding the overhead of converting text to bytes based on the assumption that the log messages are all 8-bit charsets, and can be mapped to 1-to-1 to a byte stream.
com.grey.logging.CharLogger
,
which supports arbitrary text.
LatinLogger
and CharLogger
are both single-threaded, so
MTLatinLogger
and MTCharLogger
are their MT-safe counterparts.
These are particularly recommended for the
default
logger, as it may potentially be used by multiple threads.
com.grey.logging.Logger
, and provide a constructor with the signature
classname(Parameters, String logname)
.
Thread.currentThread().getName()
) unless the system property
grey.logger.threadname
is explicitly set to No.
If the system property
grey.logger.diagnostics
is set to Yes, then progress messages on the search for the
logging.xml file and the process of creating a logger will be printed to the process's standard-output.
If the system property
grey.logger.sinkstdio
is set to Yes, then instead of missing loggers (ie. specified name not found in logging.xml file) being mapped to the SinkLogger, they will be mapped to a logger with default settings, ie. the same type of logger that would be created for a missing
default logger (which as explained above, is typically on stdout).
This can be useful if you don't want to lose any logging output regardless of your logging.xml config.
While the GreyLog framework itself has nothing to do with
SLF4J,
it contains an adapter library
(see the
greylog-slf4j
Maven project)
which enables it to act as underlying logger for SLF4J.
So long as the greylog-slf4j JAR is on your classpath, instantiations of SLF4J loggers will be redirected to GreyLog.
That is, calls to
org.slf4j.LoggerFactory.getLogger(name)
will get mapped to
com.grey.logging.Factory.getLogger(name)
and as explained above, that will load the default
logging.xml
file.
Applications based on Commons Logging (JCL) can bind to the GreyLog framework by including the
jcl-over-slf4j
and
slf4j-api
JARs on their classpath, in addition to the
greylog-slf4j
JAR.
Applications based on the JDK's built-in JUL
(java.util.logging
)
logging can bind to the GreyLog framework by including the
jul-to-slf4j
and
slf4j-api
JARs on their classpath, in addition to the
greylog-slf4j
JAR.