Logging
genhttp-kt logs through SLF4J, the logging facade of the JVM,
and allows to create loggers via the Server interface. If there is an SLF4J provider on the
classpath (such as Logback, Log4j 2 or slf4j-simple), the server logs through it. Otherwise,
the host falls back to a console logger of its own (and SLF4J warns once at startup that it
found no provider).
Logging Information
The following code shows to obtain a logger from the server instance in
a custom Handler implementation. It is recommended to create the logger
once in the preparation phase and store the reference somewhere. You can use
this pattern anywhere where you have access to Server (e.g. via request.server).
import org.genhttp.api.content.Handler
import org.genhttp.api.infrastructure.Server
import org.genhttp.api.protocol.Request
import org.genhttp.api.protocol.Response
import org.slf4j.Logger
class MyHandler : Handler {
private var logger: Logger? = null
override suspend fun prepare(server: Server) {
logger = server.logging.getLogger(MyHandler::class.java.name)
}
override suspend fun handle(request: Request): Response? {
logger?.info("I am logging important information")
return null
}
}Customize Logging
To log through a logging framework, add its SLF4J provider to your project - genhttp-kt
picks it up automatically, and the framework is configured as usual (e.g. with a logback.xml):
dependencies {
implementation("ch.qos.logback:logback-classic:1.5.18")
}This way, you can also use OpenTelemetry for logging: its Java agent captures the logs written via Logback or Log4j and exports them via OTLP, without any change to your code:
java -javaagent:opentelemetry-javaagent.jar -Dotel.service.name=my-service -jar my-service.jarThe logging() method of the host builder allows to pass a custom
logging factory (org.slf4j.ILoggerFactory) that should be used by the application instead.
The following example uses the console logger of genhttp-kt with debug output:
import org.genhttp.engine.internal.Host
import org.genhttp.engine.shared.infrastructure.logging.ConsoleLoggerFactory
import org.genhttp.modules.layouting.Layout
import org.genhttp.modules.practices.defaults
import org.slf4j.event.Level
suspend fun main() {
val handler = Layout.create()
Host.create()
.logging(ConsoleLoggerFactory(Level.DEBUG))
.handler(handler)
.defaults()
.run()
}To disable logging, you can pass a no-operation logger factory:
import org.genhttp.engine.internal.Host
import org.slf4j.helpers.NOPLoggerFactory
val host = Host.create()
.logging(NOPLoggerFactory())Request Logging
By default, genhttp-kt will install a concern that logs every request and the
response it generated (with the logger GenHTTP.Requests at level INFO).
info: GenHTTP.Requests
GET /api/ - HTTP 200 - 12 bytes - 18.52 ms
info: GenHTTP.Requests
GET /favicon.ico - HTTP 404 - 0 bytes - 1.49 ms
info: GenHTTP.Requests
GET /assets/styles.css - HTTP 200 - 0 bytes - 1.03 msIf you would like to opt-out of request logging, you can pass a flag to the
logging() method of the host builder. ConsoleLoggerFactory.createDefault() returns
the factory the host uses by default:
import org.genhttp.engine.internal.Host
import org.genhttp.engine.shared.infrastructure.logging.ConsoleLoggerFactory
import org.genhttp.modules.layouting.Layout
import org.genhttp.modules.practices.defaults
suspend fun main() {
val handler = Layout.create()
Host.create()
.logging(ConsoleLoggerFactory.createDefault(), logRequests = false)
.handler(handler)
.defaults()
.run()
}With a logging framework, you may also raise the level of the GenHTTP.Requests logger in its configuration instead.