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

output-loggers.mddocs/

0

# Output Loggers

1

2

Direct file output loggers that bypass standard logging infrastructure for high-performance logging scenarios and simple output requirements. These loggers write directly to files or streams without the overhead of Python's standard logging module.

3

4

## Capabilities

5

6

### Print Logger

7

8

Logger that prints messages to a file using Python's print() function.

9

10

```python { .api }

11

class PrintLogger:

12

"""

13

Logger that prints log messages to a file.

14

15

Uses Python's print() function to write log messages,

16

making it simple but potentially slower than WriteLogger.

17

"""

18

19

def __init__(self, file=None):

20

"""

21

Initialize PrintLogger.

22

23

Args:

24

file (file-like, optional): File object to print to.

25

Defaults to sys.stdout if None.

26

"""

27

28

def msg(self, message: str) -> None:

29

"""

30

Print a log message.

31

32

Args:

33

message (str): Message to print

34

"""

35

36

# Alias methods for different log levels

37

def log(self, message: str) -> None: ...

38

def debug(self, message: str) -> None: ...

39

def info(self, message: str) -> None: ...

40

def warn(self, message: str) -> None: ...

41

def warning(self, message: str) -> None: ...

42

def err(self, message: str) -> None: ...

43

def error(self, message: str) -> None: ...

44

def critical(self, message: str) -> None: ...

45

def fatal(self, message: str) -> None: ...

46

def failure(self, message: str) -> None: ...

47

def exception(self, message: str) -> None: ...

48

49

class PrintLoggerFactory:

50

"""Factory for creating PrintLogger instances."""

51

52

def __init__(self, file=None):

53

"""

54

Initialize PrintLoggerFactory.

55

56

Args:

57

file (file-like, optional): Default file for created loggers

58

"""

59

60

def __call__(self, *args) -> PrintLogger:

61

"""

62

Create a PrintLogger instance.

63

64

Args:

65

*args: Arguments (ignored)

66

67

Returns:

68

PrintLogger: New PrintLogger instance

69

"""

70

```

71

72

### Write Logger

73

74

Logger that writes messages to a file using direct write operations, offering better performance than PrintLogger.

75

76

```python { .api }

77

class WriteLogger:

78

"""

79

Logger that writes log messages directly to a file.

80

81

Uses direct write() calls followed by flush() for better

82

performance compared to PrintLogger.

83

"""

84

85

def __init__(self, file=None):

86

"""

87

Initialize WriteLogger.

88

89

Args:

90

file (file-like, optional): File object to write to.

91

Defaults to sys.stdout if None.

92

"""

93

94

def msg(self, message: str) -> None:

95

"""

96

Write a log message and flush.

97

98

Args:

99

message (str): Message to write

100

"""

101

102

# Alias methods for different log levels

103

def log(self, message: str) -> None: ...

104

def debug(self, message: str) -> None: ...

105

def info(self, message: str) -> None: ...

106

def warn(self, message: str) -> None: ...

107

def warning(self, message: str) -> None: ...

108

def err(self, message: str) -> None: ...

109

def error(self, message: str) -> None: ...

110

def critical(self, message: str) -> None: ...

111

def fatal(self, message: str) -> None: ...

112

def failure(self, message: str) -> None: ...

113

def exception(self, message: str) -> None: ...

114

115

class WriteLoggerFactory:

116

"""Factory for creating WriteLogger instances."""

117

118

def __init__(self, file=None):

119

"""

120

Initialize WriteLoggerFactory.

121

122

Args:

123

file (file-like, optional): Default file for created loggers

124

"""

125

126

def __call__(self, *args) -> WriteLogger:

127

"""

128

Create a WriteLogger instance.

129

130

Args:

131

*args: Arguments (ignored)

132

133

Returns:

134

WriteLogger: New WriteLogger instance

135

"""

136

```

137

138

### Bytes Logger

139

140

Logger that writes byte messages directly to a binary file or stream.

141

142

```python { .api }

143

class BytesLogger:

144

"""

145

Logger that writes log messages as bytes to a file.

146

147

Designed for binary output or when you need to control

148

the exact byte representation of log messages.

149

"""

150

151

def __init__(self, file=None):

152

"""

153

Initialize BytesLogger.

154

155

Args:

156

file (file-like, optional): Binary file object to write to.

157

Defaults to sys.stdout.buffer if None.

158

"""

159

160

def msg(self, message: bytes) -> None:

161

"""

162

Write a log message as bytes.

163

164

Args:

165

message (bytes): Message bytes to write

166

"""

167

168

# Alias methods for different log levels

169

def log(self, message: bytes) -> None: ...

170

def debug(self, message: bytes) -> None: ...

171

def info(self, message: bytes) -> None: ...

172

def warn(self, message: bytes) -> None: ...

173

def warning(self, message: bytes) -> None: ...

174

def err(self, message: bytes) -> None: ...

175

def error(self, message: bytes) -> None: ...

176

def critical(self, message: bytes) -> None: ...

177

def fatal(self, message: bytes) -> None: ...

178

def failure(self, message: bytes) -> None: ...

179

def exception(self, message: bytes) -> None: ...

180

181

class BytesLoggerFactory:

182

"""Factory for creating BytesLogger instances."""

183

184

def __init__(self, file=None):

185

"""

186

Initialize BytesLoggerFactory.

187

188

Args:

189

file (file-like, optional): Default binary file for created loggers

190

"""

191

192

def __call__(self, *args) -> BytesLogger:

193

"""

194

Create a BytesLogger instance.

195

196

Args:

197

*args: Arguments (ignored)

198

199

Returns:

200

BytesLogger: New BytesLogger instance

201

"""

202

```

203

204

## Usage Examples

205

206

### Basic PrintLogger Usage

207

208

```python

209

import structlog

210

from structlog import PrintLoggerFactory, processors

211

import sys

212

213

# Configure with PrintLogger

214

structlog.configure(

215

processors=[

216

processors.TimeStamper(fmt="iso"),

217

processors.JSONRenderer()

218

],

219

wrapper_class=structlog.BoundLogger,

220

logger_factory=PrintLoggerFactory(),

221

)

222

223

logger = structlog.get_logger()

224

logger.info("Application started", version="1.0.0")

225

# Prints JSON to stdout

226

```

227

228

### Writing to a File

229

230

```python

231

import structlog

232

from structlog import WriteLoggerFactory, processors

233

234

# Open log file

235

with open("application.log", "w") as log_file:

236

# Configure with file output

237

structlog.configure(

238

processors=[

239

processors.TimeStamper(),

240

processors.JSONRenderer()

241

],

242

wrapper_class=structlog.BoundLogger,

243

logger_factory=WriteLoggerFactory(file=log_file),

244

)

245

246

logger = structlog.get_logger()

247

logger.info("Starting application", pid=1234)

248

logger.info("Application ready", port=8080)

249

# Messages written directly to file

250

```

251

252

### High-Performance Logging

253

254

```python

255

import structlog

256

from structlog import WriteLoggerFactory, processors

257

import sys

258

259

# Configure for high-performance output

260

structlog.configure(

261

processors=[

262

processors.JSONRenderer() # Minimal processing

263

],

264

wrapper_class=structlog.BoundLogger,

265

logger_factory=WriteLoggerFactory(file=sys.stdout),

266

cache_logger_on_first_use=True, # Cache for performance

267

)

268

269

logger = structlog.get_logger()

270

271

# Fast logging in tight loops

272

for i in range(1000):

273

logger.info("Processing item", item_id=i, batch="A")

274

```

275

276

### Bytes Logger Usage

277

278

```python

279

import structlog

280

from structlog import BytesLoggerFactory, processors

281

import sys

282

283

def bytes_json_renderer(logger, name, event_dict):

284

"""Custom processor that returns bytes."""

285

import json

286

json_str = json.dumps(event_dict)

287

return json_str.encode('utf-8') + b'\n'

288

289

# Configure with BytesLogger

290

structlog.configure(

291

processors=[

292

processors.TimeStamper(),

293

bytes_json_renderer

294

],

295

wrapper_class=structlog.BoundLogger,

296

logger_factory=BytesLoggerFactory(),

297

)

298

299

logger = structlog.get_logger()

300

logger.info("Binary logging", data="test")

301

# Outputs bytes to stdout.buffer

302

```

303

304

### Multiple Output Destinations

305

306

```python

307

import structlog

308

from structlog import WriteLoggerFactory, processors

309

import sys

310

311

class MultiFileLogger:

312

"""Custom logger that writes to multiple files."""

313

314

def __init__(self, files):

315

self.files = files

316

317

def msg(self, message):

318

for file in self.files:

319

file.write(message + '\n')

320

file.flush()

321

322

# Add alias methods

323

def info(self, message): return self.msg(message)

324

def error(self, message): return self.msg(message)

325

def warning(self, message): return self.msg(message)

326

327

class MultiFileLoggerFactory:

328

def __init__(self, files):

329

self.files = files

330

331

def __call__(self, *args):

332

return MultiFileLogger(self.files)

333

334

# Open multiple output files

335

with open("app.log", "w") as app_log, \

336

open("audit.log", "w") as audit_log:

337

338

structlog.configure(

339

processors=[

340

processors.TimeStamper(),

341

processors.JSONRenderer()

342

],

343

wrapper_class=structlog.BoundLogger,

344

logger_factory=MultiFileLoggerFactory([app_log, audit_log, sys.stdout]),

345

)

346

347

logger = structlog.get_logger()

348

logger.info("Message goes to all three destinations")

349

```

350

351

### Error Stream Logging

352

353

```python

354

import structlog

355

from structlog import WriteLoggerFactory, processors

356

import sys

357

358

# Configure to write errors to stderr

359

structlog.configure(

360

processors=[

361

processors.TimeStamper(),

362

processors.add_log_level,

363

processors.JSONRenderer()

364

],

365

wrapper_class=structlog.BoundLogger,

366

logger_factory=WriteLoggerFactory(file=sys.stderr),

367

)

368

369

logger = structlog.get_logger()

370

logger.error("Application error", error_code="E001", component="database")

371

# Error written to stderr

372

```

373

374

### Log Rotation with Output Loggers

375

376

```python

377

import structlog

378

from structlog import WriteLoggerFactory, processors

379

import os

380

from datetime import datetime

381

382

class RotatingFileLogger:

383

"""Logger that rotates files based on size or time."""

384

385

def __init__(self, base_filename, max_bytes=1024*1024):

386

self.base_filename = base_filename

387

self.max_bytes = max_bytes

388

self.current_file = None

389

self.bytes_written = 0

390

self._open_new_file()

391

392

def _open_new_file(self):

393

if self.current_file:

394

self.current_file.close()

395

396

timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")

397

filename = f"{self.base_filename}.{timestamp}"

398

self.current_file = open(filename, "w")

399

self.bytes_written = 0

400

401

def msg(self, message):

402

message_bytes = len(message.encode('utf-8'))

403

404

if self.bytes_written + message_bytes > self.max_bytes:

405

self._open_new_file()

406

407

self.current_file.write(message + '\n')

408

self.current_file.flush()

409

self.bytes_written += message_bytes + 1

410

411

def info(self, message): return self.msg(message)

412

def error(self, message): return self.msg(message)

413

414

class RotatingLoggerFactory:

415

def __init__(self, base_filename, max_bytes=1024*1024):

416

self.logger = RotatingFileLogger(base_filename, max_bytes)

417

418

def __call__(self, *args):

419

return self.logger

420

421

# Configure with rotating logger

422

structlog.configure(

423

processors=[

424

processors.TimeStamper(),

425

processors.JSONRenderer()

426

],

427

wrapper_class=structlog.BoundLogger,

428

logger_factory=RotatingLoggerFactory("app.log", max_bytes=1024),

429

)

430

431

logger = structlog.get_logger()

432

for i in range(100):

433

logger.info("Log message", iteration=i, data="x" * 50)

434

# Creates multiple rotated log files

435

```

436

437

### Buffered Output Logger

438

439

```python

440

import structlog

441

from structlog import processors

442

import sys

443

import threading

444

import time

445

446

class BufferedLogger:

447

"""Logger that buffers messages and flushes periodically."""

448

449

def __init__(self, file=None, buffer_size=100, flush_interval=5.0):

450

self.file = file or sys.stdout

451

self.buffer = []

452

self.buffer_size = buffer_size

453

self.flush_interval = flush_interval

454

self.lock = threading.Lock()

455

self.last_flush = time.time()

456

457

def msg(self, message):

458

with self.lock:

459

self.buffer.append(message)

460

461

# Flush if buffer is full or enough time has passed

462

now = time.time()

463

if (len(self.buffer) >= self.buffer_size or

464

now - self.last_flush >= self.flush_interval):

465

self._flush()

466

467

def _flush(self):

468

if self.buffer:

469

for message in self.buffer:

470

self.file.write(message + '\n')

471

self.file.flush()

472

self.buffer.clear()

473

self.last_flush = time.time()

474

475

def info(self, message): return self.msg(message)

476

def error(self, message): return self.msg(message)

477

478

class BufferedLoggerFactory:

479

def __init__(self, **kwargs):

480

self.logger = BufferedLogger(**kwargs)

481

482

def __call__(self, *args):

483

return self.logger

484

485

# Configure with buffered logger

486

structlog.configure(

487

processors=[

488

processors.TimeStamper(),

489

processors.JSONRenderer()

490

],

491

wrapper_class=structlog.BoundLogger,

492

logger_factory=BufferedLoggerFactory(buffer_size=10, flush_interval=2.0),

493

)

494

495

logger = structlog.get_logger()

496

for i in range(5):

497

logger.info("Buffered message", count=i)

498

time.sleep(0.5)

499

# Messages are buffered and flushed together

500

```