Skip to content

Latest commit

 

History

History
157 lines (135 loc) · 4.07 KB

README.md

File metadata and controls

157 lines (135 loc) · 4.07 KB

Moleculer logo

NPM version NPM Downloads

Moleculer logger for ClickHouse

This is a fork from native Datadog logger

Description

Easy to save logs to ClickHouse with moleculer

Install

$ npm install @1xtr/moleculer-ch-logger --save

Usage

const ClickHouseLogger = require('@1xtr/moleculer-ch-logger')

module.exports = {
    logger: new ClickHouseLogger({
      // put here your options
    })
}

Default options

const defaultOptions = {
  url: 'http://localhost',
  port: 8123,
  dbName: 'default',
  dbUser: 'default',
  dbPassword: '',
  dbTableName: 'logs',
  // use source like TAG
  source: process.env.MOL_NODE_NAME || 'moleculer',
  hostname: hostname(),
  objectPrinter: null,
  interval: 10 * 1000,
  timeZone: 'Europe/Istanbul',
  tableTTL: 'date + INTERVAL 1 DAY RECOMPRESS CODEC(ZSTD(3))',
  useBuffer: false,
}

Log table

const body = `CREATE TABLE IF NOT EXISTS ${this.opts.dbTableName} (
          timestamp DateTime64(3, '${this.opts.timeZone}') DEFAULT now(),
          requestID String,
          subdomain String,
          caller String,
          level String,
          message String,
          nodeID String,
          namespace String,
          service String,
          version String,
          source String,
          hostname String,
          date Date DEFAULT today())
      ENGINE = MergeTree()
      ORDER BY (toStartOfHour(timestamp), service, level, subdomain, requestID, timestamp)
      PRIMARY KEY (toStartOfHour(timestamp), service, level, subdomain, requestID)
      PARTITION BY (date, toStartOfDay(timestamp))
      TTL ${this.opts.tableTTL}
      SETTINGS index_granularity = 8192;`

Buffer

const body = `CREATE TABLE IF NOT EXISTS ${this.opts.dbTableName}_buffer
      as ${this.opts.dbTableName}
      ENGINE = Buffer('${this.opts.dbName}', '${this.opts.dbTableName}', 16, 10, 100, 1000, 10000, 10000, 100000);`

Logger mixin

That mixin I use for logging (Click for open)
const defaultContext = {
  requestID: '',
  meta: { customer: { subdomain: '' } },
}

module.exports = {
  name: 'logger',
  methods: {
    log(data, ctx = defaultContext) {
      this.sendLog(data, ctx, 'info')
    },
    error(title, error, ctx = defaultContext) {
      this.logger.error({
        title,
        subdomain: ctx.meta.customer ? ctx.meta.customer.subdomain : '',
        caller: ctx.caller || '',
        error,
        requestID: ctx.requestID || '',
      })
    },
    err(error, ctx = defaultContext) {
      this.logger.error({
        title: error.message,
        subdomain: ctx.meta.customer ? ctx.meta.customer.subdomain : '',
        caller: ctx.caller || '',
        error,
        requestID: ctx.requestID || '',
      })
    },
    warn(data, ctx = defaultContext) {
      this.sendLog(data, ctx, 'warn')
    },
    sendLog(data, ctx, logType) {
      if (!ctx.meta.customer) {
        ctx.meta.customer = { subdomain: '' }
      }

      if (typeof data === 'string') {
        return this.logger[logType]({
          requestID: ctx.requestID || '',
          subdomain: ctx.meta.customer.subdomain || '',
          caller: ctx.caller || '',
          title: data,
        })
      }

      if (typeof data !== 'object') {
        return this.logger[logType]({
          requestID: ctx.requestID || '',
          subdomain: ctx.meta.customer.subdomain || '',
          caller: ctx.caller || '',
          data,
        })
      }

      return this.logger[logType]({
        requestID: ctx.requestID || '',
        subdomain: ctx.meta.customer.subdomain || '',
        caller: ctx.caller || '',
        ...data,
      })
    },
  },
}

Documentation

For more details read docs