import { LoggerTransport, LoggerTransportOptions } from '../../logger'; import errorCodes from '../../lib/error'; import { delay } from '../../utils'; import createDebuggerLogger from '../../lib/debugLogger'; const debuggerLogger = createDebuggerLogger('iot-logger-esTransport'); const { ERR_INVALID_OPT_VALUE, } = errorCodes; const DEFAULT_MAX_RETRY_TIME = Infinity; const DEFAULT_ERR_DELAY_TIME = 1000; export interface ElasticsearchTransportOptions extends Omit { skipUpload?: boolean; request: (uploadData: Record[]) => Promise; maxRetryTime?: number; errDelayTime?: number; } export class ElasticsearchTransport extends LoggerTransport { readonly skipUpload: boolean; readonly maxRetryTime: number; readonly errDelayTime: number; protected curRetryTime = 0; protected customRequest: ElasticsearchTransportOptions['request']; constructor({ skipUpload, highWaterMark = 1000, consumeNum = 30, level = 'info', consumeImme = false, maxRetryTime = DEFAULT_MAX_RETRY_TIME, errDelayTime = DEFAULT_ERR_DELAY_TIME, request, ...opts }: ElasticsearchTransportOptions) { super({ ...opts, highWaterMark, consumeNum, consumeImme, level, name: 'ElasticsearchTransport', batchConsume: true, forceDiscard: true, }); this.maxRetryTime = Math.round(Math.abs(maxRetryTime)) || DEFAULT_MAX_RETRY_TIME; this.skipUpload = skipUpload; if (typeof request !== 'function') { throw new ERR_INVALID_OPT_VALUE('request', request); } this.errDelayTime = errDelayTime; this.customRequest = request; } protected async logBatch(logs, cb) { if (this.skipUpload) { cb(); return; } const uploadData = logs.map(item => item.message); try { this.curRetryTime = 0; await this.request(uploadData); cb(); } catch (err) { cb(err); } } protected async request(uploadData: Record[]) { try { await this.customRequest(uploadData); } catch (err) { this.curRetryTime += 1; debuggerLogger.error(`exec customRequest fail, curRetryTime: ${this.curRetryTime}`, err); if (this.curRetryTime >= this.maxRetryTime) { throw err; } else { await delay(this.errDelayTime); return this.request(uploadData); } } } }