All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mpierce.gcp.logging.http.ktor.HttpRequestMetadataLogging.kt Maven / Gradle / Ivy

package org.mpierce.gcp.logging.http.ktor

import com.google.cloud.logging.HttpRequest
import io.ktor.application.Application
import io.ktor.application.ApplicationCallPipeline
import io.ktor.application.ApplicationFeature
import io.ktor.application.call
import io.ktor.features.origin
import io.ktor.http.HttpMethod
import io.ktor.request.httpMethod
import io.ktor.request.uri
import io.ktor.request.userAgent
import io.ktor.util.AttributeKey
import kotlinx.coroutines.asContextElement
import kotlinx.coroutines.withContext
import org.mpierce.gcp.logging.http.HttpRequestEnhancer

/**
 * Capture request metadata so it's accessible for [HttpRequestEnhancer].
 */
class HttpRequestMetadataLogging {
    companion object Feature : ApplicationFeature {
        override val key: AttributeKey = AttributeKey("Http request metadata thread local")

        override fun install(pipeline: Application, configure: Unit.() -> Unit): HttpRequestMetadataLogging {
            val feature = HttpRequestMetadataLogging()

            pipeline.intercept(ApplicationCallPipeline.Features) {
                val httpReq = HttpRequest.newBuilder().run {
                    val method = when (call.request.httpMethod) {
                        HttpMethod.Get -> HttpRequest.RequestMethod.GET
                        HttpMethod.Head -> HttpRequest.RequestMethod.HEAD
                        HttpMethod.Post -> HttpRequest.RequestMethod.POST
                        HttpMethod.Put -> HttpRequest.RequestMethod.PUT
                        // RequestMethod only has prebuilt instances for a few headers
                        else -> HttpRequest.RequestMethod.valueOf(call.request.httpMethod.value)
                    }

                    // other request to potentially populate:
                    // request size
                    // and also a bunch of response stuff:
                    // status
                    // response seize
                    // latency
                    // cacheLookup
                    // cacheHit
                    // cacheValidated
                    // cacheFillBytes
                    // protocol

                    setRequestMethod(method)
                    setRequestUrl(call.request.uri)
                    setUserAgent(call.request.userAgent())
                    setRemoteIp(call.request.origin.remoteHost)
                    build()
                }

                withContext(HttpRequestEnhancer.HTTP_REQUEST_METADATA.asContextElement(httpReq)) {
                    proceed()
                }
            }

            return feature
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy