From 252ab6dfe747e737c6040c7d21c6b8744468bb02 Mon Sep 17 00:00:00 2001 From: vityaman Date: Fri, 17 May 2024 13:04:01 +0300 Subject: [PATCH] #43 Add logging decorators --- .../app/spring/logic/SpringHomeworkService.kt | 8 ++- .../spring/logic/SpringPromotionService.kt | 8 ++- .../app/spring/logic/SpringRatingService.kt | 8 ++- .../app/spring/logic/SpringUserService.kt | 8 ++- .../spring/logic/SpringWorkspaceService.kt | 8 ++- .../spring/logic/SpringYandexAuthService.kt | 14 ++++-- .../security/SpringYandexOAuthService.kt | 13 +++-- .../vityaman/lms/botalka/core/logging/Log.kt | 6 +++ .../lms/botalka/core/logging/Slf4jLog.kt | 15 ++++++ .../core/logic/logging/LoggingAuthService.kt | 24 +++++++++ .../logic/logging/LoggingHomeworkService.kt | 23 +++++++++ .../logic/logging/LoggingPromotionService.kt | 45 +++++++++++++++++ .../logic/logging/LoggingRatingService.kt | 15 ++++++ .../core/logic/logging/LoggingUserService.kt | 33 +++++++++++++ .../logic/logging/LoggingWorkspaceService.kt | 49 +++++++++++++++++++ 15 files changed, 264 insertions(+), 13 deletions(-) create mode 100644 botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logging/Log.kt create mode 100644 botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logging/Slf4jLog.kt create mode 100644 botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingAuthService.kt create mode 100644 botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingHomeworkService.kt create mode 100644 botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingPromotionService.kt create mode 100644 botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingRatingService.kt create mode 100644 botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingUserService.kt create mode 100644 botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingWorkspaceService.kt diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringHomeworkService.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringHomeworkService.kt index 85f6192..ffcb66c 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringHomeworkService.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringHomeworkService.kt @@ -1,11 +1,17 @@ package ru.vityaman.lms.botalka.app.spring.logic import org.springframework.stereotype.Service +import ru.vityaman.lms.botalka.core.logging.Slf4jLog import ru.vityaman.lms.botalka.core.logic.HomeworkService import ru.vityaman.lms.botalka.core.logic.basic.BasicHomeworkService +import ru.vityaman.lms.botalka.core.logic.logging.LoggingHomeworkService import ru.vityaman.lms.botalka.core.storage.HomeworkStorage @Service class SpringHomeworkService( storage: HomeworkStorage, -) : HomeworkService by BasicHomeworkService(storage) +) : HomeworkService by +LoggingHomeworkService( + Slf4jLog("HomeworkService"), + BasicHomeworkService(storage), +) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringPromotionService.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringPromotionService.kt index 10aea73..a8089f5 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringPromotionService.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringPromotionService.kt @@ -1,9 +1,11 @@ package ru.vityaman.lms.botalka.app.spring.logic import org.springframework.stereotype.Service +import ru.vityaman.lms.botalka.core.logging.Slf4jLog import ru.vityaman.lms.botalka.core.logic.PromotionService import ru.vityaman.lms.botalka.core.logic.UserService import ru.vityaman.lms.botalka.core.logic.basic.BasicPromotionService +import ru.vityaman.lms.botalka.core.logic.logging.LoggingPromotionService import ru.vityaman.lms.botalka.core.storage.PromotionStorage import ru.vityaman.lms.botalka.core.tx.TxEnv @@ -12,4 +14,8 @@ class SpringPromotionService( storage: PromotionStorage, userService: UserService, txEnv: TxEnv, -) : PromotionService by BasicPromotionService(storage, userService, txEnv) +) : PromotionService by +LoggingPromotionService( + Slf4jLog("PromotionService"), + BasicPromotionService(storage, userService, txEnv), +) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringRatingService.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringRatingService.kt index f02e7cd..41d396c 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringRatingService.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringRatingService.kt @@ -1,11 +1,17 @@ package ru.vityaman.lms.botalka.app.spring.logic import org.springframework.stereotype.Service +import ru.vityaman.lms.botalka.core.logging.Slf4jLog import ru.vityaman.lms.botalka.core.logic.RatingService import ru.vityaman.lms.botalka.core.logic.WorkspaceService import ru.vityaman.lms.botalka.core.logic.basic.BasicRatingService +import ru.vityaman.lms.botalka.core.logic.logging.LoggingRatingService @Service class SpringRatingService( workspaces: WorkspaceService, -) : RatingService by BasicRatingService(workspaces) +) : RatingService by +LoggingRatingService( + Slf4jLog("RatingService"), + BasicRatingService(workspaces), +) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringUserService.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringUserService.kt index 2880d62..fbd8935 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringUserService.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringUserService.kt @@ -1,11 +1,17 @@ package ru.vityaman.lms.botalka.app.spring.logic import org.springframework.stereotype.Service +import ru.vityaman.lms.botalka.core.logging.Slf4jLog import ru.vityaman.lms.botalka.core.logic.UserService import ru.vityaman.lms.botalka.core.logic.basic.BasicUserService +import ru.vityaman.lms.botalka.core.logic.logging.LoggingUserService import ru.vityaman.lms.botalka.core.storage.UserStorage @Service class SpringUserService( storage: UserStorage, -) : UserService by BasicUserService(storage) +) : UserService by +LoggingUserService( + Slf4jLog("UserService"), + BasicUserService(storage), +) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringWorkspaceService.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringWorkspaceService.kt index 2c90b26..a55a5c7 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringWorkspaceService.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringWorkspaceService.kt @@ -1,9 +1,11 @@ package ru.vityaman.lms.botalka.app.spring.logic import org.springframework.stereotype.Service +import ru.vityaman.lms.botalka.core.logging.Slf4jLog import ru.vityaman.lms.botalka.core.logic.HomeworkService import ru.vityaman.lms.botalka.core.logic.WorkspaceService import ru.vityaman.lms.botalka.core.logic.basic.BasicWorkspaceService +import ru.vityaman.lms.botalka.core.logic.logging.LoggingWorkspaceService import ru.vityaman.lms.botalka.core.storage.WorkspaceStorage import java.time.Clock @@ -12,4 +14,8 @@ class SpringWorkspaceService( storage: WorkspaceStorage, homeworks: HomeworkService, clock: Clock, -) : WorkspaceService by BasicWorkspaceService(storage, homeworks, clock) +) : WorkspaceService by +LoggingWorkspaceService( + Slf4jLog("WorkspaceService"), + BasicWorkspaceService(storage, homeworks, clock), +) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringYandexAuthService.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringYandexAuthService.kt index e101388..ca1f44e 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringYandexAuthService.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/logic/SpringYandexAuthService.kt @@ -2,9 +2,11 @@ package ru.vityaman.lms.botalka.app.spring.logic import org.springframework.stereotype.Service import ru.vityaman.lms.botalka.core.external.yandex.YandexOAuthCode +import ru.vityaman.lms.botalka.core.logging.Slf4jLog import ru.vityaman.lms.botalka.core.logic.AuthService import ru.vityaman.lms.botalka.core.logic.UserService import ru.vityaman.lms.botalka.core.logic.basic.BasicAuthService +import ru.vityaman.lms.botalka.core.logic.logging.LoggingAuthService import ru.vityaman.lms.botalka.core.security.auth.AuthMethod import ru.vityaman.lms.botalka.core.tx.TxEnv @@ -13,8 +15,12 @@ class SpringYandexAuthService( method: AuthMethod, users: UserService, txEnv: TxEnv, -) : AuthService by BasicAuthService( - method, - users, - txEnv, +) : AuthService by +LoggingAuthService( + Slf4jLog("YandexAuthService"), + BasicAuthService( + method, + users, + txEnv, + ), ) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/security/SpringYandexOAuthService.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/security/SpringYandexOAuthService.kt index 6286bec..1fd59e0 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/security/SpringYandexOAuthService.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/security/SpringYandexOAuthService.kt @@ -2,9 +2,11 @@ package ru.vityaman.lms.botalka.app.spring.security import org.springframework.stereotype.Service import ru.vityaman.lms.botalka.core.external.yandex.YandexOAuthCode +import ru.vityaman.lms.botalka.core.logging.Slf4jLog import ru.vityaman.lms.botalka.core.logic.AuthService import ru.vityaman.lms.botalka.core.logic.UserService import ru.vityaman.lms.botalka.core.logic.basic.BasicAuthService +import ru.vityaman.lms.botalka.core.logic.logging.LoggingAuthService import ru.vityaman.lms.botalka.core.tx.TxEnv @Service @@ -12,8 +14,11 @@ class SpringYandexOAuthService( method: SpringYandexOAuthMethod, users: UserService, txEnv: TxEnv, -) : AuthService by BasicAuthService( - method, - users, - txEnv, +) : AuthService by LoggingAuthService( + Slf4jLog("YandexOAuthService"), + BasicAuthService( + method, + users, + txEnv, + ), ) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logging/Log.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logging/Log.kt new file mode 100644 index 0000000..5875219 --- /dev/null +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logging/Log.kt @@ -0,0 +1,6 @@ +package ru.vityaman.lms.botalka.core.logging + +interface Log { + fun info(message: String) + fun warn(message: String) +} diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logging/Slf4jLog.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logging/Slf4jLog.kt new file mode 100644 index 0000000..8d77c6b --- /dev/null +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logging/Slf4jLog.kt @@ -0,0 +1,15 @@ +package ru.vityaman.lms.botalka.core.logging + +import org.slf4j.LoggerFactory + +class Slf4jLog(name: String) : Log { + private val origin = LoggerFactory.getLogger(name) + + override fun info(message: String) { + origin.info(message) + } + + override fun warn(message: String) { + origin.warn(message) + } +} diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingAuthService.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingAuthService.kt new file mode 100644 index 0000000..1677e50 --- /dev/null +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingAuthService.kt @@ -0,0 +1,24 @@ +package ru.vityaman.lms.botalka.core.logic.logging + +import ru.vityaman.lms.botalka.core.logging.Log +import ru.vityaman.lms.botalka.core.logic.AuthService +import ru.vityaman.lms.botalka.core.model.AuthUser +import ru.vityaman.lms.botalka.core.model.User +import ru.vityaman.lms.botalka.core.security.auth.AccessToken + +class LoggingAuthService( + private val log: Log, + private val origin: AuthService, +) : AuthService { + override suspend fun signUp(draft: User.Draft, credentials: T): AuthUser = + runCatching { origin.signUp(draft, credentials) } + .onSuccess { log.info("User with ${it.user.id} signed up") } + .onFailure { log.warn("Failed to sign up") } + .getOrThrow() + + override suspend fun signIn(credentials: T): AccessToken = + runCatching { origin.signIn(credentials) } + .onSuccess { log.info("Signed in") } + .onFailure { log.warn("Failed to sign in") } + .getOrThrow() +} diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingHomeworkService.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingHomeworkService.kt new file mode 100644 index 0000000..d2d98b1 --- /dev/null +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingHomeworkService.kt @@ -0,0 +1,23 @@ +package ru.vityaman.lms.botalka.core.logic.logging + +import ru.vityaman.lms.botalka.core.logging.Log +import ru.vityaman.lms.botalka.core.logic.HomeworkService +import ru.vityaman.lms.botalka.core.model.Homework + +class LoggingHomeworkService( + private val log: Log, + private val origin: HomeworkService, +) : HomeworkService { + override suspend fun create(homework: Homework.Draft): Homework = + runCatching { origin.create(homework) } + .onSuccess { log.info("Created homework with ${it.id}") } + .onFailure { log.warn("Failed to create a homework") } + .getOrThrow() + + override suspend fun getById(id: Homework.Id): Homework? = + runCatching { origin.getById(id) } + .onFailure { + log.warn("Failed to get homework with $id: ${it.message}") + } + .getOrThrow() +} diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingPromotionService.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingPromotionService.kt new file mode 100644 index 0000000..d9b9f6b --- /dev/null +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingPromotionService.kt @@ -0,0 +1,45 @@ +package ru.vityaman.lms.botalka.core.logic.logging + +import ru.vityaman.lms.botalka.core.logging.Log +import ru.vityaman.lms.botalka.core.logic.PromotionService +import ru.vityaman.lms.botalka.core.model.PromotionRequest + +class LoggingPromotionService( + private val log: Log, + private val origin: PromotionService, +) : PromotionService { + override suspend fun request( + promotion: PromotionRequest.Draft, + ): PromotionRequest = + runCatching { origin.request(promotion) } + .onSuccess { + buildString { + append("Created a promotion request with ${it.id} ") + append("of user with ${promotion.user} to ") + append("${promotion.role}") + }.let { log.info(it) } + } + .onFailure { + buildString { + append("Failed to request promotion of user with ") + append("${promotion.user} to ${promotion.role}") + }.let { log.warn(it) } + } + .getOrThrow() + + override suspend fun approve(id: PromotionRequest.Id) = + runCatching { origin.approve(id) } + .onSuccess { log.info("Promotion request with $id was approved") } + .onFailure { + log.warn("Failed to approve promotion request with is $id") + } + .getOrThrow() + + override suspend fun reject(id: PromotionRequest.Id) = + runCatching { origin.reject(id) } + .onSuccess { log.info("Promotion request with $id was rejected") } + .onFailure { + log.warn("Failed to reject promotion request with is $id") + } + .getOrThrow() +} diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingRatingService.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingRatingService.kt new file mode 100644 index 0000000..b59492a --- /dev/null +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingRatingService.kt @@ -0,0 +1,15 @@ +package ru.vityaman.lms.botalka.core.logic.logging + +import ru.vityaman.lms.botalka.core.logging.Log +import ru.vityaman.lms.botalka.core.logic.Grades +import ru.vityaman.lms.botalka.core.logic.RatingService + +class LoggingRatingService( + private val log: Log, + private val origin: RatingService, +) : RatingService { + override suspend fun grades(): Grades = + runCatching { origin.grades() } + .onSuccess { log.info("Got grades for ${it.size} students") } + .getOrThrow() +} diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingUserService.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingUserService.kt new file mode 100644 index 0000000..5554885 --- /dev/null +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingUserService.kt @@ -0,0 +1,33 @@ +package ru.vityaman.lms.botalka.core.logic.logging + +import ru.vityaman.lms.botalka.core.logging.Log +import ru.vityaman.lms.botalka.core.logic.UserService +import ru.vityaman.lms.botalka.core.model.User + +class LoggingUserService( + private val log: Log, + private val origin: UserService, +) : UserService { + override suspend fun create(user: User.Draft): User = + runCatching { origin.create(user) } + .onSuccess { log.info("Created user with ${it.id}") } + .onFailure { log.warn("Failed to create user: ${it.message}") } + .getOrThrow() + + override suspend fun getById(id: User.Id): User? = + runCatching { origin.getById(id) } + .onSuccess { it ?: log.warn("User with $id not found") } + .onFailure { log.warn("Failed to get user with $id") } + .getOrThrow() + + override suspend fun promote(id: User.Id, role: User.Role) = + runCatching { origin.promote(id, role) } + .onSuccess { log.info("User with $id promoted to $role") } + .onFailure { + buildString { + append("Failed to promote user with ") + append("$id to $role: ${it.message}") + }.let { log.warn(it) } + } + .getOrThrow() +} diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingWorkspaceService.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingWorkspaceService.kt new file mode 100644 index 0000000..393b452 --- /dev/null +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/logic/logging/LoggingWorkspaceService.kt @@ -0,0 +1,49 @@ +package ru.vityaman.lms.botalka.core.logic.logging + +import kotlinx.coroutines.flow.Flow +import ru.vityaman.lms.botalka.core.logging.Log +import ru.vityaman.lms.botalka.core.logic.WorkspaceService +import ru.vityaman.lms.botalka.core.model.Homework +import ru.vityaman.lms.botalka.core.model.Workspace + +class LoggingWorkspaceService( + private val log: Log, + private val origin: WorkspaceService, +) : WorkspaceService { + override fun events(id: Workspace.Id): Flow = + runCatching { origin.events(id) } + .onSuccess { log.info("Got events for workspace with $id") } + .onFailure { + buildString { + append("Failed to get events for workspace with $id: ") + append(it.message) + }.let { log.warn(it) } + } + .getOrThrow() + + override suspend fun produce( + id: Workspace.Id, + event: Workspace.Event.Draft, + ): Workspace.Event = + runCatching { origin.produce(id, event) } + .onSuccess { + buildString { + append("Produced an event with ${it.id} ") + append("at workspace with $id") + }.let { log.info(it) } + } + .onFailure { + buildString { + append("Failed to produce and event ") + append("at workspace with $id: ") + append(it.message) + }.let { log.warn(it) } + } + .getOrThrow() + + override suspend fun grade(id: Workspace.Id): Homework.Score? = + origin.grade(id) + + override fun all(): Flow = + origin.all() +}