129 lines
4.9 KiB
Java
129 lines
4.9 KiB
Java
package com.baiyue.eventbridge.metrics;
|
|
|
|
import com.baiyue.common.event.EventEnvelope;
|
|
import com.baiyue.common.event.EventTypes;
|
|
import com.baiyue.eventbridge.domain.BridgeInbox;
|
|
import io.micrometer.core.instrument.MeterRegistry;
|
|
import io.micrometer.core.instrument.Timer;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
import java.time.Clock;
|
|
import java.time.Duration;
|
|
import java.time.LocalDateTime;
|
|
import java.util.Locale;
|
|
import java.util.Set;
|
|
|
|
/** Low-cardinality transport metrics for the cross-region event bridge. */
|
|
@Component
|
|
@Slf4j
|
|
public class EventBridgeMetrics {
|
|
public static final String RECEIVE_METRIC = "baiyue.event.bridge.receive";
|
|
public static final String TRANSPORT_METRIC = "baiyue.event.bridge.transport";
|
|
public static final String DELIVERY_LATENCY_METRIC = "baiyue.event.bridge.delivery.latency";
|
|
|
|
private static final Set<String> KNOWN_EVENT_TYPES = Set.of(
|
|
EventTypes.ORDER_APPROVED,
|
|
EventTypes.ORDER_CANCELLED,
|
|
EventTypes.FIRST_LEG_SHIPMENT_DEPARTED,
|
|
EventTypes.FIRST_LEG_LOADING_PLAN_COMPLETED,
|
|
EventTypes.FIRST_LEG_CONTAINER_SHIPPING_NODE_RECORDED,
|
|
EventTypes.OVERSEAS_CONTAINER_UNLOADED,
|
|
EventTypes.OVERSEAS_INBOUND_ORDER_DETAINED_CHANGED,
|
|
EventTypes.OVERSEAS_DELIVERY_COMPLETED,
|
|
EventTypes.BUSINESS_FEE_SOURCE_CHANGED,
|
|
EventTypes.WALLET_COMMAND_REQUESTED,
|
|
EventTypes.WALLET_COMMAND_COMPLETED,
|
|
EventTypes.IAM_USER_STATUS_CHANGED,
|
|
EventTypes.IAM_TENANT_STATUS_CHANGED,
|
|
EventTypes.IAM_PERMISSION_VERSION_CHANGED,
|
|
EventTypes.LAST_MILE_HANDOFF_ACCEPTED,
|
|
EventTypes.LAST_MILE_HANDOFF_REJECTED,
|
|
EventTypes.LAST_MILE_MILESTONE_CHANGED,
|
|
EventTypes.LAST_MILE_COMPLETED,
|
|
EventTypes.TRACKING_MILESTONE_PROJECTED);
|
|
|
|
private final MeterRegistry registry;
|
|
private final Clock clock;
|
|
|
|
@Autowired
|
|
public EventBridgeMetrics(MeterRegistry registry) {
|
|
this(registry, Clock.systemDefaultZone());
|
|
}
|
|
|
|
EventBridgeMetrics(MeterRegistry registry, Clock clock) {
|
|
this.registry = registry;
|
|
this.clock = clock;
|
|
}
|
|
|
|
public void recordReceive(EventEnvelope envelope, ReceiveResult result) {
|
|
try {
|
|
registry.counter(RECEIVE_METRIC,
|
|
"target_region", targetRegion(envelope.targetRegion().name()),
|
|
"event_type", eventType(envelope.eventType()),
|
|
"result", result.name()).increment();
|
|
} catch (RuntimeException exception) {
|
|
log.warn("Event Bridge 接收指标记录失败,不影响事件事务", exception);
|
|
}
|
|
}
|
|
|
|
public void recordTransport(BridgeInbox event, TransportResult result) {
|
|
try {
|
|
String targetRegion = targetRegion(event.getTargetRegion());
|
|
String eventType = eventType(event.getEventType());
|
|
registry.counter(TRANSPORT_METRIC,
|
|
"target_region", targetRegion,
|
|
"event_type", eventType,
|
|
"result", result.name()).increment();
|
|
if (result.acknowledged() && event.getReceivedAt() != null) {
|
|
Duration latency = Duration.between(event.getReceivedAt(), LocalDateTime.now(clock));
|
|
if (latency.isNegative()) {
|
|
latency = Duration.ZERO;
|
|
}
|
|
Timer.builder(DELIVERY_LATENCY_METRIC)
|
|
.description("Time from Event Bridge receipt to downstream acknowledgement")
|
|
.serviceLevelObjectives(Duration.ofSeconds(60), Duration.ofMinutes(15))
|
|
.tags("target_region", targetRegion, "event_type", eventType)
|
|
.register(registry).record(latency);
|
|
}
|
|
} catch (RuntimeException exception) {
|
|
log.warn("Event Bridge 传输指标记录失败,不影响可靠性状态机", exception);
|
|
}
|
|
}
|
|
|
|
public static String targetRegion(String value) {
|
|
String normalized = value == null ? "" : value.trim().toUpperCase(Locale.ROOT);
|
|
return "CN".equals(normalized) || "OVERSEAS".equals(normalized) ? normalized : "OTHER";
|
|
}
|
|
|
|
public static String eventType(String value) {
|
|
return value != null && KNOWN_EVENT_TYPES.contains(value) ? value : "OTHER";
|
|
}
|
|
|
|
public enum ReceiveResult {
|
|
RECEIVED,
|
|
DUPLICATE,
|
|
CONFLICT
|
|
}
|
|
|
|
public enum TransportResult {
|
|
DELIVERED(true),
|
|
RETRY(false),
|
|
DEAD(false),
|
|
ACKNOWLEDGED_LEASE_LOST(true),
|
|
FAILED_LEASE_LOST(false),
|
|
MANUAL_REPLAY(false);
|
|
|
|
private final boolean acknowledged;
|
|
|
|
TransportResult(boolean acknowledged) {
|
|
this.acknowledged = acknowledged;
|
|
}
|
|
|
|
boolean acknowledged() {
|
|
return acknowledged;
|
|
}
|
|
}
|
|
}
|