Initialize logger as the companion object where possible

This commit is contained in:
Syer10
2021-05-20 13:44:30 -04:00
parent aba23fdaf7
commit 1d79ccf80d
10 changed files with 60 additions and 45 deletions

View File

@@ -7,6 +7,7 @@
package ca.gosyer.data.server package ca.gosyer.data.server
import ca.gosyer.BuildConfig import ca.gosyer.BuildConfig
import ca.gosyer.util.system.CKLogger
import ca.gosyer.util.system.userDataDir import ca.gosyer.util.system.userDataDir
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
@@ -65,11 +66,10 @@ class ServerService @Inject constructor(
return@onEach return@onEach
} }
GlobalScope.launch { GlobalScope.launch {
val logger = KotlinLogging.logger("Server")
val jarFile = File(userDataDir, "Tachidesk.jar") val jarFile = File(userDataDir, "Tachidesk.jar")
if (!jarFile.exists()) { if (!jarFile.exists()) {
logger.info { "Copying server to resources" } info { "Copying server to resources" }
copyJar(jarFile) copyJar(jarFile)
} else { } else {
try { try {
@@ -86,11 +86,11 @@ class ServerService @Inject constructor(
jarVersion.specification != BuildConfig.TACHIDESK_SP_VERSION || jarVersion.specification != BuildConfig.TACHIDESK_SP_VERSION ||
jarVersion.implementation != BuildConfig.TACHIDESK_IM_VERSION jarVersion.implementation != BuildConfig.TACHIDESK_IM_VERSION
) { ) {
logger.info { "Updating server file from resources" } info { "Updating server file from resources" }
copyJar(jarFile) copyJar(jarFile)
} }
} catch (e: IOException) { } catch (e: IOException) {
logger.error(e) { error(e) {
"Error accessing server jar, cannot update server, ${BuildConfig.NAME} may not work properly" "Error accessing server jar, cannot update server, ${BuildConfig.NAME} may not work properly"
} }
} }
@@ -105,12 +105,13 @@ class ServerService @Inject constructor(
else -> "java" else -> "java"
} }
logger.info { "Starting server with $javaExePath" } info { "Starting server with $javaExePath" }
val reader: BufferedReader val reader: BufferedReader
process = runtime.exec("""$javaExePath -jar "${jarFile.absolutePath}"""").also { process = runtime.exec("""$javaExePath -jar "${jarFile.absolutePath}"""").also {
reader = it.inputStream.bufferedReader() reader = it.inputStream.bufferedReader()
} }
logger.info { "Server started successfully" } info { "Server started successfully" }
val logger = KotlinLogging.logger("Server")
var line: String? var line: String?
while (reader.readLine().also { line = it } != null) { while (reader.readLine().also { line = it } != null) {
if (initialized.value == ServerResult.STARTING) { if (initialized.value == ServerResult.STARTING) {
@@ -125,9 +126,9 @@ class ServerService @Inject constructor(
if (initialized.value == ServerResult.STARTING) { if (initialized.value == ServerResult.STARTING) {
initialized.value = ServerResult.FAILED initialized.value = ServerResult.FAILED
} }
logger.info { "Server closed" } info { "Server closed" }
val exitVal = process?.waitFor() val exitVal = process?.waitFor()
logger.info { "Process exitValue: $exitVal" } info { "Process exitValue: $exitVal" }
process = null process = null
} }
}.launchIn(GlobalScope) }.launchIn(GlobalScope)
@@ -141,4 +142,6 @@ class ServerService @Inject constructor(
} }
data class JarVersion(val specification: String?, val implementation: String?) data class JarVersion(val specification: String?, val implementation: String?)
private companion object : CKLogger({})
} }

View File

@@ -9,17 +9,16 @@ package ca.gosyer.ui.categories
import ca.gosyer.data.models.Category import ca.gosyer.data.models.Category
import ca.gosyer.data.server.interactions.CategoryInteractionHandler import ca.gosyer.data.server.interactions.CategoryInteractionHandler
import ca.gosyer.ui.base.vm.ViewModel import ca.gosyer.ui.base.vm.ViewModel
import ca.gosyer.util.system.CKLogger
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mu.KotlinLogging
import javax.inject.Inject import javax.inject.Inject
class CategoriesMenuViewModel @Inject constructor( class CategoriesMenuViewModel @Inject constructor(
private val categoryHandler: CategoryInteractionHandler private val categoryHandler: CategoryInteractionHandler
) : ViewModel() { ) : ViewModel() {
private val logger = KotlinLogging.logger {}
private var originalCategories = emptyList<Category>() private var originalCategories = emptyList<Category>()
private val _categories = MutableStateFlow(emptyList<MenuCategory>()) private val _categories = MutableStateFlow(emptyList<MenuCategory>())
val categories = _categories.asStateFlow() val categories = _categories.asStateFlow()
@@ -66,7 +65,7 @@ class CategoriesMenuViewModel @Inject constructor(
updatedCategories.forEach { updatedCategory -> updatedCategories.forEach { updatedCategory ->
val category = categories.find { it.id == updatedCategory.id || it.name == updatedCategory.name } ?: return@forEach val category = categories.find { it.id == updatedCategory.id || it.name == updatedCategory.name } ?: return@forEach
if (category.order != updatedCategory.order) { if (category.order != updatedCategory.order) {
logger.debug { "${category.order} to ${updatedCategory.order}" } debug { "${category.order} to ${updatedCategory.order}" }
categoryHandler.reorderCategory(updatedCategory, category.order, updatedCategory.order) categoryHandler.reorderCategory(updatedCategory, category.order, updatedCategory.order)
} }
} }
@@ -109,4 +108,6 @@ class CategoriesMenuViewModel @Inject constructor(
fun Category.toMenuCategory() = MenuCategory(id, order, name, landing) fun Category.toMenuCategory() = MenuCategory(id, order, name, landing)
data class MenuCategory(val id: Long? = null, var order: Int, val name: String, val landing: Boolean = false) data class MenuCategory(val id: Long? = null, var order: Int, val name: String, val landing: Boolean = false)
private companion object : CKLogger({})
} }

View File

@@ -11,11 +11,11 @@ import ca.gosyer.data.models.Extension
import ca.gosyer.data.server.ServerPreferences import ca.gosyer.data.server.ServerPreferences
import ca.gosyer.data.server.interactions.ExtensionInteractionHandler import ca.gosyer.data.server.interactions.ExtensionInteractionHandler
import ca.gosyer.ui.base.vm.ViewModel import ca.gosyer.ui.base.vm.ViewModel
import ca.gosyer.util.system.CKLogger
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mu.KotlinLogging
import javax.inject.Inject import javax.inject.Inject
class ExtensionsMenuViewModel @Inject constructor( class ExtensionsMenuViewModel @Inject constructor(
@@ -23,8 +23,6 @@ class ExtensionsMenuViewModel @Inject constructor(
serverPreferences: ServerPreferences, serverPreferences: ServerPreferences,
private val extensionPreferences: ExtensionPreferences private val extensionPreferences: ExtensionPreferences
) : ViewModel() { ) : ViewModel() {
private val logger = KotlinLogging.logger {}
val serverUrl = serverPreferences.server().stateIn(scope) val serverUrl = serverPreferences.server().stateIn(scope)
private lateinit var extensionList: List<Extension> private lateinit var extensionList: List<Extension>
@@ -59,7 +57,7 @@ class ExtensionsMenuViewModel @Inject constructor(
} }
fun install(extension: Extension) { fun install(extension: Extension) {
logger.info { "Install clicked" } info { "Install clicked" }
scope.launch { scope.launch {
try { try {
extensionHandler.installExtension(extension) extensionHandler.installExtension(extension)
@@ -71,7 +69,7 @@ class ExtensionsMenuViewModel @Inject constructor(
} }
fun update(extension: Extension) { fun update(extension: Extension) {
logger.info { "Update clicked" } info { "Update clicked" }
scope.launch { scope.launch {
try { try {
extensionHandler.updateExtension(extension) extensionHandler.updateExtension(extension)
@@ -83,7 +81,7 @@ class ExtensionsMenuViewModel @Inject constructor(
} }
fun uninstall(extension: Extension) { fun uninstall(extension: Extension) {
logger.info { "Uninstall clicked" } info { "Uninstall clicked" }
scope.launch { scope.launch {
try { try {
extensionHandler.uninstallExtension(extension) extensionHandler.uninstallExtension(extension)
@@ -107,4 +105,6 @@ class ExtensionsMenuViewModel @Inject constructor(
_extensions.value = extensions.toList() _extensions.value = extensions.toList()
} }
} }
private companion object : CKLogger({})
} }

View File

@@ -11,13 +11,13 @@ import ca.gosyer.data.server.interactions.ChapterInteractionHandler
import ca.gosyer.ui.reader.loader.TachideskPageLoader import ca.gosyer.ui.reader.loader.TachideskPageLoader
import ca.gosyer.ui.reader.model.ReaderChapter import ca.gosyer.ui.reader.model.ReaderChapter
import ca.gosyer.ui.reader.model.ReaderPage import ca.gosyer.ui.reader.model.ReaderPage
import ca.gosyer.util.system.CKLogger
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.take import kotlinx.coroutines.flow.take
import mu.KotlinLogging
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
class ChapterLoader( class ChapterLoader(
@@ -25,14 +25,12 @@ class ChapterLoader(
private val readerPreferences: ReaderPreferences, private val readerPreferences: ReaderPreferences,
private val chapterHandler: ChapterInteractionHandler private val chapterHandler: ChapterInteractionHandler
) { ) {
private val logger = KotlinLogging.logger {}
fun loadChapter(chapter: ReaderChapter): StateFlow<List<ReaderPage>> { fun loadChapter(chapter: ReaderChapter): StateFlow<List<ReaderPage>> {
if (chapterIsReady(chapter)) { if (chapterIsReady(chapter)) {
return (chapter.state as ReaderChapter.State.Loaded).pages return (chapter.state as ReaderChapter.State.Loaded).pages
} else { } else {
chapter.state = ReaderChapter.State.Loading chapter.state = ReaderChapter.State.Loading
logger.debug { "Loading pages for ${chapter.chapter.name}" } debug { "Loading pages for ${chapter.chapter.name}" }
val loader = TachideskPageLoader(context + Dispatchers.Default, chapter, readerPreferences, chapterHandler) val loader = TachideskPageLoader(context + Dispatchers.Default, chapter, readerPreferences, chapterHandler)
@@ -56,4 +54,6 @@ class ChapterLoader(
private fun chapterIsReady(chapter: ReaderChapter): Boolean { private fun chapterIsReady(chapter: ReaderChapter): Boolean {
return chapter.state is ReaderChapter.State.Loaded && chapter.pageLoader != null return chapter.state is ReaderChapter.State.Loaded && chapter.pageLoader != null
} }
private companion object : CKLogger({})
} }

View File

@@ -10,6 +10,7 @@ import ca.gosyer.data.reader.ReaderPreferences
import ca.gosyer.data.server.interactions.ChapterInteractionHandler import ca.gosyer.data.server.interactions.ChapterInteractionHandler
import ca.gosyer.ui.reader.model.ReaderChapter import ca.gosyer.ui.reader.model.ReaderChapter
import ca.gosyer.ui.reader.model.ReaderPage import ca.gosyer.ui.reader.model.ReaderPage
import ca.gosyer.util.system.CKLogger
import io.github.kerubistan.kroki.coroutines.priorityChannel import io.github.kerubistan.kroki.coroutines.priorityChannel
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@@ -19,7 +20,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mu.KotlinLogging
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@@ -30,7 +30,6 @@ class TachideskPageLoader(
chapterHandler: ChapterInteractionHandler chapterHandler: ChapterInteractionHandler
) : PageLoader() { ) : PageLoader() {
val scope = CoroutineScope(SupervisorJob() + context) val scope = CoroutineScope(SupervisorJob() + context)
private val logger = KotlinLogging.logger {}
/** /**
* A channel used to manage requests one by one while allowing priorities. * A channel used to manage requests one by one while allowing priorities.
@@ -56,7 +55,7 @@ class TachideskPageLoader(
try { try {
for (priorityPage in channel) { for (priorityPage in channel) {
val page = priorityPage.page val page = priorityPage.page
logger.debug { "Loading page ${page.index}" } debug { "Loading page ${page.index}" }
if (page.status.value == ReaderPage.Status.QUEUE) { if (page.status.value == ReaderPage.Status.QUEUE) {
try { try {
page.bitmap.value = chapterHandler.getPage(chapter.chapter, page.index) page.bitmap.value = chapterHandler.getPage(chapter.chapter, page.index)
@@ -169,4 +168,6 @@ class TachideskPageLoader(
scope.cancel() scope.cancel()
channel.close() channel.close()
} }
private companion object : CKLogger({})
} }

View File

@@ -8,18 +8,16 @@ package ca.gosyer.ui.reader.model
import ca.gosyer.data.models.Chapter import ca.gosyer.data.models.Chapter
import ca.gosyer.ui.reader.loader.PageLoader import ca.gosyer.ui.reader.loader.PageLoader
import ca.gosyer.util.system.CKLogger
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import mu.KotlinLogging
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
data class ReaderChapter(val context: CoroutineContext, val chapter: Chapter) { data class ReaderChapter(val context: CoroutineContext, val chapter: Chapter) {
private val logger = KotlinLogging.logger {}
var scope = CoroutineScope(context + Job()) var scope = CoroutineScope(context + Job())
private set private set
@@ -43,7 +41,7 @@ data class ReaderChapter(val context: CoroutineContext, val chapter: Chapter) {
fun recycle() { fun recycle() {
if (pageLoader != null) { if (pageLoader != null) {
logger.debug { "Recycling chapter ${chapter.name}" } debug { "Recycling chapter ${chapter.name}" }
} }
pageLoader?.recycle() pageLoader?.recycle()
pageLoader = null pageLoader = null
@@ -58,4 +56,6 @@ data class ReaderChapter(val context: CoroutineContext, val chapter: Chapter) {
class Error(val error: Throwable) : State() class Error(val error: Throwable) : State()
class Loaded(val pages: StateFlow<List<ReaderPage>>) : State() class Loaded(val pages: StateFlow<List<ReaderPage>>) : State()
} }
private companion object : CKLogger({})
} }

View File

@@ -28,21 +28,19 @@ import ca.gosyer.ui.base.prefs.PreferenceRow
import ca.gosyer.ui.base.vm.ViewModel import ca.gosyer.ui.base.vm.ViewModel
import ca.gosyer.ui.base.vm.viewModel import ca.gosyer.ui.base.vm.viewModel
import ca.gosyer.ui.main.Route import ca.gosyer.ui.main.Route
import ca.gosyer.util.system.CKLogger
import ca.gosyer.util.system.filePicker import ca.gosyer.util.system.filePicker
import ca.gosyer.util.system.fileSaver import ca.gosyer.util.system.fileSaver
import com.github.zsoltk.compose.router.BackStack import com.github.zsoltk.compose.router.BackStack
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mu.KotlinLogging
import java.io.File import java.io.File
import javax.inject.Inject import javax.inject.Inject
class SettingsBackupViewModel @Inject constructor( class SettingsBackupViewModel @Inject constructor(
private val backupHandler: BackupInteractionHandler private val backupHandler: BackupInteractionHandler
) : ViewModel() { ) : ViewModel() {
private val logger = KotlinLogging.logger {}
private val _restoring = MutableStateFlow(false) private val _restoring = MutableStateFlow(false)
val restoring = _restoring.asStateFlow() val restoring = _restoring.asStateFlow()
private val _restoreError = MutableStateFlow(false) private val _restoreError = MutableStateFlow(false)
@@ -56,14 +54,14 @@ class SettingsBackupViewModel @Inject constructor(
fun restoreFile(file: File?) { fun restoreFile(file: File?) {
scope.launch { scope.launch {
if (file == null || !file.exists()) { if (file == null || !file.exists()) {
logger.info { "Invalid file ${file?.absolutePath}" } info { "Invalid file ${file?.absolutePath}" }
} else { } else {
_restoreError.value = false _restoreError.value = false
_restoring.value = true _restoring.value = true
try { try {
backupHandler.importBackupFile(file) backupHandler.importBackupFile(file)
} catch (e: Exception) { } catch (e: Exception) {
logger.info(e) { "Error importing backup" } info(e) { "Error importing backup" }
_restoreError.value = true _restoreError.value = true
} finally { } finally {
_restoring.value = false _restoring.value = false
@@ -75,7 +73,7 @@ class SettingsBackupViewModel @Inject constructor(
fun createFile(file: File?) { fun createFile(file: File?) {
scope.launch { scope.launch {
if (file == null) { if (file == null) {
logger.info { "Invalid file ${file?.absolutePath}" } info { "Invalid file ${file?.absolutePath}" }
} else { } else {
if (file.exists()) file.delete() if (file.exists()) file.delete()
_creatingError.value = false _creatingError.value = false
@@ -83,7 +81,7 @@ class SettingsBackupViewModel @Inject constructor(
try { try {
val backup = backupHandler.exportBackupFile() val backup = backupHandler.exportBackupFile()
} catch (e: Exception) { } catch (e: Exception) {
logger.info(e) { "Error importing backup" } info(e) { "Error exporting backup" }
_creatingError.value = true _creatingError.value = true
} finally { } finally {
_creating.value = false _creating.value = false
@@ -91,6 +89,8 @@ class SettingsBackupViewModel @Inject constructor(
} }
} }
} }
private companion object : CKLogger({})
} }
@Composable @Composable

View File

@@ -11,6 +11,7 @@ import ca.gosyer.data.models.Source
import ca.gosyer.data.server.ServerPreferences import ca.gosyer.data.server.ServerPreferences
import ca.gosyer.data.server.interactions.SourceInteractionHandler import ca.gosyer.data.server.interactions.SourceInteractionHandler
import ca.gosyer.ui.base.vm.ViewModel import ca.gosyer.ui.base.vm.ViewModel
import ca.gosyer.util.system.CKLogger
import com.github.zsoltk.compose.savedinstancestate.Bundle import com.github.zsoltk.compose.savedinstancestate.Bundle
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@@ -19,7 +20,6 @@ import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mu.KotlinLogging
import javax.inject.Inject import javax.inject.Inject
class SourcesMenuViewModel @Inject constructor( class SourcesMenuViewModel @Inject constructor(
@@ -28,8 +28,6 @@ class SourcesMenuViewModel @Inject constructor(
serverPreferences: ServerPreferences, serverPreferences: ServerPreferences,
catalogPreferences: CatalogPreferences catalogPreferences: CatalogPreferences
) : ViewModel() { ) : ViewModel() {
private val logger = KotlinLogging.logger {}
val serverUrl = serverPreferences.server().stateIn(scope) val serverUrl = serverPreferences.server().stateIn(scope)
private val languages = catalogPreferences.languages().stateIn(scope) private val languages = catalogPreferences.languages().stateIn(scope)
@@ -70,9 +68,9 @@ class SourcesMenuViewModel @Inject constructor(
scope.launch { scope.launch {
try { try {
val sources = sourceHandler.getSourceList() val sources = sourceHandler.getSourceList()
logger.info { sources } info { sources }
_sources.value = sources.filter { it.lang in languages.value } _sources.value = sources.filter { it.lang in languages.value }
logger.info { _sources.value } info { _sources.value }
} catch (e: Exception) { } catch (e: Exception) {
if (e is CancellationException) throw e if (e is CancellationException) throw e
} finally { } finally {
@@ -111,7 +109,7 @@ class SourcesMenuViewModel @Inject constructor(
} }
} }
companion object { private companion object : CKLogger({}) {
const val SOURCE_TABS_KEY = "source_tabs" const val SOURCE_TABS_KEY = "source_tabs"
const val SELECTED_SOURCE_TAB = "selected_tab" const val SELECTED_SOURCE_TAB = "selected_tab"
} }

View File

@@ -7,14 +7,12 @@
package ca.gosyer.util.compose package ca.gosyer.util.compose
import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntOffset
import mu.KotlinLogging
import javax.swing.Icon import javax.swing.Icon
import javax.swing.JMenuItem import javax.swing.JMenuItem
import javax.swing.JPopupMenu import javax.swing.JPopupMenu
import javax.swing.JSeparator import javax.swing.JSeparator
class ContextMenu internal constructor() { class ContextMenu internal constructor() {
val logger = KotlinLogging.logger {}
internal val list = mutableListOf<Pair<Any, (() -> Unit)?>>() internal val list = mutableListOf<Pair<Any, (() -> Unit)?>>()
internal fun popupMenu() = JPopupMenu().apply { internal fun popupMenu() = JPopupMenu().apply {
@@ -26,8 +24,6 @@ class ContextMenu internal constructor() {
when (item) { when (item) {
is JMenuItem -> add(item).apply { is JMenuItem -> add(item).apply {
addActionListener { addActionListener {
logger.info { it.actionCommand }
logger.info { it.modifiers }
block.andClose() block.andClose()
} }
} }

View File

@@ -0,0 +1,16 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.util.system
import mu.KLogger
import mu.KotlinLogging
abstract class CKLogger(logger: KLogger) : KLogger by logger {
constructor(func: () -> Unit) : this(kLogger(func))
}
fun kLogger(func: () -> Unit) = KotlinLogging.logger(func)