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
stdout
that 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 levelINFO
or greater are sent to thestdout
sink.
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:
stdout
to the standard output stream;stderr
to the standard error stream;seq
to a Seq log aggregator server; andauditing
to a Splunk server.
Three logging configurations, which together mean:
-
Loggers with names starting with
com.example
dispatch their log events:- all at level
INFO
or greater to sinkseq
; - at level
INFO
also to sinkstdout
; and - any at level
WARN
or greater to sinkstderr
.
- all at level
-
Logger
com.example.service.FancyService
also dispatches log events with levelDEBUG
to sinkseq
. -
Loggers with names starting with
audit
dispatch 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.rest
log from levelERROR
. - All other loggers with names starting with
com.example
log 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
stdout
sink renders events with the built-in rendererRENDER_SIMPLE
and dispatches them to the standard output using the built-inSTDOUT
dispatcher. - The
seq
sink uses the built-inseq
function 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",
)
)
hecUrl
specifies the URL of the Splunk server’s HEC endpoint. It uses HTTPS by default.hecToken
is the HEC token used by Splunk for these logging events. It is a secret that should be passed in via the execution environment.index
is 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.sourceType
is the Splunksourcetype
value (optional). If not set, Splunk will usehttpevent
or a value configured for the HEC token.source
is the Splunksource
value, typically the name of an application (optional). If not set, Splunk will use a name configured with the HEC token.checkCertificate
indicates 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.BlodgeService
etc. -
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-1
andStage-2
but 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 atINFO
level and above (i.e. more severe:WARN
,ERROR
andFATAL
) to be dispatched. -
toMaxLevel(Level.INFO)
enables all events up toINFO
level and below (i.e. less severe:TRACE
andDEBUG
) to be dispatched. -
atLevel(Level.WARN)
enables only events atWARN
level to be dispatched by matching loggers. -
inLevelRange(Level.DEBUG, Level.WARN)
enables all events in the range of levels fromDEBUG
toWARN
, 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
.