feat(server-03): log unmapped events at DEBUG in DomainEventMapper
Adds a file-private SLF4J logger and replaces the silent else->null branch with a debug log line that names the payload type, sessionId, and sequence. Test extended with a log-capture case that verifies exactly one DEBUG event is emitted containing the payload class name for unrecognised event types.
This commit is contained in:
@@ -21,6 +21,9 @@ import com.correx.core.events.events.TransitionExecutedEvent
|
|||||||
import com.correx.core.events.events.WorkflowCompletedEvent
|
import com.correx.core.events.events.WorkflowCompletedEvent
|
||||||
import com.correx.core.events.events.WorkflowFailedEvent
|
import com.correx.core.events.events.WorkflowFailedEvent
|
||||||
import com.correx.core.events.types.ArtifactId
|
import com.correx.core.events.types.ArtifactId
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
|
private val log = LoggerFactory.getLogger("DomainEventMapper")
|
||||||
|
|
||||||
class DomainEventMapper(private val artifactStore: ArtifactStore = NoopArtifactStore) {
|
class DomainEventMapper(private val artifactStore: ArtifactStore = NoopArtifactStore) {
|
||||||
suspend fun map(event: StoredEvent): ServerMessage? =
|
suspend fun map(event: StoredEvent): ServerMessage? =
|
||||||
@@ -138,7 +141,15 @@ suspend fun domainEventToServerMessage(
|
|||||||
)
|
)
|
||||||
|
|
||||||
is ApprovalRequestedEvent -> mapApprovalRequested(p, seq, sessionSequence)
|
is ApprovalRequestedEvent -> mapApprovalRequested(p, seq, sessionSequence)
|
||||||
else -> null
|
else -> {
|
||||||
|
log.debug(
|
||||||
|
"DomainEventMapper: unmapped payload type={} sessionId={} sequence={}",
|
||||||
|
p::class.simpleName,
|
||||||
|
event.metadata.sessionId,
|
||||||
|
event.sequence,
|
||||||
|
)
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,8 +37,15 @@ import com.correx.core.events.types.ValidationReportId
|
|||||||
import com.correx.core.inference.TokenUsage
|
import com.correx.core.inference.TokenUsage
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import kotlinx.datetime.Instant
|
import kotlinx.datetime.Instant
|
||||||
|
import org.apache.logging.log4j.Level
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
|
import org.apache.logging.log4j.core.LogEvent
|
||||||
|
import org.apache.logging.log4j.core.LoggerContext
|
||||||
|
import org.apache.logging.log4j.core.appender.AbstractAppender
|
||||||
|
import org.apache.logging.log4j.core.config.Property
|
||||||
import org.junit.jupiter.api.Assertions.assertEquals
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
import org.junit.jupiter.api.Assertions.assertNull
|
import org.junit.jupiter.api.Assertions.assertNull
|
||||||
|
import org.junit.jupiter.api.Assertions.assertTrue
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
class DomainEventMapperTest {
|
class DomainEventMapperTest {
|
||||||
@@ -368,4 +375,33 @@ class DomainEventMapperTest {
|
|||||||
val result = domainEventToServerMessage(event, noopStore, sessionSequence = 0L)
|
val result = domainEventToServerMessage(event, noopStore, sessionSequence = 0L)
|
||||||
assertNull(result)
|
assertNull(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestAppender : AbstractAppender("TestCapture", null, null, true, Property.EMPTY_ARRAY) {
|
||||||
|
val events = mutableListOf<LogEvent>()
|
||||||
|
override fun append(event: LogEvent) {
|
||||||
|
events.add(event.toImmutable())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `unmapped event emits debug log`(): Unit = runTest {
|
||||||
|
val ctx = LogManager.getContext(false) as LoggerContext
|
||||||
|
val logger = ctx.getLogger("DomainEventMapper")
|
||||||
|
val appender = TestAppender().also { it.start() }
|
||||||
|
logger.addAppender(appender)
|
||||||
|
val origLevel = logger.level
|
||||||
|
logger.level = Level.DEBUG
|
||||||
|
try {
|
||||||
|
val event = storedEvent(SessionStartedEvent(sessionId = sessionId))
|
||||||
|
val result = domainEventToServerMessage(event, noopStore, sessionSequence = 0L)
|
||||||
|
assertNull(result)
|
||||||
|
assertEquals(1, appender.events.size)
|
||||||
|
assertEquals(Level.DEBUG, appender.events[0].level)
|
||||||
|
assertTrue(appender.events[0].message.formattedMessage.contains("SessionStartedEvent"))
|
||||||
|
} finally {
|
||||||
|
logger.removeAppender(appender)
|
||||||
|
appender.stop()
|
||||||
|
logger.level = origLevel
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user