|
1 |
| -# @sentry/pino-transport |
| 1 | +# Sentry Pino Transport |
2 | 2 |
|
3 |
| -[](https://www.npmjs.com/package/@sentry/pino-transport) |
4 |
| -[](https://www.npmjs.com/package/@sentry/pino-transport) |
5 |
| -[](https://www.npmjs.com/package/@sentry/pino-transport) |
| 3 | +A Pino transport for sending logs to Sentry using the Sentry JavaScript SDK. |
6 | 4 |
|
7 |
| -**This package is currently in alpha. Breaking changes may still occur.** |
8 |
| - |
9 |
| -A Pino transport for integrating [Pino](https://github.com/pinojs/pino) logging with [Sentry](https://sentry.io). This transport automatically captures log messages as Sentry events and breadcrumbs, making it easy to monitor your application's logs in Sentry. |
| 5 | +This transport forwards Pino logs to Sentry, allowing you to view and analyze your application logs alongside your errors and performance data in Sentry. |
10 | 6 |
|
11 | 7 | ## Installation
|
12 | 8 |
|
13 | 9 | ```bash
|
14 |
| -npm install @sentry/node @sentry/pino-transport |
| 10 | +npm install @sentry/pino-transport pino |
15 | 11 | # or
|
16 |
| -yarn add @sentry/node @sentry/pino-transport |
| 12 | +yarn add @sentry/pino-transport pino |
17 | 13 | ```
|
18 | 14 |
|
19 |
| -## Usage |
| 15 | +## Requirements |
20 | 16 |
|
21 |
| -TODO: Add usage instructions |
| 17 | +- Node.js 18+ |
| 18 | +- Pino v8 or v9 |
| 19 | +- `@sentry/node` SDK with `_experiments.enableLogs: true` |
22 | 20 |
|
23 |
| -## Requirements |
| 21 | +## Setup |
| 22 | + |
| 23 | +First, make sure Sentry is initialized with logging enabled: |
| 24 | + |
| 25 | +```javascript |
| 26 | +import * as Sentry from '@sentry/node'; |
| 27 | + |
| 28 | +Sentry.init({ |
| 29 | + dsn: 'YOUR_DSN', |
| 30 | + _experiments: { |
| 31 | + enableLogs: true, |
| 32 | + }, |
| 33 | +}); |
| 34 | +``` |
| 35 | + |
| 36 | +Then create a Pino logger with the Sentry transport: |
| 37 | + |
| 38 | +```javascript |
| 39 | +import pino from 'pino'; |
| 40 | + |
| 41 | +const logger = pino({ |
| 42 | + transport: { |
| 43 | + target: '@sentry/pino-transport', |
| 44 | + options: { |
| 45 | + // Optional: filter which log levels to send to Sentry |
| 46 | + levels: ['error', 'fatal'], // defaults to all levels |
| 47 | + }, |
| 48 | + }, |
| 49 | +}); |
| 50 | + |
| 51 | +// Now your logs will be sent to Sentry |
| 52 | +logger.info('This is an info message'); |
| 53 | +logger.error('This is an error message'); |
| 54 | +``` |
| 55 | + |
| 56 | +### Programmatic Usage |
| 57 | + |
| 58 | +You can also create the transport programmatically: |
| 59 | + |
| 60 | +```javascript |
| 61 | +import pino from 'pino'; |
| 62 | +import { createSentryPinoTransport } from '@sentry/pino-transport'; |
| 63 | + |
| 64 | +const transport = pino.transport({ |
| 65 | + targets: [ |
| 66 | + { |
| 67 | + target: 'pino-pretty', // Console output |
| 68 | + level: 'info', |
| 69 | + }, |
| 70 | + { |
| 71 | + target: createSentryPinoTransport, |
| 72 | + level: 'error', |
| 73 | + options: { |
| 74 | + levels: ['error', 'fatal'], // Only send errors and fatal logs to Sentry |
| 75 | + }, |
| 76 | + }, |
| 77 | + ], |
| 78 | +}); |
| 79 | + |
| 80 | +const logger = pino(transport); |
| 81 | +``` |
| 82 | + |
| 83 | +## Configuration Options |
| 84 | + |
| 85 | +The transport accepts the following options: |
| 86 | + |
| 87 | +### `levels` |
| 88 | + |
| 89 | +**Type:** `Array<'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal'>` |
| 90 | +**Default:** `['trace', 'debug', 'info', 'warn', 'error', 'fatal']` (all levels) |
| 91 | + |
| 92 | +Use this option to filter which log levels should be sent to Sentry. |
| 93 | + |
| 94 | +```javascript |
| 95 | +const transport = pino.transport({ |
| 96 | + target: '@sentry/pino-transport', |
| 97 | + options: { |
| 98 | + levels: ['warn', 'error', 'fatal'], // Only send warnings and above |
| 99 | + }, |
| 100 | +}); |
| 101 | +``` |
| 102 | + |
| 103 | +## Log Level Mapping |
| 104 | + |
| 105 | +Pino log levels are automatically mapped to Sentry log severity levels: |
| 106 | + |
| 107 | +| Pino Level | Pino Numeric | Sentry Level | |
| 108 | +| ---------- | ------------ | ------------ | |
| 109 | +| trace | 10 | trace | |
| 110 | +| debug | 20 | debug | |
| 111 | +| info | 30 | info | |
| 112 | +| warn | 40 | warn | |
| 113 | +| error | 50 | error | |
| 114 | +| fatal | 60 | fatal | |
| 115 | + |
| 116 | +### Custom Levels Support |
| 117 | + |
| 118 | +Custom numeric levels are mapped to Sentry levels using ranges, so levels like `11`, `23`, or `42` will map correctly: |
| 119 | + |
| 120 | +- `0-14` → `trace` |
| 121 | +- `15-24` → `debug` |
| 122 | +- `25-34` → `info` |
| 123 | +- `35-44` → `warn` |
| 124 | +- `45-54` → `error` |
| 125 | +- `55+` → `fatal` |
| 126 | + |
| 127 | +```javascript |
| 128 | +import pino from 'pino'; |
| 129 | + |
| 130 | +const logger = pino({ |
| 131 | + customLevels: { |
| 132 | + critical: 55, // Maps to 'fatal' (55+ range) |
| 133 | + notice: 35, // Maps to 'warn' (35-44 range) |
| 134 | + verbose: 11, // Maps to 'trace' (0-14 range) |
| 135 | + }, |
| 136 | + transport: { |
| 137 | + target: '@sentry/pino-transport', |
| 138 | + }, |
| 139 | +}); |
| 140 | + |
| 141 | +logger.critical('Critical issue occurred'); // → Sent as 'fatal' to Sentry |
| 142 | +logger.notice('Important notice'); // → Sent as 'warn' to Sentry |
| 143 | +logger.verbose('Detailed information'); // → Sent as 'trace' to Sentry |
| 144 | +``` |
| 145 | + |
| 146 | +#### Custom Level Attributes |
| 147 | + |
| 148 | +When using custom string levels, the original level name is preserved as `sentry.pino.level` attribute for better traceability: |
| 149 | + |
| 150 | +```javascript |
| 151 | +// Log entry in Sentry will include: |
| 152 | +// { |
| 153 | +// level: 'warn', // Mapped Sentry level |
| 154 | +// message: 'Audit event', |
| 155 | +// attributes: { |
| 156 | +// 'sentry.pino.level': 'audit', // Original custom level name |
| 157 | +// 'sentry.origin': 'auto.logging.pino', |
| 158 | +// // ... other log attributes |
| 159 | +// } |
| 160 | +// } |
| 161 | +``` |
| 162 | + |
| 163 | +### Custom Message Key |
| 164 | + |
| 165 | +The transport respects Pino's `messageKey` configuration: |
| 166 | + |
| 167 | +```javascript |
| 168 | +const logger = pino({ |
| 169 | + messageKey: 'message', // Use 'message' instead of default 'msg' |
| 170 | + transport: { |
| 171 | + target: '@sentry/pino-transport', |
| 172 | + }, |
| 173 | +}); |
| 174 | + |
| 175 | +logger.info({ message: 'Hello world' }); // Works correctly with custom messageKey |
| 176 | +``` |
| 177 | + |
| 178 | +### Nested Key Support |
| 179 | + |
| 180 | +The transport automatically supports Pino's `nestedKey` configuration, which is used to avoid property conflicts by nesting logged objects under a specific key. When `nestedKey` is configured, the transport flattens these nested properties using dot notation for better searchability in Sentry. |
| 181 | + |
| 182 | +```javascript |
| 183 | +const logger = pino({ |
| 184 | + nestedKey: 'payload', // Nest logged objects under 'payload' key |
| 185 | + transport: { |
| 186 | + target: '@sentry/pino-transport', |
| 187 | + }, |
| 188 | +}); |
| 189 | + |
| 190 | +const conflictingObject = { |
| 191 | + level: 'hi', // Conflicts with Pino's level |
| 192 | + time: 'never', // Conflicts with Pino's time |
| 193 | + foo: 'bar', |
| 194 | + userId: 123, |
| 195 | +}; |
| 196 | + |
| 197 | +logger.info(conflictingObject); |
| 198 | + |
| 199 | +// Without nestedKey, this would cause property conflicts |
| 200 | +// With nestedKey, Pino creates: { level: 30, time: 1234567890, payload: conflictingObject } |
| 201 | +// The transport flattens it to: |
| 202 | +// { |
| 203 | +// level: 'info', |
| 204 | +// message: undefined, |
| 205 | +// attributes: { |
| 206 | +// 'payload.level': 'hi', // Flattened nested properties |
| 207 | +// 'payload.time': 'never', |
| 208 | +// 'payload.foo': 'bar', |
| 209 | +// 'payload.userId': 123, |
| 210 | +// 'sentry.origin': 'auto.logging.pino', |
| 211 | +// } |
| 212 | +// } |
| 213 | +``` |
| 214 | + |
| 215 | +This flattening ensures that no property conflicts occur between logged objects and Pino's internal properties. |
| 216 | + |
| 217 | +## Usage Examples |
| 218 | + |
| 219 | +### Basic Logging |
| 220 | + |
| 221 | +```javascript |
| 222 | +import pino from 'pino'; |
| 223 | + |
| 224 | +const logger = pino({ |
| 225 | + transport: { |
| 226 | + target: '@sentry/pino-transport', |
| 227 | + }, |
| 228 | +}); |
| 229 | + |
| 230 | +logger.trace('Starting application'); |
| 231 | +logger.debug('Debug information', { userId: 123 }); |
| 232 | +logger.info('User logged in', { userId: 123, username: 'john_doe' }); |
| 233 | +logger.warn('Deprecated API used', { endpoint: '/old-api' }); |
| 234 | +logger.error('Database connection failed', { error: 'Connection timeout' }); |
| 235 | +logger.fatal('Application crashed', { reason: 'Out of memory' }); |
| 236 | +``` |
| 237 | + |
| 238 | +### Multiple Transports |
| 239 | + |
| 240 | +```javascript |
| 241 | +import pino from 'pino'; |
| 242 | + |
| 243 | +const logger = pino({ |
| 244 | + transport: { |
| 245 | + targets: [ |
| 246 | + { |
| 247 | + target: 'pino-pretty', |
| 248 | + options: { colorize: true }, |
| 249 | + level: 'debug', |
| 250 | + }, |
| 251 | + { |
| 252 | + target: '@sentry/pino-transport', |
| 253 | + options: { |
| 254 | + logLevels: ['warn', 'error', 'fatal'], |
| 255 | + }, |
| 256 | + level: 'warn', |
| 257 | + }, |
| 258 | + ], |
| 259 | + }, |
| 260 | +}); |
| 261 | +``` |
| 262 | + |
| 263 | +## Troubleshooting |
| 264 | + |
| 265 | +### Logs not appearing in Sentry |
| 266 | + |
| 267 | +1. Ensure `_experiments.enableLogs: true` is set in your Sentry configuration. |
| 268 | +2. Check that your DSN is correct and the SDK is properly initialized. |
| 269 | +3. Verify the log level is included in the `levels` configuration. |
| 270 | +4. Check your Sentry organization stats page to see if logs are being received by Sentry. |
| 271 | + |
| 272 | +## Related Documentation |
24 | 273 |
|
25 |
| -- Node.js 18 or higher |
26 |
| -- Pino 8.0.0 or higher |
27 |
| -- @sentry/node must be configured in your application |
| 274 | +- [Sentry Logs Documentation](https://docs.sentry.io/platforms/javascript/guides/node/logs/) |
| 275 | +- [Pino Documentation](https://getpino.io/) |
| 276 | +- [Pino Transports](https://getpino.io/#/docs/transports) |
28 | 277 |
|
29 | 278 | ## License
|
30 | 279 |
|
|
0 commit comments