Configuration DSL
Klogging has a configuration DSL that makes it easy to get started. Put the configuration to run as early as possible in your program.
A simple example
Here is a simple example:
loggingConfiguration {
sink("stdout", RENDER_SIMPLE, STDOUT)
sink("seq", seq("http://localhost:5341"))
logging {
fromLoggerBase("com.example")
fromMinLevel(Level.INFO) {
toSink("stdout")
}
}
}
This configuration:
-
First declares a sink called
stdoutthat renders each log event into a simple string format and sends it to the standard output stream. Sinks need to be configured first, before they can be used. -
Next declares a logging configuration that applies to loggers with names starting with
com.example. In this configuration, all log events at severity levelINFOor greater are sent to thestdoutsink.
The logging section must follow the sink declarations.
A more complex example
loggingConfiguration {
sink("stdout", RENDER_SIMPLE, STDOUT)
sink("stderr", RENDER_SIMPLE, STDERR)
sink("seq", seq(
url = "http://seq-server:5341",
apiKey = getenv("SEQ_API_KEY")
))
sink("auditing", splunkHec(
SplunkEndpoint(
hecUrl = "https://splunk-server:8088",
hecToken = getenv("AUDIT_HEC_TOKEN")!!
)
))
logging {
fromLoggerBase("com.example")
atLevel(Level.INFO) {
toSink("stdout")
toSink("seq")
}
fromMinLevel(Level.WARN) {
toSink("stderr")
toSink("seq")
}
}
logging {
exactLogger("com.example.service.FancyService")
fromMinLevel(Level.DEBUG) { toSink("seq") }
}
logging {
fromLoggerBase("audit")
toSink("auditing")
}
kloggingMinLevel(DEBUG)
minDirectLogLevel(INFO)
}
This example has four sinks:
stdoutto the standard output stream;stderrto the standard error stream;seqto a Seq log aggregator server; andauditingto a Splunk server.
Three logging configurations, which together mean:
-
Loggers with names starting with
com.exampledispatch their log events:- all at level
INFOor greater to sinkseq; - at level
INFOalso to sinkstdout; and - any at level
WARNor greater to sinkstderr.
- all at level
-
Logger
com.example.service.FancyServicealso dispatches log events with levelDEBUGto sinkseq. -
Loggers with names starting with
auditdispatch all log events to sinkauditing.
This configuration also sets minimum logging levels for Klogging’s internal logger and for sending log events directly.
Short-circuit matching with stopOnMatch
You can reduce log volumes and create detailed logging configurations with short-circuit matching of
loggers. The logger-matching functions take an optional stopOnMatch parameter that specifies
whether to continue matching or to stop.
For example:
loggingConfiguration {
sink("stdout", RENDER_ANSI, STDOUT)
logging {
fromLoggerBase("com.example.rest", stopOnMatch = true)
fromMinLevel(Level.ERROR) {
toSink("stdout")
}
}
logging {
fromLoggerBase("com.example")
fromMinLevel(Level.DEBUG) {
toSink("stdout")
}
}
}
This configuration specifies:
- Loggers with names starting with
com.example.restlog from levelERROR. - All other loggers with names starting with
com.examplelog from levelDEBUG.
So logging is as follows:
| Logger | TRACE | DEBUG | INFO | WARN | ERROR | FATAL |
|---|---|---|---|---|---|---|
com.example.rest.RestClient | ✅ | ✅ | ||||
com.example.ExampleClass | ✅ | ✅ | ✅ | ✅ | ✅ | |
com.example.service.HealthService | ✅ | ✅ | ✅ | ✅ | ✅ |
The order of logging functions determines when matching stops.
DSL reference
loggingConfiguration
This function creates a configuration for the running program. It makes sense to call this as early as possible in program startup. It uses specifications in the supplied lambda.
By default, the configuration replaces any existing one:
loggingConfiguration {
// ...
}
One scenario for appending a configuration is where the code defines a custom renderer or sender.
import com.example.customRenderer
loggingConfiguration(append = true) {
sink("custom", customRenderer, STDOUT)
}
sink
This function configures a named sink with a renderer and a sender.
This example configures two sinks:
sink("stdout", RENDER_SIMPLE, STDOUT)
sink(
"seq",
seq(
url = "https://seq.example.com:45341",
apiToken = getenv("SEQ_API_TOKEN")!!,
checkCertificate = false,
)
)
- The
stdoutsink renders events with the built-in rendererRENDER_SIMPLEand dispatches them to the standard output using the built-inSTDOUTdispatcher. - The
seqsink uses the built-inseqfunction for rendering events in CLEF compact JSON format and dispatching them to a Seq server:- The server endpoint is
https://seq.example.com:45341 - Get the API token from the running environment key
SEQ_API_TOKEN(a secret that should be passed in via the execution environment) - Trust the TLS certificate used by the Seq server
- The server endpoint is
Klogging also supports logging directly to a Splunk HTTP Event Collector
(HEC), specified using the
splunkHec function:
splunkHec(
SplunkEndpoint(
hecUrl = "https://splunk:8088",
hecToken = getenv("SPLUNK_HEC_TOKEN")!!,
source = "MyApplication",
checkCertificate = "true",
)
)
hecUrlspecifies the URL of the Splunk server’s HEC endpoint. It uses HTTPS by default.hecTokenis the HEC token used by Splunk for these logging events. It is a secret that should be passed in via the execution environment.indexis the Splunk index for the events (optional). If set, it must be a value configured in Splunk. If not set, Splunk will use the default index configured for the HEC token.sourceTypeis the Splunksourcetypevalue (optional). If not set, Splunk will usehttpeventor a value configured for the HEC token.sourceis the Splunksourcevalue, typically the name of an application (optional). If not set, Splunk will use a name configured with the HEC token.checkCertificateindicates whether Klogging should check the TLS certificate used by the Splunk server (string: default"true").
You can create a custom renderer or sender and use it in a sink definition.
logging
This function configures logging from specified loggers at specified levels to specified
sinks. Your configuration must include at least one logging function for Klogging to
emit any logs.
The following sections explain details.
fromLoggerBase, exactLogger and matchLogger
These functions specify how to match logger names. For example:
-
fromLoggerBase("com.example")matches all loggers with names that start withcom.example, such ascom.example.config.ConfigApp,com.example.services.BlodgeServiceetc. -
exactLogger("com.example.services.GlubService")matches only the logger calledcom.example.services.GlubService. No other logger with match. -
matchLogger("Stage-[0-2]")uses a Kotlin regular expression pattern that matches loggersStage-0,Stage-1andStage-2but notStage-3.
All three functions accept a boolean stopOnMatch argument with default value false.
These functions are optional: if logger names are not specified, all loggers will match. This configuration is the equivalent of the root logger in Log4j or Logback.
In the DSL, the last-used function replaces earlier ones.
fromMinlevel, toMaxLevel, atLevel and inLevelRange
These functions specify the levels at which to dispatch log events. For example:
-
fromMinLevel(Level.INFO)enables all events atINFOlevel and above (i.e. more severe:WARN,ERRORandFATAL) to be dispatched. -
toMaxLevel(Level.INFO)enables all events up toINFOlevel and below (i.e. less severe:TRACEandDEBUG) to be dispatched. -
atLevel(Level.WARN)enables only events atWARNlevel to be dispatched by matching loggers. -
inLevelRange(Level.DEBUG, Level.WARN)enables all events in the range of levels fromDEBUGtoWARN, inclusive.
The functions accept a lambda to specify which sinks to dispatch to.
At least one of these functions must be specified or else Klogging will not emit any events for the specified loggers.
toSink
This function specifies the name of a sink to dispatch events to. It can be called mulitple times for a level specification. The sink must have been defined previously by name, otherwise a short warning is written to the console and the configuration is ignored.
An example:
fromMinLevel(Level.INFO) {
toSink("console")
toSink("seq")
}
During dispatching, an event is never dispatched to a sink more than once. Given this configuration:
logging {
fromLoggerBase("com.example")
fromMinLevel(Level.INFO) {
toSink("stdout")
toSink("splunk")
}
fromMinLevel(Level.WARN) {
toSink("stderr")
toSink("splunk")
}
}
An event from logger com.example.nurdling.NurdleController at level WARN is dispatched
to splunk only once.
There is no need to disable additivity as in Log4J and Logback.
minDirectLogLevel()
This function specifies the minimum level at which log events are sent direct to sinks instead of being sent asynchronously via coroutine channels.
If not specified, the level is that set by the value of environment
variable KLOGGING_MIN_DIRECT_LOG_LEVEL, which will override
the default value WARN.
See direct logging for details.
kloggingMinLogLevel()
This function sets the minimum level used by the internal logger to decide whether to emit log messages.
If not specified, the level is that set by the value of environment
variable KLOGGING_MIN_LOG_LEVEL, which will override the
default value INFO.