diff --git a/packages/telemetry/src/context-aware-slog-file.js b/packages/telemetry/src/context-aware-slog-file.js index 003680fc2bd..39d96faec7b 100644 --- a/packages/telemetry/src/context-aware-slog-file.js +++ b/packages/telemetry/src/context-aware-slog-file.js @@ -1,4 +1,5 @@ /* eslint-env node */ +/* global globalThis */ import { makeFsStreamWriter } from '@agoric/internal/src/node/fs-stream.js'; import { makeContextualSlogProcessor } from './context-aware-slog.js'; @@ -9,6 +10,7 @@ import { serializeSlogObj } from './serialize-slog-obj.js'; */ export const makeSlogSender = async options => { const { CHAIN_ID, CONTEXTUAL_SLOGFILE } = options.env || {}; + const { console = globalThis.console } = options; if (!CONTEXTUAL_SLOGFILE) return console.warn( 'Ignoring invocation of slogger "context-aware-slog-file" without the presence of "CONTEXTUAL_SLOGFILE"', diff --git a/packages/telemetry/src/index.js b/packages/telemetry/src/index.js index 82e58ff7449..ed323102bf6 100644 --- a/packages/telemetry/src/index.js +++ b/packages/telemetry/src/index.js @@ -20,6 +20,7 @@ export * from './make-slog-sender.js'; * @typedef {MakeSlogSenderCommonOptions & Record} MakeSlogSenderOptions * @typedef {object} MakeSlogSenderCommonOptions * @property {Record} [env] + * @property {Pick} [console] * @property {string} [stateDir] * @property {string} [serviceName] */ @@ -28,11 +29,16 @@ export * from './make-slog-sender.js'; * @param {SlogSender} [slogSender] * @param {object} [options] * @param {Record} [options.env] - * @param {(...args: any[]) => void} [options.log] + * @param {MakeSlogSenderCommonOptions['console']} [options.console] + * @param {(...args) => void} [options.log] */ export const tryFlushSlogSender = async ( slogSender, - { env = {}, log } = {}, + { + env = {}, + console = globalThis.console, + log = (...args) => console.warn(...args), + } = {}, ) => { await Promise.resolve(slogSender?.forceFlush?.()).catch(err => { log?.('Failed to flush slog sender', err); @@ -81,7 +87,7 @@ export const getResourceAttributes = ({ /** * @typedef {object} Powers - * @property {{ warn: Console['warn'] }} console + * @property {MakeSlogSenderCommonOptions['console']} console * @property {NodeJS.ProcessEnv} env * @property {import('@opentelemetry/sdk-metrics').View[]} views * @property {string} [serviceName] diff --git a/packages/telemetry/src/make-slog-sender.js b/packages/telemetry/src/make-slog-sender.js index 94693661087..3557bbd2c84 100644 --- a/packages/telemetry/src/make-slog-sender.js +++ b/packages/telemetry/src/make-slog-sender.js @@ -1,3 +1,4 @@ +/* global globalThis */ import path from 'path'; import tmp from 'tmp'; import { PromiseAllOrErrors } from '@agoric/internal'; @@ -22,7 +23,12 @@ const filterTruthy = arr => /** @type {any[]} */ (arr.filter(Boolean)); * @type {import('./index.js').MakeSlogSender} */ export const makeSlogSender = async (opts = {}) => { - const { env = {}, stateDir: stateDirOption, ...otherOpts } = opts; + const { + env = {}, + console = globalThis.console, + stateDir: stateDirOption, + ...otherOpts + } = opts; const { SLOGSENDER = DEFAULT_SLOGSENDER_MODULE, SLOGSENDER_AGENT = DEFAULT_SLOGSENDER_AGENT, diff --git a/packages/telemetry/src/otel-and-flight-recorder.js b/packages/telemetry/src/otel-and-flight-recorder.js index 5ce1103daa1..df9145b6933 100644 --- a/packages/telemetry/src/otel-and-flight-recorder.js +++ b/packages/telemetry/src/otel-and-flight-recorder.js @@ -1,3 +1,4 @@ +/* global globalThis */ import { NonNullish } from '@agoric/internal'; import { makeSlogSender as makeSlogSenderFromEnv } from './make-slog-sender.js'; @@ -6,6 +7,7 @@ import { makeSlogSender as makeSlogSenderFromEnv } from './make-slog-sender.js'; */ export const makeSlogSender = async opts => { const { SLOGFILE: _1, SLOGSENDER: _2, ...otherEnv } = opts.env || {}; + const { console = globalThis.console } = opts || {}; console.warn( 'Deprecated slog sender, please use SLOGSENDER=@agoric/telemetry/src/flight-recorder.js,@agoric/telemetry/src/otel-trace.js', diff --git a/packages/telemetry/src/otel-context-aware-slog.js b/packages/telemetry/src/otel-context-aware-slog.js index 271c13da787..be6d87e324e 100644 --- a/packages/telemetry/src/otel-context-aware-slog.js +++ b/packages/telemetry/src/otel-context-aware-slog.js @@ -1,4 +1,5 @@ /* eslint-env node */ +/* global globalThis */ import { logs, SeverityNumber } from '@opentelemetry/api-logs'; import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http'; import { Resource } from '@opentelemetry/resources'; @@ -16,8 +17,13 @@ const FILE_ENCODING = 'utf8'; /** * @param {string} filePath + * @param {object} [powers] + * @param {import('./index.js').MakeSlogSenderCommonOptions['console']} [powers.console] */ -export const getContextFilePersistenceUtils = filePath => { +export const getContextFilePersistenceUtils = ( + filePath, + { console = globalThis.console } = {}, +) => { console.warn(`Using file ${filePath} for slogger context`); return { @@ -51,6 +57,7 @@ export const getContextFilePersistenceUtils = filePath => { */ export const makeSlogSender = async options => { const { CHAIN_ID, OTEL_EXPORTER_OTLP_ENDPOINT } = options.env || {}; + const { console = globalThis.console } = options; if (!(OTEL_EXPORTER_OTLP_ENDPOINT && options.stateDir)) return console.error( 'Ignoring invocation of slogger "context-aware-slog" without the presence of "OTEL_EXPORTER_OTLP_ENDPOINT" and "stateDir"', @@ -71,6 +78,7 @@ export const makeSlogSender = async options => { const persistenceUtils = getContextFilePersistenceUtils( process.env.SLOG_CONTEXT_FILE_PATH || `${options.stateDir}/${DEFAULT_CONTEXT_FILE}`, + { console: options.console }, ); const contextualSlogProcessor = makeContextualSlogProcessor( diff --git a/packages/telemetry/src/otel-trace.js b/packages/telemetry/src/otel-trace.js index 03fa348f082..2c801520286 100644 --- a/packages/telemetry/src/otel-trace.js +++ b/packages/telemetry/src/otel-trace.js @@ -1,4 +1,4 @@ -/* globals process */ +/* globals process globalThis */ import { BasicTracerProvider, BatchSpanProcessor, @@ -16,11 +16,10 @@ export const SPAN_MAX_QUEUE_SIZE = 100_000; export const SPAN_EXPORT_DELAY_MS = 1_000; /** - * @param {object} opts - * @param {Record} opts.env + * @param {import('./index.js').MakeSlogSenderCommonOptions} opts */ export const makeOtelTracingProvider = opts => { - const { env = process.env } = opts || {}; + const { env = process.env, console = globalThis.console } = opts || {}; const { OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT } = env; @@ -45,6 +44,9 @@ export const makeOtelTracingProvider = opts => { return provider; }; +/** + * @param {import('./index.js').MakeSlogSenderOptions & { version?: string }} opts + */ export const makeSlogSender = async opts => { const tracingProvider = makeOtelTracingProvider(opts) || new BasicTracerProvider(); @@ -52,7 +54,7 @@ export const makeSlogSender = async opts => { tracingProvider.register(); const tracer = tracingProvider.getTracer('slog-trace', opts.version); - const { slogSender, finish } = makeSlogToOtelKit(tracer); + const { slogSender, finish } = makeSlogToOtelKit(tracer, undefined, opts); // Cleanly shutdown if possible. const { registerShutdown } = makeShutdown(); diff --git a/packages/telemetry/src/slog-to-otel.js b/packages/telemetry/src/slog-to-otel.js index b539b7da8e4..b853b5086a3 100644 --- a/packages/telemetry/src/slog-to-otel.js +++ b/packages/telemetry/src/slog-to-otel.js @@ -1,3 +1,4 @@ +/* global globalThis */ import otel, { SpanStatusCode } from '@opentelemetry/api'; import { Fail, q } from '@endo/errors'; @@ -78,8 +79,10 @@ export const floatSecondsToHiRes = sFloat => { /** * @param {import('@opentelemetry/api').Tracer} tracer * @param {Record} [overrideAttrs] + * @param {import('./index.js').MakeSlogSenderOptions} [powers] */ -export const makeSlogToOtelKit = (tracer, overrideAttrs = {}) => { +export const makeSlogToOtelKit = (tracer, overrideAttrs = {}, powers = {}) => { + const { console = globalThis.console } = powers; let now; let nowFloat; /** @type {Record} */ diff --git a/packages/telemetry/test/import.test.js b/packages/telemetry/test/import.test.js index 88ed1da8a84..695921ff821 100644 --- a/packages/telemetry/test/import.test.js +++ b/packages/telemetry/test/import.test.js @@ -1,4 +1,5 @@ /* global setTimeout */ +import { info } from 'console'; import { test } from './prepare-test-env-ava.js'; import { getTelemetryProviders } from '../src/index.js'; @@ -8,10 +9,17 @@ const sleep = timeoutMs => test('get telemetry providers', async t => { const logged = []; + const mockMethod = + level => + (...args) => { + logged.push([level, ...args]); + }; const mockConsole = { - warn: (...args) => { - logged.push(args); - }, + debug: mockMethod('debug'), + log: mockMethod('log'), + info: mockMethod('info'), + warn: mockMethod('warn'), + error: mockMethod('error'), }; const providers = getTelemetryProviders({ console: mockConsole, env: {} }); t.is(providers.metricsProvider, undefined); @@ -31,6 +39,6 @@ test('get telemetry providers', async t => { t.deepEqual(logged, []); await sleep(250); t.deepEqual(logged, [ - ['Prometheus scrape endpoint: http://0.0.0.0:9393/metrics'], + ['warn', 'Prometheus scrape endpoint: http://0.0.0.0:9393/metrics'], ]); });