Logging Configuration
Configure application and container log collection.
Configuration
[logging]
level = "info"
format = "console"
[logging.file]
enabled = true
path = "~/.gordon/logs/gordon.log"
max_size = 100
max_backups = 3
max_age = 28
[logging.container_logs]
enabled = true
dir = "~/.gordon/logs/containers"
max_size = 100
max_backups = 3
max_age = 28
[logging.access_log]
enabled = false
format = "json"
output = "stdout"
exclude_health_checks = true
syslog_identifier = "gordon-access"
Options
General Logging
| Option |
Type |
Default |
Description |
level |
string |
"info" |
Log level: trace, debug, info, warn, error |
format |
string |
"console" |
Output format: console or json |
File Logging
| Option |
Type |
Default |
Description |
file.enabled |
bool |
false |
Enable file-based logging |
file.path |
string |
- |
Path to main log file |
file.max_size |
int |
100 |
Max file size in MB before rotation |
file.max_backups |
int |
3 |
Number of old files to keep |
file.max_age |
int |
28 |
Days to keep old files |
The Admin API and gordon logs read from the process log file. Keep
logging.file.enabled set to true if you need process log streaming.
Container Logs
| Option |
Type |
Default |
Description |
container_logs.enabled |
bool |
true |
Collect container stdout/stderr |
container_logs.dir |
string |
{data_dir}/logs/containers |
Directory for container logs |
container_logs.max_size |
int |
100 |
Max file size in MB |
container_logs.max_backups |
int |
3 |
Old files to keep |
container_logs.max_age |
int |
28 |
Days to keep files |
Access Log
| Option |
Type |
Default |
Description |
access_log.enabled |
bool |
false |
Enable a dedicated HTTP access log |
access_log.format |
string |
"json" |
Access log format: json, clf, combined |
access_log.output |
string |
"stdout" |
Output sink: stdout, file, journald |
access_log.file_path |
string |
- |
File path when output = "file" |
access_log.max_size |
int |
100 |
Max file size in MB for file output |
access_log.max_backups |
int |
3 |
Old files to keep for file output |
access_log.max_age |
int |
28 |
Days to keep file output |
access_log.exclude_health_checks |
bool |
true |
Skip health and readiness checks |
access_log.syslog_identifier |
string |
"gordon-access" |
Journald identifier |
Use the access log for reverse-proxy traffic analysis, CrowdSec/fail2ban ingestion, or request auditing without mixing entries into the main process log.
Log Levels
| Level |
Description |
trace |
Very detailed debugging |
debug |
Debug information |
info |
General information (default) |
warn |
Warnings |
error |
Errors only |
Log Directory Structure
~/.gordon/logs/
├── gordon.log # Main application logs
├── gordon.log.1 # Rotated log
├── gordon.log.2.gz # Compressed old log
└── containers/
├── app_mydomain_com.log # Container logs by domain
└── api_mydomain_com.log
Log Rotation
Gordon uses automatic log rotation:
- Size-based: Rotates when file exceeds
max_size MB
- Age-based: Removes files older than
max_age days
- Count-based: Keeps only
max_backups old files
- Compression: Old files are gzip compressed
Example with defaults:
- Log grows to 100MB → rotated to
gordon.log.1
- After 3 rotations → oldest is compressed
- Files older than 28 days → deleted
Examples
Development
[logging]
level = "debug"
format = "console"
[logging.file]
enabled = true
path = "./logs/gordon.log"
max_size = 10
max_backups = 2
max_age = 7
[logging.container_logs]
enabled = true
dir = "./logs/containers"
max_size = 10
max_backups = 2
max_age = 7
[logging.access_log]
enabled = true
format = "json"
output = "file"
file_path = "./logs/access.log"
exclude_health_checks = true
Production
[logging]
level = "info"
format = "json"
[logging.file]
enabled = true
path = "~/.gordon/logs/gordon.log"
max_size = 100
max_backups = 10
max_age = 90
[logging.container_logs]
enabled = true
dir = "~/.gordon/logs/containers"
max_size = 100
max_backups = 10
max_age = 90
Minimal (Console Only)
[logging]
level = "info"
format = "console"
[logging.file]
enabled = false
[logging.container_logs]
enabled = true
Viewing Logs
Gordon Logs
# Using gordon logs command
gordon logs -f # Follow logs
gordon logs -n 100 # Last 100 lines
# Direct file access
tail -f ~/.gordon/logs/gordon.log
# With journalctl (if using systemd)
journalctl --user -u gordon -f
Container Logs
# View container logs
tail -f ~/.gordon/logs/containers/app_mydomain_com.log
# All container logs
ls ~/.gordon/logs/containers/
2024-01-15T10:30:00Z INF container deployed domain=app.mydomain.com image=myapp:latest
2024-01-15T10:30:01Z INF proxy routing updated route=app.mydomain.com
{"level":"info","time":"2024-01-15T10:30:00Z","message":"container deployed","domain":"app.mydomain.com","image":"myapp:latest"}
{"level":"info","time":"2024-01-15T10:30:01Z","message":"proxy routing updated","route":"app.mydomain.com"}
Security
Log files are created with secure permissions:
- Directories:
0700 (owner only)
- Files:
0600 (owner only)
Sensitive values (passwords, tokens) are automatically redacted.
source
1# Logging Configuration
2
3Configure application and container log collection.
4
5## Configuration
6
7```toml
8[logging]
9level = "info"
10format = "console"
11
12[logging.file]
13enabled = true
14path = "~/.gordon/logs/gordon.log"
15max_size = 100
16max_backups = 3
17max_age = 28
18
19[logging.container_logs]
20enabled = true
21dir = "~/.gordon/logs/containers"
22max_size = 100
23max_backups = 3
24max_age = 28
25
26[logging.access_log]
27enabled = false
28format = "json"
29output = "stdout"
30exclude_health_checks = true
31syslog_identifier = "gordon-access"
32```
33
34## Options
35
36### General Logging
37
38| Option | Type | Default | Description |
39|--------|------|---------|-------------|
40| `level` | string | `"info"` | Log level: trace, debug, info, warn, error |
41| `format` | string | `"console"` | Output format: console or json |
42
43### File Logging
44
45| Option | Type | Default | Description |
46|--------|------|---------|-------------|
47| `file.enabled` | bool | `false` | Enable file-based logging |
48| `file.path` | string | - | Path to main log file |
49| `file.max_size` | int | `100` | Max file size in MB before rotation |
50| `file.max_backups` | int | `3` | Number of old files to keep |
51| `file.max_age` | int | `28` | Days to keep old files |
52
53The Admin API and `gordon logs` read from the process log file. Keep
54`logging.file.enabled` set to `true` if you need process log streaming.
55
56### Container Logs
57
58| Option | Type | Default | Description |
59|--------|------|---------|-------------|
60| `container_logs.enabled` | bool | `true` | Collect container stdout/stderr |
61| `container_logs.dir` | string | `{data_dir}/logs/containers` | Directory for container logs |
62| `container_logs.max_size` | int | `100` | Max file size in MB |
63| `container_logs.max_backups` | int | `3` | Old files to keep |
64| `container_logs.max_age` | int | `28` | Days to keep files |
65
66### Access Log
67
68| Option | Type | Default | Description |
69|--------|------|---------|-------------|
70| `access_log.enabled` | bool | `false` | Enable a dedicated HTTP access log |
71| `access_log.format` | string | `"json"` | Access log format: `json`, `clf`, `combined` |
72| `access_log.output` | string | `"stdout"` | Output sink: `stdout`, `file`, `journald` |
73| `access_log.file_path` | string | - | File path when `output = "file"` |
74| `access_log.max_size` | int | `100` | Max file size in MB for file output |
75| `access_log.max_backups` | int | `3` | Old files to keep for file output |
76| `access_log.max_age` | int | `28` | Days to keep file output |
77| `access_log.exclude_health_checks` | bool | `true` | Skip health and readiness checks |
78| `access_log.syslog_identifier` | string | `"gordon-access"` | Journald identifier |
79
80Use the access log for reverse-proxy traffic analysis, CrowdSec/fail2ban ingestion, or request auditing without mixing entries into the main process log.
81
82## Log Levels
83
84| Level | Description |
85|-------|-------------|
86| `trace` | Very detailed debugging |
87| `debug` | Debug information |
88| `info` | General information (default) |
89| `warn` | Warnings |
90| `error` | Errors only |
91
92## Log Directory Structure
93
94```
95~/.gordon/logs/
96├── gordon.log # Main application logs
97├── gordon.log.1 # Rotated log
98├── gordon.log.2.gz # Compressed old log
99└── containers/
100 ├── app_mydomain_com.log # Container logs by domain
101 └── api_mydomain_com.log
102```
103
104## Log Rotation
105
106Gordon uses automatic log rotation:
107
1081. **Size-based**: Rotates when file exceeds `max_size` MB
1092. **Age-based**: Removes files older than `max_age` days
1103. **Count-based**: Keeps only `max_backups` old files
1114. **Compression**: Old files are gzip compressed
112
113Example with defaults:
114- Log grows to 100MB → rotated to `gordon.log.1`
115- After 3 rotations → oldest is compressed
116- Files older than 28 days → deleted
117
118## Examples
119
120### Development
121
122```toml
123[logging]
124level = "debug"
125format = "console"
126
127[logging.file]
128enabled = true
129path = "./logs/gordon.log"
130max_size = 10
131max_backups = 2
132max_age = 7
133
134[logging.container_logs]
135enabled = true
136dir = "./logs/containers"
137max_size = 10
138max_backups = 2
139max_age = 7
140
141[logging.access_log]
142enabled = true
143format = "json"
144output = "file"
145file_path = "./logs/access.log"
146exclude_health_checks = true
147```
148
149### Production
150
151```toml
152[logging]
153level = "info"
154format = "json"
155
156[logging.file]
157enabled = true
158path = "~/.gordon/logs/gordon.log"
159max_size = 100
160max_backups = 10
161max_age = 90
162
163[logging.container_logs]
164enabled = true
165dir = "~/.gordon/logs/containers"
166max_size = 100
167max_backups = 10
168max_age = 90
169```
170
171### Minimal (Console Only)
172
173```toml
174[logging]
175level = "info"
176format = "console"
177
178[logging.file]
179enabled = false
180
181[logging.container_logs]
182enabled = true
183```
184
185## Viewing Logs
186
187### Gordon Logs
188
189```bash
190# Using gordon logs command
191gordon logs -f # Follow logs
192gordon logs -n 100 # Last 100 lines
193
194# Direct file access
195tail -f ~/.gordon/logs/gordon.log
196
197# With journalctl (if using systemd)
198journalctl --user -u gordon -f
199```
200
201### Container Logs
202
203```bash
204# View container logs
205tail -f ~/.gordon/logs/containers/app_mydomain_com.log
206
207# All container logs
208ls ~/.gordon/logs/containers/
209```
210
211## Log Format
212
213### Console Format
214
215```
2162024-01-15T10:30:00Z INF container deployed domain=app.mydomain.com image=myapp:latest
2172024-01-15T10:30:01Z INF proxy routing updated route=app.mydomain.com
218```
219
220### JSON Format
221
222```json
223{"level":"info","time":"2024-01-15T10:30:00Z","message":"container deployed","domain":"app.mydomain.com","image":"myapp:latest"}
224{"level":"info","time":"2024-01-15T10:30:01Z","message":"proxy routing updated","route":"app.mydomain.com"}
225```
226
227## Security
228
229Log files are created with secure permissions:
230- Directories: `0700` (owner only)
231- Files: `0600` (owner only)
232
233Sensitive values (passwords, tokens) are automatically redacted.
234
235## Related
236
237- [Configuration Overview](./index.md)
238- [CLI Commands](../cli/index.md)
239- [Troubleshooting](../reference/troubleshooting.md)