AsyncAPI specification for all Kafka event contracts in the log0 platform.
log0 is a multi-tenant log intelligence and incident management platform. Logs enter at the ingestion-gateway and flow through a linear pipeline: ingestion → normalization → clustering → incident management → notification.
Every message is keyed by tenantId to guarantee per-tenant ordering
within Kafka partitions. Each stage has a corresponding dead-letter queue
(DLQ) topic so no event is silently lost on processing failure.
Local Kafka broker started via docker-compose in docker/kafka/
Receives every accepted log event from the ingestion-gateway.
Kafka key = tenantId (ensures per-tenant ordering within partitions).
On producer failure the event is routed to raw-logs-dlq instead.
Publish a raw log event after validation
Called by the ingestion-gateway after a POST /api/v1/logs request passes header and payload validation. The event is sent asynchronously; HTTP 202 is returned to the client immediately.
Available only on servers:
Accepts the following message:
A validated log event as received by the ingestion-gateway
Published to raw-logs by the ingestion-gateway immediately after a
POST /api/v1/logs request passes validation. Carries the original log
payload enriched with platform metadata (eventId, receivedAt).
{
"eventId": "a3f2c1d4-55b6-4e89-9f12-0a1b2c3d4e5f",
"tenantId": "b7e1f290-12ab-4cd3-8ef5-6789abcd0123",
"serviceName": "payment-service",
"environment": "production",
"receivedAt": "2026-03-30T10:15:30Z",
"logTimestamp": "2026-03-30T10:15:29.842Z",
"level": "ERROR",
"message": "Connection timeout after 30000ms calling payment gateway",
"trace": "java.net.SocketTimeoutException: Read timed out\n\tat com.example..."
}
Dead-letter queue for the raw-logs pipeline. Receives events that
could not be delivered or processed by the normalization-service.
Kafka key = eventId of the original failed event.
Multiple services publish here: ingestion-gateway (producer failure)
and normalization-service (consumer processing failure).
Route failed raw log events to the DLQ
Published by the ingestion-gateway when the Kafka send to raw-logs fails.
Available only on servers:
Accepts the following message:
Wraps any failed event with error context for replay or alerting
Universal dead-letter queue envelope. Published to raw-logs-dlq by any
service that catches a processing error. Preserves the original event and
error context for replay or alerting without losing data.
{
"originalEvent": {},
"errorMessage": "org.apache.kafka.common.errors.TimeoutException: Topic raw-logs not present",
"failedAt": "normalization-service",
"failedAtTs": "2026-03-30T10:15:31Z"
}
Receives every accepted log event from the ingestion-gateway.
Kafka key = tenantId (ensures per-tenant ordering within partitions).
On producer failure the event is routed to raw-logs-dlq instead.
Consume raw log events for normalization
Manual offset acknowledgment - the offset is committed only after the
normalized event is successfully published to normalized-logs.
On failure the event is forwarded to raw-logs-dlq and the offset is
still committed to prevent partition stalls.
Available only on servers:
Accepts the following message:
A validated log event as received by the ingestion-gateway
Published to raw-logs by the ingestion-gateway immediately after a
POST /api/v1/logs request passes validation. Carries the original log
payload enriched with platform metadata (eventId, receivedAt).
{
"eventId": "a3f2c1d4-55b6-4e89-9f12-0a1b2c3d4e5f",
"tenantId": "b7e1f290-12ab-4cd3-8ef5-6789abcd0123",
"serviceName": "payment-service",
"environment": "production",
"receivedAt": "2026-03-30T10:15:30Z",
"logTimestamp": "2026-03-30T10:15:29.842Z",
"level": "ERROR",
"message": "Connection timeout after 30000ms calling payment gateway",
"trace": "java.net.SocketTimeoutException: Read timed out\n\tat com.example..."
}
Carries fully normalized and fingerprinted log events produced by
the normalization-service. Kafka key = tenantId.
On consumer failure in the clustering-service the event is routed
to raw-logs-dlq.
Publish a normalized and fingerprinted log event
Available only on servers:
Accepts the following message:
A log event after normalization and SHA-256 fingerprinting
Published to normalized-logs by the normalization-service after
cleaning the raw event and generating a deterministic SHA-256 fingerprint.
The fingerprint is the deduplication key used by the clustering-service.
{
"eventId": "a3f2c1d4-55b6-4e89-9f12-0a1b2c3d4e5f",
"tenantId": "b7e1f290-12ab-4cd3-8ef5-6789abcd0123",
"serviceName": "payment-service",
"environment": "production",
"timestamp": "2026-03-30T10:15:29.842Z",
"level": "ERROR",
"message": "Connection timeout after 30000ms calling payment gateway",
"messageTemplate": "Connection timeout after <number>ms calling payment gateway",
"fingerprint": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"attributes": {},
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
"schemaVersion": "v1"
}
Dead-letter queue for the raw-logs pipeline. Receives events that
could not be delivered or processed by the normalization-service.
Kafka key = eventId of the original failed event.
Multiple services publish here: ingestion-gateway (producer failure)
and normalization-service (consumer processing failure).
Route normalization failures to the DLQ
Available only on servers:
Accepts the following message:
Wraps any failed event with error context for replay or alerting
Universal dead-letter queue envelope. Published to raw-logs-dlq by any
service that catches a processing error. Preserves the original event and
error context for replay or alerting without losing data.
{
"originalEvent": {},
"errorMessage": "org.apache.kafka.common.errors.TimeoutException: Topic raw-logs not present",
"failedAt": "normalization-service",
"failedAtTs": "2026-03-30T10:15:31Z"
}
Carries fully normalized and fingerprinted log events produced by
the normalization-service. Kafka key = tenantId.
On consumer failure in the clustering-service the event is routed
to raw-logs-dlq.
Consume normalized log events for fingerprint-based clustering
Groups events by (tenantId + fingerprint) within a configurable tumbling window (default 5 minutes). When occurrence count reaches the configured threshold (default 10) an IncidentEvent is published.
Available only on servers:
Accepts the following message:
A log event after normalization and SHA-256 fingerprinting
Published to normalized-logs by the normalization-service after
cleaning the raw event and generating a deterministic SHA-256 fingerprint.
The fingerprint is the deduplication key used by the clustering-service.
{
"eventId": "a3f2c1d4-55b6-4e89-9f12-0a1b2c3d4e5f",
"tenantId": "b7e1f290-12ab-4cd3-8ef5-6789abcd0123",
"serviceName": "payment-service",
"environment": "production",
"timestamp": "2026-03-30T10:15:29.842Z",
"level": "ERROR",
"message": "Connection timeout after 30000ms calling payment gateway",
"messageTemplate": "Connection timeout after <number>ms calling payment gateway",
"fingerprint": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"attributes": {},
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
"schemaVersion": "v1"
}
Published by the clustering-service when a fingerprint's occurrence
count crosses the configured threshold within a 5-minute tumbling window.
Kafka key = tenantId.
Consumed by the incident-service to create or update incidents in PostgreSQL.
Publish an incident event when the occurrence threshold is crossed
Available only on servers:
Accepts the following message:
Signals that a fingerprint's occurrence count crossed the threshold
Published to incident-events by the clustering-service when a
(tenantId + fingerprint) combination exceeds the occurrence threshold
within a tumbling window. Triggers incident creation or update in PostgreSQL.
{
"tenantId": "b7e1f290-12ab-4cd3-8ef5-6789abcd0123",
"fingerprint": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"serviceName": "payment-service",
"environment": "production",
"severity": "HIGH",
"occurrenceCount": 438,
"firstSeenAt": "2026-03-30T10:10:00Z",
"lastSeenAt": "2026-03-30T10:15:00Z",
"topMessages": [
"Connection timeout after 30000ms calling payment gateway",
"Connection timeout after 28514ms calling payment gateway"
]
}
Dead-letter queue for the raw-logs pipeline. Receives events that
could not be delivered or processed by the normalization-service.
Kafka key = eventId of the original failed event.
Multiple services publish here: ingestion-gateway (producer failure)
and normalization-service (consumer processing failure).
Route clustering failures to the DLQ
Available only on servers:
Accepts the following message:
Wraps any failed event with error context for replay or alerting
Universal dead-letter queue envelope. Published to raw-logs-dlq by any
service that catches a processing error. Preserves the original event and
error context for replay or alerting without losing data.
{
"originalEvent": {},
"errorMessage": "org.apache.kafka.common.errors.TimeoutException: Topic raw-logs not present",
"failedAt": "normalization-service",
"failedAtTs": "2026-03-30T10:15:31Z"
}
Published by the clustering-service when a fingerprint's occurrence
count crosses the configured threshold within a 5-minute tumbling window.
Kafka key = tenantId.
Consumed by the incident-service to create or update incidents in PostgreSQL.
Consume incident events to create or update incidents in PostgreSQL
Deduplicates by (tenantId + fingerprint) where status != RESOLVED. On new incident: triggers async AI summarization and publishes a NotificationEvent. On update: increments occurrence count only.
Available only on servers:
Accepts the following message:
Signals that a fingerprint's occurrence count crossed the threshold
Published to incident-events by the clustering-service when a
(tenantId + fingerprint) combination exceeds the occurrence threshold
within a tumbling window. Triggers incident creation or update in PostgreSQL.
{
"tenantId": "b7e1f290-12ab-4cd3-8ef5-6789abcd0123",
"fingerprint": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"serviceName": "payment-service",
"environment": "production",
"severity": "HIGH",
"occurrenceCount": 438,
"firstSeenAt": "2026-03-30T10:10:00Z",
"lastSeenAt": "2026-03-30T10:15:00Z",
"topMessages": [
"Connection timeout after 30000ms calling payment gateway",
"Connection timeout after 28514ms calling payment gateway"
]
}
Published by the incident-service on incident lifecycle transitions
(CREATED, ASSIGNED, RESOLVED). Kafka key = tenantId.
Consumed by the notification-service to send Slack alerts.
Publish a notification event on incident lifecycle transitions
Available only on servers:
Accepts the following message:
Signals an incident lifecycle transition requiring a Slack alert
Published to notification-events by the incident-service on incident
lifecycle transitions. The notification-service consumes this to send
formatted Slack Block Kit alerts.
{
"tenantId": "b7e1f290-12ab-4cd3-8ef5-6789abcd0123",
"incidentId": "c9d8e7f6-a5b4-4c3d-2e1f-0a9b8c7d6e5f",
"fingerprint": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"serviceName": "payment-service",
"environment": "production",
"severity": "HIGH",
"status": "NEW",
"occurrenceCount": 438,
"firstSeenAt": "2026-03-30T10:10:00Z",
"lastSeenAt": "2026-03-30T10:15:00Z",
"topMessages": [
"Connection timeout after 30000ms calling payment gateway"
],
"aiSummary": "Summary: Payment gateway timeouts causing checkout failures.\nPossible Cause: Upstream latency spike...",
"notificationType": "INCIDENT_CREATED",
"assignedToUserId": "d1e2f3a4-b5c6-7d8e-9f0a-1b2c3d4e5f6a"
}
Dead-letter queue for the raw-logs pipeline. Receives events that
could not be delivered or processed by the normalization-service.
Kafka key = eventId of the original failed event.
Multiple services publish here: ingestion-gateway (producer failure)
and normalization-service (consumer processing failure).
Route incident processing failures to the DLQ
Available only on servers:
Accepts the following message:
Wraps any failed event with error context for replay or alerting
Universal dead-letter queue envelope. Published to raw-logs-dlq by any
service that catches a processing error. Preserves the original event and
error context for replay or alerting without losing data.
{
"originalEvent": {},
"errorMessage": "org.apache.kafka.common.errors.TimeoutException: Topic raw-logs not present",
"failedAt": "normalization-service",
"failedAtTs": "2026-03-30T10:15:31Z"
}
Published by the incident-service on incident lifecycle transitions
(CREATED, ASSIGNED, RESOLVED). Kafka key = tenantId.
Consumed by the notification-service to send Slack alerts.
Consume notification events and send Slack alerts
Posts formatted Slack Block Kit messages to the configured channel.
On failure routes to notification-events-dlq (internal DLQ topic).
Available only on servers:
Accepts the following message:
Signals an incident lifecycle transition requiring a Slack alert
Published to notification-events by the incident-service on incident
lifecycle transitions. The notification-service consumes this to send
formatted Slack Block Kit alerts.
{
"tenantId": "b7e1f290-12ab-4cd3-8ef5-6789abcd0123",
"incidentId": "c9d8e7f6-a5b4-4c3d-2e1f-0a9b8c7d6e5f",
"fingerprint": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"serviceName": "payment-service",
"environment": "production",
"severity": "HIGH",
"status": "NEW",
"occurrenceCount": 438,
"firstSeenAt": "2026-03-30T10:10:00Z",
"lastSeenAt": "2026-03-30T10:15:00Z",
"topMessages": [
"Connection timeout after 30000ms calling payment gateway"
],
"aiSummary": "Summary: Payment gateway timeouts causing checkout failures.\nPossible Cause: Upstream latency spike...",
"notificationType": "INCIDENT_CREATED",
"assignedToUserId": "d1e2f3a4-b5c6-7d8e-9f0a-1b2c3d4e5f6a"
}
A validated log event as received by the ingestion-gateway
Published to raw-logs by the ingestion-gateway immediately after a
POST /api/v1/logs request passes validation. Carries the original log
payload enriched with platform metadata (eventId, receivedAt).
A log event after normalization and SHA-256 fingerprinting
Published to normalized-logs by the normalization-service after
cleaning the raw event and generating a deterministic SHA-256 fingerprint.
The fingerprint is the deduplication key used by the clustering-service.
Signals that a fingerprint's occurrence count crossed the threshold
Published to incident-events by the clustering-service when a
(tenantId + fingerprint) combination exceeds the occurrence threshold
within a tumbling window. Triggers incident creation or update in PostgreSQL.
Signals an incident lifecycle transition requiring a Slack alert
Published to notification-events by the incident-service on incident
lifecycle transitions. The notification-service consumes this to send
formatted Slack Block Kit alerts.
Wraps any failed event with error context for replay or alerting
Universal dead-letter queue envelope. Published to raw-logs-dlq by any
service that catches a processing error. Preserves the original event and
error context for replay or alerting without losing data.
Published to raw-logs by the ingestion-gateway immediately after a
POST /api/v1/logs request passes validation. Carries the original log
payload enriched with platform metadata (eventId, receivedAt).
Published to normalized-logs by the normalization-service after
cleaning the raw event and generating a deterministic SHA-256 fingerprint.
The fingerprint is the deduplication key used by the clustering-service.
Published to incident-events by the clustering-service when a
(tenantId + fingerprint) combination exceeds the occurrence threshold
within a tumbling window. Triggers incident creation or update in PostgreSQL.
Published to notification-events by the incident-service on incident
lifecycle transitions. The notification-service consumes this to send
formatted Slack Block Kit alerts.
Universal dead-letter queue envelope. Published to raw-logs-dlq by any
service that catches a processing error. Preserves the original event and
error context for replay or alerting without losing data.