Structured logging & error reporting in GCP for node.js

Usage no npm install needed!

<script type="module">
  import veloveStructuredLogger from 'https://cdn.skypack.dev/@velove/structured-logger';


Velove Structured Logger

Structured logging & error reporting in GCP for node.js

By default, log messages to stdout (console), but provides an opt-in option to forward logs to Cloud Logging and Error Reporting (GCP)

Severity levels

The different levels are inspired from the Syslog levels

  • EMERGENCY: Panic condition: like a system is down
  • ALERT: Error requiring immediate attention (potentially corrupted data)
  • CRITICAL: Hard issue, system is at risk
  • ERROR: program (unexpected) errors to be handled
  • NOTICE: Not errors, but may need some attention
  • INFO: Informational messages about the program behavior
  • DEBUG: Program debugging informations
  • VERBOSE: the highest level, usually for large objects


Some options can be injected to the exposed "getLogger" function. You can use those to define generic options for your logger, potentially opt-in to GCP Cloud Logging in production for instance.

// logger.ts
import { getLogger as getBaseLogger } from '@velove/structured-logger';

// You can define some flags in env parameters if needed
// And probably define that in a shared file
export const getLogger = (request?: FastifyRequest) =>
    // default to WARNING
    level: 'WARNING',
    // Default to false, you need to opt-in if you wish to enable Cloud Logging and Error Reporting
    useGoogleCloudAgent: process.env.NODE_ENV === 'production',
    loggerAgentOptions: {
      // Name to identify logs in GCP
      name: 'velove.my-application-name',
      // Can be any string, like a commit hash or something
      version: '1.0.0',
      // Careful with GDPR and other local legislations (default to false)
      logClientIp: false,
      // Those credentials are only needed if you wish to test logging to GCP outside of it (like from your local environment)
      options: {
        projectId: process.env.GCLOUD_PROJECT_ID,
        keyFilename: process.env.GCP_CREDENTIALS_FILE

/** Possible to use directly, but will not be enriched by the HTTP request context */
const requestUnawareLogger = getLogger();

export default requestUnawareLogger;

Within a Fastify server: inject the HTTP request to get an enriched log context

// app.ts
import { getLogger } from 'logger.ts';

app.get('/foo', (request) => {
  const logger = getLogger(request);
  const contextName = 'request.foo'; // up to you

  logger.debug('Hello World', { contextName }); // log with high-level "debug"
  logger.info('My name is Bond. James Bond.', { contextName }); // log with level "info"

  try {
  } catch (error) {
    logger.error(error, { contextName }); // log an Error object will also forward it to Error Reporting

Outside of Fastify, use it straight without the request

import logger from 'logger.ts';

export function myFunction() {
  const logger = logger.warn('"myFunction" is not not 100% reliable yet.', { contextName: 'functions.myFunction' });

  if (Math.random() > 0.9) {
    throw new Error('I did warn you though');