fix: logging for sentry - #36
Conversation
📝 WalkthroughWalkthroughWinston now conditionally forwards logs to Sentry through a Sentry transport. The runtime dependency is added, and the temporary non-production ChangesSentry logging integration
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/middleware/logger.ts`:
- Around line 43-46: Update the Sentry Winston transport setup around
SentryWinstonTransport so structured Winston log calls preserve their message
text and fields when passed to captureLog, avoiding [object Object] output.
Normalize the logger input before Sentry forwarding or adjust callers to use a
string message with metadata, and add a regression test covering logger.error
with msg and err fields.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: c33f0ea8-6675-47ab-98bc-5c8f9a10eb05
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (3)
package.jsonsrc/middleware/logger.tssrc/server.ts
💤 Files with no reviewable changes (1)
- src/server.ts
| if (Sentry.isEnabled()) { | ||
| const SentryWinstonTransport = Sentry.createSentryWinstonTransport(TransportStream); | ||
| sentryTransports.push(new SentryWinstonTransport()); | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
rg -nP '\blogger\.(debug|info|warn|error)\(\s*\{' --glob '*.ts' .Repository: Daniel88dev/flexi-day-be
Length of output: 531
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf 'Files matching logger/sentry/index/errorMiddleware:\n'
for f in src/middleware/logger.ts src/index.ts src/middleware/errorMiddleware.ts; do
if [ -f "$f" ]; then
echo "--- $f ($(wc -l < "$f") lines) ---"
sed -n '1,220p' "$f"
else
echo "missing $f"
fi
done
printf '\nPackage references:\n'
rg -n '"(`@sentry/winston-transport`|winston|`@sentry/node`)"' package.json package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null || trueRepository: Daniel88dev/flexi-day-be
Length of output: 7335
🌐 Web query:
Sentry Winston transport Winston log formats info message object-valued message
💡 Result:
When using Winston with Sentry, you can send object-valued messages or metadata by passing additional properties to your log calls. Winston transports receive an info object for every log message [1]. When this info object contains specific keys, Sentry transports can automatically map them to Sentry context [2][3]. If you are using a community-maintained Sentry transport (such as winston-transport-sentry-node), the following keys in your log metadata are automatically handled [2][3]: - info.tags: If provided as an object, these are sent as Sentry Tags [2][3]. - info.user: If provided as an object, these are sent as Sentry User context [2][3]. - Other properties: Any additional properties in the info object are sent as Sentry Extra Context [2][3]. Example usage: logger.error("User login failed", { user: { id: "123", username: "jdoe" }, tags: { environment: "production" }, attemptCount: 3 // This becomes Extra Context }); If you are using the official Sentry Node.js SDK's built-in Winston support (via Sentry.createSentryWinstonTransport), you should refer to the official Sentry documentation for the latest behavior, as the implementation may differ from community packages [4][5]. For complex log formatting or if you need to rename keys before they reach Sentry, you can use a custom Winston format function to transform the info object before it hits the Sentry transport [2][3][1]: const sentryFormat = winston.format(info => { // Transform or restructure the info object here return {...info, tags: {...info.tags, customTag: 'value' } }; }); new SentryTransport({ format: sentryFormat }); Always ensure your application completes its operations before terminating (e.g., avoiding immediate process.exit), as Sentry requires time to flush queued events to the server [6][7].
Citations:
- 1: https://github.com/winstonjs/winston/blob/master/README.md
- 2: https://github.com/aandrewww/winston-transport-sentry-node
- 3: https://www.npmjs.com/package/winston-transport-sentry-node
- 4: https://docs.sentry.io/platforms/javascript/guides/node/logs/
- 5: feat(node): Add support for winston logger getsentry/sentry-javascript#15983
- 6: https://app.unpkg.com/winston-transport-sentry-node%403.0.0/files/src/transport.ts
- 7: https://stackoverflow.com/questions/75467152/why-is-sentry-capturemessage-not-working-inside-winston-transport-log-function
🌐 Web query:
@Sentry Winston transport logger.error object message Winston transport message field
💡 Result:
In Winston, when you call logger.error with an Error object, the library treats the Error instance as part of the log's info object [1][2][3]. However, to correctly extract and display properties like the error message and stack trace, you must explicitly include the errors format in your logger configuration [2][4]. Without the errors format, simply passing an Error object to logger.error may result in the logger failing to render the object's properties (such as showing undefined for the message) or incorrectly handling the object's prototype [5][2]. Recommended Implementation: To properly handle Error objects, include winston.format.errors({ stack: true }) in your logger's format configuration [2][4]. const winston = require('winston'); const logger = winston.createLogger({ format: winston.format.combine( winston.format.errors({ stack: true }), // Essential for Error object handling winston.format.json), transports: [ new winston.transports.Console ] }); // Usage logger.error(new Error('Something went wrong')); Key Considerations: 1. Format Ordering: The errors format should typically be placed early in the winston.format.combine chain to ensure subsequent formatters (like json or printf) can access the normalized error properties [2][4]. 2. Message Concatenation: If you log a string followed by an Error object (e.g., logger.error('Context message', error)), Winston may concatenate the error message to the log message [1][3]. If this behavior is undesirable, you may need a custom formatter to strip or separate these fields [6]. 3. Custom Transports: In custom transports, the info object represents the processed log entry [1][7]. If you are writing a custom transport and find that error properties are missing, ensure that the errors format was applied at the logger level before the info reached your transport [8][7]. Inside a custom transport's log method, you can inspect the info object directly to access the error's stack and message properties, provided they were properly extracted by the format pipeline [7][9].
Citations:
- 1: https://github.com/winstonjs/winston?tab=readme-ov-file
- 2: https://stackoverflow.com/questions/51630896/winston-not-displaying-error-details
- 3: Better handling of
new Error(string)throughout the pipeline(s). Fixes #1338, #1486 winstonjs/winston#1562 - 4: Weird bug or inconsistency in Error object handling winstonjs/winston#1959
- 5: logger.error() should support single raw error object for custom formatting winstonjs/winston#1642
- 6: Error.message being appended to info.message winstonjs/winston#1660
- 7: https://stackoverflow.com/questions/74659468/how-to-add-custom-data-to-the-info-object-using-a-winston-custom-transport
- 8: https://github.com/winstonjs/winston/blob/HEAD/docs/transports.md
- 9: [3.0.0] Error object is not parsed or printed winstonjs/winston#1338
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf 'Files matching logger/sentry/index/errorMiddleware:\n'
for f in src/middleware/logger.ts src/index.ts src/middleware/errorMiddleware.ts; do
if [ -f "$f" ]; then
echo "--- $f ($(wc -l < "$f") lines) ---"
sed -n '1,220p' "$f"
else
echo "missing $f"
fi
done
printf '\nPackage references:\n'
for f in package.json package-lock.json yarn.lock pnpm-lock.yaml; do
if [ -f "$f" ]; then
echo "--- $f ---"
rg -n '"(`@sentry/winston-transport`|winston|`@sentry/node`)"|(`@sentry/winston-transport`|winston|`@sentry/node`)' "$f" || true
fi
doneRepository: Daniel88dev/flexi-day-be
Length of output: 8211
🌐 Web query:
@ Sentry Winston transport Winston logger.error object message message field object Valued message
💡 Result:
When using Winston with a Sentry transport, passing an object containing a 'message' field can result in the field being ignored or overwritten because Winston reserves the 'message' property for the primary log message [1][2]. To include a custom 'message' field from an object in your logs while ensuring it reaches Sentry, consider the following approaches: 1. Pass the object as a single argument: Instead of passing a string followed by an object (which may lead to property collision), pass the entire object as the sole argument to the logger method [3]. Winston treats the first argument as the log 'info' object [2]. Example: logger.error({ message: 'Primary log message', customField: 'someValue' }); 2. Use Winston's format.splat: If you must pass a string message and a metadata object, enabling the splat format allows you to use placeholders (like %j for JSON) to include objects in your log message without triggering property collision [1]. Example: // Setup format: winston.format.combine(winston.format.splat,...) // Logging logger.error('Log message with object: %j', { message: 'ignored_if_passed_as_meta' }); 3. Sentry Transport Behavior: Most Sentry transports for Winston (e.g., winston-transport-sentry-node) automatically extract specific properties from the 'info' object, such as 'tags', 'user', and 'extra' (for arbitrary data) [4][5]. If you want your custom fields to appear in Sentry, ensure they are not named 'message' or 'level', as those are reserved by Winston and used for Sentry's internal structure [4][2]. Any metadata property outside of the reserved fields is typically sent as Sentry 'Extra' context [4][5]. If your goal is to log an Error object specifically, passing it as the primary argument (e.g., logger.error(new Error('...'))) is often the best practice to ensure Sentry captures the stack trace correctly [6][5][3].
Citations:
- 1: Field 'message' from logged object ignored by Winston winstonjs/winston#1486
- 2: https://github.com/winstonjs/winston/blob/master/README.md
- 3: Errors are not grouped correctly aandrewww/winston-transport-sentry-node#31
- 4: https://github.com/aandrewww/winston-transport-sentry-node
- 5: https://www.npmjs.com/package/sentry-transport-winston
- 6: https://www.npmjs.com/package/winston-sentry-javascript-node
🌐 Web query:
Sentry Winston transport Winston metadata message object logger.error({ msg err })
💡 Result:
To correctly pass metadata and error objects to Sentry when using a Winston transport, you should follow the structure expected by your specific Sentry transport package (such as winston-transport-sentry-node or similar) [1][2][3]. While Winston supports passing a metadata object as the second argument to logger methods [4], how Sentry handles the error depends on whether an Error object is correctly identified by the transport. To ensure proper grouping and context: 1. Pass the Error object directly: Many Sentry transports for Winston are designed to capture the stack trace correctly only if an instance of Error is passed [5][6]. Avoid splitting the error into properties like { msg, err } if possible, as this may result in the transport losing the original stack trace [5]. 2. Use the expected metadata keys: Most Sentry transports automatically look for specific keys in the metadata object to populate Sentry event context [1][3]: - tags: An object used to categorize the event (e.g., { tags: { environment: 'production' } }) [1][6]. - user: An object containing user information (e.g., { user: { id: '123' } }) [1][3]. - fingerprint: An array to override Sentry's default grouping logic [3][6]. - Extra context: Any other properties in the metadata object are typically captured as 'extra' data in Sentry [1][3]. Recommended implementation: Instead of logger.error({ msg, err }), prefer passing the error as the primary argument or within an object that the transport explicitly recognizes as an error [5]: // Preferred: Pass Error directly logger.error('An error occurred', new Error('Something went wrong')); // Or if passing metadata, keep it structured: logger.error('An error occurred', { error: myErrorInstance, // Some transports specifically look for this tags: { module: 'auth' },...myExtraData }); If your Sentry issues are being grouped incorrectly (e.g., all appearing under the transport's internal file path), ensure you are passing a native JavaScript Error object rather than just an error message string or a plain object [5].
Citations:
- 1: https://github.com/aandrewww/winston-transport-sentry-node
- 2: https://www.npmjs.com/package/winston-sentry-javascript-node
- 3: https://www.npmjs.com/package/sentry-transport-winston
- 4: https://github.com/winstonjs/winston/blob/master/README.md
- 5: Errors are not grouped correctly aandrewww/winston-transport-sentry-node#31
- 6: https://github.com/walmor/sentry-transport-winston
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf 'Lockfile Sentry package block:\n'
sed -n '9690,9825p' package-lock.json
printf '\nSearch Sentry transport source in lockfile/artifacts (if present in repo):\n'
find . -path './node_modules' -prune -o \( -name \*.js -o -name \*.d.ts \) -print 2>/dev/null | xargs rg -n 'createSentryWinstonTransport|winston|SentryLogs|info.message|message' 2>/dev/null || true
printf '\nSearch any tests mentioning logger error object form or Sentry Winston:\n'
rg -n 'createSentryWinstonTransport|logger\.(error|warn)\(\s*\{|SentryLogs|winston-transport|msg: "' --glob '*.ts' --glob '*.test.ts' .Repository: Daniel88dev/flexi-day-be
Length of output: 11322
🌐 Web query:
getsentry sentry-javascript @sentry/node createSentryWinstonTransport info.message
💡 Result:
The createSentryWinstonTransport function is a utility introduced in Sentry JavaScript SDK version 9.13.0 that allows you to integrate the Winston logging library with Sentry [1][2][3]. It is specifically available for Node.js-based SDKs [1]. Usage: To use it, import the necessary modules, create the transport using the SDK's utility, and add it to your Winston logger instance [1][2][3]: const Sentry = require('@sentry/node'); const winston = require('winston'); const Transport = require('winston-transport'); const transport = Sentry.createSentryWinstonTransport(Transport); const logger = winston.createLogger({ transports: [transport], }); Regarding info.message: In Winston, the info object contains the log data, and the message property typically holds the primary log text [4][5]. When using the Sentry Winston transport, the SDK processes the Winston info object to forward the message to Sentry. Important considerations: 1. Compatibility: This integration is designed for Node.js environments and does not add winston as a direct dependency of the Sentry SDK [1][2]. 2. Custom Mapping: You can use the customLevelMap option in the second argument of createSentryWinstonTransport to map custom Winston levels to Sentry severity levels (e.g., fatal, error, warning, info, debug, trace) [6][7]. 3. Experimental Status: Note that logging APIs in the Sentry SDK are considered experimental and may be subject to change [3]. If you find that info.message is not behaving as expected (for example, if you are using formatters that modify the message), be aware that Winston often stores the final formatted message in a Symbol property (Symbol(message)) rather than the standard info.message property [4]. Ensure your Winston setup aligns with standard transport practices if you encounter issues with captured message content.
Citations:
- 1: Sentry Structured Logging for JavaScript (Browser/Node/Bun) getsentry/sentry-javascript#15916
- 2: feat(node): Add support for winston logger getsentry/sentry-javascript#15983
- 3: https://github.com/getsentry/sentry-javascript/releases/tag/9.13.0
- 4: Formatting doesn't work aandrewww/winston-transport-sentry-node#5
- 5: https://github.com/aandrewww/winston-transport-sentry-node
- 6: https://app.unpkg.com/@sentry/node-core@10.67.0/files/build/types/integrations/winston.d.ts
- 7: feat(winston): Add customLevelMap for winston transport getsentry/sentry-javascript#18922
🌐 Web query:
github @sentry/node createSentryWinstonTransport info.message Winston transport
💡 Result:
To integrate Winston with Sentry in a Node.js environment, the official Sentry Node SDK (beginning with version 9.13.0) provides a built-in createSentryWinstonTransport function [1][2]. This approach allows you to send logs directly from Winston to Sentry without requiring external community packages [1]. Usage The function accepts the Winston transport base class as an argument to avoid making Winston a direct dependency of the Sentry SDK [1]. Example Implementation: const winston = require('winston'); const Transport = require('winston-transport'); const Sentry = require('@sentry/node'); // Initialize the transport class const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport, { // Optional: customize level mapping levels: ['error', 'warn'], }); const logger = winston.createLogger({ transports: [new SentryWinstonTransport], }); Key Considerations * Custom Level Mapping: If you use custom log levels, you can configure the transport to map these to Sentry severity levels using the customLevelMap option (available in recent versions) [3]. * Alternative Packages: Before official support was added, the community relied on packages like winston-transport-sentry-node [4][5] or sentry-transport-winston [6]. These are third-party libraries and are distinct from the native functionality now included in the official SDK [1][2]. * Official Documentation: Sentry's logging integration is part of its structured logging support [2]. For the most up-to-date configuration options and features, refer to the official Sentry Node.js logs documentation [7].
Citations:
- 1: feat(node): Add support for winston logger getsentry/sentry-javascript#15983
- 2: https://github.com/getsentry/sentry-javascript/releases/tag/9.13.0
- 3: https://github.com/getsentry/sentry-javascript/pull/18922/files
- 4: https://www.npmjs.com/package/winston-transport-sentry-node
- 5: https://registry.npmjs.org/winston-transport-sentry-node
- 6: https://github.com/walmor/sentry-transport-winston
- 7: https://docs.sentry.io/platforms/javascript/guides/node/logs/
🌐 Web query:
@ sory sentry-javascript 10.68.0 createSentryWinstonTransport info.message code
💡 Result:
In the Sentry JavaScript SDK (version 10.68.0), the createSentryWinstonTransport function is used to create a Winston transport that forwards logs to Sentry [1][2]. It requires the Winston Transport class to be passed as an argument [1][3]. The function signature is: createSentryWinstonTransport(TransportClass, sentryWinstonOptions?) [1] Configuration Options: - levels: An optional array of strings used to filter which log levels are captured (e.g., ['error', 'warn']) [1][4]. - customLevelMap: A record mapping custom Winston levels to Sentry severity levels (e.g., { myCustomLevel: 'info' }) [1][5]. Usage Example: const winston = require('winston'); const Transport = require('winston-transport'); const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport, { levels: ['error', 'warn'], customLevelMap: { myCustomLevel: 'info', }, }); const logger = winston.createLogger({ transports: [new SentryWinstonTransport], }); Regarding message and code: - Logs captured via this transport are processed by the Sentry SDK's logging infrastructure [6]. - Message parameters: If a log entry is parameterized, Sentry automatically extracts message templates and parameters into attributes like message.template and message.parameter.X [6]. - Error codes: While there is no specific code attribute explicitly called out in the transport configuration, Sentry generally captures log attributes provided by Winston. If you include an error object or additional metadata in your Winston log calls, these are typically attached to the Sentry event context [6]. Ensure that the SDK is initialized with enableLogs: true for this functionality to work [4][3].
Citations:
- 1: https://app.unpkg.com/@sentry/node-core@10.67.0/files/build/types/integrations/winston.d.ts
- 2: feat(node): Add support for winston logger getsentry/sentry-javascript#15983
- 3: https://github.com/getsentry/sentry-javascript/releases/tag/9.13.0
- 4: https://docs.sentry.io/platforms/javascript/guides/nextjs/logs/
- 5: feat(winston): Add customLevelMap for winston transport getsentry/sentry-javascript#18922
- 6: https://docs.sentry.io/platforms/javascript/guides/node/logs/
🌐 Web query:
"info.message" "createSentryWinstonTransport" "10.68"
💡 Result:
The createSentryWinstonTransport function is a utility provided by the Sentry JavaScript SDK for Node.js environments that allows you to forward logs from the Winston logging library directly to Sentry [1][2][3]. As of Sentry SDK version 10.68.0, this function is used to create a custom Winston transport instance [2][4]. To use it, you must pass the Winston Transport class to it, and ensure that the Sentry SDK is initialized with enableLogs: true [1][2][5]. Example usage: const winston = require('winston'); const Transport = require('winston-transport'); // Create the Sentry transport using the utility const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport, { levels: ['error', 'warn'], // Optional: filter which levels to capture }); const logger = winston.createLogger({ transports: [new SentryWinstonTransport], }); Key implementation details include: - Environment Requirement: This utility is designed for Node.js environments and depends on Node.js APIs [6]. - SDK Requirement: You must enable logging in your Sentry configuration (enableLogs: true) for the transport to successfully forward logs [1][2][5]. - Configuration: It supports optional parameters such as levels (to filter specific log levels) and customLevelMap (to map custom Winston levels to Sentry severity levels) [2][7]. Note: This functionality was introduced in earlier versions of the Sentry JavaScript SDK (starting around v9.13.0) and remains active and documented in the latest releases, including 10.68.0 [4][5][6].
Citations:
- 1: https://docs.sentry.io/platforms/javascript/guides/node/logs/
- 2: https://app.unpkg.com/@sentry/node-core@10.67.0/files/build/types-ts3.8/integrations/winston.d.ts
- 3: feat(node): Add support for winston logger getsentry/sentry-javascript#15983
- 4: https://github.com/getsentry/sentry-javascript/releases/tag/10.68.0
- 5: https://docs.sentry.io/platforms/javascript/guides/nextjs/logs/
- 6: Sentry Structured Logging for JavaScript (Browser/Node/Bun) getsentry/sentry-javascript#15916
- 7: https://app.unpkg.com/@sentry/node-core@10.67.0/files/build/types/integrations/winston.d.ts
🌐 Web query:
unpkg @sentry/node-core 10.68.0 build integrations winston.js info.message
💡 Result:
In Sentry JavaScript SDK version 10.68.0, support for integrating the Winston logging library is provided directly through the SDK, typically accessed via Sentry.createSentryWinstonTransport [1]. While historical integrations existed as community-maintained packages (such as winston-transport-sentry-node) [2][3], modern Sentry SDKs (version 9.13.0+) include built-in support for structured logging with Winston [1]. To use this integration, you can utilize the createSentryWinstonTransport method from the Sentry package [1]. Example usage: const winston = require('winston'); const Sentry = require('@sentry/node'); // Ensure Sentry is initialized const Transport = require('winston-transport'); const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport); const logger = winston.createLogger({ transports: [new SentryWinstonTransport], }); When logging, the message (often accessed as info.message in Winston's transport stream) and associated metadata are processed by the Sentry transport and sent to your Sentry dashboard [4][1]. The SDK automatically handles the structured data, allowing for better searchability of log attributes and parameters [4][5]. The reference to winston.js within the @sentry/node-core package build path (e.g., /build/cjs/integrations/winston.js) reflects the internal implementation of this integration within the Sentry SDK [6].
Citations:
- 1: Sentry Structured Logging for JavaScript (Browser/Node/Bun) getsentry/sentry-javascript#15916
- 2: https://github.com/aandrewww/winston-transport-sentry-node
- 3: https://www.npmjs.com/package/winston-transport-sentry-node
- 4: https://docs.sentry.io/platforms/javascript/guides/node/logs/
- 5: https://docs.sentry.io/platforms/javascript/guides/node/logs.md
- 6: https://app.unpkg.com/@sentry/node-core@10.67.0/files/build/cjs/integrations/winston.js.map
🌐 Web query:
github get sen try se ntry-javascript 10.68.0 integrations winston
💡 Result:
Sentry integration with the Winston logging library is officially supported in the Sentry JavaScript SDK for Node.js environments [1][2]. As of Sentry JavaScript SDK version 9.13.0 and later, you can send logs from Winston to Sentry [1][2]. To use the integration, ensure enableLogs: true is set in your Sentry.init configuration [3][2]. You can then utilize Sentry.createSentryWinstonTransport to create a transport for your Winston logger [1][4]. Example implementation: import winston from "winston"; import Transport from "winston-transport"; import * as Sentry from "@sentry/node"; // or appropriate platform-specific package // Ensure enableLogs is true Sentry.init({ dsn: "https://@o.ingest.sentry.io/", enableLogs: true, }); const SentryTransport = Sentry.createSentryWinstonTransport(Transport, { levels: ["error", "warn"], // Optional: filter which levels to send }); const logger = winston.createLogger({ transports: [new SentryTransport], }); Note that the Sentry SDK internally maps Winston log levels to Sentry severity levels [5]. While this integration is part of the official Sentry JavaScript SDK, it is distinct from community-maintained packages such as winston-transport-sentry-node [6]. As of July 2026, the latest release in the getsentry/sentry-javascript repository is 10.68.0 [7].
Citations:
- 1: https://github.com/getsentry/sentry-javascript/releases/tag/9.13.0
- 2: https://docs.sentry.io/platforms/javascript/guides/nextjs/logs/
- 3: https://docs.sentry.io/platforms/javascript/guides/node/logs/
- 4: feat(node): Add support for winston logger getsentry/sentry-javascript#15983
- 5: Winston Sentry integration severity level getsentry/sentry-javascript#18021
- 6: https://github.com/aandrewww/winston-transport-sentry-node
- 7: https://github.com/getsentry/sentry-javascript/releases/tag/10.68.0
🌐 Web query:
"@sentry/node-core@10.68.0" "message" "Winston"
💡 Result:
In @sentry/node-core version 10.68.0, Sentry provides native support for Winston integration [1][2]. You can implement this by using the Sentry.createSentryWinstonTransport function [1][3]. ### Implementation To integrate Sentry with Winston, pass the Winston Transport class into Sentry.createSentryWinstonTransport to create a compatible transport instance [1][2]: javascript const winston = require('winston'); const Transport = require('winston-transport'); const Sentry = require('`@sentry/node`'); // Ensure Sentry is initialized before creating the transport Sentry.init({ dsn: "your-dsn-here", }); const transport = Sentry.createSentryWinstonTransport(Transport); const logger = winston.createLogger({ transports: [transport], }); ### Key Considerations * Native Support: Sentry added this built-in Winston support in version 9.13.0 to facilitate structured logging, avoiding the need for third-party transport packages [1][3][2]. * Experimental Status: As of recent releases, the Logging APIs in the Sentry SDK, including this integration, are considered experimental and may be subject to change [1][3]. * Alternative Approaches: While native support is the recommended path, community-maintained packages (such as winston-transport-sentry-node) have historically been used, though they are no longer necessary for basic Winston integration with current Sentry Node SDKs [4][5]. * Documentation: For further context on managing logs, breadcrumbs, and attributes within Sentry, refer to the official Sentry documentation for Node.js [6].
Citations:
- 1: https://github.com/getsentry/sentry-javascript/releases/tag/9.13.0
- 2: feat(node): Add support for winston logger getsentry/sentry-javascript#15983
- 3: https://newreleases.io/project/github/getsentry/sentry-javascript/release/9.13.0
- 4: https://github.com/aandrewww/winston-transport-sentry-node
- 5: https://www.npmjs.com/package/winston-transport-sentry-node
- 6: https://docs.sentry.io/platforms/javascript/guides/node/logs/
🌐 Web query:
github get sen try-ja va sc ript 10.68.0 packages node-core src integrations winston.ts
💡 Result:
In the Sentry JavaScript SDK (repository getsentry/sentry-javascript), the file located at packages/node-core/src/integrations/winston.ts contains the implementation for Sentry's integration with the Winston logging library [1][2][3]. This integration allows users to send logs from Winston to Sentry using the createSentryWinstonTransport function [4][5][6]. As of version 10.68.0, which was released on July 24, 2026, this integration continues to be part of the @sentry/node-core package [7][8]. Key details regarding this file and the Winston integration include: - Purpose: It enables structured logging by providing a transport that bridges Winston and Sentry [4][3]. - Recent Updates: The implementation includes support for a customLevelMap, which allows users to map custom Winston log levels to Sentry severity levels [2][9]. This was added to address issues where custom levels were not being correctly identified or mapped [1][9]. - Usage: Developers can use it by importing the transport and adding it to their Winston logger configuration [4][6]. const winston = require('winston'); const Transport = require('winston-transport'); const SentryTransport = Sentry.createSentryWinstonTransport(Transport, { // Optional: configuration such as customLevelMap }); const logger = winston.createLogger({ transports: [new SentryTransport], }); You can view the source code for this integration in the official repository under packages/node-core/src/integrations/winston.ts [2][10].
Citations:
- 1: Allow customization of level mapping in
createSentryWinstonTransportgetsentry/sentry-javascript#18868 - 2: getsentry/sentry-javascript@11f38a7
- 3: feat(node): Add support for winston logger getsentry/sentry-javascript#15983
- 4: https://github.com/getsentry/sentry-javascript/releases/tag/9.13.0
- 5: Sentry Structured Logging for JavaScript (Browser/Node/Bun) getsentry/sentry-javascript#15916
- 6: https://docs.sentry.io/platforms/javascript/guides/nextjs/logs/
- 7: https://github.com/getsentry/sentry-javascript/releases/tag/10.68.0
- 8: https://www.npmjs.com/package/@sentry/core
- 9: feat(winston): Add customLevelMap for winston transport getsentry/sentry-javascript#18922
- 10: getsentry/sentry-javascript@10.36.0...10.37.0
🌐 Web query:
github.get sentry-javascript 10.68.0 packages/node-core/src/integrations/winston.ts
💡 Result:
In the sentry-javascript repository, the file packages/node-core/src/integrations/winston.ts is a core component responsible for the Winston logging integration [1][2][3]. As of the 10.68.0 release (published July 24, 2026), this integration provides a transport mechanism that allows Winston logs to be captured by Sentry [4][3]. Key characteristics and recent history of this file include: Custom Level Mapping: The integration includes support for mapping Winston log levels to Sentry severity levels [1]. A feature was added (via customLevelMap) to allow users to map custom Winston levels to Sentry levels [2], addressing limitations where custom levels were not mapped correctly [2]. Internal Mapping: It utilizes an internal constant, WINSTON_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP, to handle default level conversions [1]. Maintenance and Updates: The file is actively maintained within the repository. Recent commits have involved internal refactoring, such as consolidating non-null-object checks [5], and ongoing improvements to instrumentation and integration stability [6]. For developers using this integration, it is initialized via the createSentryWinstonTransport function [1][3]. Example usage involves passing a transport instance to a Winston logger configuration [2][3]. The source code for this file is hosted in the official getsentry/sentry-javascript GitHub repository [7][1].
Citations:
- 1: Allow customization of level mapping in
createSentryWinstonTransportgetsentry/sentry-javascript#18868 - 2: getsentry/sentry-javascript@11f38a7
- 3: feat(node): Add support for winston logger getsentry/sentry-javascript#15983
- 4: https://github.com/getsentry/sentry-javascript/releases/tag/10.68.0
- 5: getsentry/sentry-javascript@88e3b32
- 6: https://newreleases.io/project/npm/@sentry/browser/release/10.68.0
- 7: https://github.com/getsentry/sentry-javascript?files=1
🌐 Web query:
GitHub API getsentry sentry-javascript 10.68.0 packages/node-core/src/integrations/winston.ts
💡 Result:
In the Sentry JavaScript SDK (getsentry/sentry-javascript), the file packages/node-core/src/integrations/winston.ts defines the integration for the Winston logging library [1][2][3]. Version 10.68.0 of the SDK was released on July 24, 2026 [4][5]. The Winston integration allows developers to send logs from a Winston logger to Sentry using the createSentryWinstonTransport function [3][6]. A significant recent feature added to this integration is the customLevelMap option, introduced in pull request #18922 (merged in January 2026) [2][7][6]. This option allows users to map custom Winston log levels to Sentry's severity levels [2][6], which is particularly useful for scenarios involving OpenTelemetry levels or non-standard logging levels [2][7]. Usage example for the Winston transport: const winston = require('winston'); const Transport = require('winston-transport'); // Using the transport with optional custom level mapping const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport, { customLevelMap: { customCritical: 'fatal', customNotice: 'info', }, }); const logger = winston.createLogger({ levels: { customCritical: 0, customNotice: 2 }, level: 'customNotice', transports: [new SentryWinstonTransport], });
Citations:
- 1: Allow customization of level mapping in
createSentryWinstonTransportgetsentry/sentry-javascript#18868 - 2: getsentry/sentry-javascript@11f38a7
- 3: feat(node): Add support for winston logger getsentry/sentry-javascript#15983
- 4: https://github.com/getsentry/sentry-javascript/releases/tag/10.68.0
- 5: https://newreleases.io/project/github/getsentry/sentry-javascript/release/10.68.0
- 6: feat(winston): Add customLevelMap for winston transport getsentry/sentry-javascript#18922
- 7: https://github.com/getsentry/sentry-javascript/pull/18922/files
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
from urllib.request import urlopen
for ref in ["10.68.0", "v10.68.0"]:
try:
url = f"https://raw.githubusercontent.com/getsentry/sentry-javascript/{ref}/packages/node-core/src/integrations/winston.ts"
data = urlopen(url, timeout=15).read().decode()
print(f"raw found {ref}")
for i,line in enumerate(data.splitlines(), 1):
if "message" in line or "Winston" in line or "severity" in line or "Winston" in line:
print(f"{i}: {line}")
break
except Exception as e:
print(f"ref {ref} failed: {e}")
PYRepository: Daniel88dev/flexi-day-be
Length of output: 471
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
import ssl
from urllib.request import urlopen
ctx = ssl._create_unverified_context() if hasattr(ssl, "_create_unverified_context") else ssl.create_default_context()
for ref in ["10.68.0", "v10.68.0"]:
try:
url = f"https://raw.githubusercontent.com/getsentry/sentry-javascript/{ref}/packages/node-core/src/integrations/winston.ts"
data = urlopen(url, timeout=20, context=ctx).read().decode()
print(f"RAW REF: {ref}")
total = data.count("\n") + 1
print(f"TOTAL_LINES: {total}")
for i,line in enumerate(data.splitlines(), 1):
if ("message" in line or "Winston" in line or "severity" in line or "LogEvent" in line):
print(f"{i:04d}: {line}")
break
except Exception as e:
print(f"REF {ref} FAILED: {type(e).__name__}: {e}")
PYRepository: Daniel88dev/flexi-day-be
Length of output: 1969
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
node - <<'JS'
const MESSAGE_SYMBOL = Symbol.for('message');
for (const input of [
{ message: { msg: "HTTP server error", err: new Error("boom") } },
{ level: "error", [MESSAGE_SYMBOL]: "{ msg: \"HTTP server error\", err }" },
]) {
const string = input.message != null ? String(input.message)
: (input[MESSAGE_SYMBOL] != null ? String(input[MESSAGE_SYMBOL])
: String(input));
console.log(JSON.stringify({ input, output: string }, null, 2));
}
JS
python3 - <<'PY'
print("Python equivalent:")
for input_ in [
{"message": {"msg": "HTTP server error", "err": "boom"}},
]:
string = str(input_["message"])
print((str(input_), string))
PYRepository: Daniel88dev/flexi-day-be
Length of output: 507
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf 'Relevant Sentry Winston transport source lines:\n'
python3 - <<'PY'
import ssl
from urllib.request import urlopen
ctx = ssl._create_unverified_context() if hasattr(ssl, "_create_unverified_context") else ssl.create_default_context()
url = "https://raw.githubusercontent.com/getsentry/sentry-javascript/10.68.0/packages/node-core/src/integrations/winston.ts"
lines = urlopen(url, timeout=20, context=ctx).readlines()
for i in range(84, loop_end := 122):
print(f"{i+1:04d}: {lines[i].decode().rstrip()}")
print("--- attribute extraction block ---")
for i in range(90, 116):
print(f"{i+1:04d}: {lines[i].decode().rstrip()}")
PY
printf '\nAll object-first logger calls with context:\n'
python3 - <<'PY'
import subprocess, pathlib, re
files = subprocess.check_output(["git","ls-files","*.ts"], text=True).splitlines()
for fp in files:
text = pathlib.Path(fp).read_text(errors="replace").splitlines()
for idx,line in enumerate(text, start=1):
if re.search(r"\blogger\.(debug|info|warn|error)\(\s*\{", line):
starts = idx-1
end = idx+1
block = "\n".join(f"{i+j:04d}: {line}" for j,line in enumerate(text[max(0,starts):min(len(text), end)]))
print(block)
print("---")
PYRepository: Daniel88dev/flexi-day-be
Length of output: 3554
Preserve Winston message fields before sending to Sentry.
logger.error({ msg, err }) leaves info.message as the msg object, and captureLog(..., message as string, ...) stringifies it as [object Object]; the structured fields end up as attributes instead. Normalize these calls before the Sentry transport, or switch callers to logger.error("msg", { err, ... }), and add a regression test.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/middleware/logger.ts` around lines 43 - 46, Update the Sentry Winston
transport setup around SentryWinstonTransport so structured Winston log calls
preserve their message text and fields when passed to captureLog, avoiding
[object Object] output. Normalize the logger input before Sentry forwarding or
adjust callers to use a string message with metadata, and add a regression test
covering logger.error with msg and err fields.
Source: MCP tools
Summary by CodeRabbit
New Features
Bug Fixes
Chores