UNPKG

kibana-123

Version:

Kibana is an open source (Apache Licensed), browser based analytics and search dashboard for Elasticsearch. Kibana is a snap to setup and start using. Kibana strives to be easy to get started with, while also being flexible and powerful, just like Elastic

141 lines (126 loc) 4.17 kB
import Stream from 'stream'; import moment from 'moment'; import _ from 'lodash'; import numeral from '@spalger/numeral'; import ansicolors from 'ansicolors'; import stringify from 'json-stringify-safe'; import querystring from 'querystring'; import applyFiltersToKeys from './apply_filters_to_keys'; import { inspect } from 'util'; function serializeError(err) { return { message: err.message, name: err.name, stack: err.stack, code: err.code, signal: err.signal }; } let levelColor = function (code) { if (code < 299) return ansicolors.green(code); if (code < 399) return ansicolors.yellow(code); if (code < 499) return ansicolors.magenta(code); return ansicolors.red(code); }; module.exports = class TransformObjStream extends Stream.Transform { constructor(config) { super({ readableObjectMode: false, writableObjectMode: true }); this.config = config; } filter(data) { if (!this.config.filter) return data; return applyFiltersToKeys(data, this.config.filter); } _transform(event, enc, next) { let data = this.filter(this.readEvent(event)); this.push(this.format(data) + '\n'); next(); } readEvent(event) { let data = { type: event.event, '@timestamp': moment.utc(event.timestamp).format(), tags: [].concat(event.tags || []), pid: event.pid }; if (data.type === 'response') { _.defaults(data, _.pick(event, [ 'method', 'statusCode' ])); data.req = { url: event.path, method: event.method, headers: event.headers, remoteAddress: event.source.remoteAddress, userAgent: event.source.remoteAddress, referer: event.source.referer }; let contentLength = 0; if (typeof event.responsePayload === 'object') { contentLength = stringify(event.responsePayload).length; } else { contentLength = String(event.responsePayload).length; } data.res = { statusCode: event.statusCode, responseTime: event.responseTime, contentLength: contentLength }; let query = querystring.stringify(event.query); if (query) data.req.url += '?' + query; data.message = data.req.method.toUpperCase() + ' '; data.message += data.req.url; data.message += ' '; data.message += levelColor(data.res.statusCode); data.message += ' '; data.message += ansicolors.brightBlack(data.res.responseTime + 'ms'); data.message += ansicolors.brightBlack(' - ' + numeral(contentLength).format('0.0b')); } else if (data.type === 'ops') { _.defaults(data, _.pick(event, [ 'pid', 'os', 'proc', 'load' ])); data.message = ansicolors.brightBlack('memory: '); data.message += numeral(data.proc.mem.heapUsed).format('0.0b'); data.message += ' '; data.message += ansicolors.brightBlack('uptime: '); data.message += numeral(data.proc.uptime).format('00:00:00'); data.message += ' '; data.message += ansicolors.brightBlack('load: ['); data.message += data.os.load.map(function (val) { return numeral(val).format('0.00'); }).join(' '); data.message += ansicolors.brightBlack(']'); data.message += ' '; data.message += ansicolors.brightBlack('delay: '); data.message += numeral(data.proc.delay).format('0.000'); } else if (data.type === 'error') { data.level = 'error'; data.message = event.error.message; data.error = serializeError(event.error); data.url = event.url; } else if (event.data instanceof Error) { data.level = _.contains(event.tags, 'fatal') ? 'fatal' : 'error'; data.message = event.data.message; data.error = serializeError(event.data); } else if (_.isPlainObject(event.data) && event.data.tmpl) { _.assign(data, event.data); data.tmpl = undefined; data.message = _.template(event.data.tmpl)(event.data); } else { data.message = _.isString(event.data) ? event.data : inspect(event.data); } return data; } };