or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

browser.mdchild-loggers.mdindex.mdlogger-configuration.mdlogger-methods.mdserializers.mdstreams.mdtransports.md

child-loggers.mddocs/

0

# Child Loggers

1

2

Create specialized logger instances that inherit parent settings while adding contextual bindings. Child loggers provide a way to add consistent metadata to related log messages without repeating the same data in every log call.

3

4

## Capabilities

5

6

### Child Logger Creation

7

8

Create a child logger that inherits parent configuration and adds specific bindings.

9

10

```typescript { .api }

11

/**

12

* Creates a child logger with additional bindings

13

* @param bindings - Key-value pairs to include in all child logger messages

14

* @param options - Optional child-specific configuration overrides

15

* @returns New logger instance that inherits parent settings

16

*/

17

child(bindings: Bindings, options?: ChildLoggerOptions): Logger;

18

19

type Bindings = Record<string, any>;

20

21

interface ChildLoggerOptions {

22

/** Override log level for this child */

23

level?: string;

24

25

/** Additional or override serializers */

26

serializers?: { [key: string]: SerializerFn };

27

28

/** Custom levels for this child */

29

customLevels?: { [level: string]: number };

30

31

/** Child-specific formatters */

32

formatters?: {

33

level?: (label: string, number: number) => object;

34

bindings?: (bindings: Bindings) => object;

35

log?: (object: object) => object;

36

};

37

38

/** Child-specific redaction rules */

39

redact?: string[] | RedactOptions;

40

41

/** Message prefix for this child */

42

msgPrefix?: string;

43

}

44

```

45

46

**Usage Examples:**

47

48

```javascript

49

const logger = pino();

50

51

// Simple child with user context

52

const userLogger = logger.child({ userId: 123, module: 'auth' });

53

userLogger.info('User logged in');

54

// Output: {"level":30,"time":...,"msg":"User logged in","userId":123,"module":"auth",...}

55

56

// Child with request context

57

const requestLogger = logger.child({

58

requestId: 'req-456',

59

method: 'POST',

60

path: '/api/users'

61

});

62

requestLogger.info('Processing request');

63

requestLogger.error({ error: 'ValidationError' }, 'Request validation failed');

64

65

// Child with options override

66

const debugLogger = logger.child(

67

{ component: 'database' },

68

{ level: 'debug' }

69

);

70

debugLogger.debug('Executing query');

71

```

72

73

### Nested Child Loggers

74

75

Create child loggers from other child loggers to build hierarchical context.

76

77

```typescript { .api }

78

// Child loggers can create their own child loggers

79

```

80

81

**Usage Examples:**

82

83

```javascript

84

const logger = pino();

85

86

// Parent child for request context

87

const requestLogger = logger.child({ requestId: 'req-789' });

88

89

// Child of child for specific operation

90

const dbLogger = requestLogger.child({ operation: 'user-lookup' });

91

const cacheLogger = requestLogger.child({ operation: 'cache-check' });

92

93

dbLogger.info('Querying user table');

94

cacheLogger.info('Cache miss');

95

96

// All include both requestId and operation in output

97

```

98

99

### Bindings Management

100

101

Retrieve and modify bindings on existing logger instances.

102

103

```typescript { .api }

104

/**

105

* Returns current logger bindings

106

* @returns Object containing all current bindings

107

*/

108

bindings(): Bindings;

109

110

/**

111

* Adds new bindings to existing logger

112

* Note: Does not overwrite existing bindings, may result in duplicate keys

113

* @param bindings - Additional key-value pairs to bind

114

*/

115

setBindings(bindings: Bindings): void;

116

```

117

118

**Usage Examples:**

119

120

```javascript

121

const logger = pino();

122

const child = logger.child({ userId: 123, module: 'auth' });

123

124

// Get current bindings

125

const currentBindings = child.bindings();

126

console.log(currentBindings); // { userId: 123, module: 'auth' }

127

128

// Add more bindings

129

child.setBindings({ sessionId: 'sess-456', ip: '192.168.1.100' });

130

131

child.info('Action performed');

132

// Output includes: userId, module, sessionId, ip

133

```

134

135

## Child Logger Inheritance

136

137

### Settings Inheritance

138

139

Child loggers inherit all configuration from their parent logger.

140

141

**Inherited Properties:**

142

- Log level (unless overridden)

143

- Serializers (merged with child-specific ones)

144

- Formatters (merged with child-specific ones)

145

- Transport configuration

146

- Redaction rules (merged with child-specific ones)

147

- Base properties

148

- Hooks

149

- All other configuration options

150

151

**Usage Examples:**

152

153

```javascript

154

const parentLogger = pino({

155

level: 'debug',

156

name: 'my-app',

157

serializers: {

158

user: (user) => ({ id: user.id, name: user.name })

159

}

160

});

161

162

// Child inherits debug level, name, and serializers

163

const child = parentLogger.child({ module: 'payments' });

164

165

child.debug('Processing payment'); // Will output (inherits debug level)

166

child.info({ user: userObject }, 'Payment completed'); // Uses inherited serializer

167

```

168

169

### Level Control

170

171

Child loggers can have independent log levels from their parents.

172

173

**Usage Examples:**

174

175

```javascript

176

const logger = pino({ level: 'info' });

177

178

// Child with more verbose logging

179

const debugChild = logger.child(

180

{ component: 'auth' },

181

{ level: 'debug' }

182

);

183

184

// Child with less verbose logging

185

const errorChild = logger.child(

186

{ component: 'external-api' },

187

{ level: 'error' }

188

);

189

190

logger.debug('Parent debug'); // Not logged (parent is 'info')

191

debugChild.debug('Child debug'); // Logged (child is 'debug')

192

errorChild.info('Child info'); // Not logged (child is 'error')

193

```

194

195

## Child Logger Callbacks

196

197

### On Child Creation

198

199

Hook into child logger creation for custom initialization.

200

201

```typescript { .api }

202

interface LoggerOptions {

203

/** Callback executed when child logger is created */

204

onChild?: OnChildCallback;

205

}

206

207

type OnChildCallback = (child: Logger) => void;

208

209

interface Logger {

210

/** Current callback for child creation */

211

onChild: OnChildCallback;

212

}

213

```

214

215

**Usage Examples:**

216

217

```javascript

218

const logger = pino({

219

onChild: (child) => {

220

// Add automatic tracking

221

child.setBindings({

222

childCreatedAt: new Date().toISOString(),

223

parentName: logger.bindings().name || 'root'

224

});

225

}

226

});

227

228

const child = logger.child({ userId: 123 });

229

// Automatically includes childCreatedAt and parentName

230

```

231

232

## Advanced Child Logger Patterns

233

234

### Request-Scoped Logging

235

236

Create child loggers for request tracking in web applications.

237

238

**Usage Examples:**

239

240

```javascript

241

// Express middleware example

242

app.use((req, res, next) => {

243

req.logger = logger.child({

244

requestId: generateRequestId(),

245

method: req.method,

246

path: req.path,

247

userAgent: req.get('User-Agent')

248

});

249

next();

250

});

251

252

// Use in route handlers

253

app.post('/users', (req, res) => {

254

req.logger.info('Creating new user');

255

256

// Service layer inherits request context

257

const serviceLogger = req.logger.child({ service: 'user-service' });

258

serviceLogger.debug('Validating user data');

259

260

// Database layer adds more context

261

const dbLogger = serviceLogger.child({ operation: 'user-insert' });

262

dbLogger.info('Inserting user record');

263

});

264

```

265

266

### Module-Based Logging

267

268

Organize logging by application modules using child loggers.

269

270

**Usage Examples:**

271

272

```javascript

273

// Application setup

274

const rootLogger = pino({ name: 'my-app' });

275

276

// Module loggers

277

const authLogger = rootLogger.child({ module: 'authentication' });

278

const dbLogger = rootLogger.child({ module: 'database' });

279

const apiLogger = rootLogger.child({ module: 'api' });

280

281

// Sub-module loggers

282

const userAuthLogger = authLogger.child({ submodule: 'user-auth' });

283

const sessionLogger = authLogger.child({ submodule: 'session' });

284

285

// Usage maintains hierarchy

286

userAuthLogger.info('User login attempt');

287

sessionLogger.info('Session created');

288

// Both include module: 'authentication' plus their submodule

289

```

290

291

### Error Context Preservation

292

293

Use child loggers to maintain error context through async operations.

294

295

**Usage Examples:**

296

297

```javascript

298

async function processOrder(orderId, logger = rootLogger) {

299

const orderLogger = logger.child({ orderId, operation: 'process-order' });

300

301

try {

302

orderLogger.info('Starting order processing');

303

304

// Each step maintains order context

305

await validateOrder(orderLogger);

306

await chargePayment(orderLogger);

307

await updateInventory(orderLogger);

308

309

orderLogger.info('Order processing completed');

310

} catch (error) {

311

orderLogger.error({ error }, 'Order processing failed');

312

throw error;

313

}

314

}

315

316

async function validateOrder(logger) {

317

const validationLogger = logger.child({ step: 'validation' });

318

validationLogger.debug('Validating order data');

319

// Any errors here include orderId, operation, and step context

320

}

321

```