-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
서버 로깅 구현 #349
서버 로깅 구현 #349
Changes from 4 commits
e246e29
e253d7f
c3417d2
98c0150
0857cc9
4291255
f675ffe
2b5e39b
6a9b16c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
dependencies { | ||
implementation(projects.crossCuttingConcern.application.serverLog) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
dependencies { | ||
implementation(rootProject.projects.crossCuttingConcern.stdlib) | ||
api(rootProject.projects.crossCuttingConcern.domain.serverLog) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package club.staircrusher.application.server_log.port.`in` | ||
|
||
import club.staircrusher.domain.server_log.ServerLogPayload | ||
|
||
interface SccServerLogger { | ||
fun record(payload: ServerLogPayload) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package club.staircrusher.application.server_log.port.`in` | ||
|
||
import club.staircrusher.application.server_log.port.out.persistence.ServerLogRepository | ||
import club.staircrusher.domain.server_log.ServerLog | ||
import club.staircrusher.domain.server_log.ServerLogPayload | ||
import club.staircrusher.stdlib.clock.SccClock | ||
import club.staircrusher.stdlib.di.annotation.Component | ||
import club.staircrusher.stdlib.domain.entity.EntityIdGenerator | ||
import club.staircrusher.stdlib.persistence.TransactionManager | ||
|
||
@Component | ||
class SccServerPersistentLogger( | ||
private val transactionManager: TransactionManager, | ||
private val serverLogRepository: ServerLogRepository, | ||
) : SccServerLogger { | ||
override fun record(payload: ServerLogPayload) = transactionManager.doInTransaction { | ||
val serverLog = ServerLog( | ||
id = EntityIdGenerator.generateRandom(), | ||
type = payload.type, | ||
payload = payload, | ||
createdAt = SccClock.instant(), | ||
) | ||
|
||
serverLogRepository.save(serverLog) | ||
Unit | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package club.staircrusher.application.server_log.port.out.persistence | ||
|
||
import club.staircrusher.domain.server_log.ServerLog | ||
|
||
interface ServerLogRepository { | ||
fun save(entity: ServerLog): ServerLog | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
dependencies { | ||
val kotlinxSerializationVersion: String by project | ||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinxSerializationVersion") | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package club.staircrusher.domain.server_log | ||
|
||
data class NewsletterSubscribedOnSignupPayload( | ||
val userId: String, | ||
) : ServerLogPayload { | ||
override val type = ServerLogType.NEWSLETTER_SUBSCRIBED_ON_SIGN_UP | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package club.staircrusher.domain.server_log | ||
|
||
import java.time.Instant | ||
|
||
data class ServerLog( | ||
val id: String, | ||
val type: ServerLogType, | ||
val payload: ServerLogPayload, | ||
val createdAt: Instant, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package club.staircrusher.domain.server_log | ||
|
||
interface ServerLogPayload { | ||
val type: ServerLogType | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ServerLogType이 이미 ServerLog에 있는데 굳이 여기도 들어갈 필요가 있으려나요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 사실상 type 별로 payload 가 생길거라고 생각했고 그래서 payload 만 알면 type 을 바로 알 수 있도록 interface 의 val 로 넣었습니다. ServerLog (ServerEvent) 의 필드로 넣은 것은 db 에 인덱스 걸고 저장하고 싶어서였는데, db 스키마와 애플리케이션 모델이 꼭 같은 필요는 없으니 다른 더 좋은 표현 방법이 있나 고민해보겠습니다 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 4291255 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 어차피 constructor 에 없는 필드라 저장은 안되겠네요 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package club.staircrusher.domain.server_log | ||
|
||
enum class ServerLogType { | ||
NEWSLETTER_SUBSCRIBED_ON_SIGN_UP, | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import club.staircrusher.domain.server_log.ServerLogPayload; | ||
import club.staircrusher.domain.server_log.ServerLogType; | ||
|
||
CREATE TABLE IF NOT EXISTS server_log ( | ||
id VARCHAR(36) NOT NULL, | ||
type VARCHAR(64) AS ServerLogType NOT NULL, | ||
payload TEXT AS ServerLogPayload NOT NULL DEFAULT '', | ||
created_at TIMESTAMP(6) WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
PRIMARY KEY (id) | ||
); | ||
|
||
CREATE INDEX idx_server_log_1 ON server_log(type, created_at); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
save: | ||
INSERT INTO server_log | ||
VALUES :server_log | ||
ON CONFLICT(id) DO UPDATE SET | ||
id = EXCLUDED.id, | ||
type = EXCLUDED.type, | ||
payload = EXCLUDED.payload, | ||
created_at = EXCLUDED.created_at; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
dependencies { | ||
implementation(projects.crossCuttingConcern.stdlib) | ||
implementation(projects.crossCuttingConcern.infra.persistenceModel) | ||
api(rootProject.projects.crossCuttingConcern.domain.serverLog) | ||
api(rootProject.projects.crossCuttingConcern.application.serverLog) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package club.staircrusher.infra.server_log.out.persistence | ||
|
||
import club.staircrusher.application.server_log.port.out.persistence.ServerLogRepository | ||
import club.staircrusher.domain.server_log.ServerLog | ||
import club.staircrusher.infra.persistence.sqldelight.DB | ||
import club.staircrusher.infra.server_log.out.persistence.sqldelight.toPersistenceModel | ||
import club.staircrusher.stdlib.di.annotation.Component | ||
|
||
@Component | ||
class ServerLogRepository( | ||
db: DB, | ||
) : ServerLogRepository { | ||
private val queries = db.serverLogQueries | ||
|
||
override fun save(entity: ServerLog): ServerLog { | ||
queries.save(entity.toPersistenceModel()) | ||
return entity | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package club.staircrusher.infra.server_log.out.persistence.sqldelight | ||
|
||
import club.staircrusher.domain.server_log.ServerLog | ||
import club.staircrusher.infra.persistence.sqldelight.migration.Server_log | ||
import club.staircrusher.stdlib.time.toOffsetDateTime | ||
|
||
fun ServerLog.toPersistenceModel() = Server_log( | ||
id = id, | ||
type = type, | ||
payload = payload, | ||
created_at = createdAt.toOffsetDateTime(), | ||
) | ||
|
||
fun Server_log.toDomainModel() = ServerLog( | ||
id = id, | ||
type = type, | ||
payload = payload, | ||
createdAt = created_at.toInstant(), | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package club.staircrusher.spring_web.mock | ||
|
||
import club.staircrusher.application.server_log.port.out.persistence.ServerLogRepository | ||
import club.staircrusher.domain.server_log.ServerLog | ||
import club.staircrusher.stdlib.di.annotation.Component | ||
|
||
@Component | ||
class MockServerLogRepository : ServerLogRepository { | ||
override fun save(entity: ServerLog): ServerLog { | ||
return ServerLog( | ||
id = entity.id, | ||
type = entity.type, | ||
payload = entity.payload, | ||
createdAt = entity.createdAt | ||
) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 domain event랑 약간 겹치더라도 log 보다는 event라는 이름이 더 좋을 것 같은데요, log랑 event라는 워딩에서 느껴지는 차이가 꽤 분명한 것 같기 때문입니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0857cc9
log -> event 로 이름 변경했습니다