Kronos-logging

配置 Kronos SQL 执行日志,使用内置日志或 kronos-logging 适配器。

使用内置日志

通过 Kronos.logging 配置 SQL 执行日志。kronos-core 已包含内置日志实现;JVM 实现可以输出到控制台、写入文件,或同时输出到两个位置。

console and file

import com.kotlinorm.Kronos
import com.kotlinorm.enums.KLoggerType

with(Kronos.logging) {
    type = KLoggerType.DEFAULT_LOGGER
    path = ["console", "logs/kronos"]
}

执行 ORM 任务时,内置日志会输出操作类型、SQL、参数和结果。

output

[yyyy-MM-dd HH:mm:ss.SSS] [info] [Kronos] Executing [SELECT] task:
SQL:    SELECT `id`, `name` FROM `user` WHERE `id` = :id
PARAMS: {id=1}
Found rows: 1
-----------------------

写入日志目录

需要让内置日志创建每日文件时,将目录路径加入 Kronos.logging.path。

file only

with(Kronos.logging) {
    type = KLoggerType.DEFAULT_LOGGER
    path = ["logs/kronos"]
}

文件名使用内置日志的默认规则。

file

logs/kronos/kronos-log-yyyy-MM-dd.log

开启或关闭日志

Kronos.logging.enabled 是日志输出的总开关,对 JVM 和 Kotlin/Native 上的内置、平台和自定义 logger 都生效。默认值为 true,默认输出路径为 ["console"]。

Kronos.logging.enabled = false

重新开启时保留原来的日志类型、路径和自定义工厂:

Kronos.logging.enabled = true

关闭时不会创建日志适配器,也不会执行惰性的日志消息构建。需要按级别过滤时,配置最低级别;最终输出同时遵守适配器自身的级别设置:

import com.kotlinorm.enums.KLogLevel

Kronos.logging.minimumLevel = KLogLevel.WARN

path 选择内置日志的输出位置,空数组只停止这些位置的输出,不改变自定义 logger 或日志框架适配器:

Kronos.logging.path = []

Kotlin/Native 的内置适配器使用 console 输出,并包含异常堆栈;目录输出由 JVM 内置 logger 提供。应用可通过自定义工厂连接平台日志实现:

Kronos.logging.factory = { source -> applicationLogger(source) }
// 恢复使用已安装的平台适配器。
Kronos.logging.factory = null

applicationLogger 是应用提供的函数,返回 KLogger。总开关和最低级别同样作用于它返回的 logger。设置工厂会保留 logging.type。

Android 日志

Android/JVM 日志配置说明统一放在 📚Android SQLite 接入章节。

添加kronos-logging

需要让 Kronos 日志进入 Android Log、JDK Logger 或 Apache Commons Logging 等适配器时,引入 kronos-logging。

gradle(kts)

dependencies {
    implementation("com.kotlinorm:kronos-logging:0.4.0")
}

maven

<dependency>
    <groupId>com.kotlinorm</groupId>
    <artifactId>kronos-logging</artifactId>
    <version>0.4.0</version>
</dependency>

使用 JDK Logger

在应用启动时调用一次 KronosLoggerApp.detectLoggerImplementation(),再选择 JDK logger 类型。

kotlin

import com.kotlinorm.Kronos
import com.kotlinorm.KronosLoggerApp
import com.kotlinorm.enums.KLoggerType

KronosLoggerApp.detectLoggerImplementation()

Kronos.logging.type = KLoggerType.JDK_LOGGER

JDK Logger 会接收同样的 ORM 执行信息。

output

INFO: Executing [INSERT] task:
SQL:    INSERT INTO `user` (`name`) VALUES (:name)
PARAMS: {name=Kronos}
Affected rows: 1
-----------------------

使用 Apache Commons Logging

加入应用使用的 Commons Logging API 后,选择 KLoggerType.COMMONS_LOGGER。

gradle(kts)

dependencies {
    implementation("com.kotlinorm:kronos-logging:0.4.0")
    implementation("commons-logging:commons-logging:<latest-stable>")
}

kotlin

import com.kotlinorm.Kronos
import com.kotlinorm.KronosLoggerApp
import com.kotlinorm.enums.KLoggerType

KronosLoggerApp.detectLoggerImplementation()

Kronos.logging.type = KLoggerType.COMMONS_LOGGER

适配器会从运行时 classpath 创建目标 logger。选择对应 KLoggerType 前,先加入应用实际使用的日志 API 和 binding。

使用 SLF4J 和 Logback

kronos-logging 通过 SLF4J 输出日志。应用加入一个 SLF4J binding 后即可选择对应适配器,Logback 是常用选择。

gradle(kts)

dependencies {
    implementation("com.kotlinorm:kronos-logging:0.4.0")
    implementation("ch.qos.logback:logback-classic:<version>")
}

maven

<dependency>
    <groupId>com.kotlinorm</groupId>
    <artifactId>kronos-logging</artifactId>
    <version>0.4.0</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>${logback.version}</version>
</dependency>

在 src/main/resources/logback.xml 中配置 appender 和日志级别:

logback.xml

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
        </encoder>
    </appender>
    <logger name="com.kotlinorm" level="INFO"/>
    <root level="WARN">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

应用启动时选择 SLF4J 适配器:

kotlin

import com.kotlinorm.Kronos
import com.kotlinorm.KronosLoggerApp
import com.kotlinorm.enums.KLoggerType

KronosLoggerApp.detectLoggerImplementation()
Kronos.logging.type = KLoggerType.SLF4J_LOGGER

使用 SLF4J 和 Log4j2

Log4j2 通过 SLF4J 2 binding 接入。三个 Log4j2 模块使用相同版本。

gradle(kts)

dependencies {
    implementation("com.kotlinorm:kronos-logging:0.4.0")
    implementation("org.apache.logging.log4j:log4j-api:<version>")
    runtimeOnly("org.apache.logging.log4j:log4j-core:<version>")
    runtimeOnly("org.apache.logging.log4j:log4j-slf4j2-impl:<version>")
}

maven

<dependency>
    <groupId>com.kotlinorm</groupId>
    <artifactId>kronos-logging</artifactId>
    <version>0.4.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>${log4j2.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>${log4j2.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j2-impl</artifactId>
    <version>${log4j2.version}</version>
</dependency>

在 src/main/resources/log4j2.xml 中配置 com.kotlinorm logger:

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Logger name="com.kotlinorm" level="info"/>
        <Root level="warn">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

探测可用适配器

detectLoggerImplementation() 会检查运行时 classpath,并安装探测到的平台适配器;显式设置的 Kronos.logging.factory 会被保留。

kotlin

import com.kotlinorm.Kronos
import com.kotlinorm.KronosLoggerApp

KronosLoggerApp.detectLoggerImplementation()

println(Kronos.logging.type)

在只包含 JDK logger 的标准 JVM 项目中,探测结果为:

output

JDK_LOGGER

完整数据库连接配置请参考 📚连接到数据库 和 📚全局设置。