Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions contributing/logging-conventions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
title: "Logging Conventions"
description: "How we write logs that are clear, consistent, and incident-ready"
---

## Rules

### Core rules

- Write for humans first (machines second).
- Always include context.
- Be explicit about what failed.
- Use consistent structure.
- Match log level to intent.
- Log once, at the right layer.
- Never log secrets or PII.
- Avoid logs that describe the obvious.
- Log outcomes, not intentions.
- Prefer facts over emotions.
- Make logs searchable.
- Use English and a neutral, professional tone.

<Note>Rule of thumb: If someone sees the log at 3 a.m., they should immediately know what happened, where, and why.</Note>

### Logging structure

Consistency makes logs searchable and parseable.

Check warning on line 27 in contributing/logging-conventions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (grounds) - vale-spellcheck

contributing/logging-conventions.mdx#L27

Did you really mean 'parseable'?

**Recommended pattern**

```
<action> <result> (key=value, key=value)
```

**Example**

```
Fetched player session successfully (playerId=9c1e..., durationMs=12)
```

### Always include context

Context turns noise into signal.

Include:

- IDs (`requestId`, `userId`, `orderId`, `correlationId`)
- Important parameters (never secrets)
- System state if relevant

**Good**

```
User authentication failed (userId=42, ip=192.168.1.10)
```

**Bad**

```
Authentication failed
```

### Be explicit about what failed

Avoid vague verbs like "error occurred".

**Good**

```
Failed to parse JWT token (reason=invalid_signature)
```

**Bad**

```
JWT error
```

### Match log level to intent

Misused log levels destroy signal.

| Level | When to use |
| --- | --- |
| TRACE | Very detailed internal flow (almost never in prod) |
| DEBUG | Useful for developers, disabled in prod |
| INFO | Expected, important lifecycle events |
| WARN | Unexpected but recoverable situations |
| ERROR | Failed operation, user impact possible |
| FATAL | App cannot continue |

### Log once, at the right layer

Do not log the same failure at every level of the stack.

**Rule**

- Log where you can add the most context.
- Lower layers should throw, higher layers should log.

### Never log secrets or PII

This includes:

- Passwords
- Tokens (JWT, API keys)
- Session cookies
- Personal data (unless legally approved)

## Quick checklist before committing

Ask yourself:

- Can I understand this without reading the code?
- Does it include enough context?
- Is the log level correct?
- Would this help during an incident?
- Is anything sensitive included?
3 changes: 2 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@
{
"tab": "Contributing",
"pages": [
"contributing/naming-conventions"
"contributing/naming-conventions",
"contributing/logging-conventions"
]
}
],
Expand Down