UNPKG

dd-trace

Version:

Datadog APM tracing client for JavaScript

142 lines (115 loc) 3.77 kB
'use strict' const { storage } = require('../../../datadog-core') const { LogChannel } = require('./channels') const { Log } = require('./log') const defaultLogger = { debug: msg => console.debug(msg), /* eslint-disable-line no-console */ info: msg => console.info(msg), /* eslint-disable-line no-console */ warn: msg => console.warn(msg), /* eslint-disable-line no-console */ error: msg => console.error(msg) /* eslint-disable-line no-console */ } let enabled = false let logger = defaultLogger let logChannel = new LogChannel() let stackTraceLimitFunction = onError function withNoop (fn) { const store = storage('legacy').getStore() storage('legacy').enterWith({ noop: true }) fn() storage('legacy').enterWith(store) } function unsubscribeAll () { logChannel.unsubscribe({ trace: onTrace, debug: onDebug, info: onInfo, warn: onWarn, error: onError }) } function toggleSubscription (enable, level) { unsubscribeAll() if (enable) { logChannel = new LogChannel(level) logChannel.subscribe({ trace: onTrace, debug: onDebug, info: onInfo, warn: onWarn, error: onError }) } } function toggle (enable, level) { enabled = enable toggleSubscription(enabled, level) } function use (newLogger) { if (typeof newLogger?.debug === 'function' && typeof newLogger.error === 'function') { logger = newLogger } } function reset () { logger = defaultLogger enabled = false toggleSubscription(false) } function getErrorLog (err) { if (typeof err?.delegate === 'function') { const result = err.delegate() return Array.isArray(result) ? Log.parse(...result) : Log.parse(result) } return err } function setStackTraceLimitFunction (fn) { if (typeof fn !== 'function') { throw new TypeError('stackTraceLimitFunction must be a function') } stackTraceLimitFunction = fn } function onError (err) { const { formatted, cause } = getErrorLog(err) // calling twice logger.error() because Error cause is only available in nodejs v16.9.0 // TODO: replace it with Error(message, { cause }) when cause has broad support if (formatted) { withNoop(() => { const l = Error.stackTraceLimit Error.stackTraceLimit = 0 const e = new Error(formatted) Error.stackTraceLimit = l Error.captureStackTrace(e, stackTraceLimitFunction) logger.error(e) }) } if (cause) withNoop(() => logger.error(cause)) } function onWarn (log) { const { formatted, cause } = getErrorLog(log) if (formatted) withNoop(() => logger.warn(formatted)) if (cause) withNoop(() => logger.warn(cause)) } function onInfo (log) { const { formatted, cause } = getErrorLog(log) if (formatted) withNoop(() => logger.info(formatted)) if (cause) withNoop(() => logger.info(cause)) } function onDebug (log) { const { formatted, cause } = getErrorLog(log) if (formatted) withNoop(() => logger.debug(formatted)) if (cause) withNoop(() => logger.debug(cause)) } function onTrace (log) { const { formatted, cause } = getErrorLog(log) // Using logger.debug() because not all loggers have trace level, // and console.trace() has a completely different meaning. if (formatted) withNoop(() => logger.debug(formatted)) if (cause) withNoop(() => logger.debug(cause)) } function error (...args) { onError(Log.parse(...args)) } function warn (...args) { const log = Log.parse(...args) if (!logger.warn) return onDebug(log) onWarn(log) } function info (...args) { const log = Log.parse(...args) if (!logger.info) return onDebug(log) onInfo(log) } function debug (...args) { onDebug(Log.parse(...args)) } function trace (...args) { onTrace(Log.parse(...args)) } module.exports = { use, toggle, reset, error, warn, info, debug, trace, setStackTraceLimitFunction }