# Registry: Metrics # SSOT: wiki/projects/ca-tmpl/registries/metrics.yaml # Schema owner: feature-contract-registry-governance # Owner branch: feature-metrics-alerting-contract # Last updated: 2026-05-22 # # Notes # - Naming: Micrometer dot.case + unit suffix (.seconds | .bytes | .total). # - Tag cardinality bounds are SSOT of feature-metrics-alerting-contract "Cardinality Bounds" table. # - High-cardinality tags forbidden globally: user_id, request_id, raw_url, raw_query, # raw_header_value, ip_address. These MUST NOT appear in any row. # - tenant_id label is bounded mapping table id OR cohort bucket only (ULID raw forbidden). # - error_code tag cardinality_limit follows error-codes.yaml row count (max 100). metrics: # === HTTP server (inbound) === # source: feature-metrics-alerting-contract — Metric/Alert Defaults # "HTTP metric | http.server.requests with method/status/uri-template | raw URL or user id tag" - name: http.server.requests type: timer unit: seconds tags: - name: method cardinality_limit: 8 allowed_values: [GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, OTHER] - name: status cardinality_limit: 7 allowed_values: [1xx, 2xx, 3xx, 4xx, 5xx, ok, other] - name: uri_template cardinality_limit: 200 validation: must_be_template_not_raw_uri percentiles: [0.5, 0.9, 0.95, 0.99] histogram_buckets: slo_driven alert_severity_thresholds: p1: "error_rate > 5% for 5m OR > 10% for 1m" p2: "error_rate > 1% for 10m" p3: "error_rate > 0.1% for 1h" owner_branch: feature-metrics-alerting-contract log_field_mapping: [method, status, uri_template] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-metrics-alerting-contract — P1/P2/P3 정량 기준 (HTTP latency p99) # "P1: p99 > 5s 5분 / P2: p99 > 1s 10분 / P3: p99 > 500ms 30분" - name: http.server.requests.latency type: timer unit: seconds tags: - name: method cardinality_limit: 8 allowed_values: [GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, OTHER] - name: uri_template cardinality_limit: 200 validation: must_be_template_not_raw_uri percentiles: [0.5, 0.9, 0.95, 0.99] histogram_buckets: slo_driven alert_severity_thresholds: p1: "p99 > 5s for 5m" p2: "p99 > 1s for 10m" p3: "p99 > 500ms for 30m" owner_branch: feature-metrics-alerting-contract log_field_mapping: [method, uri_template, duration_ms] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # === HTTP client (outbound dependency) === # source: feature-metrics-alerting-contract — Metric/Alert Defaults # "dependency metric | dependency.client.requests with dependency.name/type/outcome | endpoint with secret tag" # source: feature-outbound-http-client-baseline — "circuit breaker metric은 dependency.name, dependency.type, outcome까지만 tag로 허용" - name: dependency.client.requests type: timer unit: seconds tags: - name: dependency_name cardinality_limit: 50 - name: dependency_type cardinality_limit: 10 allowed_values: [http, grpc, db, cache, queue, broker, other] - name: outcome cardinality_limit: 5 allowed_values: [SUCCESS, FAILURE, CIRCUIT_OPEN, TIMEOUT, REJECTED] percentiles: [0.5, 0.9, 0.95, 0.99] histogram_buckets: slo_driven alert_severity_thresholds: p1: "required dep unavailable for 2m" p2: "optional dep degraded for 5m" p3: "spike alert (10x baseline)" owner_branch: feature-metrics-alerting-contract log_field_mapping: [dependency_name, dependency_type, outcome, duration_ms] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-outbound-http-client-baseline — decisions # "retry/circuit breaker 기본 라이브러리는 Resilience4j" # source: feature-metrics-alerting-contract — "retry/CB minimum: resilience4j.retry.calls{outcome}" - name: resilience4j.retry.calls type: counter unit: total tags: - name: name cardinality_limit: 50 - name: outcome cardinality_limit: 5 allowed_values: [SUCCESS, FAILURE, CIRCUIT_OPEN, TIMEOUT, REJECTED] percentiles: null histogram_buckets: null alert_severity_thresholds: p2: "retry exhaustion rate > 1% for 10m" owner_branch: feature-outbound-http-client-baseline log_field_mapping: [dependency_name, outcome, retry_attempt] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-metrics-alerting-contract — "resilience4j.circuitbreaker.state" - name: resilience4j.circuitbreaker.state type: gauge unit: total tags: - name: name cardinality_limit: 50 - name: state cardinality_limit: 6 allowed_values: [CLOSED, OPEN, HALF_OPEN, DISABLED, FORCED_OPEN, METRICS_ONLY] percentiles: null histogram_buckets: null alert_severity_thresholds: p1: "state == OPEN for required dependency for 2m" p2: "state == OPEN for optional dependency for 5m" owner_branch: feature-outbound-http-client-baseline log_field_mapping: [dependency_name] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-metrics-alerting-contract — "resilience4j.circuitbreaker.calls{outcome}" - name: resilience4j.circuitbreaker.calls type: timer unit: seconds tags: - name: name cardinality_limit: 50 - name: outcome cardinality_limit: 5 allowed_values: [SUCCESS, FAILURE, CIRCUIT_OPEN, TIMEOUT, REJECTED] percentiles: [0.5, 0.9, 0.95, 0.99] histogram_buckets: slo_driven alert_severity_thresholds: p2: "CIRCUIT_OPEN rate > 1% for 10m" owner_branch: feature-outbound-http-client-baseline log_field_mapping: [dependency_name, outcome, duration_ms] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # === DB connection pool === # source: feature-persistence-failure-baseline — Hikari Alert Threshold # "pool wait p99 > 100ms 5분 지속 → P2 / pool exhaustion (active = max) > 1분 → P1" # source: feature-metrics-alerting-contract — "hikaricp.connections.acquire{outcome='timeout'} p99 > 100ms" - name: hikaricp.connections.acquire type: timer unit: seconds tags: - name: pool cardinality_limit: 5 - name: outcome cardinality_limit: 3 allowed_values: [SUCCESS, TIMEOUT, FAILURE] percentiles: [0.5, 0.9, 0.95, 0.99] histogram_buckets: slo_driven alert_severity_thresholds: p1: "pool exhaustion (active == max) for 1m" p2: "acquire p99 > 100ms for 5m" owner_branch: feature-persistence-failure-baseline log_field_mapping: [pool, outcome] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-persistence-failure-baseline — In scope "Hikari metric 노출 기준" + Hikari Alert Threshold - name: hikaricp.connections.usage type: timer unit: seconds tags: - name: pool cardinality_limit: 5 percentiles: [0.5, 0.9, 0.95, 0.99] histogram_buckets: slo_driven alert_severity_thresholds: p2: "usage p99 elevated > 10m" owner_branch: feature-persistence-failure-baseline log_field_mapping: [pool] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-persistence-failure-baseline — In scope "Hikari metric 노출 기준" - name: hikaricp.connections.active type: gauge unit: total tags: - name: pool cardinality_limit: 5 percentiles: null histogram_buckets: null alert_severity_thresholds: p1: "active == max for 1m" owner_branch: feature-persistence-failure-baseline log_field_mapping: [pool] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-metrics-alerting-contract — Histogram Buckets/Percentile "DB query: same" - name: db.query.duration type: timer unit: seconds tags: - name: operation cardinality_limit: 20 allowed_values: [select, insert, update, delete, batch, ddl, other] - name: outcome cardinality_limit: 3 allowed_values: [SUCCESS, FAILURE, TIMEOUT] percentiles: [0.5, 0.9, 0.95, 0.99] histogram_buckets: slo_driven alert_severity_thresholds: p2: "p99 > 1s for 10m" owner_branch: feature-metrics-alerting-contract log_field_mapping: [operation, outcome, duration_ms] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # === Background job / async executor === # source: feature-background-job-async-contract — Decisionized Work Items "saturation policy" # "AbortPolicy default (core=10, max=50, queue=200)" - name: executor.saturation type: gauge unit: total tags: - name: executor_name cardinality_limit: 10 percentiles: null histogram_buckets: null alert_severity_thresholds: p2: "queue size > 80% capacity for 5m" p1: "rejection rate > 0 for 1m" owner_branch: feature-background-job-async-contract log_field_mapping: [executor_name] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-background-job-async-contract — Decisionized Work Items "saturation | bounded executor + rejection log" - name: executor.rejected.total type: counter unit: total tags: - name: executor_name cardinality_limit: 10 - name: policy cardinality_limit: 3 allowed_values: [AbortPolicy, CallerRunsPolicy, DiscardPolicy] percentiles: null histogram_buckets: null alert_severity_thresholds: p1: "rejection_count > 0 for 1m" owner_branch: feature-background-job-async-contract log_field_mapping: [executor_name, policy] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-background-job-async-contract — Decisionized Work Items "retry/DLQ | exp backoff jitter, max 3, DLQ exhausted" - name: job.retry.total type: counter unit: total tags: - name: job_name cardinality_limit: 50 - name: outcome cardinality_limit: 4 allowed_values: [SUCCESS, RETRY, EXHAUSTED, DLQ] percentiles: null histogram_buckets: null alert_severity_thresholds: p2: "EXHAUSTED rate > 1% for 10m" owner_branch: feature-background-job-async-contract log_field_mapping: [job_name, outcome, retry_attempt] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-background-job-async-contract — "DLQ after exhausted attempts" - name: job.dlq.total type: counter unit: total tags: - name: job_name cardinality_limit: 50 percentiles: null histogram_buckets: null alert_severity_thresholds: p1: "DLQ rate sustained > 0 for 5m" owner_branch: feature-background-job-async-contract log_field_mapping: [job_name] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # === Distributed lock === # source: feature-distributed-lock-contract D7 — "metric lock.acquisition (tag: outcome = # acquired/timeout/error) — 신규 제안" / D5 — try-lock + 유한 waitTime + lease(TTL). 분산 # 상호배제(distributedLockProvider) 획득 시도 결과를 센다. key 는 tag 로 넣지 않는다 # (무한 cardinality — 위 전역 금지 규칙). timeout outcome 은 LOCK_ACQUISITION_TIMEOUT 발생과 1:1. - name: lock.acquisition type: counter unit: total tags: - name: outcome cardinality_limit: 3 allowed_values: [acquired, timeout, error] percentiles: null histogram_buckets: null alert_severity_thresholds: p2: "timeout rate > 5% for 10m" owner_branch: feature-distributed-lock-contract log_field_mapping: [outcome] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-distributed-lock-contract §Edge / D5 (SI-LOCK-C5) — "lease 만료 후 unlock → # ConcurrentModificationException — 삼킴 금지, 로그+metric 후 정상 흐름 복귀". Counts releases that # found the lease already expired (the JdbcLock row was reclaimed by another instance before # the holder called close()). A sustained nonzero rate means lease TTL is shorter than real # critical-section duration — raise APP/lease TTL or shorten the protected work. Not an # acquisition outcome, hence a separate counter from lock.acquisition. - name: lock.lease.expired type: counter unit: total tags: [] percentiles: null histogram_buckets: null alert_severity_thresholds: p2: "lease-expired rate sustained > 0 for 10m" owner_branch: feature-distributed-lock-contract log_field_mapping: [] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # === Outbox publisher === # source: feature-domain-event-outbox-contract — Outbox Defaults # "DB outbox table with eventId, aggregateId, eventType, payload, occurredAt, status, attemptCount, nextAttemptAt" - name: outbox.publisher.published.total type: counter unit: total tags: - name: event_type cardinality_limit: 50 - name: outcome cardinality_limit: 4 allowed_values: [PUBLISHED, FAILED, DEAD, IN_FLIGHT] percentiles: null histogram_buckets: null alert_severity_thresholds: p2: "FAILED rate > 1% for 10m" owner_branch: feature-domain-event-outbox-contract log_field_mapping: [event_type, outcome, event_id] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-domain-event-outbox-contract — row status enum PENDING/IN_FLIGHT/PUBLISHED/FAILED/DEAD - name: outbox.publisher.lag type: gauge unit: seconds tags: - name: event_type cardinality_limit: 50 percentiles: null histogram_buckets: null alert_severity_thresholds: p2: "lag > 60s for 10m" p1: "lag > 300s for 5m" owner_branch: feature-domain-event-outbox-contract log_field_mapping: [event_type] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-domain-event-outbox-contract — row status enum + Outbox Defaults attemptCount - name: outbox.pending.size type: gauge unit: total tags: - name: status cardinality_limit: 5 allowed_values: [PENDING, IN_FLIGHT, PUBLISHED, FAILED, DEAD] percentiles: null histogram_buckets: null alert_severity_thresholds: p2: "PENDING size growing for 10m" owner_branch: feature-domain-event-outbox-contract log_field_mapping: [status] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # === Cache === # source: feature-cache-consistency-contract — Decisionized Work Items "cache pattern | cache-aside default" - name: cache.gets.total type: counter unit: total tags: - name: cache_name cardinality_limit: 50 - name: result cardinality_limit: 3 allowed_values: [hit, miss, error] percentiles: null histogram_buckets: null alert_severity_thresholds: p3: "hit_ratio < baseline 0.5x for 1h" owner_branch: feature-cache-consistency-contract log_field_mapping: [cache_name, result] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-cache-consistency-contract — "invalidation = after-commit only", "invalidation 실패가 조용히 무시되면 실패" - name: cache.invalidations.total type: counter unit: total tags: - name: cache_name cardinality_limit: 50 - name: outcome cardinality_limit: 3 allowed_values: [SUCCESS, FAILURE, SKIPPED] percentiles: null histogram_buckets: null alert_severity_thresholds: p2: "FAILURE rate > 0 for 5m" owner_branch: feature-cache-consistency-contract log_field_mapping: [cache_name, outcome] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: redis-production-capability — optional bounded cache-only L1 - name: cache.local.requests.total type: counter unit: total tags: - name: cache_name cardinality_limit: 50 - name: result cardinality_limit: 4 allowed_values: [hit, miss, error, bypass] percentiles: null histogram_buckets: null alert_severity_thresholds: p3: "bypass or error rate above baseline for 15m" owner_branch: redis-production-capability log_field_mapping: [cache_name, result] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: redis-production-capability — local stale-age bound - name: cache.local.entry.age.seconds type: timer unit: seconds tags: - name: cache_name cardinality_limit: 50 percentiles: [0.5, 0.9, 0.95, 0.99] histogram_buckets: slo_driven alert_severity_thresholds: p3: "p99 approaches configured local TTL for 30m" owner_branch: redis-production-capability log_field_mapping: [cache_name] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: redis-production-capability — bounded invalidation and generation reconciliation - name: cache.local.maintenance.total type: counter unit: total tags: - name: cache_name cardinality_limit: 50 - name: event cardinality_limit: 14 allowed_values: - evict_cardinality - evict_weight - evict_ttl - evict_invalidation - flush_invalidation - reconcile_generation_changed - reconcile_unchanged - reconcile_error - subscriber_disconnected - subscriber_overflow - subscriber_malformed - subscriber_publish_success - subscriber_publish_error - other percentiles: null histogram_buckets: null alert_severity_thresholds: p2: "reconcile_error, subscriber_overflow, or sustained disconnects for 5m" owner_branch: redis-production-capability log_field_mapping: [cache_name, event] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: redis-production-capability Task 16 — closed semantic operation outcomes - name: redis.capability.operations.total type: counter unit: total tags: - name: capability cardinality_limit: 6 allowed_values: [cache, rate_limit, idempotency, efficiency_lease, session, runtime] - name: role cardinality_limit: 3 allowed_values: [cache, coordination, session] - name: operation cardinality_limit: 24 allowed_values: - lookup - record - invalidate - refresh_claim - refresh_release - rate_evaluate - idempotency_claim - idempotency_start - idempotency_renew - idempotency_complete - idempotency_fail - idempotency_release - idempotency_inspect - lease_acquire - lease_inspect - lease_renew - lease_release - session_create - session_inspect - session_save - session_touch - session_revoke - session_rotate - route_command - name: redis_outcome cardinality_limit: 15 allowed_values: - success - hit - miss - denied - contended - conflict - incompatible - unavailable - overloaded - closed - indeterminate - stale - skipped - tombstoned - absolute_expired - name: certainty cardinality_limit: 3 allowed_values: [definite, not_applied, indeterminate] percentiles: null histogram_buckets: null alert_severity_thresholds: p1: "required coordination/session unavailable or indeterminate mutation sustained for 2m" p2: "optional cache unavailable or overloaded above baseline for 5m" owner_branch: redis-production-capability log_field_mapping: [capability, role, operation, redis_outcome, certainty] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: redis-production-capability Task 16 — monotonic semantic operation duration - name: redis.capability.duration.seconds type: timer unit: seconds tags: - name: capability cardinality_limit: 6 allowed_values: [cache, rate_limit, idempotency, efficiency_lease, session, runtime] - name: role cardinality_limit: 3 allowed_values: [cache, coordination, session] - name: operation cardinality_limit: 24 allowed_values: - lookup - record - invalidate - refresh_claim - refresh_release - rate_evaluate - idempotency_claim - idempotency_start - idempotency_renew - idempotency_complete - idempotency_fail - idempotency_release - idempotency_inspect - lease_acquire - lease_inspect - lease_renew - lease_release - session_create - session_inspect - session_save - session_touch - session_revoke - session_rotate - route_command - name: redis_outcome cardinality_limit: 15 allowed_values: - success - hit - miss - denied - contended - conflict - incompatible - unavailable - overloaded - closed - indeterminate - stale - skipped - tombstoned - absolute_expired percentiles: [0.5, 0.9, 0.95, 0.99] histogram_buckets: slo_driven alert_severity_thresholds: p2: "p99 approaches the configured command or caller deadline for 10m" owner_branch: redis-production-capability log_field_mapping: [capability, role, operation, redis_outcome] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: redis-production-capability Task 16 — admission rejected before command ownership - name: redis.capability.admission.rejected.total type: counter unit: total tags: - name: role cardinality_limit: 3 allowed_values: [cache, coordination, session] - name: admission cardinality_limit: 2 allowed_values: [rejected_saturated, rejected_closed] percentiles: null histogram_buckets: null alert_severity_thresholds: p1: "required role rejection sustained above zero for 2m" p2: "optional cache saturation sustained for 5m" owner_branch: redis-production-capability log_field_mapping: [role, admission] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: redis-production-capability Task 16 — bounded admitted command count observation - name: redis.capability.inflight.total type: gauge unit: total tags: - name: role cardinality_limit: 3 allowed_values: [cache, coordination, session] - name: state cardinality_limit: 3 allowed_values: [idle, active, saturated] percentiles: null histogram_buckets: null alert_severity_thresholds: p2: "saturated series remains nonzero for 5m" owner_branch: redis-production-capability log_field_mapping: [role, state] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: redis-production-capability Task 16 — observations of exact sanitized RoleHealth - name: redis.capability.readiness.total type: counter unit: total tags: - name: capability cardinality_limit: 5 allowed_values: [cache, rate_limit, idempotency, efficiency_lease, session] - name: role cardinality_limit: 3 allowed_values: [cache, coordination, session] - name: state cardinality_limit: 3 allowed_values: [available, unavailable, overloaded] - name: reason cardinality_limit: 11 allowed_values: - command_unavailable - route_closed - semantic_probe_succeeded - semantic_read_write_failed - semantic_program_acl_denied - semantic_program_failed - server_version_unsupported - semantic_probe_in_progress - semantic_observation_stale - command_saturated - recent_command_failure - name: requirement cardinality_limit: 2 allowed_values: [optional, required] percentiles: null histogram_buckets: null alert_severity_thresholds: p1: "required coordination/session unavailable for 2m" p2: "optional cache unavailable or overloaded for 5m" owner_branch: redis-production-capability log_field_mapping: [capability, role, state, reason, requirement] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: redis-production-capability Task 16 — bounded router shutdown drain result - name: redis.capability.lifecycle.drain.total type: counter unit: total tags: - name: role cardinality_limit: 3 allowed_values: [cache, coordination, session] - name: drain_outcome cardinality_limit: 3 allowed_values: [drained, forced_after_timeout, interrupted] percentiles: null histogram_buckets: null alert_severity_thresholds: p1: "required role forced_after_timeout or interrupted during shutdown" p2: "optional cache forced close during shutdown" owner_branch: redis-production-capability log_field_mapping: [role, drain_outcome] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # === Log appender === # source: feature-log-management-contract — Sampling Policy (final) # "async appender overflow default: drop oldest INFO/DEBUG with counter metric (log.appender.dropped.total)" - name: log.appender.dropped.total type: counter unit: total tags: - name: appender cardinality_limit: 5 - name: level cardinality_limit: 2 allowed_values: [INFO, DEBUG] percentiles: null histogram_buckets: null alert_severity_thresholds: p2: "dropped > 0 sustained for 10m" owner_branch: feature-log-management-contract log_field_mapping: [appender, level] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # === Distributed tracing === # source: feature-distributed-tracing-contract — decisions # "trace sampling rate default = prod 1%, staging 10%, dev/local 100%" - name: tracing.sampling.rate type: gauge unit: total tags: - name: profile cardinality_limit: 4 allowed_values: [prod, staging, dev, local] percentiles: null histogram_buckets: null alert_severity_thresholds: p3: "effective rate deviates from configured for 1h" owner_branch: feature-distributed-tracing-contract log_field_mapping: [profile] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # === JVM baseline === # source: feature-metrics-alerting-contract — In scope "JVM/process metric" - name: jvm.memory.used type: gauge unit: bytes tags: - name: area cardinality_limit: 2 allowed_values: [heap, nonheap] - name: id cardinality_limit: 10 percentiles: null histogram_buckets: null alert_severity_thresholds: p2: "heap used / max > 0.85 for 10m" owner_branch: feature-metrics-alerting-contract log_field_mapping: [area, id] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-metrics-alerting-contract — In scope "JVM/process metric" - name: jvm.gc.pause type: timer unit: seconds tags: - name: action cardinality_limit: 10 - name: cause cardinality_limit: 10 percentiles: [0.5, 0.9, 0.95, 0.99] histogram_buckets: slo_driven alert_severity_thresholds: p2: "p99 pause > 500ms for 10m" owner_branch: feature-metrics-alerting-contract log_field_mapping: [action, cause] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-metrics-alerting-contract — In scope "JVM/process metric" - name: jvm.threads.live type: gauge unit: total tags: [] percentiles: null histogram_buckets: null alert_severity_thresholds: p3: "thread count > 2x baseline for 30m" owner_branch: feature-metrics-alerting-contract log_field_mapping: [] compatibility_impact: additive required_test: contract-verification:metrics-cardinality # source: feature-metrics-alerting-contract — In scope "JVM/process metric" (process uptime) - name: process.uptime type: gauge unit: seconds tags: [] percentiles: null histogram_buckets: null alert_severity_thresholds: p1: "uptime reset unexpectedly < 60s (crash loop signal)" owner_branch: feature-metrics-alerting-contract log_field_mapping: [] compatibility_impact: additive required_test: contract-verification:metrics-cardinality