Search code examples
google-cloud-platformwinstongoogle-cloud-logging

Custom labels coming in text payload


I am trying to use google-cloud/logging-winston Cloud Function.

I want to use prefix & labels but when I configure them based on the google-cloud/logging-winston documentation nothing works.

As it can be seen in the pic. Label is added to the textpayload and prefix is not used at all.

Any idea whats wrong and how to fix this...

/**
 * Responds to any HTTP request.
 *
 * @param {!express:Request} req HTTP request context.
 * @param {!express:Response} res HTTP response context.
 */
exports.helloWorld = (req, res) => {

  const winston = require('winston');

  // Imports the Google Cloud client library for Winston
  const {LoggingWinston} = require('@google-cloud/logging-winston');

  const loggingWinston = new LoggingWinston({ 
    serviceContext: {
      service: 'winston-test',
      version: '1'
    },
    prefix: 'DataInflow' 
  });

  // Create a Winston logger that streams to Stackdriver Logging
  // Logs will be written to: "projects/YOUR_PROJECT_ID/logs/winston_log"
  const logger = winston.createLogger({
    level: 'info',
    transports: [
      new winston.transports.Console(),
      // Add Stackdriver Logging
      loggingWinston,
    ],
  });

  // Writes some log entries
  //logger.debug('Testing labels', { labels: { module: 'Test Winston Logging' }});
  logger.error('Testing labels', { custom_metadata: 'yes', labels: { module: 'Test Winston Logging' }});

  let message = req.query.message || req.body.message || 'Hello World!';
  res.status(200).send(message);
};

enter image description here

Edit#1: If I specify the keyFilename=path-to-sa-json-file then it works.

  const loggingWinston = new LoggingWinston({ 
    serviceContext: {
      service: 'winston-test',
      version: '1'
    },
    prefix: 'DataInflow',
    keyFilename=path-to-sa-json-file.json
  });

But this is strange. Cloud Function & logging-winston library should use Application Default Credentials (ADC).

So if the service account I use with my CF has stackdriver write access then it should be fine.

Is my understanding wrong? Anyone having other insights...

Edit#2: Seems to be an issue with Cloud Functions on Nodejs 10. Its working quite fine with Nodejs 8 without specifying the keyFilename... quite strange...


Solution

  • Finally I managed to sort out the issue. All winston logs are stored in stackdriver under custom label so this was the issue in my case.

    With the below code I was able to log the error to stackdriver and also to error reporting.

    In error reporting I could find my errors under service -> winston-test and in stackdriver under All logs -> winston_log

     /**
     * Responds to any HTTP request.
     *
     * @param {!express:Request} req HTTP request context.
     * @param {!express:Response} res HTTP response context.
     */
    exports.helloWorld = (req, res) => {
    
      const winston = require('winston');
    
      // Imports the Google Cloud client library for Winston
      const {LoggingWinston} = require('@google-cloud/logging-winston');
    
      const metadata = {
        resource: {
          type: 'global',
          serviceContext: {
            service: 'winston-test',
            version: '1'
          },
          prefix: 'DataInflow' 
        }
      };
    
    
      const resource = {
        // This example targets the "global" resource for simplicity
        type: 'global',
      };
    
    
      const loggingWinston = new LoggingWinston({ resource: resource });
    
      // Create a Winston logger that streams to Stackdriver Logging
      // Logs will be written to: "projects/YOUR_PROJECT_ID/logs/winston_log"
      const logger = winston.createLogger({
        level: 'info',
        transports: [
          new winston.transports.Console(),
          // Add Stackdriver Logging
          loggingWinston,
        ],
      });
    
      // Writes some log entries
      //logger.debug('Testing labels', { labels: { module: 'Test Winston Logging' }});
      logger.error(Error('Testing labels'));
    
      let message = req.query.message || req.body.message || 'Hello World!';
      res.status(200).send(message);
    };