Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
518 views
in Technique[技术] by (71.8m points)

kotlin - Ktor doesn't log exceptions

Ktor (1.4.2) seems to be suppresing exceptions. According to documentation I need to re-throw exception like this

install(StatusPages) {
    exception<Throwable> { ex ->
        val callstack: String = ....
        call.respond(HttpStatusCode.InternalServerError,
                ApiError(ex.javaClass.simpleName, ex.message ?: "Empty Message", callstack)
        )
        throw ex
    }
}

I wrote wrapper around Logger interface to make sure it's calling Logger.error() (it doesn't) and configured it like this

install(CallLogging) {
            level = org.slf4j.event.Level.INFO
            logger = Log4j2Wrapper(logger2)
        }

I can see INFO-level logs. What am I missing ?

question from:https://stackoverflow.com/questions/65887243/ktor-doesnt-log-exceptions

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Turned out the problem is in rather akward design of ktor api. Summary of my findings:

Contrary to common expectation to see log events of specified log level and above it doesn't that way with CallLogging. It expects exact match of the logging level which minimizes usefulness of this feature.

You need to overwrite logger specified in ApplicationEnvironment.log. But if you follow official ktor examples and do it like this

val server = embeddedServer(Netty, port) {
  applicationEngineEnvironment {
      log = YOUR_LOGGER
  }
}

it won't work because value call.application.environment inside function io.ktor.server.engine.defaultEnginePipeline(env) is still original one, created from logger name in config file or NOP logger.

Hence you'll need to initialize your server like this

val env = applicationEngineEnvironment {
    log = YOUR_LOGGER
    module {
        install(CallLogging) {
            level = org.slf4j.event.Level.INFO
        }
        install(StatusPages) {
            exception<Throwable> { ex ->
                val callstack: String = ...
                call.respond(HttpStatusCode.InternalServerError,
                        ApiError(ex.javaClass.simpleName, ex.message ?: "Empty Message", callstack)
                )
                throw ex
            }
        }

        routing {
        }
    }

    connector {
        host = "0.0.0.0"
        port = ...
    }
}

val server = embeddedServer(Netty, env)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...