Skip to content

Logging Guide

This guide explains how to view and use the comprehensive logging system in the application.

Overview

The application uses structured JSON logging to track all API invocations and errors. Each request gets a unique request ID that can be used to trace errors back to the original request.

Running Locally to See Logs

This is the easiest way to see all logs in real-time:

# Terminal 1: Start Supabase
supabase start

# Terminal 2: Start the API server
deno task dev

What you'll see: - All logs appear directly in the terminal as structured JSON - Request logs for every API call - Response logs with timing information - Error logs with full context when errors occur

Example output:

{"timestamp":"2024-01-15T10:30:00.123Z","level":"info","requestId":"550e8400-e29b-41d4-a716-446655440000","type":"request","method":"GET","path":"/api/v1/domains","query":{},"userAgent":"Mozilla/5.0...","ip":"127.0.0.1"}
{"timestamp":"2024-01-15T10:30:00.456Z","level":"info","requestId":"550e8400-e29b-41d4-a716-446655440000","type":"response","method":"GET","path":"/api/v1/domains","statusCode":200,"durationMs":45}

Option 2: Supabase Edge Function (For Testing Edge Function Deployment)

If you want to test the app as it would run in production (as a Supabase Edge Function):

# Terminal 1: Start Supabase
supabase start

# Terminal 2: Serve the Edge Function
supabase functions serve browse

Note: When running as an Edge Function, logs are still output to the terminal, but they may be formatted by Supabase's logging system. The structured JSON logs will still be present.

Viewing Logs

Real-Time Log Viewing

When running deno task dev, all logs appear in the terminal in real-time. Each log entry is a single line of JSON, making it easy to:

  1. View in terminal: See logs as they happen
  2. Pipe to a file: Save logs for later analysis
    deno task dev 2>&1 | tee api.log
    
  3. Filter logs: Use jq to filter and format logs
    deno task dev 2>&1 | jq 'select(.level == "error")'
    

Log Types

Request Logs

Every incoming request is logged with: - Request ID (unique identifier) - HTTP method and path - Query parameters - Headers (sanitized - auth tokens removed) - User agent and IP address

Response Logs

Every outgoing response is logged with: - Request ID (matches the request log) - HTTP status code - Duration in milliseconds - Response size (if available)

Error Logs

All errors are logged with: - Request ID (for tracing back to the request) - Full error details (message, stack trace, error type) - Request context (method, path, query params) - User ID (if authenticated)

Testing Error Logging

To verify error logging is working:

1. Test a 404 Error

curl http://localhost:8000/api/v1/domains/non-existent-domain

You should see an error log like:

{
  "timestamp": "2024-01-15T10:30:00.789Z",
  "level": "error",
  "requestId": "550e8400-e29b-41d4-a716-446655440000",
  "type": "error",
  "error": {
    "name": "NotFoundError",
    "message": "Domain 'non-existent-domain' not found",
    "code": "NOT_FOUND",
    "statusCode": 404
  },
  "request": {
    "method": "GET",
    "path": "/api/v1/domains/non-existent-domain",
    "query": {}
  }
}

2. Test a 500 Error

Trigger an internal error by making a request that causes a database error or other internal issue.

3. Test with Authentication

Make an authenticated request that fails:

curl -H "Authorization: Bearer invalid-token" http://localhost:8000/api/v1/me

The error log will include the user context if authentication was attempted.

Using Request IDs

Every request gets a unique X-Request-ID header in the response. You can use this to:

  1. Trace errors: Find the request that caused an error
  2. Debug issues: Search logs for a specific request ID
  3. Client-side correlation: Include the request ID in bug reports

Example: Finding All Logs for a Request

# Get the request ID from response headers
curl -i http://localhost:8000/api/v1/domains | grep X-Request-ID

# Search logs for that request ID
deno task dev 2>&1 | jq 'select(.requestId == "550e8400-e29b-41d4-a716-446655440000")'

Log Filtering Examples

View Only Errors

deno task dev 2>&1 | jq 'select(.level == "error")'

View Slow Requests (>1000ms)

deno task dev 2>&1 | jq 'select(.type == "response" and .durationMs > 1000)'

View All Logs for a Specific Endpoint

deno task dev 2>&1 | jq 'select(.path == "/api/v1/domains")'

View Errors with Stack Traces

deno task dev 2>&1 | jq 'select(.level == "error") | .error.stack'

Log Aggregation Tools

The structured JSON format makes it easy to integrate with log aggregation tools:

  • Datadog: Can parse JSON logs automatically
  • CloudWatch: Supports JSON log parsing
  • ELK Stack: Elasticsearch can index JSON logs
  • Loki: Grafana Loki can parse JSON logs

Troubleshooting

Logs Not Appearing

  1. Check you're running the dev server:

    deno task dev
    

  2. Verify Supabase is running:

    supabase status
    

  3. Check environment variables:

    cat .env
    

  4. Look for startup errors: The dev server should show:

    ✅ Loaded environment variables from .env file
    🚀 Starting local browse server on http://localhost:8000
    📡 Supabase URL: http://127.0.0.1:54321
    

Logs Appearing but Not Formatted

If logs appear but aren't in JSON format, check: - The logger utility is imported correctly - The middleware is running (check that request IDs are being generated)

Testing Log Output

Make a test request and verify you see both request and response logs:

# In one terminal
deno task dev

# In another terminal
curl http://localhost:8000/api/v1/domains

You should see two JSON log lines: one for the request and one for the response.

Production Considerations

In production (Supabase Edge Functions), logs are automatically collected by Supabase and can be viewed via:

Supabase Dashboard: 1. Go to https://supabase.com/dashboard 2. Select your project 3. Navigate to Edge Functions > Logs 4. Select your function name (e.g., browse) 5. View logs with filtering and search capabilities

The structured JSON logs will be available in Supabase's logging dashboard. Logs include: - Function invocations - Request/response data - Platform events - Custom log messages (console.log, console.error, etc.)