---
title: "Logging"
description: "Logging configuration and best practices"
keywords: [logging, logs, monitoring, observability]
---

# Logging

Logging configuration and best practices for TraceRTM.

## Logging Configuration

### Python Logging

```python
import logging
import sys

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.StreamHandler(sys.stdout),
        logging.FileHandler('tracertm.log')
    ]
)

logger = logging.getLogger(__name__)
```

### Structured Logging

```python
import json
import logging

class JSONFormatter(logging.Formatter):
    def format(self, record):
        log_data = {
            "timestamp": self.formatTime(record),
            "level": record.levelname,
            "logger": record.name,
            "message": record.getMessage(),
            **getattr(record, "extra", {})
        }
        return json.dumps(log_data)

handler = logging.StreamHandler()
handler.setFormatter(JSONFormatter())
logger.addHandler(handler)
```

## Log Levels

### Standard Levels

```python
# DEBUG: Detailed information
logger.debug("Processing item %s", item_id)

# INFO: General information
logger.info("Item created: %s", item_id)

# WARNING: Warning messages
logger.warning("Rate limit approaching: %d/%d", current, limit)

# ERROR: Error messages
logger.error("Failed to create item: %s", error)

# CRITICAL: Critical errors
logger.critical("Database connection lost")
```

## Request Logging

### Middleware Logging

```python
import logging
import time
from fastapi import Request

logger = logging.getLogger(__name__)

class LoggingMiddleware:
    async def __call__(self, request: Request, call_next):
        start_time = time.time()
        
        logger.info(
            "Request started",
            extra={
                "method": request.method,
                "path": request.url.path,
                "client": request.client.host
            }
        )
        
        response = await call_next(request)
        
        process_time = time.time() - start_time
        logger.info(
            "Request completed",
            extra={
                "method": request.method,
                "path": request.url.path,
                "status_code": response.status_code,
                "process_time": process_time
            }
        )
        
        return response
```

## Log Aggregation

### Docker Logs

```bash
# View container logs
docker logs tracertm-api

# Follow logs
docker logs -f tracertm-api

# Last 100 lines
docker logs --tail=100 tracertm-api
```

### Kubernetes Logs

```bash
# Pod logs
kubectl logs tracertm-api-xxx

# Follow logs
kubectl logs -f tracertm-api-xxx

# All pods
kubectl logs -l app=tracertm-api
```

## Log Rotation

### Logrotate

```bash
# /etc/logrotate.d/tracertm
/var/log/tracertm/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 0640 appuser appuser
}
```

## Best Practices

### 1. Use Appropriate Levels

```python
# Use INFO for normal operations
logger.info("Item created: %s", item_id)

# Use ERROR for exceptions
logger.error("Failed to create item", exc_info=True)
```

### 2. Include Context

```python
# Good - includes context
logger.info("Item created", extra={
    "item_id": item_id,
    "project_id": project_id,
    "user_id": user_id
})

# Bad - no context
logger.info("Item created")
```

### 3. Don't Log Sensitive Data

```python
# Bad - logs password
logger.info("User login: %s, password: %s", username, password)

# Good - no sensitive data
logger.info("User login: %s", username)
```

## Related Documentation

- [ELK Stack](./05a-elk-stack) - Log aggregation
- [Monitoring](./04a-prometheus) - Monitoring setup
