Documentation Index Fetch the complete documentation index at: https://mintlify.com/minekube/gate/llms.txt
Use this file to discover all available pages before exploring further.
Logging Configuration
Gate uses structured logging with Uber’s Zap logger, providing high-performance, leveled logging with structured fields. Logs can be configured via command-line flags and environment variables.
Log Levels
Gate supports multiple log verbosity levels, controlled by the --verbosity flag or GATE_VERBOSITY environment variable:
Verbosity Level Use Case 0Info Production (default) - Essential operational messages 1Debug Development - Detailed debugging information 2+Trace Deep debugging - Very detailed internal operations
Setting Log Level
# Via command-line flag
gate --verbosity 1
# Via environment variable
export GATE_VERBOSITY = 1
gate
# Enable debug mode (sets highest verbosity)
gate --debug
export GATE_DEBUG = true
Configuration
Command-Line Flags
# Verbosity control
gate --verbosity 2 # Set specific verbosity level
gate -v 2 # Short form
# Debug mode (maximum verbosity)
gate --debug # Enable debug logging
gate -d # Short form
# Show version
gate --version # Display version and exit
gate -V # Short form (Unix convention)
Environment Variables
export GATE_VERBOSITY = 1 # Set verbosity level
export GATE_DEBUG = true # Enable debug mode
export GATE_CONFIG = "/path/to/config.yml" # Config file location
Configuration File
# config.yml
config :
debug : false # Enable debug mode
Gate uses different log formats depending on the mode:
JSON-structured logs optimized for machine parsing:
{
"level" : "info" ,
"ts" : "2024-03-04T10:30:45.123Z" ,
"logger" : "gate" ,
"msg" : "starting Gate proxy" ,
"version" : "v0.28.0"
}
Human-readable console logs with colors:
2024-03-04T10:30:45.123Z INFO gate starting Gate proxy {"version": "v0.28.0"}
Logger Implementation
Gate’s logger is configured in cmd/gate/root.go:191:
func newLogger ( debug bool , v int ) ( l logr . Logger , err error ) {
var cfg zap . Config
if debug {
cfg = zap . NewDevelopmentConfig ()
} else {
cfg = zap . NewProductionConfig ()
}
cfg . Level = zap . NewAtomicLevelAt ( zapcore . Level ( - v ))
cfg . Encoding = "console"
cfg . EncoderConfig . EncodeLevel = zapcore . CapitalColorLevelEncoder
cfg . EncoderConfig . EncodeTime = zapcore . ISO8601TimeEncoder
zl , err := cfg . Build ()
if err != nil {
return logr . Discard (), err
}
return zapr . NewLogger ( zl ), nil
}
Structured Fields
Gate logs include structured fields for easy filtering:
log . Info ( "player connected" ,
"username" , player . Name ,
"uuid" , player . UUID ,
"address" , conn . RemoteAddr (),
)
Output:
{
"level" : "info" ,
"msg" : "player connected" ,
"username" : "Notch" ,
"uuid" : "069a79f4-44e9-4726-a5be-fca90e38aaf5" ,
"address" : "192.168.1.100:54321"
}
OpenTelemetry Integration
When OpenTelemetry tracing is enabled, logs automatically include trace context:
export OTEL_TRACES_ENABLED = "true"
export OTEL_EXPORTER_OTLP_ENDPOINT = "http://localhost:4318"
Logs will include trace and span IDs:
{
"level" : "info" ,
"msg" : "processing packet" ,
"trace_id" : "4bf92f3577b34da6a3ce929d0e0e4736" ,
"span_id" : "00f067aa0ba902b7"
}
This enables correlation between logs and traces in observability platforms.
Log Aggregation
Grafana Loki
Loki is designed for aggregating logs from multiple sources.
Docker Compose with Loki
services :
gate :
image : ghcr.io/minekube/gate:latest
environment :
- GATE_VERBOSITY=1
logging :
driver : loki
options :
loki-url : "http://localhost:3100/loki/api/v1/push"
loki-external-labels : "service=gate,environment=production"
networks :
- logging
loki :
image : grafana/loki:latest
command : -config.file=/etc/loki/local-config.yaml
ports :
- "3100:3100"
networks :
- logging
grafana :
image : grafana/grafana:latest
environment :
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
volumes :
- ./grafana-datasources.yml:/etc/grafana/provisioning/datasources/datasources.yaml
ports :
- "3000:3000"
networks :
- logging
networks :
logging :
Loki Configuration
# grafana-datasources.yml
apiVersion : 1
datasources :
- name : Loki
type : loki
access : proxy
url : http://loki:3100
isDefault : true
Querying Logs in Grafana
# All Gate logs
{service="gate"}
# Error logs only
{service="gate"} |= "level=error"
# Player connection logs
{service="gate"} |= "player connected"
# Logs for specific player
{service="gate"} | json | username="Notch"
# Logs with trace ID
{service="gate"} | json | trace_id=~".+"
Promtail for Log Shipping
Use Promtail to ship logs from files to Loki:
# promtail-config.yml
server :
http_listen_port : 9080
grpc_listen_port : 0
positions :
filename : /tmp/positions.yaml
clients :
- url : http://loki:3100/loki/api/v1/push
scrape_configs :
- job_name : gate
static_configs :
- targets :
- localhost
labels :
job : gate
__path__ : /var/log/gate/*.log
Elasticsearch and Kibana
For Elasticsearch-based log aggregation:
services :
gate :
image : ghcr.io/minekube/gate:latest
environment :
- GATE_VERBOSITY=1
logging :
driver : "json-file"
options :
max-size : "10m"
max-file : "3"
filebeat :
image : docker.elastic.co/beats/filebeat:8.10.0
user : root
volumes :
- ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
elasticsearch :
image : docker.elastic.co/elasticsearch/elasticsearch:8.10.0
environment :
- discovery.type=single-node
- xpack.security.enabled=false
ports :
- "9200:9200"
kibana :
image : docker.elastic.co/kibana/kibana:8.10.0
ports :
- "5601:5601"
environment :
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
Best Practices
1. Production Logging
# Production: Info level, JSON format
export GATE_VERBOSITY = 0
export GATE_DEBUG = false
Log only essential information:
Service startup/shutdown
Player connections/disconnections
Configuration changes
Errors and warnings
2. Development Logging
# Development: Debug level, console format
gate --debug --verbosity 2
Includes:
Detailed packet information
Authentication flows
Internal state changes
Performance metrics
3. Structured Fields
Always use structured fields instead of string formatting:
// Good - Structured
log . Info ( "player joined" ,
"player" , player . Name ,
"server" , server . Name ,
"time" , time . Now (),
)
// Bad - String formatting
log . Info ( fmt . Sprintf ( "Player %s joined server %s " , player . Name , server . Name ))
4. Log Sampling
For high-frequency events, use sampling to reduce log volume:
// Log only 10% of packet events
if rand . Float64 () < 0.1 {
log . V ( 1 ). Info ( "packet received" , "type" , packet . Type )
}
5. Sensitive Data
Never log sensitive information:
// Bad - Logs sensitive data
log . Info ( "auth token" , "token" , authToken )
// Good - Redacted
log . Info ( "auth token" , "token" , "<redacted>" )
6. Error Context
Include context when logging errors:
if err := connectToServer ( server ); err != nil {
log . Error ( err , "failed to connect to server" ,
"server" , server . Name ,
"attempt" , retryCount ,
"max_retries" , maxRetries ,
)
}
Log Rotation
Using logrotate (Linux)
# /etc/logrotate.d/gate
/var/log/gate/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 gate gate
sharedscripts
postrotate
systemctl reload gate || true
endscript
}
Using Docker logging driver
services :
gate :
image : ghcr.io/minekube/gate:latest
logging :
driver : "json-file"
options :
max-size : "100m"
max-file : "10"
compress : "true"
Custom Plugin Logging
Use the context logger in your plugins:
import (
" context "
" github.com/go-logr/logr "
)
func MyPluginInit ( ctx context . Context ) error {
log := logr . FromContextOrDiscard ( ctx ). WithName ( "my-plugin" )
log . Info ( "plugin initialized" , "version" , "1.0.0" )
// Debug logging (only shown at verbosity >= 1)
log . V ( 1 ). Info ( "debug information" , "detail" , "value" )
// Error logging
if err := doSomething (); err != nil {
log . Error ( err , "operation failed" , "context" , "additional info" )
}
return nil
}
Troubleshooting
No Logs Appearing
Check verbosity level:
Ensure debug mode is not disabled in config:
config :
debug : true # Enable for development
Verify logger initialization in Gate startup logs
Too Many Logs
Reduce verbosity:
Disable debug mode:
Implement log sampling for high-frequency events
Gate uses console encoding by default. For JSON logs, you need to modify the logger configuration or use a log shipper to parse console logs.
Next Steps
OpenTelemetry Set up comprehensive observability
Metrics Monitor proxy performance metrics