Julien-R44 / pino-loki

🔉 This package provides a transport for pino that forwards messages to Loki.
MIT License
113 stars 18 forks source link

How to send debug/trace log level log to loki #29

Open SirMishaa opened 2 months ago

SirMishaa commented 2 months ago

Hello,

First, thank you for your package, it's working good !

I have just a small question, I'd to see log with level debug / trace, but I cannot see it on Grafana

image

Result is :

image

I guess I'm missing something in the configuration of pino or of the transport itself See the configuration for pino :

'use strict';

import pino from 'pino';
import config from 'config';
import * as Sentry from './sentry';

import pkg from '../../package';
import { LokiLogLevel, LokiOptions } from 'pino-loki';

const streams = [
  {
    level: config.logLevel || 'debug',
    stream: process.stdout,
  },
];

const hooks = {
  logMethod(inputArgs, method, level) {
    if (level >= 50) {
      const [__, details] = inputArgs;

      if (details && details?.err instanceof Error) {
        const error = details?.err;

        Sentry.captureException(error, {
          extra: error.metadata,
        });
      }
    }

    if (inputArgs.length >= 2) {
      const arg1 = inputArgs.shift();
      const arg2 = inputArgs.shift();
      return method.apply(this, [arg2, arg1, ...inputArgs]);
    }

    return method.apply(this, inputArgs);
  },
};

const transport = pino.transport<LokiOptions>({
  target: 'pino-loki',
  level: 'trace',
  levels: {
    trace: 10,
    debug: 20,
    info: 30,
    warn: 40,
    error: 50,
    fatal: 60,
  },
  options: {
    batching: true,
    interval: 5,
    levelMap: {
      10: LokiLogLevel.Debug,
      20: LokiLogLevel.Debug,
      30: LokiLogLevel.Info,
      40: LokiLogLevel.Warning,
      50: LokiLogLevel.Error,
      60: LokiLogLevel.Critical,
    },
    host: 'http://localhost:3100',
    basicAuth: null,
  },
});

let log = pino(
  {
    name: pkg.name,
    level: config.logLevel || 'debug',
    customLevels: {
      trace: 10,
      debug: 20,
      info: 30,
      warn: 40,
      error: 50,
      fatal: 60,
    },
    hooks,
  },
  pino.multistream([...streams, transport]),
);

export default log;

Best regards

SirMishaa commented 2 months ago

Note that I've tried without all customLevels and levels things, but result is the same, I don't get any logs below the info level

danikane commented 2 months ago

Here's my simple setup, hope it helps.

import 'dotenv/config';
import express from 'express';
import { pino, transport } from 'pino';

const APP_PORT = process.env.APP_PORT || 3333;
const LOKI_HOST = process.env.LOKI_HOST || 'http://localhost:3100';

const app = express();
app.set('name', 'pino-loki-example');

const environment = process.env.NODE_ENV || 'development';
const production = environment === 'production';

// const loadNs = process.hrtime()
// const loadMs = new Date().getTime()

// function nanoseconds() {
//   const diffNs = process.hrtime(loadNs)
//   return BigInt(loadMs) * BigInt(1e6) + BigInt(diffNs[0] * 1e9 + diffNs[1])
// }

const level = production ? 'info' : 'trace';
const multiTransport = transport({
  targets: [
    {
      target: 'pino-loki',
      level,
      options: {
        batching: false,
        host: LOKI_HOST,
        labels: {
          app: app.get('name'),
          stream: environment
        },
      },
    },
    {
      target: 'pino-pretty',
      level,
      options: {
        formatter: 'pretty',
        colorize: true,
        translateTime: 'SYS:standard',
      },
    },
  ]
})

const logger = pino(
  {
    level,
    // timestamp: () => `,"time":${nanoseconds()}`,
  },
  multiTransport
)

app.get('/', (req, res) => {
  logger.trace('Trace!')
  logger.debug('Debug!')
  logger.info('Info!')
  logger.warn('Warn!')
  logger.error('Error!')
  logger.fatal('Fatal!')
  res.send('Hello World!');
});

app.listen(APP_PORT, () => {
  console.log(`Server is running on port ${APP_PORT}`);
});

Result

Console: image Grafana: image

Note

Now, you might notice how the ordering in Grafana is messed up. 😄 The logs go up so fast that the timestamp is the same, no joke :) You might need nanoseconds on your entries, but keep in mind it will add some overhead. Uncomment the commented out code and you will get the correct order. For more reference: GitHub Issue