UNPKG

winston-ovh

Version:

A winston transport to log on OVH Laas product

157 lines (130 loc) 3.39 kB
import Transport from 'winston-transport' import Gelf from 'gelf-pro' export interface ovhTransporterOptions { token: string name?: string level?: string host?: string port?: number tls?: boolean } export default class ovhTransporter extends Transport { private token: string private gelf: any constructor(opts: ovhTransporterOptions) { super(opts) /** * Your OVH Logs Data Platform token */ this.token = opts.token this.level = opts.level || 'debug' this.gelf = Gelf.setConfig({ fields: { "X-OVH-TOKEN": this.token, }, adapterName: opts.tls === false ? 'tcp' : 'tcp-tls', adapterOptions: { host: opts.host || 'discover.logs.ovh.com', port: opts.port || 12202, family: 4, // IP stack, timeout: 1000 // 1s } }) } get name() { return 'ovh' } static getLevel(l: string): number { if (~l.indexOf('error')) { return 3 } if (~l.indexOf('warn')) { return 4 } if (~l.indexOf('info')) { return 5 } if (~l.indexOf('verbose')) { return 6 } if (~l.indexOf('debug') || ~l.indexOf('silly')) { return 7 } return 3 } /** * Log a message into Laas * @param {string} level * @param {string} msg * @param {Object} meta * @param {Function} callback */ log(info: any, cb: (err?: Error) => void): any { setImmediate(() => this.emit('logged', info)) const { message } = info let { level, ...meta } = info meta = ovhTransporter.suffixing(meta) // Laas naming logic this.gelf.message(message, ovhTransporter.getLevel(level), meta, (err: any) => { cb(err as Error) }) } // stream version // logv() {} close() {} /** * Attempt to preserve meta values type * Suffix all properties of object, according to the log data platform * @param {Object} o Object to suffix * @return {Object} Suffixed object */ static suffixing(o: any) { if (typeof o !== 'object') return {} if (o.message && o.stack) { return { error: o.message + ': ' + o.name || o.stack } } const n: any = {} Object.keys(o).forEach(prop => { if (prop === 'message') return if (prop === 'level') return const v = o[prop] switch (typeof v) { case 'number': if (v % 1 === 0) { n[`_${prop}_long`] = v break } n[`_${prop}_num`] = v break case 'boolean': n[`_${prop}_bool`] = v break case 'string': // Can be Geo position if (v.split(',').length === 2) { n[`_${prop}_geolocation`] = v break } n[prop] = v break // it's an object default: if (v instanceof Date) { n[`_${prop}_date`] = v.toISOString() break } if (v instanceof Error) { n[prop] = v.name + ': ' + v.message break } try { n[prop] = JSON.stringify(v) } catch (err) { n[prop] = null } } }) return n } }