Skip to content
This repository was archived by the owner on Mar 11, 2026. It is now read-only.
This repository was archived by the owner on Mar 11, 2026. It is now read-only.

pino plugin please #875

Open
Open

Description

@naseemkullah

Describe the solution you'd like
an equivalent to the bunyan or winston plugins, but for https://github.com/pinojs/pino

Describe alternatives you've considered
manually configuring pino: https://github.com/pinojs/pino/blob/master/docs/help.md#stackdriver

Activity

  1. mcollina commented on Aug 13, 2020

    @mcollina

    I'm happy to assist/review.

  2. naseemkullah commented on Aug 13, 2020

    @naseemkullah
    Author

    Apart from the level to severity mapping, an important consideration to work with error reporting, the stack trace for errors should be in a specific field, according to an exchange with the Error Reporting team these are message, exception or stack_trace ... @mcollina please correct me if I am wrong but I believe we could configure a pino error serializer slightly different than the standard err serializer to output the error stack on the field expected by Google Cloud Error Reporting (exception or stack_trace are preferred, whereas as message should be saved for https://github.com/pinojs/pino/blob/master/docs/api.md#message-string, where we could put a stack trace in technically, but probably better to leverage the serializer).

    The field isn't customizable. Error Reporting will also accept "stack_trace" or "exception" as aliases for "message" (which leaves the "message" field available for a more human readable text).

  3. naseemkullah commented on Aug 14, 2020

    @naseemkullah
    Author

    @mcollina please correct me if I am wrong but I believe we could configure a pino error serializer slightly different than the standard err serializer to output the error stack on the field expected by Google Cloud Error Reporting (exception or stack_trace are preferred,

    Conversely, Google Cloud Error Reporting may wish to add err.stack to the aliases of stack trace fields, that way we can take full advantage of pino's error serializer as is.

  4. mcollina commented on Aug 14, 2020

    @mcollina

    @naseemkullah I think so, yes! See https://www.npmjs.com/package/@elastic/ecs-pino-format as an example for a custom config for a specific cloud provider.

  5. added
    type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.
    and removed
    🚨This issue needs some love.
    on Aug 18, 2020
  6. self-assigned this
    on Aug 18, 2020
  7. naseemkullah commented on Sep 10, 2020

    @naseemkullah
    Author

    @simonz130 In case this helps, this is our current config, which most if not all could be offloaded to the plugin. the fact that we add the @type prop to every severity>=ERROR log should probably be an option

    import {context, getSpan} from '@opentelemetry/api';
    import * as pino from 'pino';
    
    // Map Pino levels to Google Cloud Logging severity levels
    // https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#LogSeverity
    const levelToSeverity = {
      trace: 'DEBUG',
      debug: 'DEBUG',
      info: 'INFO',
      warn: 'WARNING',
      error: 'ERROR',
      fatal: 'CRITICAL',
    };
    
    export function initLogger(opts: {
      serviceName: string;
      level?: pino.Level;
      format?: 'text' | 'json';
      pinoLoggerOptions?: pino.LoggerOptions;
    }) {
      const {serviceName, level, format, pinoLoggerOptions} = opts;
    
      const prettyPrint =
        (format || process.env.LOG_FORMAT?.toLowerCase()) === 'text';
    
      return pino({
        ...{
          // https://cloud.google.com/error-reporting/docs/formatting-error-messages#json_representation
          base: {serviceContext: {service: serviceName}},
          formatters: {
            level(label) {
              const pinoLevel = label as pino.Level;
              // `@type` property tells Error Reporting to track even if there is no `stack_trace`
              const typeProp =
                label === 'error' || label === 'fatal'
                  ? {
                      '@type':
                        'type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent',
                    }
                  : {};
              return {
                level: pinoLevel,
                severity: levelToSeverity[pinoLevel],
                ...typeProp,
              };
            },
            log(object: object & {err?: Error}) {
              const stackTrace = object.err?.stack;
              const stackProp = stackTrace ? {stack_trace: stackTrace} : {};
              return {
                ...object,
                ...stackProp,
              };
            },
          },
          level: level || process.env.LOG_LEVEL?.toLowerCase() || 'info',
          messageKey: 'message',
          mixin: () => getSpan(context.active())?.context() ?? {},
          prettyPrint,
          timestamp: prettyPrint
            ? pino.stdTimeFunctions.isoTime
            : () => `,"eventTime":${Date.now() / 1000.0}`,
        },
        ...pinoLoggerOptions,
      });
    }
  8. added
    priority: p3Desirable enhancement or fix. May not be included in next release.
    on Nov 5, 2020
  9. teebot commented on Jan 17, 2021

    @teebot

    @naseemkullah thanks for opening this issue and providing the required config for ErrorReporting to work with pino!

  10. 1 remaining item

  11. removed their assignment
    on Mar 10, 2021
  12. Mistic92 commented on Apr 12, 2021

    @Mistic92

    Hi, how is work going on this plugin? We are using Cloud Run and struggling with using "normal" Pino with structured logs. Would be great if there was just a plugin

  13. gnarea commented on Apr 12, 2021

    @gnarea

    @Mistic92, did you try the library I mentioned in the previous comment?

  14. Mistic92 commented on Apr 12, 2021

    @Mistic92

    I missed it when browsing on mobile. Looks good but I don't see way to make it use httpRequest field for structured logging. Is it only for fix severity issue?

  15. guillenotfound commented on Apr 17, 2021

    @guillenotfound

    @Mistic92 I created https://github.com/guillenotfound/pino-gcp-logger and so far is working for logging & error reporting 👍

  16. Mistic92 commented on Apr 19, 2021

    @Mistic92

    @guillenotfound do you have plans for structured logging, trace and httprequest fields?

  17. yoitsro commented on Jul 8, 2021

    @yoitsro

    Hey! Any updates on this? 🙏 Is there anything we can do to push this forward?

  18. guillenotfound commented on Feb 20, 2022

    @guillenotfound

    @guillenotfound do you have plans for structured logging, trace and httprequest fields?

    Sorry for the late reply, point me to the docs and I'll investigate 👍

  19. removed their assignment
    on Jul 3, 2023
  20. jordanebelanger commented on Jul 11, 2023

    @jordanebelanger

    This is what I use on CloudRun, it does the job for me.

    function pinoLevelToStackdriverSeverity(level) {
      switch (level) {
        case 10 /* PINO_LEVELS.trace */:
        case 20 /* PINO_LEVELS.debug */:
          return "DEBUG" /* StackdriverSeverity.debug */;
        case 30 /* PINO_LEVELS.info */:
          return "INFO" /* StackdriverSeverity.info */;
        case 40 /* PINO_LEVELS.warn */:
          return "WARNING" /* StackdriverSeverity.warning */;
        case 50 /* PINO_LEVELS.error */:
          return "ERROR" /* StackdriverSeverity.error */;
        case 60 /* PINO_LEVELS.fatal */:
          return "CRITICAL" /* StackdriverSeverity.critical */;
        default:
          return "DEFAULT" /* StackdriverSeverity.default */;
      }
    }
    function truncateToDecimalPlace(value, decimalPlace) {
      return Math.trunc(value * Math.pow(10, decimalPlace)) / Math.pow(10, decimalPlace);
    }
    /** Logs Stackdriver structured JSON to stdout */
    const stackdriverLoggerOptions = {
      messageKey: "message",
      timestamp: false,
      base: undefined,
      formatters: {
        level(_label, number) {
          return {
            severity: pinoLevelToStackdriverSeverity(number),
          };
        },
        log(object) {
          // Setuping the Stackdriver httpRequest property on the log entry
          if (object.req != null) {
            object.httpRequest = {
              ...(object.httpRequest ?? {},
              {
                requestMethod: object.req.method,
                requestUrl: object.req.url,
                userAgent: object.req.headers["user-agent"],
                remoteIp: object.req.ips?.[0] ?? object.req.ip,
                protocol: object.req.protocol,
              }),
            };
          }
          if (object.res != null) {
            object.httpRequest = {
              ...(object.httpRequest ?? {},
              {
                requestMethod: object.res.request.method,
                requestUrl: object.res.request.url,
                status: object.res.statusCode,
                userAgent: object.res.request.headers["user-agent"],
                latency: `${truncateToDecimalPlace(object.res.getResponseTime() / 1000, 9)}s`,
                remoteIp: object.res.request.ips?.[0] ?? object.res.request.ip,
                protocol: object.res.request.protocol,
              }),
            };
          }
          return object;
        },
      },
      serializers: {
        // Nullifying the standard Fastify Request/Response serializer for better stackdriver support
        req() {
          return undefined;
        },
        res() {
          return undefined;
        },
        responseTime: function () {
          return undefined;
        },
      },
    };
    
    export default stackdriverLoggerOptions;
  21. bkw commented on Dec 18, 2024

    @bkw
  22. mbrevda commented on Dec 31, 2024

    @mbrevda

    @google-cloud/pino-logging-gcp-config is an interesting approach, but shouldn't that be a transport instead of taking over the ensure pino settings?

  23. dir commented on Dec 3, 2025

    @dir

    @mbrevda Yes, yes it should.

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

    api: loggingIssues related to the googleapis/nodejs-logging API.priority: p3Desirable enhancement or fix. May not be included in next release.type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions