1
0

logger.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. /**
  2. * logger.js: TODO: add file header description.
  3. *
  4. * (C) 2010 Charlie Robbins
  5. * MIT LICENCE
  6. */
  7. 'use strict';
  8. function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
  9. function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
  10. function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
  11. function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
  12. function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
  13. function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
  14. function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
  15. function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
  16. function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
  17. function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
  18. function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
  19. function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
  20. function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
  21. function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
  22. var _require = require('readable-stream'),
  23. Stream = _require.Stream,
  24. Transform = _require.Transform;
  25. var asyncForEach = require('async/forEach');
  26. var _require2 = require('triple-beam'),
  27. LEVEL = _require2.LEVEL,
  28. SPLAT = _require2.SPLAT;
  29. var isStream = require('is-stream');
  30. var ExceptionHandler = require('./exception-handler');
  31. var RejectionHandler = require('./rejection-handler');
  32. var LegacyTransportStream = require('winston-transport/legacy');
  33. var Profiler = require('./profiler');
  34. var _require3 = require('./common'),
  35. warn = _require3.warn;
  36. var config = require('./config');
  37. /**
  38. * Captures the number of format (i.e. %s strings) in a given string.
  39. * Based on `util.format`, see Node.js source:
  40. * https://github.com/nodejs/node/blob/b1c8f15c5f169e021f7c46eb7b219de95fe97603/lib/util.js#L201-L230
  41. * @type {RegExp}
  42. */
  43. var formatRegExp = /%[scdjifoO%]/g;
  44. /**
  45. * TODO: add class description.
  46. * @type {Logger}
  47. * @extends {Transform}
  48. */
  49. var Logger = /*#__PURE__*/function (_Transform) {
  50. /**
  51. * Constructor function for the Logger object responsible for persisting log
  52. * messages and metadata to one or more transports.
  53. * @param {!Object} options - foo
  54. */
  55. function Logger(options) {
  56. var _this;
  57. _classCallCheck(this, Logger);
  58. _this = _callSuper(this, Logger, [{
  59. objectMode: true
  60. }]);
  61. _this.configure(options);
  62. return _this;
  63. }
  64. _inherits(Logger, _Transform);
  65. return _createClass(Logger, [{
  66. key: "child",
  67. value: function child(defaultRequestMetadata) {
  68. var logger = this;
  69. return Object.create(logger, {
  70. write: {
  71. value: function value(info) {
  72. var infoClone = Object.assign({}, defaultRequestMetadata, info);
  73. // Object.assign doesn't copy inherited Error
  74. // properties so we have to do that explicitly
  75. //
  76. // Remark (indexzero): we should remove this
  77. // since the errors format will handle this case.
  78. //
  79. if (info instanceof Error) {
  80. infoClone.stack = info.stack;
  81. infoClone.message = info.message;
  82. }
  83. logger.write(infoClone);
  84. }
  85. }
  86. });
  87. }
  88. /**
  89. * This will wholesale reconfigure this instance by:
  90. * 1. Resetting all transports. Older transports will be removed implicitly.
  91. * 2. Set all other options including levels, colors, rewriters, filters,
  92. * exceptionHandlers, etc.
  93. * @param {!Object} options - TODO: add param description.
  94. * @returns {undefined}
  95. */
  96. }, {
  97. key: "configure",
  98. value: function configure() {
  99. var _this2 = this;
  100. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  101. silent = _ref.silent,
  102. format = _ref.format,
  103. defaultMeta = _ref.defaultMeta,
  104. levels = _ref.levels,
  105. _ref$level = _ref.level,
  106. level = _ref$level === void 0 ? 'info' : _ref$level,
  107. _ref$exitOnError = _ref.exitOnError,
  108. exitOnError = _ref$exitOnError === void 0 ? true : _ref$exitOnError,
  109. transports = _ref.transports,
  110. colors = _ref.colors,
  111. emitErrs = _ref.emitErrs,
  112. formatters = _ref.formatters,
  113. padLevels = _ref.padLevels,
  114. rewriters = _ref.rewriters,
  115. stripColors = _ref.stripColors,
  116. exceptionHandlers = _ref.exceptionHandlers,
  117. rejectionHandlers = _ref.rejectionHandlers;
  118. // Reset transports if we already have them
  119. if (this.transports.length) {
  120. this.clear();
  121. }
  122. this.silent = silent;
  123. this.format = format || this.format || require('logform/json')();
  124. this.defaultMeta = defaultMeta || null;
  125. // Hoist other options onto this instance.
  126. this.levels = levels || this.levels || config.npm.levels;
  127. this.level = level;
  128. if (this.exceptions) {
  129. this.exceptions.unhandle();
  130. }
  131. if (this.rejections) {
  132. this.rejections.unhandle();
  133. }
  134. this.exceptions = new ExceptionHandler(this);
  135. this.rejections = new RejectionHandler(this);
  136. this.profilers = {};
  137. this.exitOnError = exitOnError;
  138. // Add all transports we have been provided.
  139. if (transports) {
  140. transports = Array.isArray(transports) ? transports : [transports];
  141. transports.forEach(function (transport) {
  142. return _this2.add(transport);
  143. });
  144. }
  145. if (colors || emitErrs || formatters || padLevels || rewriters || stripColors) {
  146. throw new Error(['{ colors, emitErrs, formatters, padLevels, rewriters, stripColors } were removed in winston@3.0.0.', 'Use a custom winston.format(function) instead.', 'See: https://github.com/winstonjs/winston/tree/master/UPGRADE-3.0.md'].join('\n'));
  147. }
  148. if (exceptionHandlers) {
  149. this.exceptions.handle(exceptionHandlers);
  150. }
  151. if (rejectionHandlers) {
  152. this.rejections.handle(rejectionHandlers);
  153. }
  154. }
  155. }, {
  156. key: "isLevelEnabled",
  157. value: function isLevelEnabled(level) {
  158. var _this3 = this;
  159. var givenLevelValue = getLevelValue(this.levels, level);
  160. if (givenLevelValue === null) {
  161. return false;
  162. }
  163. var configuredLevelValue = getLevelValue(this.levels, this.level);
  164. if (configuredLevelValue === null) {
  165. return false;
  166. }
  167. if (!this.transports || this.transports.length === 0) {
  168. return configuredLevelValue >= givenLevelValue;
  169. }
  170. var index = this.transports.findIndex(function (transport) {
  171. var transportLevelValue = getLevelValue(_this3.levels, transport.level);
  172. if (transportLevelValue === null) {
  173. transportLevelValue = configuredLevelValue;
  174. }
  175. return transportLevelValue >= givenLevelValue;
  176. });
  177. return index !== -1;
  178. }
  179. /* eslint-disable valid-jsdoc */
  180. /**
  181. * Ensure backwards compatibility with a `log` method
  182. * @param {mixed} level - Level the log message is written at.
  183. * @param {mixed} msg - TODO: add param description.
  184. * @param {mixed} meta - TODO: add param description.
  185. * @returns {Logger} - TODO: add return description.
  186. *
  187. * @example
  188. * // Supports the existing API:
  189. * logger.log('info', 'Hello world', { custom: true });
  190. * logger.log('info', new Error('Yo, it\'s on fire'));
  191. *
  192. * // Requires winston.format.splat()
  193. * logger.log('info', '%s %d%%', 'A string', 50, { thisIsMeta: true });
  194. *
  195. * // And the new API with a single JSON literal:
  196. * logger.log({ level: 'info', message: 'Hello world', custom: true });
  197. * logger.log({ level: 'info', message: new Error('Yo, it\'s on fire') });
  198. *
  199. * // Also requires winston.format.splat()
  200. * logger.log({
  201. * level: 'info',
  202. * message: '%s %d%%',
  203. * [SPLAT]: ['A string', 50],
  204. * meta: { thisIsMeta: true }
  205. * });
  206. *
  207. */
  208. /* eslint-enable valid-jsdoc */
  209. }, {
  210. key: "log",
  211. value: function log(level, msg) {
  212. for (var _len = arguments.length, splat = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
  213. splat[_key - 2] = arguments[_key];
  214. }
  215. // eslint-disable-line max-params
  216. // Optimize for the hotpath of logging JSON literals
  217. if (arguments.length === 1) {
  218. // Yo dawg, I heard you like levels ... seriously ...
  219. // In this context the LHS `level` here is actually the `info` so read
  220. // this as: info[LEVEL] = info.level;
  221. level[LEVEL] = level.level;
  222. this._addDefaultMeta(level);
  223. this.write(level);
  224. return this;
  225. }
  226. // Slightly less hotpath, but worth optimizing for.
  227. if (arguments.length === 2) {
  228. if (msg && _typeof(msg) === 'object') {
  229. msg[LEVEL] = msg.level = level;
  230. this._addDefaultMeta(msg);
  231. this.write(msg);
  232. return this;
  233. }
  234. msg = _defineProperty(_defineProperty(_defineProperty({}, LEVEL, level), "level", level), "message", msg);
  235. this._addDefaultMeta(msg);
  236. this.write(msg);
  237. return this;
  238. }
  239. var meta = splat[0];
  240. if (_typeof(meta) === 'object' && meta !== null) {
  241. // Extract tokens, if none available default to empty array to
  242. // ensure consistancy in expected results
  243. var tokens = msg && msg.match && msg.match(formatRegExp);
  244. if (!tokens) {
  245. var info = Object.assign({}, this.defaultMeta, meta, _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, LEVEL, level), SPLAT, splat), "level", level), "message", msg));
  246. if (meta.message) info.message = "".concat(info.message, " ").concat(meta.message);
  247. if (meta.stack) info.stack = meta.stack;
  248. this.write(info);
  249. return this;
  250. }
  251. }
  252. this.write(Object.assign({}, this.defaultMeta, _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, LEVEL, level), SPLAT, splat), "level", level), "message", msg)));
  253. return this;
  254. }
  255. /**
  256. * Pushes data so that it can be picked up by all of our pipe targets.
  257. * @param {mixed} info - TODO: add param description.
  258. * @param {mixed} enc - TODO: add param description.
  259. * @param {mixed} callback - Continues stream processing.
  260. * @returns {undefined}
  261. * @private
  262. */
  263. }, {
  264. key: "_transform",
  265. value: function _transform(info, enc, callback) {
  266. if (this.silent) {
  267. return callback();
  268. }
  269. // [LEVEL] is only soft guaranteed to be set here since we are a proper
  270. // stream. It is likely that `info` came in through `.log(info)` or
  271. // `.info(info)`. If it is not defined, however, define it.
  272. // This LEVEL symbol is provided by `triple-beam` and also used in:
  273. // - logform
  274. // - winston-transport
  275. // - abstract-winston-transport
  276. if (!info[LEVEL]) {
  277. info[LEVEL] = info.level;
  278. }
  279. // Remark: really not sure what to do here, but this has been reported as
  280. // very confusing by pre winston@2.0.0 users as quite confusing when using
  281. // custom levels.
  282. if (!this.levels[info[LEVEL]] && this.levels[info[LEVEL]] !== 0) {
  283. // eslint-disable-next-line no-console
  284. console.error('[winston] Unknown logger level: %s', info[LEVEL]);
  285. }
  286. // Remark: not sure if we should simply error here.
  287. if (!this._readableState.pipes) {
  288. // eslint-disable-next-line no-console
  289. console.error('[winston] Attempt to write logs with no transports, which can increase memory usage: %j', info);
  290. }
  291. // Here we write to the `format` pipe-chain, which on `readable` above will
  292. // push the formatted `info` Object onto the buffer for this instance. We trap
  293. // (and re-throw) any errors generated by the user-provided format, but also
  294. // guarantee that the streams callback is invoked so that we can continue flowing.
  295. try {
  296. this.push(this.format.transform(info, this.format.options));
  297. } finally {
  298. this._writableState.sync = false;
  299. // eslint-disable-next-line callback-return
  300. callback();
  301. }
  302. }
  303. /**
  304. * Delays the 'finish' event until all transport pipe targets have
  305. * also emitted 'finish' or are already finished.
  306. * @param {mixed} callback - Continues stream processing.
  307. */
  308. }, {
  309. key: "_final",
  310. value: function _final(callback) {
  311. var transports = this.transports.slice();
  312. asyncForEach(transports, function (transport, next) {
  313. if (!transport || transport.finished) return setImmediate(next);
  314. transport.once('finish', next);
  315. transport.end();
  316. }, callback);
  317. }
  318. /**
  319. * Adds the transport to this logger instance by piping to it.
  320. * @param {mixed} transport - TODO: add param description.
  321. * @returns {Logger} - TODO: add return description.
  322. */
  323. }, {
  324. key: "add",
  325. value: function add(transport) {
  326. // Support backwards compatibility with all existing `winston < 3.x.x`
  327. // transports which meet one of two criteria:
  328. // 1. They inherit from winston.Transport in < 3.x.x which is NOT a stream.
  329. // 2. They expose a log method which has a length greater than 2 (i.e. more then
  330. // just `log(info, callback)`.
  331. var target = !isStream(transport) || transport.log.length > 2 ? new LegacyTransportStream({
  332. transport: transport
  333. }) : transport;
  334. if (!target._writableState || !target._writableState.objectMode) {
  335. throw new Error('Transports must WritableStreams in objectMode. Set { objectMode: true }.');
  336. }
  337. // Listen for the `error` event and the `warn` event on the new Transport.
  338. this._onEvent('error', target);
  339. this._onEvent('warn', target);
  340. this.pipe(target);
  341. if (transport.handleExceptions) {
  342. this.exceptions.handle();
  343. }
  344. if (transport.handleRejections) {
  345. this.rejections.handle();
  346. }
  347. return this;
  348. }
  349. /**
  350. * Removes the transport from this logger instance by unpiping from it.
  351. * @param {mixed} transport - TODO: add param description.
  352. * @returns {Logger} - TODO: add return description.
  353. */
  354. }, {
  355. key: "remove",
  356. value: function remove(transport) {
  357. if (!transport) return this;
  358. var target = transport;
  359. if (!isStream(transport) || transport.log.length > 2) {
  360. target = this.transports.filter(function (match) {
  361. return match.transport === transport;
  362. })[0];
  363. }
  364. if (target) {
  365. this.unpipe(target);
  366. }
  367. return this;
  368. }
  369. /**
  370. * Removes all transports from this logger instance.
  371. * @returns {Logger} - TODO: add return description.
  372. */
  373. }, {
  374. key: "clear",
  375. value: function clear() {
  376. this.unpipe();
  377. return this;
  378. }
  379. /**
  380. * Cleans up resources (streams, event listeners) for all transports
  381. * associated with this instance (if necessary).
  382. * @returns {Logger} - TODO: add return description.
  383. */
  384. }, {
  385. key: "close",
  386. value: function close() {
  387. this.exceptions.unhandle();
  388. this.rejections.unhandle();
  389. this.clear();
  390. this.emit('close');
  391. return this;
  392. }
  393. /**
  394. * Sets the `target` levels specified on this instance.
  395. * @param {Object} Target levels to use on this instance.
  396. */
  397. }, {
  398. key: "setLevels",
  399. value: function setLevels() {
  400. warn.deprecated('setLevels');
  401. }
  402. /**
  403. * Queries the all transports for this instance with the specified `options`.
  404. * This will aggregate each transport's results into one object containing
  405. * a property per transport.
  406. * @param {Object} options - Query options for this instance.
  407. * @param {function} callback - Continuation to respond to when complete.
  408. */
  409. }, {
  410. key: "query",
  411. value: function query(options, callback) {
  412. if (typeof options === 'function') {
  413. callback = options;
  414. options = {};
  415. }
  416. options = options || {};
  417. var results = {};
  418. var queryObject = Object.assign({}, options.query || {});
  419. // Helper function to query a single transport
  420. function queryTransport(transport, next) {
  421. if (options.query && typeof transport.formatQuery === 'function') {
  422. options.query = transport.formatQuery(queryObject);
  423. }
  424. transport.query(options, function (err, res) {
  425. if (err) {
  426. return next(err);
  427. }
  428. if (typeof transport.formatResults === 'function') {
  429. res = transport.formatResults(res, options.format);
  430. }
  431. next(null, res);
  432. });
  433. }
  434. // Helper function to accumulate the results from `queryTransport` into
  435. // the `results`.
  436. function addResults(transport, next) {
  437. queryTransport(transport, function (err, result) {
  438. // queryTransport could potentially invoke the callback multiple times
  439. // since Transport code can be unpredictable.
  440. if (next) {
  441. result = err || result;
  442. if (result) {
  443. results[transport.name] = result;
  444. }
  445. // eslint-disable-next-line callback-return
  446. next();
  447. }
  448. next = null;
  449. });
  450. }
  451. // Iterate over the transports in parallel setting the appropriate key in
  452. // the `results`.
  453. asyncForEach(this.transports.filter(function (transport) {
  454. return !!transport.query;
  455. }), addResults, function () {
  456. return callback(null, results);
  457. });
  458. }
  459. /**
  460. * Returns a log stream for all transports. Options object is optional.
  461. * @param{Object} options={} - Stream options for this instance.
  462. * @returns {Stream} - TODO: add return description.
  463. */
  464. }, {
  465. key: "stream",
  466. value: function stream() {
  467. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  468. var out = new Stream();
  469. var streams = [];
  470. out._streams = streams;
  471. out.destroy = function () {
  472. var i = streams.length;
  473. while (i--) {
  474. streams[i].destroy();
  475. }
  476. };
  477. // Create a list of all transports for this instance.
  478. this.transports.filter(function (transport) {
  479. return !!transport.stream;
  480. }).forEach(function (transport) {
  481. var str = transport.stream(options);
  482. if (!str) {
  483. return;
  484. }
  485. streams.push(str);
  486. str.on('log', function (log) {
  487. log.transport = log.transport || [];
  488. log.transport.push(transport.name);
  489. out.emit('log', log);
  490. });
  491. str.on('error', function (err) {
  492. err.transport = err.transport || [];
  493. err.transport.push(transport.name);
  494. out.emit('error', err);
  495. });
  496. });
  497. return out;
  498. }
  499. /**
  500. * Returns an object corresponding to a specific timing. When done is called
  501. * the timer will finish and log the duration. e.g.:
  502. * @returns {Profile} - TODO: add return description.
  503. * @example
  504. * const timer = winston.startTimer()
  505. * setTimeout(() => {
  506. * timer.done({
  507. * message: 'Logging message'
  508. * });
  509. * }, 1000);
  510. */
  511. }, {
  512. key: "startTimer",
  513. value: function startTimer() {
  514. return new Profiler(this);
  515. }
  516. /**
  517. * Tracks the time inbetween subsequent calls to this method with the same
  518. * `id` parameter. The second call to this method will log the difference in
  519. * milliseconds along with the message.
  520. * @param {string} id Unique id of the profiler
  521. * @returns {Logger} - TODO: add return description.
  522. */
  523. }, {
  524. key: "profile",
  525. value: function profile(id) {
  526. var time = Date.now();
  527. if (this.profilers[id]) {
  528. var timeEnd = this.profilers[id];
  529. delete this.profilers[id];
  530. // Attempt to be kind to users if they are still using older APIs.
  531. for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
  532. args[_key2 - 1] = arguments[_key2];
  533. }
  534. if (typeof args[args.length - 2] === 'function') {
  535. // eslint-disable-next-line no-console
  536. console.warn('Callback function no longer supported as of winston@3.0.0');
  537. args.pop();
  538. }
  539. // Set the duration property of the metadata
  540. var info = _typeof(args[args.length - 1]) === 'object' ? args.pop() : {};
  541. info.level = info.level || 'info';
  542. info.durationMs = time - timeEnd;
  543. info.message = info.message || id;
  544. return this.write(info);
  545. }
  546. this.profilers[id] = time;
  547. return this;
  548. }
  549. /**
  550. * Backwards compatibility to `exceptions.handle` in winston < 3.0.0.
  551. * @returns {undefined}
  552. * @deprecated
  553. */
  554. }, {
  555. key: "handleExceptions",
  556. value: function handleExceptions() {
  557. var _this$exceptions;
  558. // eslint-disable-next-line no-console
  559. console.warn('Deprecated: .handleExceptions() will be removed in winston@4. Use .exceptions.handle()');
  560. (_this$exceptions = this.exceptions).handle.apply(_this$exceptions, arguments);
  561. }
  562. /**
  563. * Backwards compatibility to `exceptions.handle` in winston < 3.0.0.
  564. * @returns {undefined}
  565. * @deprecated
  566. */
  567. }, {
  568. key: "unhandleExceptions",
  569. value: function unhandleExceptions() {
  570. var _this$exceptions2;
  571. // eslint-disable-next-line no-console
  572. console.warn('Deprecated: .unhandleExceptions() will be removed in winston@4. Use .exceptions.unhandle()');
  573. (_this$exceptions2 = this.exceptions).unhandle.apply(_this$exceptions2, arguments);
  574. }
  575. /**
  576. * Throw a more meaningful deprecation notice
  577. * @throws {Error} - TODO: add throws description.
  578. */
  579. }, {
  580. key: "cli",
  581. value: function cli() {
  582. throw new Error(['Logger.cli() was removed in winston@3.0.0', 'Use a custom winston.formats.cli() instead.', 'See: https://github.com/winstonjs/winston/tree/master/UPGRADE-3.0.md'].join('\n'));
  583. }
  584. /**
  585. * Bubbles the `event` that occured on the specified `transport` up
  586. * from this instance.
  587. * @param {string} event - The event that occured
  588. * @param {Object} transport - Transport on which the event occured
  589. * @private
  590. */
  591. }, {
  592. key: "_onEvent",
  593. value: function _onEvent(event, transport) {
  594. function transportEvent(err) {
  595. // https://github.com/winstonjs/winston/issues/1364
  596. if (event === 'error' && !this.transports.includes(transport)) {
  597. this.add(transport);
  598. }
  599. this.emit(event, err, transport);
  600. }
  601. if (!transport['__winston' + event]) {
  602. transport['__winston' + event] = transportEvent.bind(this);
  603. transport.on(event, transport['__winston' + event]);
  604. }
  605. }
  606. }, {
  607. key: "_addDefaultMeta",
  608. value: function _addDefaultMeta(msg) {
  609. if (this.defaultMeta) {
  610. Object.assign(msg, this.defaultMeta);
  611. }
  612. }
  613. }]);
  614. }(Transform);
  615. function getLevelValue(levels, level) {
  616. var value = levels[level];
  617. if (!value && value !== 0) {
  618. return null;
  619. }
  620. return value;
  621. }
  622. /**
  623. * Represents the current readableState pipe targets for this Logger instance.
  624. * @type {Array|Object}
  625. */
  626. Object.defineProperty(Logger.prototype, 'transports', {
  627. configurable: false,
  628. enumerable: true,
  629. get: function get() {
  630. var pipes = this._readableState.pipes;
  631. return !Array.isArray(pipes) ? [pipes].filter(Boolean) : pipes;
  632. }
  633. });
  634. module.exports = Logger;