UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

154 lines (125 loc) 3.93 kB
import { Deque } from "../../../core/collection/queue/Deque.js"; import { LoggerBackend } from "../LoggerBackend.js"; /** Transformer function to transform log data as provided by winston into a message structure which is more appropriate for indexing in ES. @param {Object} logData @param {Object} logData.message - the log message @param {Object} logData.level - the log level @param {Object} logData.meta - the log meta data (JSON object) @returns {Object} transformed message */ function defaultTransformer(logData) { const transformed = {}; transformed['@timestamp'] = logData.timestamp ? logData.timestamp : new Date().toISOString(); transformed.message = logData.message; transformed.severity = logData.level; transformed.fields = logData.meta; if (logData.meta['transaction.id']) transformed.transaction = { id: logData.meta['transaction.id'] }; if (logData.meta['trace.id']) transformed.trace = { id: logData.meta['trace.id'] }; if (logData.meta['span.id']) transformed.span = { id: logData.meta['span.id'] }; return transformed; } class Record { constructor() { this.time = 0; this.message = 0; this.level = 0; } } export class ElasticSearchLogger extends LoggerBackend { constructor({ url = 'http://localhost:9200', target = `log-${new Date().toISOString()}` } = {}) { super(); /** * * @type {Deque<Record>} * @private */ this.__buffer = new Deque(); /** * Number of records * @type {number} * @private */ this.__flush_size = 500; /** * In milliseconds * @type {number} * @private */ this.__flush_timeout = 2000; /** * * @type {string} * @private */ this.__url = url; /** * * @type {string} * @private */ this.__target = target; /** * setTimeout handle * @type {number} * @private */ this.__timeout_ms = -1; /** * * @type {any} * @private */ this.__bound_flush = this.flush.bind(this); } flush() { // clear timeout if (this.__timeout !== -1) { clearTimeout(this.__timeout); this.__timeout = -1; } const buffer = this.__buffer; if (buffer.isEmpty()) { // do nothing return; } const data = []; while (!buffer.isEmpty()) { const record = buffer.removeFirst(); data.push({ create: { '@timestamp': record.time, 'level': record.level, 'message': record.message } }); } const xhr = new XMLHttpRequest(); xhr.onreadystatechange = (evt) => { console.warn(evt); }; xhr.open('POST', `${this.__url}/${this.__target}/_bulk`, true); xhr.overrideMimeType('text/plain'); xhr.send(JSON.stringify(data)); } __prod() { const buffer_size = this.__buffer.size(); if (buffer_size >= this.__flush_size) { this.flush(); } else if (this.__timeout === -1) { this.__timeout = setTimeout(this.__bound_flush, this.__flush_timeout); } } log(level, message) { const record = new Record(); record.message = message; record.level = level; record.time = performance.now(); this.__buffer.addLast(record); this.__prod(); } }