mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-16 00:30:02 +00:00
Add seperate root log level config property
Adjust logging behaviour of Gameyfin
This commit is contained in:
@@ -46,7 +46,8 @@ function LogManagementLayout({getConfig, formik}: any) {
|
||||
<div className="flex flex-row gap-4">
|
||||
<ConfigFormField configElement={getConfig("logs.folder")}/>
|
||||
<ConfigFormField configElement={getConfig("logs.max-history-days")}/>
|
||||
<ConfigFormField configElement={getConfig("logs.level")}/>
|
||||
<ConfigFormField configElement={getConfig("logs.level.gameyfin")}/>
|
||||
<ConfigFormField configElement={getConfig("logs.level.root")}/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col">
|
||||
@@ -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")
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
@@ -224,13 +224,23 @@ sealed class ConfigProperties<T : Serializable>(
|
||||
30
|
||||
)
|
||||
|
||||
data object Level : ConfigProperties<LogLevel>(
|
||||
LogLevel::class,
|
||||
"logs.level",
|
||||
"Log level",
|
||||
LogLevel.INFO,
|
||||
LogLevel.entries
|
||||
)
|
||||
sealed class Level {
|
||||
data object Gameyfin : ConfigProperties<LogLevel>(
|
||||
LogLevel::class,
|
||||
"logs.level.gameyfin",
|
||||
"Log level (Gameyfin)",
|
||||
LogLevel.INFO,
|
||||
LogLevel.entries
|
||||
)
|
||||
|
||||
data object Root : ConfigProperties<LogLevel>(
|
||||
LogLevel::class,
|
||||
"logs.level.root",
|
||||
"Log level (Root)",
|
||||
LogLevel.INFO,
|
||||
LogLevel.entries
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ class ConfigService(
|
||||
*/
|
||||
fun getAll(prefix: String?): List<ConfigEntryDto> {
|
||||
|
||||
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 <T : Serializable> 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)
|
||||
|
||||
+1
-1
@@ -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
|
||||
+12
-8
@@ -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()
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package de.grimsi.gameyfin.logs.dto
|
||||
package de.grimsi.gameyfin.core.logging.dto
|
||||
|
||||
import org.springframework.boot.logging.LogLevel
|
||||
|
||||
+1
-1
@@ -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
|
||||
+4
-4
@@ -15,7 +15,7 @@ class PluginConfigService(
|
||||
private val log = KotlinLogging.logger {}
|
||||
|
||||
fun getConfigMetadata(pluginId: String): List<PluginConfigElement> {
|
||||
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<String, String?> {
|
||||
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<String, String>) {
|
||||
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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
+4
-4
@@ -20,7 +20,7 @@ class MessageTemplateService {
|
||||
private val log = KotlinLogging.logger {}
|
||||
|
||||
fun getMessageTemplates(): List<MessageTemplateDto> {
|
||||
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())
|
||||
|
||||
+3
-3
@@ -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 <T : Serializable> get(userPreference: UserPreferences<T>): 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 <T : Serializable> set(key: String, value: T) {
|
||||
log.info { "Set user preference '$key'" }
|
||||
log.debug { "Set user preference '$key'" }
|
||||
|
||||
val userPreferenceKey = findUserPreference(key)
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -15,10 +15,9 @@
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Spams the logs on DEBUG due to a loop (log -> push to client -> log the push -> repeat) -->
|
||||
<logger name="com.vaadin.hilla.push.PushEndpoint" level="INFO"/>
|
||||
<logger name="de.grimsi.gameyfin" level="{LOG_LEVEL_GAMEYFIN}"/>
|
||||
|
||||
<root level="{LOG_LEVEL}">
|
||||
<root level="{LOG_LEVEL_ROOT}">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="FILE"/>
|
||||
</root>
|
||||
|
||||
Reference in New Issue
Block a user