From b5b79b94f2d634510b20d819f498b2aadad04c0b Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Mon, 29 Aug 2022 14:13:13 -0500 Subject: [PATCH] Manually instrument some archive logic (#44) --- server/fetch-events-in-range.js | 3 +- server/fetch-room-data.js | 3 +- .../1-render-hydrogen-to-string.js | 3 +- server/tracing/trace-utilities.js | 62 +++++++++++++++++++ 4 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 server/tracing/trace-utilities.js diff --git a/server/fetch-events-in-range.js b/server/fetch-events-in-range.js index 582c1e5..36ae229 100644 --- a/server/fetch-events-in-range.js +++ b/server/fetch-events-in-range.js @@ -4,6 +4,7 @@ const assert = require('assert'); const urlJoin = require('url-join'); const { fetchEndpointAsJson } = require('./lib/fetch-endpoint'); +const { traceFunction } = require('./tracing/trace-utilities'); const config = require('./lib/config'); const matrixServerUrl = config.get('matrixServerUrl'); @@ -140,4 +141,4 @@ async function fetchEventsInRange(accessToken, roomId, startTs, endTs, limit) { }; } -module.exports = fetchEventsInRange; +module.exports = traceFunction(fetchEventsInRange); diff --git a/server/fetch-room-data.js b/server/fetch-room-data.js index 7bf03b6..48b0915 100644 --- a/server/fetch-room-data.js +++ b/server/fetch-room-data.js @@ -4,6 +4,7 @@ const assert = require('assert'); const urlJoin = require('url-join'); const { fetchEndpointAsJson } = require('./lib/fetch-endpoint'); +const { traceFunction } = require('./tracing/trace-utilities'); const config = require('./lib/config'); const matrixServerUrl = config.get('matrixServerUrl'); @@ -48,4 +49,4 @@ async function fetchRoomData(accessToken, roomId) { }; } -module.exports = fetchRoomData; +module.exports = traceFunction(fetchRoomData); diff --git a/server/hydrogen-render/1-render-hydrogen-to-string.js b/server/hydrogen-render/1-render-hydrogen-to-string.js index dbdf841..6c9c40d 100644 --- a/server/hydrogen-render/1-render-hydrogen-to-string.js +++ b/server/hydrogen-render/1-render-hydrogen-to-string.js @@ -8,6 +8,7 @@ const fork = require('child_process').fork; const assert = require('assert'); const RethrownError = require('../lib/rethrown-error'); +const { traceFunction } = require('../tracing/trace-utilities'); // The render should be fast. If it's taking more than 5 seconds, something has // gone really wrong. @@ -105,4 +106,4 @@ async function renderHydrogenToString(options) { } } -module.exports = renderHydrogenToString; +module.exports = traceFunction(renderHydrogenToString); diff --git a/server/tracing/trace-utilities.js b/server/tracing/trace-utilities.js new file mode 100644 index 0000000..ccc9c0d --- /dev/null +++ b/server/tracing/trace-utilities.js @@ -0,0 +1,62 @@ +'use strict'; + +const assert = require('assert'); +const opentelemetryApi = require('@opentelemetry/api'); + +const packageInfo = require('../../package.json'); +assert(packageInfo.name); +assert(packageInfo.version); + +const tracer = opentelemetryApi.trace.getTracer(packageInfo.name, packageInfo.version); + +/** + * Wraps an existing function to instrument it with OpenTelemetry tracing. Now + * whenever the function runs, it will create a span with the given name. It's + * basically `tracer.startActiveSpan` with some sensible default behaviors to + * automatically end spans: + * - when function completes successfully, status of span also set + * - when function throws (exception recorded against span) + * - if function returns a Promise, the promise is resolved + * @param name Span name, passed through to `tracer.startActiveSpan` + * @param fn The function to wrap + * @returns The wrapped function + * + * via + * https://github.com/open-telemetry/opentelemetry-js-api/issues/164#issuecomment-1174925516 + */ +function trace(name, fn) { + return function (...args) { + return tracer.startActiveSpan(name, async (span) => { + try { + const result = await Promise.resolve(fn(...args)); + span.setStatus({ + code: opentelemetryApi.SpanStatusCode.OK, + }); + return result; + } catch (e) { + const err = e; + span.recordException(err); + span.setStatus({ + code: opentelemetryApi.SpanStatusCode.ERROR, + message: err.message, + }); + throw err; + } finally { + span.end(); + } + }); + }; +} + +/** + * Wraps an existing function to instrument it with OpenTelemetry tracing. The + * span name will be the name of the function. + */ +function traceFunction(fn) { + return trace(fn.name, fn); +} + +module.exports = { + trace, + traceFunction, +};