Skip to main content

Logs

This guide explains how to view and manage PCH-SIG logs.

Log types

LogSourceContent
Backend SymfonyPHP-FPMPHP errors, API requests, authentication
Nginx FrontendNginxHTTP access, server errors
Nginx BackendNginxAPI requests, proxying
PostgreSQLPostgreSQLSQL queries, DB errors
RedisRedisCache operations
DockerContainersStartup, shutdown, errors

View Docker logs

Container logs

# Backend logs
docker logs pch_backend

# Last 100 lines
docker logs pch_backend --tail 100

# Follow logs in real-time
docker logs pch_backend -f

# Logs with timestamps
docker logs pch_backend --timestamps

All containers logs

# Via docker compose
cd deploy
docker compose logs

# Follow in real-time
docker compose logs -f

# Specific container
docker compose logs -f backend

Backend Symfony Logs

Location

Symfony logs are in /app/var/log/ of the container:

# List log files
docker exec pch_backend ls -la /app/var/log/

# Typical content
# dev.log - Development environment
# prod.log - Production environment

View logs

# Last lines of prod log
docker exec pch_backend tail -100 /app/var/log/prod.log

# Follow in real-time
docker exec pch_backend tail -f /app/var/log/prod.log

# Search for errors
docker exec pch_backend grep -i "error" /app/var/log/prod.log

Log levels

LevelDescription
DEBUGDetailed debug information
INFOInformational events
NOTICENormal but significant events
WARNINGWarnings
ERRORRuntime errors
CRITICALCritical errors
ALERTImmediate action required
EMERGENCYSystem unusable

Monolog configuration

File: backend/config/packages/monolog.yaml

monolog:
handlers:
main:
type: rotating_file
path: '%kernel.logs_dir%/%kernel.environment%.log'
level: info
max_files: 10

console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine"]

Nginx Logs

Frontend

# Access logs
docker exec pch_frontend cat /var/log/nginx/access.log

# Error logs
docker exec pch_frontend cat /var/log/nginx/error.log

# Follow in real-time
docker exec pch_frontend tail -f /var/log/nginx/access.log

Backend API

# API access logs
docker exec pch_nginx_backend cat /var/log/nginx/access.log

# Error logs
docker exec pch_nginx_backend tail -f /var/log/nginx/error.log

Nginx log format

192.168.1.100 - - [15/Jan/2024:10:30:45 +0000] "GET /api/menages HTTP/1.1" 200 1234 "-" "Mozilla/5.0..."
FieldDescription
IPClient address
DateDate and time
MethodGET, POST, etc.
URIRequested URL
StatusHTTP code (200, 404, 500...)
SizeResponse size
User-AgentClient browser

PostgreSQL Logs

View logs

# PostgreSQL logs
docker logs pch_postgres

# Last lines
docker logs pch_postgres --tail 50

Enable query logging

In postgresql.conf:

log_statement = 'all'           # none, ddl, mod, all
log_min_duration_statement = 0 # Log all queries
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d '

Analyze slow queries

# Queries over 1 second
docker logs pch_postgres 2>&1 | grep "duration:"

Redis Logs

# Redis logs
docker logs pch_redis

# Server info
docker exec pch_redis redis-cli -a redis_secure_2025 INFO

Centralization with Loki

PCH-SIG uses Loki to centralize logs.

Architecture

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│ Containers │────▶│ Promtail │────▶│ Loki │
│ Docker │ │ (collector) │ │ (storage) │
└─────────────────┘ └─────────────────┘ └────────┬────────┘


┌─────────────────┐
│ Grafana │
│ (visualization) │
└─────────────────┘

Access logs in Grafana

  1. Open Grafana: http://localhost:3001
  2. Go to Explore
  3. Select Loki datasource
  4. Use LogQL to search

LogQL queries

# Backend logs
{container="pch_backend"}

# Errors only
{container="pch_backend"} |= "error"

# Specific user logs
{container="pch_backend"} |= "admin@pch-sig.sn"

# Last hour logs with errors
{container="pch_backend"} |= "error" | json | level="ERROR"

Log rotation

Docker

By default, Docker limits log size. Configuration in docker-compose.yml:

services:
backend:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "5"

Symfony

Rotation is managed by Monolog (rotating_file handler):

main:
type: rotating_file
max_files: 10 # Keep last 10 files

Manual cleanup

# Clear container logs
docker exec pch_backend truncate -s 0 /app/var/log/prod.log

# Delete old logs
docker exec pch_backend find /app/var/log -name "*.log.*" -mtime +7 -delete

Basic grep

# Search for error
docker logs pch_backend 2>&1 | grep -i "error"

# Search for user
docker logs pch_backend 2>&1 | grep "admin@pch-sig.sn"

# Search for period
docker logs pch_backend 2>&1 | grep "2024-01-15"

With context

# 3 lines before and after
docker logs pch_backend 2>&1 | grep -B 3 -A 3 "Exception"

Count occurrences

# Number of errors by type
docker logs pch_backend 2>&1 | grep -o "Exception.*$" | sort | uniq -c | sort -rn

Log alerts

Monitoring script

# check-logs.ps1
$ErrorPatterns = @("ERROR", "CRITICAL", "Exception", "Fatal")
$Logs = docker logs pch_backend --since 1h 2>&1

foreach ($Pattern in $ErrorPatterns) {
$Matches = $Logs | Select-String -Pattern $Pattern
if ($Matches) {
Write-Host "ALERT: $($Matches.Count) occurrences of '$Pattern'" -ForegroundColor Red
$Matches | Select-Object -First 5
}
}

With Grafana

  1. Create a dashboard with logs
  2. Add an alert on error count
  3. Configure notifications (email, Slack, etc.)

Best practices

Structured logging

Use JSON for logs:

$this->logger->info('Household created', [
'menage_id' => $menage->getId(),
'user' => $user->getEmail(),
'ip' => $request->getClientIp()
]);

Do not log

  • Passwords (even hashed)
  • Authentication tokens
  • Full identity document numbers
  • Banking data

Retention

  • Error logs: 90 days minimum
  • Access logs: 30 days
  • Debug logs: 7 days

Next steps