├── .gitignore ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle.kts ├── gradle.properties ├── src ├── commonMain │ └── kotlin │ │ └── lumberjack │ │ ├── message │ │ ├── Message.kt │ │ ├── ThreadLocalMutableObjectMessage.kt │ │ ├── ObjectMessage.kt │ │ └── MutableObjectMessage.kt │ │ ├── Marker.kt │ │ ├── MDC.kt │ │ ├── Level.kt │ │ └── Logger.kt ├── sawtoothMain │ └── kotlin │ │ └── lumberjack │ │ ├── internal │ │ ├── KClassUtil.kt │ │ ├── Reference.kt │ │ └── ConcurrentMap.kt │ │ ├── message │ │ ├── Message.kt │ │ └── ThreadLocalMutableObjectMessage.kt │ │ ├── sawtooth │ │ ├── appender │ │ │ ├── RegexAppender.kt │ │ │ ├── Appender.kt │ │ │ └── RegexCompositeAppender.kt │ │ ├── event │ │ │ ├── LogProperty.kt │ │ │ ├── PropertyKey.kt │ │ │ ├── LogEventFactory.kt │ │ │ ├── LogEvent.kt │ │ │ ├── ThreadLocalLogEvent.kt │ │ │ └── ThreadLocalLogEventFactory.kt │ │ ├── level │ │ │ ├── RegexLevel.kt │ │ │ ├── LevelFactory.kt │ │ │ └── RegexLevelFactory.kt │ │ ├── layout │ │ │ ├── Layout.kt │ │ │ └── DeprecatedLayout.kt │ │ └── Configuration.kt │ │ ├── Marker.kt │ │ ├── MDC.kt │ │ ├── Level.kt │ │ └── Logger.kt ├── jsMain │ └── kotlin │ │ └── lumberjack │ │ ├── internal │ │ ├── KClassUtil.kt │ │ ├── Reference.kt │ │ └── ConcurrentMap.kt │ │ └── sawtooth │ │ └── appender │ │ ├── RegexCompositeAppender.kt │ │ └── ConsoleAppender.kt ├── nativeMain │ └── kotlin │ │ └── lumberjack │ │ ├── internal │ │ ├── KClassUtil.kt │ │ ├── Reference.kt │ │ ├── AtomicUtil.kt │ │ └── ConcurrentMap.kt │ │ └── sawtooth │ │ └── appender │ │ ├── RegexCompositeAppender.kt │ │ └── PrintAppender.kt └── jvmMain │ └── kotlin │ └── lumberjack │ ├── message │ ├── Message.kt │ └── ThreadLocalMutableObjectMessage.kt │ ├── Marker.kt │ ├── Logger.kt │ ├── MDC.kt │ └── Level.kt ├── .github └── workflows │ └── build.yml ├── gradlew.bat ├── gradlew ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Gradle 2 | .gradle/ 3 | build/ 4 | 5 | # IDEA 6 | *.iml 7 | .idea/ 8 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danthonywalker/Lumberjack/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | rootProject.name = "Lumberjack" 18 | 19 | enableFeaturePreview("GRADLE_METADATA") 20 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Lumberjack. 3 | # 4 | # Lumberjack is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU Lesser General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # Lumberjack is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public License 15 | # along with Lumberjack. If not, see . 16 | # 17 | kotlin.code.style=official 18 | kotlin.mpp.enableGranularSourceSetsMetadata=true 19 | kotlin.native.enableDependencyPropagation=false 20 | -------------------------------------------------------------------------------- /src/commonMain/kotlin/lumberjack/message/Message.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.message 18 | 19 | expect interface Message { 20 | 21 | fun writeTo(builder: StringBuilder) 22 | } 23 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/internal/KClassUtil.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.internal 18 | 19 | import kotlin.reflect.KClass 20 | 21 | internal expect val KClass<*>.name: String 22 | -------------------------------------------------------------------------------- /src/commonMain/kotlin/lumberjack/message/ThreadLocalMutableObjectMessage.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.message 18 | 19 | expect object ThreadLocalMutableObjectMessage : MutableObjectMessage 20 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/internal/Reference.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.internal 18 | 19 | internal expect class Reference(initialValue: T) { 20 | 21 | var value: T 22 | } 23 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/message/Message.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.message 18 | 19 | actual interface Message { 20 | 21 | actual fun writeTo(builder: StringBuilder) 22 | } 23 | -------------------------------------------------------------------------------- /src/jsMain/kotlin/lumberjack/internal/KClassUtil.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.internal 18 | 19 | import kotlin.reflect.KClass 20 | 21 | internal actual val KClass<*>.name: String 22 | get() = js.name 23 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/appender/RegexAppender.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.appender 18 | 19 | data class RegexAppender( 20 | 21 | val regex: Regex, 22 | 23 | val appender: Appender 24 | ) 25 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/event/LogProperty.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.event 18 | 19 | interface LogProperty { 20 | 21 | val key: PropertyKey 22 | 23 | fun value(event: LogEvent): T? 24 | } 25 | -------------------------------------------------------------------------------- /src/jsMain/kotlin/lumberjack/sawtooth/appender/RegexCompositeAppender.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.appender 18 | 19 | internal actual val RegexCompositeAppender.Factory.DEFAULT_APPENDER: Appender 20 | get() = ConsoleAppender.DEFAULT 21 | -------------------------------------------------------------------------------- /src/nativeMain/kotlin/lumberjack/internal/KClassUtil.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.internal 18 | 19 | import kotlin.reflect.KClass 20 | 21 | internal actual val KClass<*>.name: String 22 | get() = qualifiedName ?: simpleName ?: toString() 23 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/internal/ConcurrentMap.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.internal 18 | 19 | internal expect class ConcurrentMap() : MutableMap { 20 | 21 | inline fun getOrUpdate(key: K, value: () -> V): V 22 | } 23 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/appender/Appender.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.appender 18 | 19 | import lumberjack.sawtooth.event.LogEvent 20 | 21 | interface Appender { 22 | 23 | fun append(event: LogEvent) 24 | } 25 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/level/RegexLevel.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.level 18 | 19 | import lumberjack.Level 20 | 21 | data class RegexLevel( 22 | 23 | val regex: Regex, 24 | 25 | val level: Level 26 | ) 27 | -------------------------------------------------------------------------------- /src/nativeMain/kotlin/lumberjack/sawtooth/appender/RegexCompositeAppender.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.appender 18 | 19 | internal actual val RegexCompositeAppender.Factory.DEFAULT_APPENDER: Appender 20 | get() = PrintAppender.DEFAULT 21 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/layout/Layout.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.layout 18 | 19 | import lumberjack.sawtooth.event.LogEvent 20 | 21 | interface Layout { 22 | 23 | fun writeTo(builder: StringBuilder, event: LogEvent) 24 | } 25 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/event/PropertyKey.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.event 18 | 19 | import kotlin.reflect.KClass 20 | 21 | data class PropertyKey( 22 | 23 | val name: String, 24 | 25 | val type: KClass 26 | ) 27 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/level/LevelFactory.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.level 18 | 19 | import lumberjack.Level 20 | import lumberjack.Logger 21 | 22 | interface LevelFactory { 23 | 24 | fun fromLogger(logger: Logger): Level 25 | } 26 | -------------------------------------------------------------------------------- /src/commonMain/kotlin/lumberjack/message/ObjectMessage.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.message 18 | 19 | interface ObjectMessage : Message { 20 | 21 | val message: Any? 22 | 23 | override fun writeTo(builder: StringBuilder): Unit = builder.append(message).run {} 24 | } 25 | -------------------------------------------------------------------------------- /src/jvmMain/kotlin/lumberjack/message/Message.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.message 18 | 19 | typealias Log4JMessage = org.apache.logging.log4j.message.Message 20 | 21 | actual interface Message { 22 | 23 | val log4JMessage: Log4JMessage 24 | 25 | actual fun writeTo(builder: StringBuilder) 26 | } 27 | -------------------------------------------------------------------------------- /src/commonMain/kotlin/lumberjack/message/MutableObjectMessage.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.message 18 | 19 | interface MutableObjectMessage : ObjectMessage { 20 | 21 | override var message: Any? 22 | } 23 | 24 | fun T.message(message: Any?): T = apply { this.message = message } 25 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/message/ThreadLocalMutableObjectMessage.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.message 18 | 19 | import kotlin.native.concurrent.ThreadLocal 20 | 21 | @ThreadLocal 22 | actual object ThreadLocalMutableObjectMessage : MutableObjectMessage { 23 | 24 | override var message: Any? = null 25 | 26 | override fun toString(): String = message.toString() 27 | } 28 | -------------------------------------------------------------------------------- /src/jsMain/kotlin/lumberjack/internal/Reference.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.internal 18 | 19 | internal actual class Reference actual constructor(initialValue: T) { 20 | 21 | actual var value: T = initialValue 22 | 23 | override fun equals(other: Any?): Boolean { 24 | return (other is Reference<*>) && (other.value == value) 25 | } 26 | 27 | override fun hashCode(): Int = value.hashCode() 28 | 29 | override fun toString(): String = value.toString() 30 | } 31 | -------------------------------------------------------------------------------- /src/commonMain/kotlin/lumberjack/Marker.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | @file:JvmName("MarkerJVM") 18 | 19 | package lumberjack 20 | 21 | import kotlin.jvm.JvmName 22 | 23 | expect class Marker { 24 | 25 | val name: String 26 | 27 | val parents: Map 28 | 29 | companion object Factory { 30 | 31 | fun fromName(name: String, parents: Set = emptySet()): Marker 32 | } 33 | } 34 | 35 | fun Marker.Factory.fromName(name: String, vararg parents: Marker): Marker = fromName(name, setOf(*parents)) 36 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | pull_request: 5 | types: [opened, reopened, synchronize] 6 | push: 7 | branches: 8 | - master 9 | release: 10 | types: [published] 11 | 12 | jobs: 13 | build: 14 | strategy: 15 | matrix: 16 | os: [windows-latest, ubuntu-latest, macos-latest] 17 | 18 | runs-on: ${{ matrix.os }} 19 | 20 | steps: 21 | - name: Checkout Repository 22 | uses: actions/checkout@v2 23 | 24 | - name: Setup Cache 25 | uses: actions/cache@v2 26 | with: 27 | path: | 28 | ~/.gradle 29 | ~/.konan 30 | key: ${{ matrix.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }} 31 | restore-keys: | 32 | ${{ matrix.os }}-gradle- 33 | 34 | - name: Setup Java 35 | uses: actions/setup-java@v1 36 | with: 37 | java-version: 8 38 | 39 | - name: Gradle Build 40 | run: ./gradlew build 41 | 42 | - name: Gradle Upload 43 | if: ${{ github.event_name == 'release' }} 44 | run: ./gradlew bintrayUpload 45 | env: 46 | BINTRAY_USER: ${{ secrets.BINTRAY_USER }} 47 | BINTRAY_KEY: ${{ secrets.BINTRAY_KEY }} 48 | 49 | - name: Gradle Stop 50 | run: ./gradlew --stop 51 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/event/LogEventFactory.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.event 18 | 19 | import lumberjack.Level 20 | import lumberjack.Logger 21 | import lumberjack.Marker 22 | import lumberjack.message.Message 23 | import kotlin.coroutines.CoroutineContext 24 | 25 | interface LogEventFactory { 26 | 27 | fun fromLogging( 28 | logger: Logger, 29 | level: Level, 30 | message: Message, 31 | marker: Marker?, 32 | cause: Throwable?, 33 | context: CoroutineContext 34 | ): LogEvent 35 | } 36 | -------------------------------------------------------------------------------- /src/commonMain/kotlin/lumberjack/MDC.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack 18 | 19 | import kotlin.coroutines.CoroutineContext 20 | import kotlin.coroutines.coroutineContext 21 | 22 | typealias Context = Map 23 | 24 | expect class MDC : CoroutineContext.Element, Context { 25 | 26 | companion object Key : CoroutineContext.Key { 27 | 28 | fun fromContext(context: Context = emptyMap()): MDC 29 | } 30 | } 31 | 32 | suspend inline fun mdc(block: (MDC) -> Context = { it }): MDC = 33 | MDC.fromContext(block(coroutineContext[MDC] ?: MDC.fromContext())) 34 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/event/LogEvent.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.event 18 | 19 | import lumberjack.Level 20 | import lumberjack.Logger 21 | import lumberjack.Marker 22 | import lumberjack.message.Message 23 | import kotlin.coroutines.CoroutineContext 24 | 25 | interface LogEvent { 26 | 27 | val logger: Logger 28 | 29 | val level: Level 30 | 31 | val message: Message 32 | 33 | val marker: Marker? 34 | 35 | val cause: Throwable? 36 | 37 | val context: CoroutineContext 38 | 39 | fun property(key: PropertyKey): T? 40 | } 41 | -------------------------------------------------------------------------------- /src/jsMain/kotlin/lumberjack/internal/ConcurrentMap.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.internal 18 | 19 | internal actual class ConcurrentMap private constructor( 20 | 21 | private val delegate: MutableMap 22 | ) : MutableMap by delegate { 23 | 24 | actual constructor() : this(HashMap()) 25 | 26 | actual inline fun getOrUpdate(key: K, value: () -> V): V = getOrPut(key, value) 27 | 28 | override fun equals(other: Any?): Boolean = (delegate == other) 29 | 30 | override fun hashCode(): Int = delegate.hashCode() 31 | 32 | override fun toString(): String = delegate.toString() 33 | } 34 | -------------------------------------------------------------------------------- /src/commonMain/kotlin/lumberjack/Level.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack 18 | 19 | expect sealed class Level : Comparable { 20 | 21 | val name: String 22 | 23 | val value: Int 24 | 25 | object None : Level 26 | 27 | object Fatal : Level 28 | 29 | object Error : Level 30 | 31 | object Warn : Level 32 | 33 | object Info : Level 34 | 35 | object Debug : Level 36 | 37 | object Trace : Level 38 | 39 | object All : Level 40 | 41 | class Custom : Level 42 | 43 | companion object Factory { 44 | 45 | fun fromName(name: String, defaultLevel: Level = Debug): Level 46 | 47 | fun toLevel(name: String, value: Int): Level 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/nativeMain/kotlin/lumberjack/internal/Reference.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.internal 18 | 19 | import kotlin.native.concurrent.AtomicReference 20 | import kotlin.native.concurrent.freeze 21 | 22 | internal actual class Reference actual constructor(initialValue: T) { 23 | 24 | private val _value = AtomicReference(initialValue.freeze()) 25 | 26 | actual var value: T 27 | get() = _value.value 28 | set(value) = value.run { _value.value = freeze() } 29 | 30 | override fun equals(other: Any?): Boolean { 31 | return (other is Reference<*>) && (other.value == value) 32 | } 33 | 34 | override fun hashCode(): Int = value.hashCode() 35 | 36 | override fun toString(): String = value.toString() 37 | } 38 | -------------------------------------------------------------------------------- /src/jvmMain/kotlin/lumberjack/message/ThreadLocalMutableObjectMessage.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.message 18 | 19 | import org.apache.logging.log4j.message.ReusableObjectMessage 20 | 21 | actual object ThreadLocalMutableObjectMessage : MutableObjectMessage { 22 | 23 | @Suppress("ObjectPropertyName") 24 | private val _log4JMessage = ThreadLocal.withInitial(::ReusableObjectMessage) 25 | 26 | override val log4JMessage: Log4JMessage 27 | get() = _log4JMessage.get() 28 | 29 | override var message: Any? 30 | get() = _log4JMessage.get().parameter 31 | set(value) = _log4JMessage.get().set(value) 32 | 33 | override fun writeTo(builder: StringBuilder): Unit = _log4JMessage.get().formatTo(builder) 34 | 35 | override fun toString(): String = message.toString() 36 | } 37 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/Marker.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack 18 | 19 | import lumberjack.internal.ConcurrentMap 20 | 21 | actual class Marker private constructor( 22 | 23 | actual val name: String, 24 | 25 | actual val parents: Map 26 | ) { 27 | 28 | override fun equals(other: Any?): Boolean { 29 | return (other as? Marker)?.name == name 30 | } 31 | 32 | override fun hashCode(): Int = name.hashCode() 33 | 34 | override fun toString(): String = name 35 | 36 | actual companion object Factory { 37 | 38 | private val markers = ConcurrentMap() 39 | 40 | actual fun fromName(name: String, parents: Set): Marker = 41 | markers.getOrUpdate(name) { Marker(name, parents.associateBy(Marker::name)) } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/MDC.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack 18 | 19 | import kotlin.coroutines.AbstractCoroutineContextElement 20 | import kotlin.coroutines.CoroutineContext 21 | 22 | actual class MDC private constructor( 23 | 24 | private val context: Context 25 | ) : AbstractCoroutineContextElement(MDC), 26 | CoroutineContext.Element, 27 | Context by context { 28 | 29 | override fun toString(): String = context.toString() 30 | 31 | override fun equals(other: Any?): Boolean = (context == other) 32 | 33 | override fun hashCode(): Int = context.hashCode() 34 | 35 | actual companion object Key : CoroutineContext.Key { 36 | 37 | private val EMPTY: MDC = MDC(emptyMap()) 38 | 39 | actual fun fromContext(context: Context): MDC { 40 | return when { // Avoid allocate if possible 41 | context.isEmpty() -> EMPTY 42 | context is MDC -> context 43 | else -> MDC(context) 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/nativeMain/kotlin/lumberjack/sawtooth/appender/PrintAppender.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.appender 18 | 19 | import lumberjack.sawtooth.event.LogEvent 20 | import lumberjack.sawtooth.layout.DeprecatedLayout 21 | import lumberjack.sawtooth.layout.Layout 22 | 23 | class PrintAppender private constructor( 24 | 25 | private val layout: Layout 26 | ) : Appender { 27 | 28 | override fun append(event: LogEvent) { 29 | // Always print to standard output 30 | builder.clear() 31 | layout.writeTo(builder, event) 32 | println(builder) 33 | } 34 | 35 | override fun equals(other: Any?): Boolean { 36 | return (other as? PrintAppender)?.layout == layout 37 | } 38 | 39 | override fun hashCode(): Int = layout.hashCode() 40 | 41 | override fun toString(): String { 42 | return "PrintAppender(" + 43 | "layout=$layout" + 44 | ")" 45 | } 46 | 47 | companion object Factory { 48 | 49 | val DEFAULT: PrintAppender = withLayout() 50 | 51 | fun withLayout( 52 | layout: Layout = DeprecatedLayout 53 | ): PrintAppender = PrintAppender(layout) 54 | } 55 | } 56 | 57 | @ThreadLocal 58 | private val builder = StringBuilder() 59 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/Configuration.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth 18 | 19 | import lumberjack.sawtooth.appender.Appender 20 | import lumberjack.sawtooth.appender.RegexCompositeAppender 21 | import lumberjack.sawtooth.event.LogEventFactory 22 | import lumberjack.sawtooth.event.ThreadLocalLogEventFactory 23 | import lumberjack.sawtooth.level.LevelFactory 24 | import lumberjack.sawtooth.level.RegexLevelFactory 25 | 26 | @Suppress("DataClassPrivateConstructor") 27 | data class Configuration private constructor( 28 | 29 | internal val levelFactory: LevelFactory, 30 | 31 | internal val logEventFactory: LogEventFactory, 32 | 33 | internal val appender: Appender 34 | ) { 35 | 36 | companion object Factory { 37 | 38 | val DEFAULT: Configuration = configure() 39 | 40 | fun configure( 41 | levelFactory: LevelFactory = RegexLevelFactory.DEFAULT, 42 | logEventFactory: LogEventFactory = ThreadLocalLogEventFactory.DEFAULT, 43 | appender: Appender = RegexCompositeAppender.DEFAULT 44 | ): Configuration = Configuration( 45 | levelFactory = levelFactory, 46 | logEventFactory = logEventFactory, 47 | appender = appender 48 | ) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/nativeMain/kotlin/lumberjack/internal/AtomicUtil.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.internal 18 | 19 | import kotlin.native.concurrent.AtomicReference 20 | import kotlin.native.concurrent.freeze 21 | 22 | internal inline fun AtomicReference.update(block: (T) -> T) { 23 | while (true) { // Effectively blocks the thread until a CAS is successful 24 | val current = value 25 | val update = block(current).freeze() 26 | 27 | if (compareAndSet(current, update)) { 28 | return 29 | } 30 | } 31 | } 32 | 33 | internal inline fun AtomicReference.getAndUpdate(block: (T) -> T): T { 34 | while (true) { // Effectively blocks the thread until a CAS is successful 35 | val current = value 36 | val update = block(current).freeze() 37 | 38 | if (compareAndSet(current, update)) { 39 | return current 40 | } 41 | } 42 | } 43 | 44 | internal inline fun AtomicReference.updateAndGet(block: (T) -> T): T { 45 | while (true) { // Effectively blocks the thread until a CAS is successful 46 | val current = value 47 | val update = block(current).freeze() 48 | 49 | if (compareAndSet(current, update)) { 50 | return update 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/level/RegexLevelFactory.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.level 18 | 19 | import lumberjack.Level 20 | import lumberjack.Logger 21 | import lumberjack.internal.ConcurrentMap 22 | 23 | class RegexLevelFactory private constructor( 24 | 25 | private val defaultLevel: Level, 26 | 27 | private val regexLevels: List 28 | ) : LevelFactory { 29 | 30 | private val cache = ConcurrentMap() 31 | 32 | override fun fromLogger(logger: Logger): Level = cache.getOrUpdate(logger) { 33 | regexLevels.firstOrNull { it.regex.matches(logger.name) }?.level ?: defaultLevel 34 | } 35 | 36 | override fun toString(): String { 37 | return "RegexLevelFactory(" + 38 | "defaultLevel=$defaultLevel" + 39 | ", regexLevels=$regexLevels" + 40 | ")" 41 | } 42 | 43 | companion object Factory { 44 | 45 | val DEFAULT: RegexLevelFactory = configure() 46 | 47 | fun configure( 48 | defaultLevel: Level = Level.Debug, 49 | regexLevels: List = emptyList() 50 | ): RegexLevelFactory = RegexLevelFactory( 51 | defaultLevel = defaultLevel, 52 | regexLevels = regexLevels 53 | ) 54 | } 55 | } 56 | 57 | fun RegexLevelFactory.Factory.configure( 58 | defaultLevel: Level = Level.Debug, 59 | vararg regexLevels: RegexLevel 60 | ): RegexLevelFactory = configure(defaultLevel, listOf(*regexLevels)) 61 | -------------------------------------------------------------------------------- /src/jsMain/kotlin/lumberjack/sawtooth/appender/ConsoleAppender.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.appender 18 | 19 | import lumberjack.Level 20 | import lumberjack.sawtooth.event.LogEvent 21 | import lumberjack.sawtooth.layout.DeprecatedLayout 22 | import lumberjack.sawtooth.layout.Layout 23 | 24 | class ConsoleAppender private constructor( 25 | 26 | private val layout: Layout 27 | ) : Appender { 28 | 29 | private val builder = StringBuilder() 30 | 31 | override fun append(event: LogEvent) { 32 | builder.clear() 33 | layout.writeTo(builder, event) 34 | 35 | val level = event.level 36 | val message = builder.toString() 37 | 38 | when { 39 | level <= Level.Error -> console.error(message) 40 | level <= Level.Warn -> console.warn(message) 41 | level <= Level.Info -> console.info(message) 42 | else -> console.log(message) 43 | } 44 | } 45 | 46 | override fun equals(other: Any?): Boolean { 47 | return (other as? ConsoleAppender)?.layout == layout 48 | } 49 | 50 | override fun hashCode(): Int = layout.hashCode() 51 | 52 | override fun toString(): String { 53 | return "ConsoleAppender(" + 54 | "layout=$layout" + 55 | ")" 56 | } 57 | 58 | companion object Factory { 59 | 60 | val DEFAULT: ConsoleAppender = withLayout() 61 | 62 | fun withLayout( 63 | layout: Layout = DeprecatedLayout 64 | ): ConsoleAppender = ConsoleAppender(layout) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/event/ThreadLocalLogEvent.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.event 18 | 19 | import lumberjack.Level 20 | import lumberjack.Logger 21 | import lumberjack.Marker 22 | import lumberjack.message.Message 23 | import lumberjack.message.ThreadLocalMutableObjectMessage 24 | import kotlin.coroutines.CoroutineContext 25 | import kotlin.coroutines.EmptyCoroutineContext 26 | import kotlin.native.concurrent.ThreadLocal 27 | 28 | @ThreadLocal 29 | internal object ThreadLocalLogEvent : LogEvent { 30 | 31 | override var logger: Logger = Logger.fromKClass(ThreadLocalLogEvent::class) 32 | 33 | override var level: Level = Level.None 34 | 35 | override var message: Message = ThreadLocalMutableObjectMessage 36 | 37 | override var marker: Marker? = null 38 | 39 | override var cause: Throwable? = null 40 | 41 | override var context: CoroutineContext = EmptyCoroutineContext 42 | 43 | var properties: Map, LogProperty<*>> = emptyMap() 44 | 45 | @Suppress("UNCHECKED_CAST") 46 | override fun property(key: PropertyKey): T? { 47 | return properties[key]?.value(this) as? T 48 | } 49 | 50 | override fun toString(): String { 51 | return "ThreadLocalLogEvent(" + 52 | "logger=$logger" + 53 | ", level=$level" + 54 | ", message=$message" + 55 | ", marker=$marker" + 56 | ", cause=$cause" + 57 | ", context=$context" + 58 | ", properties=$properties" + 59 | ")" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/jvmMain/kotlin/lumberjack/Marker.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack 18 | 19 | import org.apache.logging.log4j.MarkerManager 20 | import java.util.concurrent.ConcurrentHashMap 21 | 22 | typealias Log4JMarker = org.apache.logging.log4j.Marker 23 | 24 | actual class Marker private constructor( 25 | 26 | val log4JMarker: Log4JMarker 27 | ) { 28 | 29 | actual val name: String 30 | get() = log4JMarker.name 31 | 32 | actual val parents: Map 33 | // Implementation creates temporary `Pair` objects vs. optimal none 34 | get() = log4JMarker.parents.associate { it.name to fromMarker(it) } 35 | 36 | override fun toString(): String = log4JMarker.toString() 37 | 38 | override fun equals(other: Any?): Boolean { 39 | return (other as? Marker)?.log4JMarker == log4JMarker 40 | } 41 | 42 | override fun hashCode(): Int = log4JMarker.hashCode() 43 | 44 | actual companion object Factory { 45 | 46 | private val markers = ConcurrentHashMap() 47 | 48 | actual fun fromName(name: String, parents: Set): Marker { 49 | return markers.computeIfAbsent(MarkerManager.getMarker(name)) { 50 | // Implementation creates 3 `parents` copies vs. optimal 2 51 | val log4JMarkerParents = parents.map(Marker::log4JMarker) 52 | it.setParents(*log4JMarkerParents.toTypedArray()) 53 | Marker(it) 54 | } 55 | } 56 | 57 | fun fromMarker(marker: Log4JMarker): Marker = markers.computeIfAbsent(marker, ::Marker) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/jvmMain/kotlin/lumberjack/Logger.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack 18 | 19 | import lumberjack.message.Message 20 | import org.apache.logging.log4j.LogManager 21 | import java.util.concurrent.ConcurrentHashMap 22 | import kotlin.coroutines.CoroutineContext 23 | import kotlin.reflect.KClass 24 | 25 | typealias Log4JLogger = org.apache.logging.log4j.Logger 26 | 27 | actual class Logger private constructor( 28 | 29 | val log4JLogger: Log4JLogger 30 | ) { 31 | 32 | actual val name: String 33 | get() = log4JLogger.name 34 | 35 | actual val level: Level 36 | get() = Level.fromLevel(log4JLogger.level) 37 | 38 | actual fun logc(level: Level, message: Message, marker: Marker?, cause: Throwable?, context: CoroutineContext) { 39 | log4JLogger.log(level.log4JLevel, marker?.log4JMarker, message.log4JMessage, cause) // TODO CoroutineContext 40 | } 41 | 42 | override fun toString(): String = log4JLogger.toString() 43 | 44 | override fun equals(other: Any?): Boolean { 45 | return (other as? Logger)?.log4JLogger == log4JLogger 46 | } 47 | 48 | override fun hashCode(): Int = log4JLogger.hashCode() 49 | 50 | actual companion object Factory { 51 | 52 | private val loggers = ConcurrentHashMap() 53 | 54 | actual fun fromName(name: String): Logger = fromLogger(LogManager.getLogger(name)) 55 | 56 | actual fun fromKClass(kClass: KClass<*>): Logger = fromLogger(LogManager.getLogger(kClass.java)) 57 | 58 | fun fromLogger(logger: Log4JLogger): Logger = loggers.computeIfAbsent(logger, ::Logger) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/jvmMain/kotlin/lumberjack/MDC.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack 18 | 19 | import kotlinx.coroutines.ThreadContextElement 20 | import org.apache.logging.log4j.ThreadContext 21 | import kotlin.coroutines.AbstractCoroutineContextElement 22 | import kotlin.coroutines.CoroutineContext 23 | 24 | actual class MDC private constructor( 25 | 26 | private val context: Context 27 | ) : AbstractCoroutineContextElement(MDC), 28 | CoroutineContext.Element, 29 | Context by context, 30 | ThreadContextElement { 31 | 32 | override fun restoreThreadContext(context: CoroutineContext, oldState: Context) { 33 | ThreadContext.clearMap() 34 | ThreadContext.putAll(oldState) 35 | } 36 | 37 | override fun updateThreadContext(context: CoroutineContext): Context { 38 | // Get a *copy* of the context map; oldState does not view changes 39 | val oldState = ThreadContext.getContext() 40 | ThreadContext.clearMap() 41 | ThreadContext.putAll(this) 42 | return oldState 43 | } 44 | 45 | override fun toString(): String = context.toString() 46 | 47 | override fun equals(other: Any?): Boolean = (context == other) 48 | 49 | override fun hashCode(): Int = context.hashCode() 50 | 51 | actual companion object Key : CoroutineContext.Key { 52 | 53 | private val EMPTY: MDC = MDC(emptyMap()) 54 | 55 | actual fun fromContext(context: Context): MDC { 56 | return when { // Avoid allocate if possible 57 | context.isEmpty() -> EMPTY 58 | context is MDC -> context 59 | else -> MDC(context) 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/layout/DeprecatedLayout.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.layout 18 | 19 | import lumberjack.MDC 20 | import lumberjack.sawtooth.event.LogEvent 21 | 22 | @Deprecated( 23 | """ 24 | This class was designed to be a quick, temporary, default Layout implementation for Appender instances. It is 25 | intended for this class to be removed and replaced with a more customizable, permanent, default alternative. 26 | """ 27 | ) 28 | object DeprecatedLayout : Layout { 29 | 30 | override fun writeTo(builder: StringBuilder, event: LogEvent) { 31 | builder.append(event.level.name) 32 | builder.append(' ') 33 | builder.append(event.logger.name) 34 | builder.append(' ') 35 | 36 | val marker = event.marker 37 | if (marker != null) { 38 | builder.append(marker.name) 39 | builder.append(' ') 40 | } 41 | 42 | event.message.writeTo(builder) 43 | 44 | val context = event.context[MDC] 45 | if (!context.isNullOrEmpty()) { 46 | builder.append(' ') 47 | builder.append(context) 48 | } 49 | 50 | var cause = event.cause 51 | while (cause != null) { 52 | builder.append( 53 | """ 54 | 55 | Caused by: 56 | """.trimIndent() 57 | ) 58 | 59 | builder.append(cause::class.simpleName) 60 | builder.append(" (") 61 | builder.append(cause.message) 62 | builder.append(')') 63 | 64 | cause = cause.cause 65 | } 66 | } 67 | 68 | override fun toString(): String = "DeprecatedLayout()" 69 | } 70 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/appender/RegexCompositeAppender.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.appender 18 | 19 | import lumberjack.Logger 20 | import lumberjack.internal.ConcurrentMap 21 | import lumberjack.sawtooth.event.LogEvent 22 | 23 | class RegexCompositeAppender private constructor( 24 | 25 | private val defaultAppender: Appender, 26 | 27 | private val regexAppenders: List 28 | ) : Appender { 29 | 30 | private val cache = ConcurrentMap() 31 | 32 | override fun append(event: LogEvent) { 33 | val logger = event.logger 34 | 35 | cache.getOrUpdate(logger) { 36 | regexAppenders.firstOrNull { it.regex.matches(logger.name) }?.appender ?: defaultAppender 37 | }.append(event) 38 | } 39 | 40 | override fun toString(): String { 41 | return "RegexCompositeAppender(" + 42 | "defaultAppender=$defaultAppender" + 43 | ", regexAppenders=$regexAppenders" + 44 | ")" 45 | } 46 | 47 | companion object Factory { 48 | 49 | val DEFAULT: RegexCompositeAppender = configure() 50 | 51 | fun configure( 52 | defaultAppender: Appender = DEFAULT_APPENDER, 53 | regexAppenders: List = emptyList() 54 | ): RegexCompositeAppender = RegexCompositeAppender( 55 | defaultAppender = defaultAppender, 56 | regexAppenders = regexAppenders 57 | ) 58 | } 59 | } 60 | 61 | fun RegexCompositeAppender.Factory.configure( 62 | defaultAppender: Appender = DEFAULT_APPENDER, 63 | vararg regexAppenders: RegexAppender 64 | ): RegexCompositeAppender = configure(defaultAppender, listOf(*regexAppenders)) 65 | 66 | internal expect val RegexCompositeAppender.Factory.DEFAULT_APPENDER: Appender 67 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/sawtooth/event/ThreadLocalLogEventFactory.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.sawtooth.event 18 | 19 | import lumberjack.Level 20 | import lumberjack.Logger 21 | import lumberjack.Marker 22 | import lumberjack.message.Message 23 | import kotlin.coroutines.CoroutineContext 24 | 25 | class ThreadLocalLogEventFactory private constructor( 26 | 27 | properties: Set> 28 | ) : LogEventFactory { 29 | 30 | private val properties = properties.associateBy(LogProperty<*>::key) 31 | 32 | override fun fromLogging( 33 | logger: Logger, 34 | level: Level, 35 | message: Message, 36 | marker: Marker?, 37 | cause: Throwable?, 38 | context: CoroutineContext 39 | ): LogEvent { 40 | ThreadLocalLogEvent.logger = logger 41 | ThreadLocalLogEvent.level = level 42 | ThreadLocalLogEvent.message = message 43 | ThreadLocalLogEvent.marker = marker 44 | ThreadLocalLogEvent.cause = cause 45 | ThreadLocalLogEvent.context = context 46 | ThreadLocalLogEvent.properties = properties 47 | return ThreadLocalLogEvent 48 | } 49 | 50 | override fun toString(): String { 51 | return "ThreadLocalLogEventFactory(" + 52 | "properties=$properties" + 53 | ")" 54 | } 55 | 56 | companion object Factory { 57 | 58 | val DEFAULT: ThreadLocalLogEventFactory = withProperties() 59 | 60 | fun withProperties( 61 | properties: Set> = emptySet() 62 | ): ThreadLocalLogEventFactory = ThreadLocalLogEventFactory(properties) 63 | } 64 | } 65 | 66 | fun ThreadLocalLogEventFactory.Factory.withProperties( 67 | vararg properties: LogProperty<*> 68 | ): ThreadLocalLogEventFactory = withProperties(setOf(*properties)) 69 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/Level.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack 18 | 19 | import lumberjack.internal.ConcurrentMap 20 | 21 | actual sealed class Level( 22 | 23 | actual val name: String, 24 | 25 | actual val value: Int 26 | ) : Comparable { 27 | 28 | final override fun compareTo(other: Level): Int = value.compareTo(other.value) 29 | 30 | final override fun equals(other: Any?): Boolean { 31 | return (other as? Level)?.name == name 32 | } 33 | 34 | final override fun hashCode(): Int = name.hashCode() 35 | 36 | final override fun toString(): String = name 37 | 38 | actual object None : Level("OFF", 0) 39 | 40 | actual object Fatal : Level("FATAL", 100) 41 | 42 | actual object Error : Level("ERROR", 200) 43 | 44 | actual object Warn : Level("WARN", 300) 45 | 46 | actual object Info : Level("INFO", 400) 47 | 48 | actual object Debug : Level("DEBUG", 500) 49 | 50 | actual object Trace : Level("TRACE", 600) 51 | 52 | actual object All : Level("ALL", Int.MAX_VALUE) 53 | 54 | actual class Custom internal constructor(name: String, value: Int) : Level(name, value) 55 | 56 | actual companion object Factory { 57 | 58 | private val levels = ConcurrentMap() 59 | 60 | actual fun fromName(name: String, defaultLevel: Level): Level { 61 | return fromName(name) ?: levels[name] ?: defaultLevel 62 | } 63 | 64 | actual fun toLevel(name: String, value: Int): Level = 65 | levels.getOrUpdate(name) { fromName(name) ?: Custom(name, value) } 66 | 67 | private fun fromName(name: String): Level? { 68 | return when (name) { 69 | None.name -> None 70 | Fatal.name -> Fatal 71 | Error.name -> Error 72 | Warn.name -> Warn 73 | Info.name -> Info 74 | Debug.name -> Debug 75 | Trace.name -> Trace 76 | All.name -> All 77 | else -> null 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/sawtoothMain/kotlin/lumberjack/Logger.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack 18 | 19 | import lumberjack.internal.ConcurrentMap 20 | import lumberjack.internal.Reference 21 | import lumberjack.internal.name 22 | import lumberjack.message.Message 23 | import lumberjack.sawtooth.Configuration 24 | import kotlin.coroutines.CoroutineContext 25 | import kotlin.reflect.KClass 26 | 27 | actual class Logger private constructor( 28 | 29 | actual val name: String 30 | ) { 31 | 32 | actual val level: Level 33 | get() = configuration.levelFactory.fromLogger(this) 34 | 35 | actual fun logc( 36 | level: Level, 37 | message: Message, 38 | marker: Marker?, 39 | cause: Throwable?, 40 | context: CoroutineContext 41 | ) { 42 | if ((level > Level.None) && (this.level >= level)) { 43 | val event = configuration.logEventFactory.fromLogging( 44 | logger = this, 45 | level = level, 46 | message = message, 47 | marker = marker, 48 | cause = cause, 49 | context = context 50 | ) 51 | 52 | configuration.appender.append(event) 53 | } 54 | } 55 | 56 | override fun equals(other: Any?): Boolean { 57 | return (other as? Logger)?.name == name 58 | } 59 | 60 | override fun hashCode(): Int = name.hashCode() 61 | 62 | override fun toString(): String = name 63 | 64 | actual companion object Factory { 65 | 66 | @Suppress("ObjectPropertyName") 67 | private val _configuration = Reference(Configuration.DEFAULT) 68 | 69 | private val loggers = ConcurrentMap() 70 | 71 | var configuration: Configuration 72 | get() = _configuration.value 73 | set(value) = value.run { _configuration.value = this } 74 | 75 | actual fun fromName(name: String): Logger = 76 | loggers.getOrUpdate(name) { Logger(name) } 77 | 78 | actual fun fromKClass(kClass: KClass<*>): Logger = fromName(kClass.name) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /src/jvmMain/kotlin/lumberjack/Level.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack 18 | 19 | import java.util.concurrent.ConcurrentHashMap 20 | 21 | typealias Log4JLevel = org.apache.logging.log4j.Level 22 | 23 | actual sealed class Level( 24 | 25 | val log4JLevel: Log4JLevel 26 | ) : Comparable { 27 | 28 | actual val name: String 29 | get() = log4JLevel.name() 30 | 31 | actual val value: Int 32 | get() = log4JLevel.intLevel() 33 | 34 | final override fun compareTo(other: Level): Int = log4JLevel.compareTo(other.log4JLevel) 35 | 36 | final override fun toString(): String = log4JLevel.toString() 37 | 38 | final override fun equals(other: Any?): Boolean { 39 | return (other as? Level)?.log4JLevel == log4JLevel 40 | } 41 | 42 | final override fun hashCode(): Int = log4JLevel.hashCode() 43 | 44 | actual object None : Level(Log4JLevel.OFF) 45 | 46 | actual object Fatal : Level(Log4JLevel.FATAL) 47 | 48 | actual object Error : Level(Log4JLevel.ERROR) 49 | 50 | actual object Warn : Level(Log4JLevel.WARN) 51 | 52 | actual object Info : Level(Log4JLevel.INFO) 53 | 54 | actual object Debug : Level(Log4JLevel.DEBUG) 55 | 56 | actual object Trace : Level(Log4JLevel.TRACE) 57 | 58 | actual object All : Level(Log4JLevel.ALL) 59 | 60 | actual class Custom internal constructor(log4JLevel: Log4JLevel) : Level(log4JLevel) 61 | 62 | actual companion object Factory { 63 | 64 | private val levels = ConcurrentHashMap(8) 65 | 66 | actual fun fromName(name: String, defaultLevel: Level): Level { 67 | return fromLevel(Log4JLevel.toLevel(name, defaultLevel.log4JLevel)) 68 | } 69 | 70 | actual fun toLevel(name: String, value: Int): Level = fromLevel(Log4JLevel.forName(name, value)) 71 | 72 | fun fromLevel(level: Log4JLevel): Level = levels.computeIfAbsent(level) { 73 | when (it) { // Use `it` so JVM can optimize lambda to prevent garbage 74 | None.log4JLevel -> None 75 | Fatal.log4JLevel -> Fatal 76 | Error.log4JLevel -> Error 77 | Warn.log4JLevel -> Warn 78 | Info.log4JLevel -> Info 79 | Debug.log4JLevel -> Debug 80 | Trace.log4JLevel -> Trace 81 | All.log4JLevel -> All 82 | else -> Custom(it) 83 | } 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/nativeMain/kotlin/lumberjack/internal/ConcurrentMap.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | package lumberjack.internal 18 | 19 | import kotlin.native.concurrent.AtomicReference 20 | 21 | internal actual class ConcurrentMap actual constructor() : MutableMap { 22 | 23 | private val delegate = AtomicReference(emptyMap()) 24 | 25 | override val entries: MutableSet> 26 | get() = TODO(this::entries.name) 27 | 28 | override val keys: MutableSet 29 | get() = TODO(this::keys.name) 30 | 31 | override val size: Int 32 | get() = delegate.value.size 33 | 34 | override val values: MutableCollection 35 | get() = TODO(this::values.name) 36 | 37 | override fun clear(): Unit = delegate.run { value = emptyMap() } 38 | 39 | override fun containsKey(key: K): Boolean = delegate.value.containsKey(key) 40 | 41 | override fun containsValue(value: V): Boolean = delegate.value.containsValue(value) 42 | 43 | override fun get(key: K): V? = delegate.value[key] 44 | 45 | override fun isEmpty(): Boolean = delegate.value.isEmpty() 46 | 47 | override fun put(key: K, value: V): V? { 48 | var cachedPair: Pair? = null 49 | 50 | return delegate.getAndUpdate { 51 | if ((key in it) && (it[key] == value)) { 52 | return@getAndUpdate it 53 | } 54 | 55 | cachedPair = cachedPair ?: (key to value) 56 | it + cachedPair!! 57 | }[key] 58 | } 59 | 60 | override fun putAll(from: Map): Unit = delegate.update { it + from } 61 | 62 | override fun remove(key: K): V? { 63 | return delegate.getAndUpdate { 64 | if (key !in it) { 65 | return@getAndUpdate it 66 | } 67 | 68 | it - key 69 | }[key] 70 | } 71 | 72 | actual inline fun getOrUpdate(key: K, value: () -> V): V { 73 | // Cache helps reduce allocations during contentions 74 | var cachedPair: Pair? = null 75 | 76 | return delegate.updateAndGet { 77 | if (key in it) { 78 | return@updateAndGet it 79 | } 80 | 81 | cachedPair = cachedPair ?: (key to value()) 82 | it + cachedPair!! 83 | }.getValue(key) 84 | } 85 | 86 | override fun equals(other: Any?): Boolean = (delegate.value == other) 87 | 88 | override fun hashCode(): Int = delegate.value.hashCode() 89 | 90 | override fun toString(): String = delegate.value.toString() 91 | } 92 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Discord](https://img.shields.io/discord/356994728614690818?label=NeonTech&color=7289DA&style=for-the-badge)](https://discord.gg/ThGXvNF) 2 | [![Actions](https://img.shields.io/github/workflow/status/NeonTech/Lumberjack/Build?style=for-the-badge)](https://github.com/NeonTech/Lumberjack/actions) 3 | [![Bintray](https://img.shields.io/bintray/v/neontech/maven/lumberjack?color=43a047&style=for-the-badge)](https://bintray.com/beta/#/neontech/maven/lumberjack) 4 | [![License](https://img.shields.io/github/license/NeonTech/Lumberjack?style=for-the-badge)](https://www.gnu.org/licenses/lgpl-3.0.en.html) 5 | 6 | # Lumberjack 7 | 8 | Kotlin Coroutine Multiplatform Logging Library 9 | 10 | ## 💎 Benefits 11 | 12 | * 💪 **Powerful** - Heavily inspired by [Log4J2](https://logging.apache.org/log4j/2.x/), Lumberjack enables powerful logging API concepts such as MDC (Mapped Diagnostic Context), markers, custom levels, and an abstract `Message` API to be utilized in `common` and non-JVM platforms. 13 | 14 | * 🧰 **Configurable** - For JVM targets, Lumberjack delegates to [Log4J2 API](https://logging.apache.org/log4j/2.x/) which enables extensive customization in [runtime implementation](https://logging.apache.org/log4j/2.x/runtime-dependencies.html) including delegating to [SLF4J](http://www.slf4j.org/) or, if using `log4j-core`, powerful [configuration](https://logging.apache.org/log4j/2.x/manual/configuration.html) options. 15 | 16 | For non-JVM targets, Lumberjack delegates to *Sawtooth*; an in-house logging engine and configuration API. *Sawtooth* configurations can be changed during runtime and its abstract APIs allow potentially infinite customization. 17 | 18 | * 🚀 **Efficient** - By reusing buffers and objects, utilizing caches, and inlining functions; Lumberjack operates with minimal memory overhead and contributes little to no additional pressure for the garbage collector. 19 | 20 | * 🌌 **Universal** - Lumberjack supports *all* [Kotlin Multiplatform targets](https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#supported-platforms) which makes it perfect for any Kotlin library or application for any platform. 21 | 22 | ## 📦 Installation 23 | 24 | Lumberjack can be installed like any other Kotlin library via [Gradle](https://gradle.org/). For all proceeding examples, `$VERSION` should be replaced with the latest available version on [Bintray](https://bintray.com/neontech/maven/lumberjack). While it is not recommended to manually install dependencies, raw artifacts can also be found on Bintray. 25 | 26 | ```kotlin 27 | repositories { 28 | jcenter() 29 | } 30 | 31 | dependencies { 32 | // Replace $PLATFORM with jvm, js, linuxx64, macosx64, mingwx64, etc. 33 | implementation("dev.neontech.lumberjack:lumberjack-$PLATFORM:$VERSION") 34 | } 35 | ``` 36 | 37 | ### Kotlin Multiplatform 38 | 39 | For [Kotlin Mutliplatform](https://kotlinlang.org/docs/reference/multiplatform.html) projects, Lumberjack provides [Gradle Metadata](https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#metadata-publishing) to resolve individual platforms automatically. 40 | 41 | ```kotlin 42 | repositories { 43 | jcenter() 44 | } 45 | 46 | kotlin { 47 | sourceSets { 48 | val commonMain by getting { 49 | dependencies { 50 | // Implementations for jvm, js, etc. automatically resolve 51 | implementation("dev.neontech.lumberjack:lumberjack:$VERSION") 52 | } 53 | } 54 | } 55 | } 56 | ``` 57 | 58 | Alternatively, implementations may manually be resolved with an explicit `-common` declaration in `commonMain`. 59 | 60 | ```kotlin 61 | repositories { 62 | jcenter() 63 | } 64 | 65 | kotlin { 66 | sourceSets { 67 | val commonMain by getting { 68 | dependencies { 69 | implementation("dev.neontech.lumberjack:lumberjack-common:$VERSION") 70 | } 71 | } 72 | 73 | val jvmMain by getting { 74 | dependencies { 75 | implementation("dev.neontech.lumberjack:lumberjack-jvm:$VERSION") 76 | } 77 | } 78 | 79 | // etc. 80 | } 81 | } 82 | ``` 83 | 84 | ## 🖇️ Common API 85 | 86 | ### Logger 87 | 88 | `Logger` is the core class of the Lumberjack API and is responsible for *logging*. 89 | 90 | ```kotlin 91 | fun myFunction() { 92 | // May optionally provide a Marker, cause (Throwable), and/or CoroutineContext 93 | logger.logc(Level.Info, ThreadLocalMutableObjectMessage.message("Hello World!")) 94 | } 95 | ``` 96 | 97 | Lumberjack provides **many** extension functions to automatically apply a `Level` and, lazily, construct a `Message` from any arbitrary object. 98 | 99 | ```kotlin 100 | fun myFunction() { 101 | logger.infoc { "Hello World!" } 102 | } 103 | ``` 104 | 105 | Lumberjack enables users to embed additional *context* in log outputs via [`MDC`](#mdc). For non-`suspend` functions, the context must be manually provided via a `CoroutineContext` instance; hence the `c` suffix. For `suspend` functions, the `CoroutineContext` can be automatically provided by removing the `c` suffix. 106 | 107 | ```kotlin 108 | suspend fun myFunction() { 109 | logger.info { "Hello World" } 110 | } 111 | ``` 112 | 113 | Loggers can be instantiated with the `Logger.fromName` or the `Logger.fromKClass` factory functions. 114 | 115 | ### Message 116 | 117 | Messages can act as wrappers around objects so that the user can have control over converting objects to String instances without requiring complicated formatters. The conversion is *lazy* and may never be executed (for example, insufficient logging level) which prevents unnecessary allocation of garbage. 118 | 119 | ### Level 120 | 121 | Levels enable users to categorize log statements by *urgency*. This categorization allows filtering persistent logs, controlling the amount of information logged, or a combination of both and additional factors. 122 | 123 | Lumberjack provides the following standard logging levels; accessible via `Level` subclasses: 124 | 125 | | Object | Name | Value | 126 | | ------- | ----- | --------------- | 127 | | `None` | OFF | 0 | 128 | | `Fatal` | FATAL | 100 | 129 | | `Error` | ERROR | 200 | 130 | | `Warn` | WARN | 300 | 131 | | `Info` | INFO | 400 | 132 | | `Debug` | DEBUG | 500 | 133 | | `Trace` | TRACE | 600 | 134 | | `All` | ALL | `Int.MAX_VALUE` | 135 | 136 | Lumberjack additionally supports custom logging levels. Invoking the `Level.toLevel` factory function will instantiate a `Level.Custom` instance, or return an existing `Level` if previously instantiated. `Level.fromName` is also provided to *only* return previously instantiated `Level` instances, or otherwise return the provided `defaultLevel` or `Level.Debug`. 137 | 138 | ### Marker 139 | 140 | [Markers can be used to *color* or mark a *single* log statement.](https://stackoverflow.com/a/16820978) Markers can be instantiated with the `Marker.fromName` factory function; optionally, with related parent instances. 141 | 142 | ```kotlin 143 | val NOTIFY: Marker = Marker.fromName("NOTIFY") 144 | val NOTIFY_ADMIN: Marker = Marker.fromName("NOTIFY_ADMIN", NOTIFY) 145 | ``` 146 | 147 | ### MDC 148 | 149 | *Mapped Diagnostic Context* enables users to embed additional *context* in log outputs without exposing abstractions to unnecessary information. For example, a rate limiter would log *when* a rate limit has been triggered, but, assuming an abstracted rate limiter API, it would not be possible to log *what* triggered the rate limit; especially in highly concurrent applications. 150 | 151 | Lumberjack uses [`CoroutineContext`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines/-coroutine-context/) instances to pass context around in highly concurrent applications. `MDC` is a special `CoroutineContext` that Lumberjack will automatically utilize and provides an interface for storing generic information as a `Map`. 152 | 153 | Calling the `mdc` top-level function will return the current `MDC` of any coroutine. An optional function can be provided to add or remove key/value pairs to instantiate a new `MDC` for new coroutines. 154 | 155 | ```kotlin 156 | suspend fun myFunction() { 157 | val context = mdc { it + ("key" to "value") } 158 | withContext(context) { 159 | logger.info { "Hello World" } 160 | } 161 | } 162 | ``` 163 | 164 | The `MDC.fromContext` factory function instantiates a new `MDC` from non-`suspend` functions. This function discards previous contexts and is ***not*** recommended. 165 | 166 | ```kotlin 167 | fun myFunction() { 168 | val context = MDC.fromContext(mapOf("key" to "value")) 169 | logger.infoc(context = context) { "Hello World" } 170 | } 171 | ``` 172 | -------------------------------------------------------------------------------- /src/commonMain/kotlin/lumberjack/Logger.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Lumberjack. 3 | * 4 | * Lumberjack is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * Lumberjack is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with Lumberjack. If not, see . 16 | */ 17 | @file:JvmName("LoggerJVM") 18 | 19 | package lumberjack 20 | 21 | import lumberjack.message.Message 22 | import lumberjack.message.ThreadLocalMutableObjectMessage 23 | import lumberjack.message.message 24 | import kotlin.coroutines.CoroutineContext 25 | import kotlin.coroutines.EmptyCoroutineContext 26 | import kotlin.coroutines.coroutineContext 27 | import kotlin.jvm.JvmName 28 | import kotlin.reflect.KClass 29 | 30 | expect class Logger { 31 | 32 | val name: String 33 | 34 | val level: Level 35 | 36 | fun logc( 37 | level: Level, 38 | message: Message, 39 | marker: Marker? = null, 40 | cause: Throwable? = null, 41 | context: CoroutineContext = EmptyCoroutineContext 42 | ) 43 | 44 | companion object Factory { 45 | 46 | fun fromName(name: String): Logger 47 | 48 | fun fromKClass(kClass: KClass<*>): Logger 49 | } 50 | } 51 | 52 | inline fun Logger.logc( 53 | level: Level, 54 | marker: Marker? = null, 55 | cause: Throwable? = null, 56 | context: CoroutineContext = EmptyCoroutineContext, 57 | message: () -> Any? 58 | ) { 59 | if ((level > Level.None) && (this.level >= level)) { 60 | val rawMessage = message() // ThreadLocalMutableObjectMessage is most efficient for generic object 61 | val typedMessage = (rawMessage as? Message) ?: ThreadLocalMutableObjectMessage.message(rawMessage) 62 | logc(level, typedMessage, marker, cause, context) 63 | } 64 | } 65 | 66 | suspend inline fun Logger.log( 67 | level: Level, 68 | message: Message, 69 | marker: Marker? = null, 70 | cause: Throwable? = null 71 | ): Unit = logc(level, message, marker, cause, coroutineContext) 72 | 73 | suspend inline fun Logger.log( 74 | level: Level, 75 | marker: Marker? = null, 76 | cause: Throwable? = null, 77 | message: () -> Any? 78 | ): Unit = logc(level, marker, cause, coroutineContext, message) 79 | 80 | fun Logger.nonec( 81 | message: Message, 82 | marker: Marker? = null, 83 | cause: Throwable? = null, 84 | context: CoroutineContext = EmptyCoroutineContext 85 | ): Unit = logc(Level.None, message, marker, cause, context) 86 | 87 | inline fun Logger.nonec( 88 | marker: Marker? = null, 89 | cause: Throwable? = null, 90 | context: CoroutineContext = EmptyCoroutineContext, 91 | message: () -> Any? 92 | ): Unit = logc(Level.None, marker, cause, context, message) 93 | 94 | suspend inline fun Logger.none( 95 | message: Message, 96 | marker: Marker? = null, 97 | cause: Throwable? = null 98 | ): Unit = log(Level.None, message, marker, cause) 99 | 100 | suspend inline fun Logger.none( 101 | marker: Marker? = null, 102 | cause: Throwable? = null, 103 | message: () -> Any? 104 | ): Unit = log(Level.None, marker, cause, message) 105 | 106 | fun Logger.fatalc( 107 | message: Message, 108 | marker: Marker? = null, 109 | cause: Throwable? = null, 110 | context: CoroutineContext = EmptyCoroutineContext 111 | ): Unit = logc(Level.Fatal, message, marker, cause, context) 112 | 113 | inline fun Logger.fatalc( 114 | marker: Marker? = null, 115 | cause: Throwable? = null, 116 | context: CoroutineContext = EmptyCoroutineContext, 117 | message: () -> Any? 118 | ): Unit = logc(Level.Fatal, marker, cause, context, message) 119 | 120 | suspend inline fun Logger.fatal( 121 | message: Message, 122 | marker: Marker? = null, 123 | cause: Throwable? = null 124 | ): Unit = log(Level.Fatal, message, marker, cause) 125 | 126 | suspend inline fun Logger.fatal( 127 | marker: Marker? = null, 128 | cause: Throwable? = null, 129 | message: () -> Any? 130 | ): Unit = log(Level.Fatal, marker, cause, message) 131 | 132 | fun Logger.errorc( 133 | message: Message, 134 | marker: Marker? = null, 135 | cause: Throwable? = null, 136 | context: CoroutineContext = EmptyCoroutineContext 137 | ): Unit = logc(Level.Error, message, marker, cause, context) 138 | 139 | inline fun Logger.errorc( 140 | marker: Marker? = null, 141 | cause: Throwable? = null, 142 | context: CoroutineContext = EmptyCoroutineContext, 143 | message: () -> Any? 144 | ): Unit = logc(Level.Error, marker, cause, context, message) 145 | 146 | suspend inline fun Logger.error( 147 | message: Message, 148 | marker: Marker? = null, 149 | cause: Throwable? = null 150 | ): Unit = log(Level.Error, message, marker, cause) 151 | 152 | suspend inline fun Logger.error( 153 | marker: Marker? = null, 154 | cause: Throwable? = null, 155 | message: () -> Any? 156 | ): Unit = log(Level.Error, marker, cause, message) 157 | 158 | fun Logger.warnc( 159 | message: Message, 160 | marker: Marker? = null, 161 | cause: Throwable? = null, 162 | context: CoroutineContext = EmptyCoroutineContext 163 | ): Unit = logc(Level.Warn, message, marker, cause, context) 164 | 165 | inline fun Logger.warnc( 166 | marker: Marker? = null, 167 | cause: Throwable? = null, 168 | context: CoroutineContext = EmptyCoroutineContext, 169 | message: () -> Any? 170 | ): Unit = logc(Level.Warn, marker, cause, context, message) 171 | 172 | suspend inline fun Logger.warn( 173 | message: Message, 174 | marker: Marker? = null, 175 | cause: Throwable? = null 176 | ): Unit = log(Level.Warn, message, marker, cause) 177 | 178 | suspend inline fun Logger.warn( 179 | marker: Marker? = null, 180 | cause: Throwable? = null, 181 | message: () -> Any? 182 | ): Unit = log(Level.Warn, marker, cause, message) 183 | 184 | fun Logger.infoc( 185 | message: Message, 186 | marker: Marker? = null, 187 | cause: Throwable? = null, 188 | context: CoroutineContext = EmptyCoroutineContext 189 | ): Unit = logc(Level.Info, message, marker, cause, context) 190 | 191 | inline fun Logger.infoc( 192 | marker: Marker? = null, 193 | cause: Throwable? = null, 194 | context: CoroutineContext = EmptyCoroutineContext, 195 | message: () -> Any? 196 | ): Unit = logc(Level.Info, marker, cause, context, message) 197 | 198 | suspend inline fun Logger.info( 199 | message: Message, 200 | marker: Marker? = null, 201 | cause: Throwable? = null 202 | ): Unit = log(Level.Info, message, marker, cause) 203 | 204 | suspend inline fun Logger.info( 205 | marker: Marker? = null, 206 | cause: Throwable? = null, 207 | message: () -> Any? 208 | ): Unit = log(Level.Info, marker, cause, message) 209 | 210 | fun Logger.debugc( 211 | message: Message, 212 | marker: Marker? = null, 213 | cause: Throwable? = null, 214 | context: CoroutineContext = EmptyCoroutineContext 215 | ): Unit = logc(Level.Debug, message, marker, cause, context) 216 | 217 | inline fun Logger.debugc( 218 | marker: Marker? = null, 219 | cause: Throwable? = null, 220 | context: CoroutineContext = EmptyCoroutineContext, 221 | message: () -> Any? 222 | ): Unit = logc(Level.Debug, marker, cause, context, message) 223 | 224 | suspend inline fun Logger.debug( 225 | message: Message, 226 | marker: Marker? = null, 227 | cause: Throwable? = null 228 | ): Unit = log(Level.Debug, message, marker, cause) 229 | 230 | suspend inline fun Logger.debug( 231 | marker: Marker? = null, 232 | cause: Throwable? = null, 233 | message: () -> Any? 234 | ): Unit = log(Level.Debug, marker, cause, message) 235 | 236 | fun Logger.tracec( 237 | message: Message, 238 | marker: Marker? = null, 239 | cause: Throwable? = null, 240 | context: CoroutineContext = EmptyCoroutineContext 241 | ): Unit = logc(Level.Trace, message, marker, cause, context) 242 | 243 | inline fun Logger.tracec( 244 | marker: Marker? = null, 245 | cause: Throwable? = null, 246 | context: CoroutineContext = EmptyCoroutineContext, 247 | message: () -> Any? 248 | ): Unit = logc(Level.Trace, marker, cause, context, message) 249 | 250 | suspend inline fun Logger.trace( 251 | message: Message, 252 | marker: Marker? = null, 253 | cause: Throwable? = null 254 | ): Unit = log(Level.Trace, message, marker, cause) 255 | 256 | suspend inline fun Logger.trace( 257 | marker: Marker? = null, 258 | cause: Throwable? = null, 259 | message: () -> Any? 260 | ): Unit = log(Level.Trace, marker, cause, message) 261 | 262 | fun Logger.allc( 263 | message: Message, 264 | marker: Marker? = null, 265 | cause: Throwable? = null, 266 | context: CoroutineContext = EmptyCoroutineContext 267 | ): Unit = logc(Level.All, message, marker, cause, context) 268 | 269 | inline fun Logger.allc( 270 | marker: Marker? = null, 271 | cause: Throwable? = null, 272 | context: CoroutineContext = EmptyCoroutineContext, 273 | message: () -> Any? 274 | ): Unit = logc(Level.All, marker, cause, context, message) 275 | 276 | suspend inline fun Logger.all( 277 | message: Message, 278 | marker: Marker? = null, 279 | cause: Throwable? = null 280 | ): Unit = log(Level.All, message, marker, cause) 281 | 282 | suspend inline fun Logger.all( 283 | marker: Marker? = null, 284 | cause: Throwable? = null, 285 | message: () -> Any? 286 | ): Unit = log(Level.All, marker, cause, message) 287 | --------------------------------------------------------------------------------