From 180242fdf3d943a543144935d44a42c399920288 Mon Sep 17 00:00:00 2001 From: grimsi <9295182+grimsi@users.noreply.github.com> Date: Sun, 11 May 2025 13:57:03 +0200 Subject: [PATCH] Add seperate root log level config property Adjust logging behaviour of Gameyfin --- .../administration/LogManagement.tsx | 8 +++++-- .../gameyfin/config/ConfigProperties.kt | 24 +++++++++++++------ .../grimsi/gameyfin/config/ConfigService.kt | 6 ++--- .../{logs => core/logging}/LogEndpoint.kt | 2 +- .../{logs => core/logging}/LogService.kt | 20 +++++++++------- .../logging}/dto/LogConfigDto.kt | 2 +- .../logging}/util/AsyncFileTailer.kt | 2 +- .../plugins/config/PluginConfigService.kt | 8 +++---- .../de/grimsi/gameyfin/games/GameService.kt | 2 +- .../gameyfin/libraries/LibraryService.kt | 6 ++--- .../templates/MessageTemplateService.kt | 8 +++---- .../preferences/UserPreferencesService.kt | 6 ++--- .../src/main/resources/application-dev.yml | 4 ---- .../templates/log-config-template.xml | 5 ++-- 14 files changed, 58 insertions(+), 45 deletions(-) rename gameyfin/src/main/kotlin/de/grimsi/gameyfin/{logs => core/logging}/LogEndpoint.kt (93%) rename gameyfin/src/main/kotlin/de/grimsi/gameyfin/{logs => core/logging}/LogService.kt (82%) rename gameyfin/src/main/kotlin/de/grimsi/gameyfin/{logs => core/logging}/dto/LogConfigDto.kt (78%) rename gameyfin/src/main/kotlin/de/grimsi/gameyfin/{logs => core/logging}/util/AsyncFileTailer.kt (97%) diff --git a/gameyfin/src/main/frontend/components/administration/LogManagement.tsx b/gameyfin/src/main/frontend/components/administration/LogManagement.tsx index b96ad2a..3172f67 100644 --- a/gameyfin/src/main/frontend/components/administration/LogManagement.tsx +++ b/gameyfin/src/main/frontend/components/administration/LogManagement.tsx @@ -46,7 +46,8 @@ function LogManagementLayout({getConfig, formik}: any) {
- + +
@@ -86,7 +87,10 @@ const validationSchema = Yup.object({ logs: Yup.object({ folder: Yup.string().required("Required"), "max-history-days": Yup.number().required("Required"), - level: Yup.string().required("Required") + level: Yup.object({ + gameyfin: Yup.string().required("Required"), + root: Yup.string().required("Required") + }) }) }); diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/config/ConfigProperties.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/config/ConfigProperties.kt index b57289e..79c33cb 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/config/ConfigProperties.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/config/ConfigProperties.kt @@ -224,13 +224,23 @@ sealed class ConfigProperties( 30 ) - data object Level : ConfigProperties( - LogLevel::class, - "logs.level", - "Log level", - LogLevel.INFO, - LogLevel.entries - ) + sealed class Level { + data object Gameyfin : ConfigProperties( + LogLevel::class, + "logs.level.gameyfin", + "Log level (Gameyfin)", + LogLevel.INFO, + LogLevel.entries + ) + + data object Root : ConfigProperties( + LogLevel::class, + "logs.level.root", + "Log level (Root)", + LogLevel.INFO, + LogLevel.entries + ) + } } } diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/config/ConfigService.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/config/ConfigService.kt index 9c00ccb..ba4d74f 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/config/ConfigService.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/config/ConfigService.kt @@ -58,7 +58,7 @@ class ConfigService( */ fun getAll(prefix: String?): List { - log.info { "Getting all config values for prefix '$prefix'" } + log.debug { "Getting all config values for prefix '$prefix'" } var configProperties = ConfigProperties::class.sealedSubclasses.flatMap { subclass -> subclass.objectInstance?.let { listOf(it) } ?: listOf() @@ -91,7 +91,7 @@ class ConfigService( */ @Suppress("UNCHECKED_CAST") fun set(key: String, value: T) { - log.info { "Set config value '$key'" } + log.debug { "Set config value '$key'" } val configProperty = findConfigProperty(key) @@ -143,7 +143,7 @@ class ConfigService( */ fun deleteConfig(key: String) { - log.info { "Delete config value '$key'" } + log.debug { "Delete config value '$key'" } val configKey = findConfigProperty(key) appConfigRepository.deleteById(configKey.key) diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/logs/LogEndpoint.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/logging/LogEndpoint.kt similarity index 93% rename from gameyfin/src/main/kotlin/de/grimsi/gameyfin/logs/LogEndpoint.kt rename to gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/logging/LogEndpoint.kt index 3a08a0e..b0a31c6 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/logs/LogEndpoint.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/logging/LogEndpoint.kt @@ -1,4 +1,4 @@ -package de.grimsi.gameyfin.logs +package de.grimsi.gameyfin.core.logging import com.vaadin.flow.server.auth.AnonymousAllowed import com.vaadin.hilla.Endpoint diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/logs/LogService.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/logging/LogService.kt similarity index 82% rename from gameyfin/src/main/kotlin/de/grimsi/gameyfin/logs/LogService.kt rename to gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/logging/LogService.kt index b209327..97b702a 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/logs/LogService.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/logging/LogService.kt @@ -1,10 +1,10 @@ -package de.grimsi.gameyfin.logs +package de.grimsi.gameyfin.core.logging import ch.qos.logback.classic.LoggerContext import ch.qos.logback.classic.joran.JoranConfigurator import de.grimsi.gameyfin.config.ConfigProperties import de.grimsi.gameyfin.config.ConfigService -import de.grimsi.gameyfin.logs.util.AsyncFileTailer +import de.grimsi.gameyfin.core.logging.util.AsyncFileTailer import io.github.oshai.kotlinlogging.KotlinLogging import org.slf4j.LoggerFactory import org.springframework.boot.context.event.ApplicationStartedEvent @@ -41,18 +41,20 @@ class LogService( return configureFileLogging( config.get(ConfigProperties.Logs.Folder)!!, config.get(ConfigProperties.Logs.MaxHistoryDays)!!, - config.get(ConfigProperties.Logs.Level)!! + config.get(ConfigProperties.Logs.Level.Gameyfin)!!, + config.get(ConfigProperties.Logs.Level.Root)!! ) } - fun configureFileLogging(folder: String, maxHistoryDays: Int, level: LogLevel) { + fun configureFileLogging(folder: String, maxHistoryDays: Int, levelGameyfin: LogLevel, levelRoot: LogLevel) { val context = LoggerFactory.getILoggerFactory() as LoggerContext val configurator = JoranConfigurator() configurator.context = context context.reset() - generateLogConfigXml(folder.removeSuffix("/"), maxHistoryDays, level).use { - log.info { "Setting log level to $level" } + generateLogConfigXml(folder.removeSuffix("/"), maxHistoryDays, levelGameyfin, levelRoot).use { + log.info { "Setting log level for Gameyfin to $levelGameyfin" } + log.info { "Setting log level for Root to $levelRoot" } log.info { "Setting log retention to $maxHistoryDays days" } configurator.doConfigure(it) @@ -74,7 +76,8 @@ class LogService( private fun generateLogConfigXml( folder: String, maxHistoryDays: Int, - level: LogLevel + levelGameyfin: LogLevel, + levelRoot: LogLevel ): InputStream { val template = javaClass.classLoader.getResourceAsStream(LOG_CONFIG_TEMPLATE) ?: throw IllegalStateException("Log config template not found") @@ -84,7 +87,8 @@ class LogService( .replace("{LOG_FOLDER}", folder) .replace("{LOG_FILE_NAME}", LOG_FILE_NAME) .replace("{LOG_MAX_HISTORY_DAYS}", maxHistoryDays.toString()) - .replace("{LOG_LEVEL}", level.toString()) + .replace("{LOG_LEVEL_GAMEYFIN}", levelGameyfin.toString()) + .replace("{LOG_LEVEL_ROOT}", levelRoot.toString()) .byteInputStream() } } \ No newline at end of file diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/logs/dto/LogConfigDto.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/logging/dto/LogConfigDto.kt similarity index 78% rename from gameyfin/src/main/kotlin/de/grimsi/gameyfin/logs/dto/LogConfigDto.kt rename to gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/logging/dto/LogConfigDto.kt index 8759d0c..72757b9 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/logs/dto/LogConfigDto.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/logging/dto/LogConfigDto.kt @@ -1,4 +1,4 @@ -package de.grimsi.gameyfin.logs.dto +package de.grimsi.gameyfin.core.logging.dto import org.springframework.boot.logging.LogLevel diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/logs/util/AsyncFileTailer.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/logging/util/AsyncFileTailer.kt similarity index 97% rename from gameyfin/src/main/kotlin/de/grimsi/gameyfin/logs/util/AsyncFileTailer.kt rename to gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/logging/util/AsyncFileTailer.kt index 77018ec..1abf827 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/logs/util/AsyncFileTailer.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/logging/util/AsyncFileTailer.kt @@ -1,4 +1,4 @@ -package de.grimsi.gameyfin.logs.util +package de.grimsi.gameyfin.core.logging.util import io.github.oshai.kotlinlogging.KotlinLogging import kotlinx.coroutines.CoroutineScope diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/config/PluginConfigService.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/config/PluginConfigService.kt index 9bcc13c..842eb52 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/config/PluginConfigService.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/plugins/config/PluginConfigService.kt @@ -15,7 +15,7 @@ class PluginConfigService( private val log = KotlinLogging.logger {} fun getConfigMetadata(pluginId: String): List { - log.info { "Getting config metadata for plugin $pluginId" } + log.debug { "Getting config metadata for plugin $pluginId" } val plugin = try { pluginManager.getPlugin(pluginId).plugin @@ -29,19 +29,19 @@ class PluginConfigService( } fun getConfig(pluginId: String): Map { - log.info { "Getting config for plugin $pluginId" } + log.debug { "Getting config for plugin $pluginId" } return pluginConfigRepository.findAllById_PluginId(pluginId).associate { it.id.key to it.value } } fun setConfigEntries(pluginId: String, config: Map) { - log.info { "Setting config entries for plugin $pluginId" } + log.debug { "Setting config entries for plugin $pluginId" } val entries = config.map { PluginConfigEntry(PluginConfigEntryKey(pluginId, it.key), it.value) } pluginConfigRepository.saveAll(entries) pluginManager.restart(pluginId) } fun setConfigEntry(pluginId: String, key: String, value: String) { - log.info { "Setting config entry $key for plugin $pluginId" } + log.debug { "Setting config entry $key for plugin $pluginId" } val entry = PluginConfigEntry(PluginConfigEntryKey(pluginId, key), value) pluginConfigRepository.save(entry) pluginManager.restart(pluginId) diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/GameService.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/GameService.kt index 07b879d..2a7cc66 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/GameService.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/GameService.kt @@ -149,7 +149,7 @@ class GameService( val bestMatchingTitle = FuzzySearch.extractOne(originalQuery, providerToTitle.values).string - log.info { + log.debug { "Best matching title: '$bestMatchingTitle' (${ providerToTitle.count { it.value.fuzzyMatchTitle(bestMatchingTitle) } }/${providerToTitle.size} matches) for '$originalQuery' determined from $providerToTitle" diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/libraries/LibraryService.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/libraries/LibraryService.kt index 4ff388c..fb7b5dd 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/libraries/LibraryService.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/libraries/LibraryService.kt @@ -186,7 +186,7 @@ class LibraryService( } val progress = completedMetadata.incrementAndGet() - log.info { "${progress}/${totalPaths} metadata matched" } + log.debug { "${progress}/${totalPaths} metadata matched" } return@Callable game } catch (e: Exception) { @@ -225,7 +225,7 @@ class LibraryService( completedImageDownload.andIncrement } - log.info { "${completedImageDownload}/${totalImages} images downloaded" } + log.debug { "${completedImageDownload}/${totalImages} images downloaded" } game } catch (e: Exception) { @@ -239,7 +239,7 @@ class LibraryService( // 3. Persist new games val persistedGames = gameService.create(gamesWithImages) - log.info { "${persistedGames.size}/${totalPaths} saved to database" } + log.debug { "${persistedGames.size}/${totalPaths} saved to database" } // 4. Add new games to library addGamesToLibrary(persistedGames, library) diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/messages/templates/MessageTemplateService.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/messages/templates/MessageTemplateService.kt index bdaed2b..4cc412a 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/messages/templates/MessageTemplateService.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/messages/templates/MessageTemplateService.kt @@ -20,7 +20,7 @@ class MessageTemplateService { private val log = KotlinLogging.logger {} fun getMessageTemplates(): List { - log.info { "Getting all message templates" } + log.debug { "Getting all message templates" } val messageTemplates = MessageTemplates::class.sealedSubclasses.flatMap { subclass -> subclass.objectInstance?.let { listOf(it) } ?: listOf() } @@ -35,7 +35,7 @@ class MessageTemplateService { } fun getMessageTemplateContent(key: String, type: TemplateType): String { - log.info { "Reading message template content for '$key.${type.extension}'" } + log.debug { "Reading message template content for '$key.${type.extension}'" } return getTemplateFile(key, type).readText() } @@ -53,7 +53,7 @@ class MessageTemplateService { } fun setMessageTemplateContent(key: String, type: TemplateType, content: String) { - log.info { "Saving message template content for key '$key'" } + log.debug { "Saving message template content for key '$key'" } getOrCreateTemplateFile(key, type).writeText(content) } @@ -80,7 +80,7 @@ class MessageTemplateService { } private fun getDefaultTemplateFile(key: String, type: TemplateType): Path { - log.info { "No custom message template found for '$key.${type.extension}', returning default" } + log.debug { "No custom message template found for '$key.${type.extension}', returning default" } val resourceUrl = javaClass.classLoader.getResource("$DEFAULT_TEMPLATE_PATH/$key.${type.extension}") ?: throw IllegalStateException("Default template file not found for '$key.${type.extension}'") return Paths.get(resourceUrl.toURI()) diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/users/preferences/UserPreferencesService.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/users/preferences/UserPreferencesService.kt index af88c35..4ac18a0 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/users/preferences/UserPreferencesService.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/users/preferences/UserPreferencesService.kt @@ -21,7 +21,7 @@ class UserPreferencesService( * @return The current value if set or the default value or null if no value is set and no default value exists */ fun get(userPreference: UserPreferences): T? { - log.info { "Getting user preference '${userPreference.key}'" } + log.debug { "Getting user preference '${userPreference.key}'" } val id = id(userPreference.key) val appConfig = userPreferenceRepository.findById(id).orElse(null) @@ -42,7 +42,7 @@ class UserPreferencesService( */ fun get(key: String): String? { - log.info { "Getting user preference '$key'" } + log.debug { "Getting user preference '$key'" } val userPreference = findUserPreference(key) val id = id(key) @@ -75,7 +75,7 @@ class UserPreferencesService( * @throws IllegalArgumentException if the value can't be cast to the type defined for the user preference */ fun set(key: String, value: T) { - log.info { "Set user preference '$key'" } + log.debug { "Set user preference '$key'" } val userPreferenceKey = findUserPreference(key) diff --git a/gameyfin/src/main/resources/application-dev.yml b/gameyfin/src/main/resources/application-dev.yml index 0ffe8cd..a57c468 100644 --- a/gameyfin/src/main/resources/application-dev.yml +++ b/gameyfin/src/main/resources/application-dev.yml @@ -1,7 +1,3 @@ -logging.level.de.grimsi.gameyfin: DEBUG -logging.level.org.hibernate.SQL: DEBUG -logging.level.org.hibernate.type: TRACE - spring: datasource: url: jdbc:h2:file:./db/${spring.datasource.db-name};AUTO_SERVER=TRUE \ No newline at end of file diff --git a/gameyfin/src/main/resources/templates/log-config-template.xml b/gameyfin/src/main/resources/templates/log-config-template.xml index e048536..573d52d 100644 --- a/gameyfin/src/main/resources/templates/log-config-template.xml +++ b/gameyfin/src/main/resources/templates/log-config-template.xml @@ -15,10 +15,9 @@ - - + - +