Skip to main content

Distributed Tracing

Gate supports distributed tracing through OpenTelemetry, allowing you to track requests as they flow through your proxy infrastructure. Tracing helps identify performance bottlenecks, debug connection issues, and understand player request flows.

Enabling Tracing

Tracing is disabled by default. Enable it using the OTEL_TRACES_ENABLED environment variable:

Trace Instrumentation

Gate automatically instruments key operations with tracing spans. The instrumentation is implemented throughout the codebase using OpenTelemetry’s Go SDK.

Instrumented Operations

Gate creates traces for the following operations:

Proxy Operations (pkg/edition/java/proxy/proxy.go:XX)

  • Proxy.Start - Proxy startup and initialization
  • HandleConn - New player connection handling
    • Attributes: net.peer.addr, net.peer.port

Authentication (pkg/edition/java/auth/authenticator.go:XX)

  • AuthenticateJoin - Player authentication with Mojang
    • Attributes: player.username, player.uuid, player.ip

Network Operations (pkg/edition/java/netmc/connection.go:XX)

  • startReadLoop - Packet reading loop
    • Attributes: connection.id, connection.state
  • HandlePacket - Individual packet processing
    • Attributes: packet.type, packet.size

Server Connections (pkg/edition/java/proxy/server.go:XX)

  • serverConnection.dial - Backend server connection
    • Attributes: server.name, server.address, server.port

Trace Context Propagation

Gate uses the W3C Trace Context standard for propagation:
This allows traces to span across:
  • Gate proxy instances
  • Backend servers (if instrumented)
  • External authentication services
  • Custom plugins and middleware

Configuration

Basic Setup

Advanced Configuration

Sampling Configuration

Control trace sampling to manage volume and costs:
Sampling options:
  • always_on - Sample all traces (default)
  • always_off - Sample no traces
  • traceidratio - Sample based on trace ID ratio
  • parentbased_always_on - Respect parent sampling decision, otherwise always sample
  • parentbased_traceidratio - Respect parent, otherwise sample by ratio

Backend Integration

Jaeger

Jaeger is a popular open-source distributed tracing system.

Direct to Jaeger

Via OpenTelemetry Collector

Docker Compose with Jaeger

Access Jaeger UI at http://localhost:16686

Grafana Tempo

Tempo is Grafana’s high-scale distributed tracing backend.

Configuration

Docker Compose with Tempo

Tempo Configuration

Grafana Cloud

Get credentials from your Grafana Cloud stack settings.

Honeycomb

Trace Analysis

Understanding Trace Structure

A typical player connection trace shows:

Example Queries

Jaeger UI

  • Find slow connections: Filter by duration > 1s
  • Search by player: Use tag player.username=<name>
  • Error traces: Filter by tag error=true
  • By operation: Select operation like AuthenticateJoin

Grafana with Tempo

Common Patterns

Slow Player Connections

Look for high duration in:
  • AuthenticateJoin - Mojang API slowness
  • serverConnection.dial - Backend server latency
  • HandlePacket - Packet processing issues

Connection Failures

Check for error status in:
  • HandleConn - Initial connection problems
  • AuthenticateJoin - Authentication failures
  • serverConnection.dial - Backend unreachable

Trace Correlation

Linking Traces to Metrics

Use exemplars to link metrics to traces in Grafana:
Click on a data point to see associated traces.

Linking Traces to Logs

Gate automatically includes trace context in logs when using structured logging:
Search logs by trace ID to find related log entries.

Custom Tracing

Add custom spans in your Gate plugins:

Performance Considerations

Overhead

  • Tracing adds ~1-2% CPU overhead when enabled
  • Memory impact: ~100-200 bytes per span
  • Network: Traces are batched and compressed

Optimization Tips

  1. Use sampling for high-traffic proxies:
  2. Batch traces in the collector:
  3. Filter unnecessary spans:

Troubleshooting

No Traces Appearing

  1. Verify tracing is enabled:
  2. Test the endpoint:
  3. Check Gate logs for trace export errors

Incomplete Traces

  • Ensure all services use the same propagation format
  • Verify trace context is passed through middleware
  • Check for trace context being lost at service boundaries

High Trace Volume

  • Implement sampling: OTEL_TRACES_SAMPLER_ARG
  • Use tail-based sampling in the collector
  • Filter low-value spans

Next Steps

Metrics

Monitor proxy performance with metrics

Logging

Configure structured logging