Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /opt/push-server/node_modules/winston/lib/winston/transports/ |
Upload File : |
/** * http.js: Transport for outputting to a json-rpcserver. * * (C) 2010 Charlie Robbins * MIT LICENCE */ 'use strict'; const http = require('http'); const https = require('https'); const { Stream } = require('readable-stream'); const TransportStream = require('winston-transport'); const jsonStringify = require('safe-stable-stringify'); /** * Transport for outputting to a json-rpc server. * @type {Stream} * @extends {TransportStream} */ module.exports = class Http extends TransportStream { /** * Constructor function for the Http transport object responsible for * persisting log messages and metadata to a terminal or TTY. * @param {!Object} [options={}] - Options for this instance. */ // eslint-disable-next-line max-statements constructor(options = {}) { super(options); this.options = options; this.name = options.name || 'http'; this.ssl = !!options.ssl; this.host = options.host || 'localhost'; this.port = options.port; this.auth = options.auth; this.path = options.path || ''; this.agent = options.agent; this.headers = options.headers || {}; this.headers['content-type'] = 'application/json'; this.batch = options.batch || false; this.batchInterval = options.batchInterval || 5000; this.batchCount = options.batchCount || 10; this.batchOptions = []; this.batchTimeoutID = -1; this.batchCallback = {}; if (!this.port) { this.port = this.ssl ? 443 : 80; } } /** * Core logging method exposed to Winston. * @param {Object} info - TODO: add param description. * @param {function} callback - TODO: add param description. * @returns {undefined} */ log(info, callback) { this._request(info, null, null, (err, res) => { if (res && res.statusCode !== 200) { err = new Error(`Invalid HTTP Status Code: ${res.statusCode}`); } if (err) { this.emit('warn', err); } else { this.emit('logged', info); } }); // Remark: (jcrugzz) Fire and forget here so requests dont cause buffering // and block more requests from happening? if (callback) { setImmediate(callback); } } /** * Query the transport. Options object is optional. * @param {Object} options - Loggly-like query options for this instance. * @param {function} callback - Continuation to respond to when complete. * @returns {undefined} */ query(options, callback) { if (typeof options === 'function') { callback = options; options = {}; } options = { method: 'query', params: this.normalizeQuery(options) }; const auth = options.params.auth || null; delete options.params.auth; const path = options.params.path || null; delete options.params.path; this._request(options, auth, path, (err, res, body) => { if (res && res.statusCode !== 200) { err = new Error(`Invalid HTTP Status Code: ${res.statusCode}`); } if (err) { return callback(err); } if (typeof body === 'string') { try { body = JSON.parse(body); } catch (e) { return callback(e); } } callback(null, body); }); } /** * Returns a log stream for this transport. Options object is optional. * @param {Object} options - Stream options for this instance. * @returns {Stream} - TODO: add return description */ stream(options = {}) { const stream = new Stream(); options = { method: 'stream', params: options }; const path = options.params.path || null; delete options.params.path; const auth = options.params.auth || null; delete options.params.auth; let buff = ''; const req = this._request(options, auth, path); stream.destroy = () => req.destroy(); req.on('data', data => { data = (buff + data).split(/\n+/); const l = data.length - 1; let i = 0; for (; i < l; i++) { try { stream.emit('log', JSON.parse(data[i])); } catch (e) { stream.emit('error', e); } } buff = data[l]; }); req.on('error', err => stream.emit('error', err)); return stream; } /** * Make a request to a winstond server or any http server which can * handle json-rpc. * @param {function} options - Options to sent the request. * @param {Object?} auth - authentication options * @param {string} path - request path * @param {function} callback - Continuation to respond to when complete. */ _request(options, auth, path, callback) { options = options || {}; auth = auth || this.auth; path = path || this.path || ''; if (this.batch) { this._doBatch(options, callback, auth, path); } else { this._doRequest(options, callback, auth, path); } } /** * Send or memorize the options according to batch configuration * @param {function} options - Options to sent the request. * @param {function} callback - Continuation to respond to when complete. * @param {Object?} auth - authentication options * @param {string} path - request path */ _doBatch(options, callback, auth, path) { this.batchOptions.push(options); if (this.batchOptions.length === 1) { // First message stored, it's time to start the timeout! const me = this; this.batchCallback = callback; this.batchTimeoutID = setTimeout(function () { // timeout is reached, send all messages to endpoint me.batchTimeoutID = -1; me._doBatchRequest(me.batchCallback, auth, path); }, this.batchInterval); } if (this.batchOptions.length === this.batchCount) { // max batch count is reached, send all messages to endpoint this._doBatchRequest(this.batchCallback, auth, path); } } /** * Initiate a request with the memorized batch options, stop the batch timeout * @param {function} callback - Continuation to respond to when complete. * @param {Object?} auth - authentication options * @param {string} path - request path */ _doBatchRequest(callback, auth, path) { if (this.batchTimeoutID > 0) { clearTimeout(this.batchTimeoutID); this.batchTimeoutID = -1; } const batchOptionsCopy = this.batchOptions.slice(); this.batchOptions = []; this._doRequest(batchOptionsCopy, callback, auth, path); } /** * Make a request to a winstond server or any http server which can * handle json-rpc. * @param {function} options - Options to sent the request. * @param {function} callback - Continuation to respond to when complete. * @param {Object?} auth - authentication options * @param {string} path - request path */ _doRequest(options, callback, auth, path) { // Prepare options for outgoing HTTP request const headers = Object.assign({}, this.headers); if (auth && auth.bearer) { headers.Authorization = `Bearer ${auth.bearer}`; } const req = (this.ssl ? https : http).request({ ...this.options, method: 'POST', host: this.host, port: this.port, path: `/${path.replace(/^\//, '')}`, headers: headers, auth: (auth && auth.username && auth.password) ? (`${auth.username}:${auth.password}`) : '', agent: this.agent }); req.on('error', callback); req.on('response', res => ( res.on('end', () => callback(null, res)).resume() )); req.end(Buffer.from(jsonStringify(options, this.options.replacer), 'utf8')); } };