Skip to content

Structured log package in node core #49296

Description

@Raynos

What is the problem this feature will solve?

To have a structured log package available in stdlib so that all npm modules can log in a single fashion instead of

  • logging to console
  • not logging
  • Having some arbitrary logger interface
  • Emitting random log events
  • Worst case: they literally depend on Winston and it’s 200 transitive dependencies

What is the feature you are proposing to solve the problem?

Implement something like https://go.dev/blog/slog

What alternatives have you considered?

No response

Activity

  1. NextThread commented on Aug 29, 2023

    @NextThread

    Hi,
    Can I work on this

  2. MoLow commented on Aug 29, 2023

    @MoLow
    Member

    You can work on this, but I must give a disclaimer: this kind of feature will probably involve a lot of "soft" work in terms of achieving consensus both on its necessity and then on the implementation.
    if you are looking for a smooth entry to this project I would choose an issue with less complexity that also has a consensus about how it should be handled

  3. NextThread commented on Aug 29, 2023

    @NextThread

    You can work on this, but I must give a disclaimer: this kind of feature will probably involve a lot of "soft" work in terms of achieving consensus both on its necessity and then on the implementation.
    if you are looking for a smooth entry to this project I would choose an issue with less complexity that also has a consensus about how it should be handled

    yeah sure,
    please give me an issue with less complexity

  4. github-actions commented on Feb 26, 2024

    @github-actions
    Contributor

    There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment.

    For more information on how the project manages feature requests, please consult the feature request management document.

  5. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Feb 26, 2024
  6. github-actions commented on Mar 28, 2024

    @github-actions
    Contributor

    There has been no activity on this feature request and it is being closed. If you feel closing this issue is not the right thing to do, please leave a comment.

    For more information on how the project manages feature requests, please consult the feature request management document.

  7. debadree25 commented on Mar 29, 2024

    @debadree25
    Contributor
  8. H4ad commented on Mar 29, 2024

    @H4ad
    Member

    As soon I get some time, I will research how the other langs are handling logs, and I will try to bring some API suggestions on how we can introduce logging at Node.

    I think if we create a good abstraction for logging, we can then bring the pino implementation to have some default features, like structured logging, redact, and other features.

    /cc @mcollina to bring more ideas on this topic since you know a lot about logging & pino.

  9. Delapouite commented on Mar 29, 2024

    @Delapouite
    Contributor

    I will research how the other langs are handling logs

    Here's a 2023 article of the official Go blog about this : https://go.dev/blog/slog

  10. mcollina commented on Mar 29, 2024

    @mcollina
    SponsorMember

    I think we could bring 80% of the pino infrastructure down to core. pino is composed of:

    1. public api
    2. off thread logging processing (especially useful for network destinstions and heavy processing).
    3. main thread log redaction
    4. opinionated log format
    5. re-do of createWritableStream to maximize speed and handling of overflow situations (disk is busy, what do you want to do?)

    It'd need to loose some of the opinions and add some overhead to be more generic, but that can be balanced.

  11. 51 remaining items

  12. trentm commented on Oct 28, 2025

    @trentm
    Contributor

    I don't like info({ merging: 'object' }, 'message'), and I prefer info('message', { merging: 'object' }).

    I thought Raynos did a good job arguing for message first info('hi', {foo:'bar'}) over merging-object first above. The reason "merging-object first" exists is because I wanted to support varargs-style in Bunyan at the time, to be closer to console.log(). Since then, (a) JS grew string templates for those that really want a varying message and (b) personally I've come to prefer a static string key for the msg (as Raynos was arguing for).

  13. Qard commented on Oct 28, 2025

    @Qard
    Member

    Either of info({ merging: 'object' }, 'message') or info('message', { merging: 'object' }) will need to then merge the object and the message together somehow anyway, so it makes the most sense to me to just do info({ message: 'message', other: ... }).

  14. mcollina commented on Oct 28, 2025

    @mcollina
    SponsorMember

    We can safely support two arguments, ideally with the string first.

    We would need to have an internal data structure anyway:

    1. time (maybe this can actually be avoided, which would be best)
    2. level
    3. message
    4. merging

    So that you know, I recommend avoiding merging at the first step and delegating this to transports / formatters. We would lose some perf compared to pino, but it would allow for a clearer standardization.

  15. mertcanaltin commented on Oct 29, 2025

    @mertcanaltin
    Member

    hello, thanks again for details, I sended some commits in today, first look I try implemented string first and Two arguments : https://github.com/nodejs/node/pull/60468/files

    than, I try @Qard suggestion (#60468 (comment)): e149af2

    and first performance results:
    #60468 (comment)

  16. jsumners commented on Oct 29, 2025

    @jsumners
    Contributor

    I don't really follow what you're proposing. My understanding is that your proposal would only provide logging from within core itself.

    No, it would be the internals of the described public API.

    import { createLogger, JSONHandler } from 'node:log'

    // Construct a JSON output handler, attaching diagnostics_channel subscribers
    // to whichever levelled channels it cares about
    const handler = new JSONHandler({ level: ... })
    handler.capture()

    const logger = createLogger()

    logger.info({ msg: 'hello' }) // dispatches to a "log:info" diagnostics_channel internally

    I have been thinking about this and I'm unsure about the viability when thinking about destinations. There are a few people that want to stream to different destinations based upon log level, and this would certainly make that possible, but the typical case is streaming everything to a single destination with interleaved levels. Which leads to ordering: I'm not clear if the proposed approach would be able to guarantee ordering of logs. People really don't like it when Log Line B is written before Log Line A.

  17. mcollina commented on Oct 30, 2025

    @mcollina
    SponsorMember

    Yes it would allow supporting the ordering of logs.

    The question on using diagnostic_channels for this is how can we support a destination only receiving logs from a given logger.

    This might not be a use case we want to support. If we don't, having a createLogger() might be redundant.

  18. Qard commented on Oct 30, 2025

    @Qard
    Member

    If we give each logger a unique name, we could map to channels like log:info:grandparent:parent:child or something like that. Easy enough to support listening to specific loggers if that's a thing we want. We can also have a discovery channel like log:new to be notified any time a new logger is constructed to decide if the channel is worth subscribing to.

  19. github-actions commented on May 29, 2026

    @github-actions
    Contributor

    This issue has been marked as stale due to 210 days of inactivity.
    It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

  20. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on May 29, 2026
  21. jsumners commented on May 29, 2026

    @jsumners
    Contributor

    It is actively being worked on. This is not stale.

  22. mertcanaltin commented on May 29, 2026

    @mertcanaltin
    Member

    It is actively being worked on. This is not stale.

    +1, for follow #60468

  23. removed
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on May 30, 2026
  24. tobie commented on Jun 16, 2026

    @tobie
    Contributor

    Hi all, I'm a little late to the party here; apologies. I was wondering why closer integration with OpenTelemetry hadn't been explored further given how much the industry is converging towards it. This goes beyond the log event model and semantic field names, and ties into how logged events can be tied back to their relevant traces and spans. For instance, Deno's automatically tying logs back to spans if they occurred within one. I'm not suggesting this is the right mechanism for Node.js, just suggesting closer integration with OTel (even if through external libraries) might be worthwhile to explore.

  25. tobie commented on Sep 13, 2026

    @tobie
    Contributor

    FYI: there's a draft PR in the works at #65840

  26. jasnell commented on Sep 14, 2026

    @jasnell
    Member

    ... I was wondering why closer integration with OpenTelemetry hadn't been explored further...

    It has been really. In the prior PR it was discussed and there was a separate thread exploring OTel integration. I think it's far from settled.

    In my new attempt the goal is to separate the concerns. The provider-based model with synchronous delivery makes it fairly easy to integrate. I think we need to first settle, however, on the question of whether Otel support should be baked into core at all. Once we settle on that, figuring out the integration points with things like a structured logging API become easier to work through.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature requestIssues requesting new Node.js features.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions