UNPKG

@sentry/google-cloud-serverless

Version:
71 lines (68 loc) • 3.21 kB
import { URL_PATH, HTTP_REQUEST_METHOD, SENTRY_ORIGIN, SENTRY_SEGMENT_NAME_SOURCE, FAAS_TRIGGER, FAAS_NAME, SENTRY_OP } from '@sentry/conventions/attributes'; import { FUNCTION_GCP } from '@sentry/conventions/op'; import { stripUrlQueryAndFragment, isString, httpRequestToRequestData, getClient, hasSpanStreamingEnabled, SERVERLESS_FUNCTION_SPAN_NAME_FALLBACK, setHttpStatus, debug, handleCallbackErrors } from '@sentry/core'; import { continueTrace, getCurrentScope, startSpanManual, flush, captureException } from '@sentry/node'; import { DEBUG_BUILD } from '../debug-build.js'; import { proxyFunction, domainify, getFunctionName, markEventUnhandled } from '../utils.js'; function wrapHttpFunction(fn, wrapOptions = {}) { const wrap = (f) => domainify(_wrapHttpFunction(f, wrapOptions)); let overrides; const emulatorFunc = fn.__emulator_func; if (emulatorFunc) { overrides = { __emulator_func: proxyFunction(emulatorFunc, wrap) }; } return proxyFunction(fn, wrap, overrides); } function _wrapHttpFunction(fn, options) { const flushTimeout = options.flushTimeout || 2e3; return (req, res) => { const reqMethod = (req.method || "").toUpperCase(); const reqUrl = stripUrlQueryAndFragment(req.originalUrl || req.url || ""); const sentryTrace = req.headers && isString(req.headers["sentry-trace"]) ? req.headers["sentry-trace"] : void 0; const baggage = req.headers?.baggage; return continueTrace({ sentryTrace, baggage }, () => { const normalizedRequest = httpRequestToRequestData(req); getCurrentScope().setSDKProcessingMetadata({ normalizedRequest }); const functionName = getFunctionName(); const client = getClient(); const hasSpanStreaming = client && hasSpanStreamingEnabled(client); const name = hasSpanStreaming ? functionName || SERVERLESS_FUNCTION_SPAN_NAME_FALLBACK : `${reqMethod} ${reqUrl}`; return startSpanManual( { name, attributes: { [SENTRY_OP]: FUNCTION_GCP, [FAAS_NAME]: functionName, [FAAS_TRIGGER]: "http", [SENTRY_SEGMENT_NAME_SOURCE]: hasSpanStreaming ? "component" : "route", [SENTRY_ORIGIN]: "auto.function.serverless.gcp_http", // The method and path used to be the span name; they stay on the span so that // information survives the low-cardinality rename. [HTTP_REQUEST_METHOD]: reqMethod || void 0, [URL_PATH]: reqUrl || void 0 } }, (span) => { const _end = res.end; res.end = function(chunk, encoding, cb) { setHttpStatus(span, res.statusCode); span.end(); flush(flushTimeout).then(null, (e) => { DEBUG_BUILD && debug.error(e); }).then(() => { _end.call(this, chunk, encoding, cb); }); }; return handleCallbackErrors( () => fn(req, res), (err) => { captureException(err, (scope) => markEventUnhandled(scope, "auto.function.serverless.gcp_http")); } ); } ); }); }; } export { wrapHttpFunction }; //# sourceMappingURL=http.js.map