Skip to main content
Version: 5.x

Event Schema Reference

Applies to MTE Relay v5

This schema applies to MTE Relay v5 (MRS and MAR). It is the contract the monitoring integrations on this site build against.

MTE Relay writes JSON lines with zerolog, on two streams:

  • stderr: operational logs, such as the startup configuration line, the per request "Request completed" line, warnings, and errors.
  • stdout: structured events, one JSON object per line with a single nested event object.

Container runtimes collect both streams by default. No custom parsing rules are needed in Datadog, New Relic, Loki, CloudWatch Logs Insights, Splunk, or Elastic.

Configuration​

Env varDefaultEffect
LOG_LEVELinfoFilters both streams. Security events log at info, warn, or error by severity, so high and critical security events survive LOG_LEVEL=warn.
USE_CONSOLE_LOGSfalseTurns the stderr stream into human readable console lines for local development. Structured events on stdout stay JSON.

There is no sampling setting: every request produces its performance events.

Common fields​

Every line carries time (RFC 3339 with milliseconds, for example 2026-09-29T14:03:07.123Z) and message, and every line except the perf stats and pprof lines carries level. Operational lines on stderr also carry caller, the source file and line that wrote the line. Lines the request handlers write carry correlationId; lines from the state store and the outbound relay client, and two response path warnings, do not.

A secret that appears in a log line, such as the license key or a client_id_secret on the startup configuration line, shows its first three characters followed by asterisks.

SocketX writes the same time format and the same caller field, so one pipeline can parse both products. Its field names are snake_case where the relay's operational lines are camelCase; one vocabulary is a later change.

An event line on stdout carries exactly one nested object under one of these keys: performance_event, security_event, encryption_event, or error_event. The object has its own correlation_id, which equals the correlationId of the operational lines for the same request and the X-MTE-Relay-Request-Id the relay returns to the client. The exception is the outbound relay client: its relay_<reason> events and its response side header_mismatch events carry an empty correlation_id.

The relay does not add a service name, product, instance, or version field to these lines. Attach service and any other tags in your log shipper, as the vendor guides show. The startup line reports mteVersion, marVersion, and mrsVersion.

performance_event​

  • request_timing, every request, including pass through requests and errors: correlation_id, request_path, request_method, total_time_ms, status_code (the relay's HTTP status).
  • phase_breakdown, every encrypted request that reached the upstream: correlation_id, request_method, total_time_ms, validation_ms, decryption_ms, proxy_ms, encryption_ms, status_code (the upstream's status), client_id, pair_id, encrypted_data_bytes, decrypted_data_bytes.

On a relay that answers with frames, an encrypted response travels as HTTP 200, so request_timing reports 200 for relayed requests and the relay error code for relay errors, while phase_breakdown reports the upstream's own status. On an outbound domain, request_timing reports the status returned to the calling service, which is the origin's status or the relay's own error code. Pass through routes report the origin's status.

security_event​

Fields: event_type, severity (low, medium, high, critical), origin, reason, client_id, pair_id, success, correlation_id. origin is the connection's peer address as ip:port, so behind a load balancer it is the load balancer's address. TRUSTED_PROXIES does not change it. Severity maps to the log level: low to info, medium to warn, high and critical to error.

event_typeSeverityMeaning
auth_invalid_tokenlowAn invalid or aged token presented at discovery; the relay issued a new client id. SocketX raises the same event.
pair_invalid_client_idhigh, or low when the token only expiredThe token was refused at pairing (475).
keepalive_invalid_client_idhigh, or low when the token only expiredThe token was refused at keepalive (475).
invalid_client_idmediumThe token signature failed on an encrypted request (475).
client_pairs_exhaustedlowThe relay holds no pairs for the client, so the client must repair (475).
pair_not_foundmediumPair state is missing: expired, poisoned, or never created (470).
state_restore_failedhighDecoder state could not be restored.
replay_rejectedmediumThe decoder rejected a replayed or out of order frame (479).
header_mismatchhighEncrypted metadata or frame flags disagree with the plaintext envelope (483).
relay_replay_rejected, relay_header_mismatchmediumOn an outbound domain, the next relay answered 479 or 483. Other next relay errors raise no security event.

The relay raises no security event when it cannot write pair state. A failed decoder save on an encrypted request answers 503 state_store_write_failed, and a failed write at pairing or keepalive answers 503 state_store_unavailable; both show as relayCode 503 on the "Request completed" line. A failed encoder save after the response has gone out only logs a Pair poisoned warning, and the next request on that pair gets 470, or 475 if it was the client's last pair.

encryption_event​

An audit record for each encrypted request that reached the upstream. The audit record holds no plaintext. At LOG_LEVEL=debug, stderr lines carry the decoded request path, and the Proxying to upstream line carries the upstream URL with its query.

  • event_type: decryption, direction: inbound_request.

Fields: correlation_id, incoming_protocol, host, origin, upstream_host, url_payload_hash (SHA-256 of the request path without the query), url_payload_length, mte_type (MKE or MTE), data_size_bytes, client_id, pair_id, streaming, success, eeid.

error_event​

Fields: event_type, severity, message, reason, error_code, stack_trace, origin, correlation_id. Current catalog: panic (critical), a recovered handler panic with its stack trace.

Operational lines worth dashboarding​

  • "Request completed" on stderr, for every request: method, path, statusCode, duration_ms, correlationId, plus upstreamStatus when the upstream answered and relayCode and relayReason when the relay answered an error. Echo and HEALTH_CHECK_PATH hits are logged at debug, not info, so a load balancer check does not fill the log.
  • Perf stats summary lines, only when ENABLE_PERF_STATS=true.

Vendor guides​

  • Datadog: pipeline, facets and measures, dashboard, monitors
  • New Relic: dashboard, alert policy
  • Grafana: CloudWatch Logs Insights and Loki dashboards