--- title: Configure Logging --- # Configure Logging Configure structured logging with multiple output formats and integrate with log aggregation systems.
#### Before you begin - SMG [installed](index.md) - Completed the [Getting Started](index.md) guide - Log aggregation system (optional): Elasticsearch, Loki, or similar
--- ## Configuration Options SMG supports flexible logging configuration via CLI flags or environment variables. ### CLI Flags | Flag | Default | Description | |------|---------|-------------| | `--log-level` | `info` | Log level: debug, info, warn, error | | `--log-json` | `false` | Output logs as JSON | | `--log-dir` | None | Directory for log files (enables file logging) | ### Environment Variable ```bash # Override log level RUST_LOG=debug smg --worker-urls http://worker:8000 # Per-module logging RUST_LOG=smg=debug,hyper=warn smg --worker-urls http://worker:8000 ``` --- ## Log Levels | Level | Description | Use Case | |-------|-------------|----------| | `error` | Error conditions only | Production (minimal) | | `warn` | Warnings and errors | Production (recommended) | | `info` | Informational messages | Production (verbose) | | `debug` | Debug information | Development | ### Set Log Level ```bash # Via flag smg --worker-urls http://worker:8000 --log-level debug # Via environment RUST_LOG=info smg --worker-urls http://worker:8000 ``` --- ## Output Formats ### Plain Text (Default) Human-readable format with optional ANSI colors: ``` 2024-01-15 10:30:45 INFO smg::routing Request routed to worker worker=http://worker1:8000 policy=cache_aware ``` ### JSON Format Machine-readable format for log aggregation: ```bash smg --worker-urls http://worker:8000 --log-json ``` Output: ```json { "timestamp": "2024-01-15T10:30:45.123Z", "level": "INFO", "target": "smg::routing", "message": "Request routed to worker", "fields": { "request_id": "abc123", "worker": "http://worker1:8000", "policy": "cache_aware", "latency_ms": 150 } } ``` --- ## File Logging Enable persistent log files with automatic daily rotation. ### Enable File Logging ```bash smg \ --worker-urls http://worker:8000 \ --log-dir /var/log/smg \ --log-level info ``` ### Features - **Daily rotation**: New file created each day - **Non-blocking I/O**: Logging doesn't block request handling - **File naming**: `smg.YYYY-MM-DD.log` ### Example Directory Structure ``` /var/log/smg/ ├── smg.2024-01-13.log ├── smg.2024-01-14.log └── smg.2024-01-15.log ``` --- ## Docker Logging ### Basic Configuration ```yaml title="docker-compose.yml" services: smg: image: smg:latest environment: - RUST_LOG=info command: > --worker-urls http://worker:8000 --log-json logging: driver: json-file options: max-size: "100m" max-file: "3" ``` ### Production Configuration ```yaml title="docker-compose.yml" services: smg: image: smg:latest command: > --worker-urls http://worker:8000 --log-level info --log-json --log-dir /var/log/smg volumes: - smg-logs:/var/log/smg logging: driver: json-file options: max-size: "50m" max-file: "5" volumes: smg-logs: ``` --- ## Kubernetes Logging ### Basic Pod Logging ```bash # Follow logs kubectl logs -n inference -l app=smg -f # Previous container logs kubectl logs -n inference -l app=smg --previous # All containers in pod kubectl logs -n inference --all-containers ``` ### Deployment Configuration ```yaml title="smg-deployment.yaml" apiVersion: apps/v1 kind: Deployment metadata: name: smg spec: template: spec: containers: - name: smg args: - --worker-urls=http://worker:8000 - --log-level=info - --log-json env: - name: RUST_LOG value: "smg=info" ``` --- ## Log Aggregation ### Grafana Loki ```yaml title="promtail-config.yaml" server: http_listen_port: 9080 clients: - url: http://loki:3100/loki/api/v1/push scrape_configs: - job_name: smg kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_label_app] regex: smg action: keep - source_labels: [__meta_kubernetes_namespace] target_label: namespace - source_labels: [__meta_kubernetes_pod_name] target_label: pod pipeline_stages: - json: expressions: level: level target: target request_id: fields.request_id - labels: level: target: ``` ### Elasticsearch + Fluentd ```yaml title="fluentd-config.yaml" @type tail path /var/log/containers/smg*.log pos_file /var/log/fluentd-smg.pos tag smg.* @type json time_key timestamp time_format %Y-%m-%dT%H:%M:%S.%NZ @type parser key_name log @type json @type elasticsearch host elasticsearch port 9200 index_name smg-logs ``` --- ## Log Queries ### Loki/LogQL ```logql # All SMG logs {app="smg"} # Error logs only {app="smg"} | json | level="ERROR" # Specific request {app="smg"} | json | request_id="abc123" # Routing decisions {app="smg"} |= "routed" | json # By module {app="smg"} | json | target=~"smg::routing.*" ``` ### Elasticsearch/Kibana ```json { "query": { "bool": { "must": [ { "match": { "target": "smg::routing" } }, { "match": { "level": "ERROR" } } ], "filter": [ { "range": { "timestamp": { "gte": "now-1h" } } } ] } } } ``` --- ## OpenTelemetry Integration When OpenTelemetry is enabled, log levels are automatically adjusted: | OTEL Enabled | Event Level | Behavior | |--------------|-------------|----------| | Yes | INFO | Exported to OTLP collector | | No | DEBUG | Not exported (local only) | This ensures request events are captured in traces when OTEL is active. ```bash # Enable OTEL with logging smg \ --worker-urls http://worker:8000 \ --enable-trace \ --otlp-traces-endpoint localhost:4317 \ --log-level info ``` --- ## Request Correlation ### Request ID Propagation SMG generates unique request IDs and propagates them through logs: ```bash # Send request with custom ID curl -H "X-Request-ID: my-trace-123" \ http://localhost:30000/v1/chat/completions \ -d '{"model": "llama", "messages": [{"role": "user", "content": "Hi"}]}' ``` ### Trace a Request ```bash # Find all logs for a request kubectl logs -n inference -l app=smg | grep "my-trace-123" # In Loki {app="smg"} | json | request_id="my-trace-123" ``` --- ## Log Rotation ### Linux logrotate ```conf title="/etc/logrotate.d/smg" /var/log/smg/*.log { daily rotate 7 compress delaycompress missingok notifempty create 0640 smg smg } ``` ### Docker ```yaml logging: driver: json-file options: max-size: "100m" max-file: "5" ``` --- ## Verification ```bash # Check log output smg --worker-urls http://worker:8000 --log-level debug 2>&1 | head -20 # Verify JSON format smg --worker-urls http://worker:8000 --log-json 2>&1 | jq . # Test log level filtering smg --worker-urls http://worker:8000 --log-level warn 2>&1 | grep -c INFO # Should output: 0 # Check file logging smg --worker-urls http://worker:8000 --log-dir /tmp/smg-logs & ls -la /tmp/smg-logs/ ``` --- ## Troubleshooting ??? question "No logs appearing" 1. Check log level is not too restrictive: ```bash smg --log-level debug ... ``` 2. Verify logs are going to stderr: ```bash smg --worker-urls http://worker:8000 2>&1 | head ``` 3. Check RUST_LOG isn't overriding: ```bash unset RUST_LOG smg --log-level info ... ``` ??? question "Logs not in JSON format" 1. Ensure `--log-json` flag is set: ```bash smg --log-json --worker-urls http://worker:8000 ``` 2. Verify you're reading stderr, not stdout ??? question "File logs not appearing" 1. Check directory exists and is writable: ```bash mkdir -p /var/log/smg chmod 755 /var/log/smg ``` 2. Verify `--log-dir` flag is set correctly ??? question "Log aggregator not receiving logs" 1. Verify JSON format is enabled 2. Check network connectivity to aggregator 3. Verify log format matches parser expectations --- ## What's Next? - [Monitoring](monitoring.md) — Metrics, tracing, and alerting - [Configuration Reference](../reference/configuration.md) — Full CLI options