<commit_before>package org.jetbrains.ktor.logging

import org.jetbrains.ktor.application.*
import org.jetbrains.ktor.http.*
import org.jetbrains.ktor.pipeline.*
import org.jetbrains.ktor.request.*
import org.jetbrains.ktor.util.*

object CallLogging : ApplicationFeature<Application, Unit, Unit> {
    override val key: AttributeKey<Unit> = AttributeKey("Call Logging")

    override fun install(pipeline: Application, configure: Unit.() -> Unit) {
        val loggingPhase = PipelinePhase("Logging")
        pipeline.phases.insertBefore(ApplicationCallPipeline.Infrastructure, loggingPhase)
        pipeline.intercept(loggingPhase) { call ->
            try {
                proceed()
                pipeline.logCallFinished(call)
            } catch(t: Throwable) {
                pipeline.logCallFailed(call, t)
            }
        }
    }

    private fun Application.logCallFinished(call: ApplicationCall) {
        val status = call.response.status() ?: "Unhandled"
        when (status) {
            HttpStatusCode.Found -> environment.log.trace("$status: ${call.request.logInfo()} -> ${call.response.headers[HttpHeaders.Location]}")
            else -> environment.log.trace("$status: ${call.request.logInfo()}")
        }
    }

    private fun Application.logCallFailed(call: ApplicationCall, e: Throwable) {
        try {
            val status = call.response.status() ?: "Unhandled"
            environment.log.error("$status: ${call.request.logInfo()}", e)
        } catch (oom: OutOfMemoryError) {
            try {
                environment.log.error(e)
            } catch (oomAttempt2: OutOfMemoryError) {
                System.err.print("OutOfMemoryError: ")
                System.err.println(e.message)
            }
        }
    }

    private fun ApplicationRequest.logInfo() = "${httpMethod.value} - ${path()}"
}<commit_msg>Refactor CallLogging to accept configuration, making it possible to log errors only<commit_after>package org.jetbrains.ktor.logging

import org.jetbrains.ktor.application.*
import org.jetbrains.ktor.http.*
import org.jetbrains.ktor.pipeline.*
import org.jetbrains.ktor.request.*
import org.jetbrains.ktor.util.*

class CallLogging(val log: ApplicationLog, val logSuccess: Boolean) {

    class Configuration {
        var logSuccess = true
    }

    companion object Feature : ApplicationFeature<Application, CallLogging.Configuration, CallLogging> {
        override val key: AttributeKey<CallLogging> = AttributeKey("Call Logging")
        override fun install(pipeline: Application, configure: Configuration.() -> Unit): CallLogging {
            val loggingPhase = PipelinePhase("Logging")
            val configuration = Configuration().apply(configure)
            val feature = CallLogging(pipeline.environment.log, configuration.logSuccess)
            pipeline.phases.insertBefore(ApplicationCallPipeline.Infrastructure, loggingPhase)
            pipeline.intercept(loggingPhase) { call ->
                try {
                    proceed()
                    if (feature.logSuccess)
                        feature.logSuccess(call)
                } catch(t: Throwable) {
                    feature.logFailure(call, t)
                }
            }
            return feature
        }
    }

    private fun logSuccess(call: ApplicationCall) {
        val status = call.response.status() ?: "Unhandled"
        when (status) {
            HttpStatusCode.Found -> log.trace("$status: ${call.request.logInfo()} -> ${call.response.headers[HttpHeaders.Location]}")
            else -> log.trace("$status: ${call.request.logInfo()}")
        }
    }

    private fun logFailure(call: ApplicationCall, e: Throwable) {
        try {
            val status = call.response.status() ?: "Unhandled"
            log.error("$status: ${call.request.logInfo()}", e)
        } catch (oom: OutOfMemoryError) {
            try {
                log.error(e)
            } catch (oomAttempt2: OutOfMemoryError) {
                System.err.print("OutOfMemoryError: ")
                System.err.println(e.message)
            }
        }
    }

    private fun ApplicationRequest.logInfo() = "${httpMethod.value} - ${path()}"
}
{'fraction_non_alphanumeric': 0.11782982791586998, 'fraction_numerical': 0.0004780114722753346, 'mean_word_length': 2.37772397094431, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6346996', 'n_tokens_mistral': 1127, 'n_tokens_neox': 1118, 'n_words': 216}