Request baggage #
Request baggage attaches key-value metadata to the logs and metrics emitted during RPC prcessing. The name is borrowed from OpenTelemetry to signal that the data is non-essential — useful for observability but not meant to be relied on for game features. Effort should be taken to minimize use of request baggage– it increases cardinality across monitoring systems and can overwhelm the network and/or downstream metrics, logging, and telemetry systems.
Enabling request baggage #
Request baggage processing is disabled by default. Enable it on the backend(s) where you want metadata attached:
game:
core:
logging:
requestBaggageEnabled: true
social:
core:
logging:
requestBaggageEnabled: true
DefaultRequestBaggagePlugin #
The plugin registered on every backend by default. It attaches a traceId (a randomly generated Uuid) to inbound requests and propagates it through resulting service-to-service calls, providing a single identifier to correlate log entries across a distributed call path.
| Method | Behavior |
|---|---|
getForExternalRequest | Returns a new baggage map containing a generated traceId. |
getForServiceRpc | Returns the current baggage unchanged when a traceId is already present; otherwise inserts one. These entries will propagate across service-to-service requests. |
getForMetrics | Returns an empty map; no entries are attached as metric tags by default. |
RequestBaggagePluginWithSessionBaggage #
Extends DefaultRequestBaggagePlugin. Overrides one method to include session-baggage entries automatically, otherwise behaves the same is its base class (including generation of the traceId)
| Method | Behavior |
|---|---|
getForExternalRequest | Returns the inherited traceId plus all entries currently stored in the session’s baggage cache. |
For how to populate the session baggage cache, see Session baggage.
Custom plugins #
Extend either provided plugin to customize selected hooks. The example below extends RequestBaggagePluginWithSessionBaggage to add a session-derived displayName to every inbound request and to forward only the buildId entry as a metric tag — extend DefaultRequestBaggagePlugin instead if you don’t want session baggage attached automatically.
import pragma.ExternalRequest
import pragma.logging.MutableRequestBaggage
import pragma.logging.RequestBaggage
import pragma.logging.RequestBaggagePluginWithSessionBaggage
import pragma.session.RpcExecutionContext
//...
class MyRequestBaggagePlugin : RequestBaggagePluginWithSessionBaggage() {
override fun getForExternalRequest(
request: ExternalRequest,
session: RpcExecutionContext,
): MutableRequestBaggage {
val result = super.getForExternalRequest(request, session)
result["displayName"] = session.activePragmaSession.playerSession.displayName
return result
}
override fun getForMetrics(metricName: String, requestBaggage: RequestBaggage): MutableRequestBaggage {
val result: MutableRequestBaggage = mutableMapOf()
requestBaggage["buildId"]?.let { result["buildId"] = it }
return result
}
}
Take extra care with getForMetrics — any tag whose value space is unbounded will overwhelm OTel collection. Only use tags whose values come from a small, fixed set (such as an enum).Register the plugin #
Register the plugin by assigning it to pragmaNode.requestBaggagePlugin inside an AlwaysStartedNodeService.
This plugin is registered in a non-standard manner because it resides within pragma-core, whereas most plugins reside within a Pragma service (which provides first party support for plugins).
import pragma.PragmaNode
import pragma.services.AlwaysStartedNodeService
import pragma.services.PragmaService
import pragma.settings.BackendType
//...
@PragmaService(
backendTypes = [BackendType.GAME, BackendType.SOCIAL],
)
class MyBaggageSetupService(pragmaNode: PragmaNode) : AlwaysStartedNodeService(pragmaNode) {
override suspend fun run() {
pragmaNode.requestBaggagePlugin = MyRequestBaggagePlugin()
}
}
Plugin output limits #
After a plugin returns entries, the engine validates them against SessionCoreConfig before attaching the result to logs emitted during the RPC. Entries whose key or value exceeds the size limits are dropped and a warning is logged; if the total entry count exceeds baggageEntryLimit, all entries are rejected.
While these config keys also appear on DefaultSessionPluginConfig for session-baggage storage — the two sets of limits are discrete and enforced independently.| Setting | Default | Description |
|---|---|---|
baggageEntryLimit | 5 | Maximum number of entries a plugin may return. |
baggageKeySizeLimit | 36 | Maximum character length of each key. |
baggageValueSizeLimit | 36 | Maximum character length of each value. |
Example raising the entry cap:
game:
core:
sessionCoreConfig:
baggageEntryLimit: 10
social:
core:
sessionCoreConfig:
baggageEntryLimit: 10
Related resources #
- Session baggage — a session-scoped key-value cache that
RequestBaggagePluginWithSessionBaggagereads to attach per-session context to logs.