From b3313f030d713b6037b454038354e57f85fbc3a5 Mon Sep 17 00:00:00 2001 From: tursom Date: Sat, 14 Dec 2019 22:36:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=BC=BA=20log=20=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- log/build.gradle | 2 + .../kotlin/cn/tursom/log/LogbackPattern.kt | 87 +++++++++++++++++++ .../main/kotlin/cn/tursom/log/Slf4jEnhance.kt | 83 ++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 log/src/main/kotlin/cn/tursom/log/LogbackPattern.kt diff --git a/log/build.gradle b/log/build.gradle index d1f6b37..03cf037 100644 --- a/log/build.gradle +++ b/log/build.gradle @@ -1,4 +1,6 @@ dependencies { implementation group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: '1.3.61' api group: 'org.slf4j', name: 'slf4j-api', version: '1.7.29' + api group: 'ch.qos.logback', name: 'logback-core', version: '1.2.3' + api 'ch.qos.logback:logback-classic:1.2.3' } \ No newline at end of file diff --git a/log/src/main/kotlin/cn/tursom/log/LogbackPattern.kt b/log/src/main/kotlin/cn/tursom/log/LogbackPattern.kt new file mode 100644 index 0000000..7f9f86a --- /dev/null +++ b/log/src/main/kotlin/cn/tursom/log/LogbackPattern.kt @@ -0,0 +1,87 @@ +package cn.tursom.log + +@Suppress("unused", "MemberVisibilityCanBePrivate") +object LogbackPattern { + enum class ColorEnum(val code: String) { + BLACK("black"), RED("red"), GREEN("green"), YELLOW("yellow"), BLUE("blue"), + MAGENTA("magenta"), CYAN("cyan"), WHITE("white"), GRAY("gray"), + BOLD_RED("boldRed"), BOLD_GREEN("boldGreen"), BOLD_YELLOW("boldYellow"), + BOLD_BLUE("boldBlue"), BOLD_MAGENTA("boldMagenta"), BOLD_CYAN("boldCyan"), + BOLD_WHITE("boldWhite"), HIGHLIGHT("highlight"); + + operator fun unaryPlus() = "%$this" + operator fun invoke(content: String) = "$this($content)" + operator fun get(content: String) = "$this{$content}" + override fun toString(): String = code + } + + object Color { + val black = ColorEnum.BLACK + val red = ColorEnum.RED + val green = ColorEnum.GREEN + val yellow = ColorEnum.YELLOW + val blue = ColorEnum.BLUE + val magenta = ColorEnum.MAGENTA + val cyan = ColorEnum.CYAN + val white = ColorEnum.WHITE + val gray = ColorEnum.GRAY + val boldRed = ColorEnum.BOLD_RED + val boldGreen = ColorEnum.BOLD_GREEN + val boldYellow = ColorEnum.BOLD_YELLOW + val boldBlue = ColorEnum.BOLD_BLUE + val boldMagenta = ColorEnum.BOLD_MAGENTA + val boldCyan = ColorEnum.BOLD_CYAN + val boldWhite = ColorEnum.BOLD_WHITE + val highlight = ColorEnum.HIGHLIGHT + } + + inline fun color(action: Color.() -> ColorEnum) = Color.action() + + const val nextLine = "n" + const val logger = "c" + const val logger_ = "lo" + const val logger__ = "logger" + const val clazz = "C" + const val class_ = "class" + const val date = "d" + const val date_ = "date" + const val caller = "caller" + const val line = "L" + const val line_ = "line" + const val message = "m" + const val message_ = "msg" + const val message__ = "message" + const val method = "M" + const val method_ = "method" + const val level = "p" + const val level_ = "le" + const val level__ = "level" + const val relative = "r" + const val relative_ = "relative" + const val thread = "t" + const val thread_ = "thread" + const val mdc = "X" + const val mdc_ = "mdc" + const val throwable = "throwable" + const val exception = "ex" + const val exception_ = "exception" + const val exception_short = "ex{short}" + const val exception_full = "ex{full}" + + fun String.finish() = +this + operator fun String.unaryPlus() = "%$this" + operator fun String.invoke(content: Any) = "$this($content)" + operator fun String.get(content: Any) = "$this{$content}" + + fun String.size(min: Int) = "$min$this" + fun String.size(min: Int? = null, max: Int) = "${min?.toString() ?: ""}.$max$this" + + fun String.left() = "-$this" + fun String.left(min: Int) = "-$min$this" + fun String.left(min: Int? = null, max: Int) = "-${min?.toString() ?: ""}.$max$this" + fun String.right() = this + fun String.right(min: Int) = "$min$this" + fun String.right(min: Int? = null, max: Int) = "${min?.toString() ?: ""}.$max$this" + + inline fun make(action: LogbackPattern.() -> String) = this.action() +} \ No newline at end of file diff --git a/log/src/main/kotlin/cn/tursom/log/Slf4jEnhance.kt b/log/src/main/kotlin/cn/tursom/log/Slf4jEnhance.kt index bb40c15..da96e87 100644 --- a/log/src/main/kotlin/cn/tursom/log/Slf4jEnhance.kt +++ b/log/src/main/kotlin/cn/tursom/log/Slf4jEnhance.kt @@ -1,6 +1,89 @@ package cn.tursom.log +import ch.qos.logback.classic.LoggerContext +import ch.qos.logback.classic.encoder.PatternLayoutEncoder +import ch.qos.logback.classic.spi.ILoggingEvent +import ch.qos.logback.core.ConsoleAppender +import ch.qos.logback.core.OutputStreamAppender +import ch.qos.logback.core.rolling.RollingFileAppender +import ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP +import ch.qos.logback.core.rolling.TimeBasedRollingPolicy +import ch.qos.logback.core.util.FileSize import org.slf4j.Logger import org.slf4j.LoggerFactory +import org.slf4j.event.Level inline fun T.slf4jLogger(): Logger = LoggerFactory.getLogger(T::class.java) + +fun setLogLevel(level: Level, pkg: String = Logger.ROOT_LOGGER_NAME) { + val root = LoggerFactory.getLogger(pkg) as ch.qos.logback.classic.Logger + root.level = ch.qos.logback.classic.Level.toLevel(level.toString()) +} + +fun setLogLevel(level: String, pkg: String = Logger.ROOT_LOGGER_NAME) = setLogLevel(Level.valueOf(level.toUpperCase()), pkg) + + +/** + * desc: 策略:每份日志文件最大1000KB,真实大小可能会略大,且最多保存7天 + * author: Xubin + * date: 2017/4/17 16:06 + * update: 2017/4/17 + */ +fun configureLogbackDirectly(logDir: String, filePrefix: String) { + val context: LoggerContext = LoggerFactory.getILoggerFactory() as LoggerContext + val rollingFileAppender = RollingFileAppender().also { rollingFileAppender -> + rollingFileAppender.isAppend = true + rollingFileAppender.context = context + rollingFileAppender.encoder = PatternLayoutEncoder().also { encoder -> + encoder.pattern = "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" + encoder.context = context + encoder.start() + } + } + val rollingPolicy = TimeBasedRollingPolicy() + rollingPolicy.fileNamePattern = "$logDir/${filePrefix}_%d{yyyyMMdd}_%i.log" + rollingPolicy.maxHistory = 7 + rollingPolicy.setParent(rollingFileAppender) + rollingPolicy.context = context + val sizeAndTimeBasedFNATP = SizeAndTimeBasedFNATP() + sizeAndTimeBasedFNATP.setMaxFileSize(FileSize.valueOf("1000KB")) + sizeAndTimeBasedFNATP.context = context + sizeAndTimeBasedFNATP.setTimeBasedRollingPolicy(rollingPolicy) + rollingPolicy.timeBasedFileNamingAndTriggeringPolicy = sizeAndTimeBasedFNATP + rollingPolicy.start() + sizeAndTimeBasedFNATP.start() + rollingFileAppender.rollingPolicy = rollingPolicy + rollingFileAppender.start() + + val root = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME) as ch.qos.logback.classic.Logger + root.addAppender(rollingFileAppender) +} + +val defaultColorfulPattern = LogbackPattern.make { + +color { green }(+date)["yyyy-MM-dd HH:mm:ss.SSS"] + " " + + +color { magenta }("[${+thread}]") + " " + + +color { highlight }(+level.left(5)) + " " + + +color { cyan }("[${+logger["20"].right(20, 20)}]") + " - " + + +color { highlight }(+message) + " " + + +nextLine +} + +fun colorfulConsoleLogger(appender: OutputStreamAppender<*>, pattern: String = defaultColorfulPattern) { + LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME).warn("change console color: {}", pattern) + val context: LoggerContext = LoggerFactory.getILoggerFactory() as LoggerContext + appender.encoder = PatternLayoutEncoder().also { encoder -> + encoder.pattern = pattern + encoder.context = context + encoder.start() + } +} + +fun colorfulConsoleLogger(pattern: String = defaultColorfulPattern) { + (LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME) as ch.qos.logback.classic.Logger) + .iteratorForAppenders() + .forEach { + if (it is ConsoleAppender) { + colorfulConsoleLogger(it, pattern) + } + } +} \ No newline at end of file