fun Application.logRequests() {
    val logRequestPhase = PipelinePhase("log request")

    receivePipeline.insertPhaseAfter(ApplicationReceivePipeline.Phases.Transform, logRequestPhase)

    receivePipeline.intercept(logRequestPhase) { subject ->
        log.trace(
            buildString {
                append("Request: ")
                append(call.request.httpMethod.value)
                append(" ")
                append(call.request.uri)
                append(", body: ")
                append(subject.value)
            }
        )
    }
}

fun Application.logResponses() {
    val logResponsePhase = PipelinePhase("log response")

    sendPipeline.insertPhaseAfter(ApplicationSendPipeline.Phases.Render, logResponsePhase)

    sendPipeline.intercept(logResponsePhase) { subject ->
        log.trace(
            buildString {
                append("Request: ")
                append(call.request.httpMethod.value)
                append(" ")
                append(call.request.uri)
                append(" - Response: ")
                append(call.response.status())
                append(", body: ")
                append(subject)
            }
        )
    }
}