or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bound-loggers.mdconfiguration.mdcontext-management.mddevelopment-tools.mdexception-handling.mdindex.mdlogger-creation.mdoutput-loggers.mdprocessors.mdstdlib-integration.mdtesting.md

processors.mddocs/

0

# Log Processors

1

2

Extensible pipeline of functions that transform, filter, and format log events as they flow through the structlog system. Processors can add data, remove data, change formats, or perform side effects like writing to files or sending to external systems.

3

4

## Capabilities

5

6

### Timestamp Processors

7

8

Add timestamp information to log events with configurable formatting and timezone handling.

9

10

```python { .api }

11

class TimeStamper:

12

"""Add timestamp to event dictionary."""

13

14

def __init__(self, fmt=None, utc=True, key="timestamp"):

15

"""

16

Args:

17

fmt (str, optional): Timestamp format ("iso", datetime format string, or None for epoch)

18

utc (bool): Use UTC timezone (default: True)

19

key (str): Key name for timestamp in event dict (default: "timestamp")

20

"""

21

22

def __call__(self, logger, name, event_dict) -> EventDict: ...

23

24

class MaybeTimeStamper:

25

"""Add timestamp only if the timestamp key doesn't already exist."""

26

27

def __init__(self, fmt=None, utc=True, key="timestamp"):

28

"""

29

Args:

30

fmt (str, optional): Timestamp format

31

utc (bool): Use UTC timezone

32

key (str): Key name for timestamp

33

"""

34

35

def __call__(self, logger, name, event_dict) -> EventDict: ...

36

```

37

38

### Rendering Processors

39

40

Transform structured event dictionaries into formatted strings for output.

41

42

```python { .api }

43

class JSONRenderer:

44

"""Render event dictionary as JSON string."""

45

46

def __init__(self, serializer=json.dumps, **dumps_kw):

47

"""

48

Args:

49

serializer (callable): JSON serialization function (default: json.dumps)

50

**dumps_kw: Additional keyword arguments for serializer

51

"""

52

53

def __call__(self, logger, name, event_dict) -> str | bytes: ...

54

55

class KeyValueRenderer:

56

"""Render event dictionary as key=value pairs."""

57

58

def __init__(self, sort_keys=False, key_order=None, drop_missing=False, repr_native_str=True):

59

"""

60

Args:

61

sort_keys (bool): Sort keys alphabetically

62

key_order (list, optional): Specific key ordering

63

drop_missing (bool): Drop keys with None values

64

repr_native_str (bool): Use repr() for string values

65

"""

66

67

def __call__(self, logger, method_name, event_dict) -> str: ...

68

69

class LogfmtRenderer:

70

"""Render event dictionary in logfmt format."""

71

72

def __init__(self, sort_keys=False, key_order=None, drop_missing=False, bool_as_flag=True):

73

"""

74

Args:

75

sort_keys (bool): Sort keys alphabetically

76

key_order (list, optional): Specific key ordering

77

drop_missing (bool): Drop keys with None values

78

bool_as_flag (bool): Render True as flag, False as key=false

79

"""

80

81

def __call__(self, logger, method_name, event_dict) -> str: ...

82

```

83

84

### Text Processing Processors

85

86

Handle text encoding, decoding, and formatting operations.

87

88

```python { .api }

89

class UnicodeEncoder:

90

"""Encode unicode values in event dictionary."""

91

92

def __init__(self, encoding="utf-8", errors="backslashreplace"):

93

"""

94

Args:

95

encoding (str): Text encoding to use

96

errors (str): Error handling strategy

97

"""

98

99

def __call__(self, logger, name, event_dict) -> EventDict: ...

100

101

class UnicodeDecoder:

102

"""Decode byte string values in event dictionary."""

103

104

def __init__(self, encoding="utf-8", errors="replace"):

105

"""

106

Args:

107

encoding (str): Text encoding to use

108

errors (str): Error handling strategy for decode errors

109

"""

110

111

def __call__(self, logger, name, event_dict) -> EventDict: ...

112

```

113

114

### Exception Handling Processors

115

116

Process and format exception information in log events.

117

118

```python { .api }

119

class ExceptionRenderer:

120

"""Replace exc_info tuple with formatted exception string."""

121

122

def __init__(self, exception_formatter=_format_exception):

123

"""

124

Args:

125

exception_formatter (callable): Function to format exceptions

126

"""

127

128

def __call__(self, logger, name, event_dict) -> EventDict: ...

129

130

class ExceptionPrettyPrinter:

131

"""Pretty print exceptions and remove exc_info from event dict."""

132

133

def __init__(self, file=None, exception_formatter=_format_exception):

134

"""

135

Args:

136

file (file-like, optional): File to write exceptions to

137

exception_formatter (callable): Function to format exceptions

138

"""

139

140

def __call__(self, logger, name, event_dict) -> EventDict: ...

141

```

142

143

### Stack Information Processors

144

145

Add stack frame and call site information to log events.

146

147

```python { .api }

148

class StackInfoRenderer:

149

"""Add stack information to event dictionary."""

150

151

def __init__(self, additional_ignores=None):

152

"""

153

Args:

154

additional_ignores (list, optional): Additional modules to ignore in stack traces

155

"""

156

157

def __call__(self, logger, name, event_dict) -> EventDict: ...

158

159

class CallsiteParameterAdder:

160

"""Add call site parameters (filename, line number, etc.) to event dictionary."""

161

162

def __init__(self, parameters=CallsiteParameter.all_parameters, additional_ignores=None):

163

"""

164

Args:

165

parameters (list): List of CallsiteParameter enum values to include

166

additional_ignores (list, optional): Additional modules to ignore

167

"""

168

169

def __call__(self, logger, name, event_dict) -> EventDict: ...

170

171

class CallsiteParameter(Enum):

172

"""Enumeration of available call site parameters."""

173

PATHNAME = "pathname"

174

FILENAME = "filename"

175

MODULE = "module"

176

FUNC_NAME = "funcName"

177

LINENO = "lineno"

178

THREAD = "thread"

179

THREAD_NAME = "threadName"

180

PROCESS = "process"

181

PROCESS_NAME = "processName"

182

```

183

184

### Utility Processors

185

186

General-purpose processors for common transformations and operations.

187

188

```python { .api }

189

class EventRenamer:

190

"""Rename the event key to a different name."""

191

192

def __init__(self, to: str, replace_by=None):

193

"""

194

Args:

195

to (str): New name for the event key

196

replace_by (str, optional): Replace event value if key already exists

197

"""

198

199

def __call__(self, logger, name, event_dict) -> EventDict: ...

200

201

def add_log_level(logger, method_name, event_dict) -> EventDict:

202

"""

203

Add log level name to event dictionary.

204

205

Args:

206

logger: Logger instance

207

method_name (str): Logger method name

208

event_dict (dict): Event dictionary

209

210

Returns:

211

dict: Event dictionary with 'level' key added

212

"""

213

```

214

215

### Pre-built Processor Instances

216

217

Common processor instances ready for use in configuration.

218

219

```python { .api }

220

format_exc_info: ExceptionRenderer

221

"""Pre-configured ExceptionRenderer instance for formatting exceptions."""

222

223

dict_tracebacks: ExceptionRenderer

224

"""Pre-configured ExceptionRenderer instance for structured traceback dictionaries."""

225

```

226

227

## Usage Examples

228

229

### Basic Processor Chain

230

231

```python

232

import structlog

233

from structlog import processors

234

235

structlog.configure(

236

processors=[

237

processors.TimeStamper(fmt="iso"),

238

processors.add_log_level,

239

processors.JSONRenderer()

240

],

241

wrapper_class=structlog.BoundLogger,

242

)

243

244

logger = structlog.get_logger()

245

logger.info("Test message")

246

# Output: {"timestamp": "2023-10-01T12:00:00Z", "level": "info", "event": "Test message"}

247

```

248

249

### Custom Formatting Chain

250

251

```python

252

import structlog

253

from structlog import processors

254

255

structlog.configure(

256

processors=[

257

processors.TimeStamper(fmt="%Y-%m-%d %H:%M:%S", utc=False),

258

processors.add_log_level,

259

processors.KeyValueRenderer(sort_keys=True, key_order=["timestamp", "level", "event"])

260

],

261

wrapper_class=structlog.BoundLogger,

262

)

263

264

logger = structlog.get_logger()

265

logger.info("Test message", user_id=123)

266

# Output: timestamp='2023-10-01 12:00:00' level='info' event='Test message' user_id=123

267

```

268

269

### Exception Processing

270

271

```python

272

import structlog

273

from structlog import processors

274

275

structlog.configure(

276

processors=[

277

processors.TimeStamper(),

278

processors.ExceptionRenderer(),

279

processors.JSONRenderer()

280

],

281

wrapper_class=structlog.BoundLogger,

282

)

283

284

logger = structlog.get_logger()

285

286

try:

287

1 / 0

288

except ZeroDivisionError:

289

logger.exception("Division by zero occurred")

290

# Exception information will be formatted and included in JSON output

291

```

292

293

### Stack Information

294

295

```python

296

import structlog

297

from structlog import processors

298

299

structlog.configure(

300

processors=[

301

processors.CallsiteParameterAdder(

302

parameters=[

303

processors.CallsiteParameter.FILENAME,

304

processors.CallsiteParameter.LINENO,

305

processors.CallsiteParameter.FUNC_NAME

306

]

307

),

308

processors.JSONRenderer()

309

],

310

wrapper_class=structlog.BoundLogger,

311

)

312

313

logger = structlog.get_logger()

314

logger.info("Debug message")

315

# Output includes filename, line number, and function name

316

```

317

318

### Text Processing

319

320

```python

321

import structlog

322

from structlog import processors

323

324

structlog.configure(

325

processors=[

326

processors.UnicodeEncoder(encoding="utf-8"),

327

processors.KeyValueRenderer()

328

],

329

wrapper_class=structlog.BoundLogger,

330

)

331

332

logger = structlog.get_logger()

333

logger.info("Message with unicode", text="Hello 世界")

334

```

335

336

### Custom Processor

337

338

```python

339

import structlog

340

from structlog import processors

341

342

def add_hostname_processor(logger, method_name, event_dict):

343

"""Custom processor to add hostname to every log entry."""

344

import socket

345

event_dict["hostname"] = socket.gethostname()

346

return event_dict

347

348

structlog.configure(

349

processors=[

350

processors.TimeStamper(),

351

add_hostname_processor,

352

processors.JSONRenderer()

353

],

354

wrapper_class=structlog.BoundLogger,

355

)

356

357

logger = structlog.get_logger()

358

logger.info("Test message")

359

# Output includes hostname field

360

```

361

362

### Conditional Processing

363

364

```python

365

import structlog

366

from structlog import processors

367

368

def sensitive_data_filter(logger, method_name, event_dict):

369

"""Remove sensitive data from logs."""

370

sensitive_keys = ["password", "token", "secret"]

371

for key in sensitive_keys:

372

if key in event_dict:

373

event_dict[key] = "[REDACTED]"

374

return event_dict

375

376

structlog.configure(

377

processors=[

378

sensitive_data_filter,

379

processors.TimeStamper(),

380

processors.JSONRenderer()

381

],

382

wrapper_class=structlog.BoundLogger,

383

)

384

385

logger = structlog.get_logger()

386

logger.info("User login", username="alice", password="secret123")

387

# Output: password field will show "[REDACTED]"

388

```

389

390

### Processor with Configuration

391

392

```python

393

import structlog

394

from structlog import processors

395

396

# Configure timestamp processor

397

timestamper = processors.TimeStamper(

398

fmt="iso",

399

utc=True,

400

key="@timestamp" # Use custom key for timestamp

401

)

402

403

# Configure JSON renderer with custom options

404

json_renderer = processors.JSONRenderer(

405

sort_keys=True,

406

ensure_ascii=False,

407

separators=(',', ':')

408

)

409

410

structlog.configure(

411

processors=[

412

timestamper,

413

processors.add_log_level,

414

json_renderer

415

],

416

wrapper_class=structlog.BoundLogger,

417

)

418

```