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

fuookami.ospf.kotlin.framework.log.LogContext.kt Maven / Gradle / Ivy

There is a newer version: 1.0.31
Show newest version
package fuookami.ospf.kotlin.framework.log

import java.util.*
import kotlin.time.*
import kotlin.time.Duration.Companion.days
import kotlinx.coroutines.*
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import org.apache.logging.log4j.kotlin.*
import fuookami.ospf.kotlin.utils.context.*
import fuookami.ospf.kotlin.utils.functional.*
import fuookami.ospf.kotlin.utils.serialization.*

interface Pushing {
    operator fun  invoke(serializer: KSerializer, value: LogRecordPO): Try {
        val json = Json {
            ignoreUnknownKeys = true
        }
        return this({ json.encodeToString(LogRecordPO.serializer(serializer), it) }, value)
    }

    operator fun  invoke(serializer: (LogRecordPO) -> String, value: LogRecordPO): Try
}

@OptIn(InternalSerializationApi::class)
inline operator fun  Pushing.invoke(value: LogRecordPO): Try {
    return this(T::class.serializer(), value)
}

interface Saving {
    operator fun  invoke(serializer: KSerializer, value: LogRecordPO): Try

    @Suppress("INAPPLICABLE_JVM_NAME")
    @JvmName("saveAsString")
    operator fun  invoke(serializer: (T) -> String, value: LogRecordPO): Try {
        return ok
    }

    @Suppress("INAPPLICABLE_JVM_NAME")
    @JvmName("saveAsBytes")
    operator fun  invoke(serializer: (T) -> ByteArray, value: LogRecordPO): Try {
        return ok
    }
}

@OptIn(InternalSerializationApi::class)
inline operator fun  Saving.invoke(value: LogRecordPO): Try {
    return this(T::class.serializer(), value)
}

data class LogContextBuilder(
    var app: String = "",
    var version: String = "",
    var requestId: String = "",
    var pushing: Pushing? = null,
    val saving: Saving? = null
) {
    operator fun invoke(): LogContext {
        return LogContext(
            app = app,
            version = version,
            requestId = requestId,
            pushing = pushing,
            saving = saving
        )
    }
}

class LogContext private constructor(
    val app: String,
    val version: String,
    val serviceId: String,
    val pushing: Pushing? = null,
    val saving: Saving? = null
) : Cloneable {
    private val logger = logger()

    companion object {
        operator fun invoke(
            app: String = "",
            version: String,
            requestId: String,
            pushing: Pushing? = null,
            saving: Saving? = null
        ): LogContext {
            val uuid = UUID.nameUUIDFromBytes("${app}${version}${requestId}".toByteArray(charset("UTF-8")))
            return LogContext(
                app = app,
                version = version,
                serviceId = uuid.toString(),
                pushing = pushing,
                saving = saving
            )
        }

        fun build(builder: LogContextBuilder.() -> Unit): LogContext {
            val context = LogContextBuilder()
            builder(context)
            return context()
        }
    }

    @OptIn(InternalSerializationApi::class)
    inline fun  push(
        step: String,
        value: T,
        type: LogRecordType = LogRecordType.Info,
        availableTime: Duration = 90.days
    ) {
        return push(step, { writeJson(LogRecordPO.serializer(T::class.serializer()), it) }, value, type, availableTime)
    }

    fun  push(
        step: String,
        serializer: KSerializer,
        value: T,
        type: LogRecordType = LogRecordType.Info,
        availableTime: Duration = 90.days
    ) {
        return push(step, { writeJson(LogRecordPO.serializer(serializer), it) }, value, type, availableTime)
    }

    fun  push(
        step: String,
        serializer: (LogRecordPO) -> String,
        value: T,
        type: LogRecordType = LogRecordType.Info,
        availableTime: Duration = 90.days
    ) {
        if (pushing != null) {
            val pushing = this.pushing

            val record = LogRecordPO(
                app = app,
                version = version,
                serviceId = serviceId,
                step = step,
                value = value,
                type = type,
                availableTime = availableTime
            )
            when (val result = pushing(
                serializer = serializer,
                value = record
            )) {
                is Ok -> {
                    logger.info { "pushing log success" }
                }

                is Failed -> {
                    logger.info { "pushing log failed: ${result.error.message}" }
                }
            }
        }
    }

    @OptIn(InternalSerializationApi::class)
    inline fun  save(
        step: String,
        value: T,
        type: LogRecordType = LogRecordType.Info,
        availableTime: Duration = 90.days
    ) {
        return save(step, T::class.serializer(), value, type, availableTime)
    }

    fun  save(
        step: String,
        serializer: KSerializer,
        value: T,
        type: LogRecordType = LogRecordType.Info,
        availableTime: Duration = 90.days
    ) {
        if (saving != null) {
            val saving = this.saving
            val record = LogRecordPO(
                app = app,
                version = version,
                serviceId = serviceId,
                step = step,
                value = value,
                type = type,
                availableTime = availableTime
            )

            when (val result = saving(
                serializer = serializer,
                value = record
            )) {
                is Ok -> {
                    logger.info { "saving log success" }
                }

                is Failed -> {
                    logger.info { "saving log failed: ${result.error.message}" }
                }
            }
        }
    }

    @JvmName("saveAsString")
    fun  save(
        step: String,
        serializer: (T) -> String,
        value: T,
        type: LogRecordType = LogRecordType.Info,
        availableTime: Duration = 90.days
    ) {
        if (saving != null) {
            val saving = this.saving
            val record = LogRecordPO(
                app = app,
                version = version,
                serviceId = serviceId,
                step = step,
                value = value,
                type = type,
                availableTime = availableTime
            )

            when (val result = saving(
                serializer = serializer,
                value = record
            )) {
                is Ok -> {
                    logger.info { "saving log success" }
                }

                is Failed -> {
                    logger.info { "saving log failed: ${result.error.message}" }
                }
            }
        }
    }

    @JvmName("saveAsBytes")
    fun  save(
        step: String,
        serializer: (T) -> ByteArray,
        value: T,
        type: LogRecordType = LogRecordType.Info,
        availableTime: Duration = 90.days
    ) {
        if (saving != null) {
            val saving = this.saving
            val record = LogRecordPO(
                app = app,
                version = version,
                serviceId = serviceId,
                step = step,
                value = value,
                type = type,
                availableTime = availableTime
            )

            when (val result = saving(
                serializer = serializer,
                value = record
            )) {
                is Ok -> {
                    logger.info { "saving log success" }
                }

                is Failed -> {
                    logger.info { "saving log failed: ${result.error.message}" }
                }
            }
        }
    }
}

val logContext = ContextVar(LogContext(app = "", version = "", requestId = ""))




© 2015 - 2025 Weber Informatics LLC | Privacy Policy