UNPKG

@multiplayer-app/otlp-core

Version:

Multiplayer otlp core

227 lines 13.1 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; import * as zlib from 'zlib'; import { ATTR_MULTIPLAYER_HTTP_REQUEST_BODY, ATTR_MULTIPLAYER_HTTP_REQUEST_HEADERS, ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY, ATTR_MULTIPLAYER_HTTP_RESPONSE_HEADERS, MULTIPLAYER_MAX_HTTP_REQUEST_RESPONSE_SIZE, ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY_ENCODING, MULTIPLAYER_TRACE_DEBUG_PREFIX, } from './constants.node'; import { mask, schemify, isGzip, maskHeaders } from './helpers'; export var MultiplayerHttpInstrumentationHooksNode = { responseHook: function (options) { if (options === void 0) { options = {}; } return function (span, response) { try { options = __assign({ maskDebSpanPayload: true, schemifyDocSpanPayload: true }, options); var _response_1 = response; var traceId_1 = span.spanContext().traceId; if (_response_1.setHeader) { _response_1.setHeader('X-Trace-Id', traceId_1); } var _a = __read([_response_1.write, _response_1.end], 2), oldWrite_1 = _a[0], oldEnd_1 = _a[1]; var chunks_1 = []; _response_1.write = function () { var restArgs = []; for (var _i = 0; _i < arguments.length; _i++) { restArgs[_i] = arguments[_i]; } chunks_1.push(Buffer.from(restArgs[0])); // eslint-disable-next-line // @ts-ignore oldWrite_1.apply(_response_1, restArgs); }; // eslint-disable-next-line // @ts-ignore _response_1.end = function () { var restArgs = []; for (var _i = 0; _i < arguments.length; _i++) { restArgs[_i] = arguments[_i]; } return __awaiter(this, void 0, void 0, function () { var responseBuffer, responseBody, skipResponseBodyModification, dezippedBuffer, headers, stringifiedHeaders; return __generator(this, function (_a) { switch (_a.label) { case 0: if (restArgs[0]) { chunks_1.push(Buffer.from(restArgs[0])); } responseBuffer = Buffer.concat(chunks_1); if (responseBuffer.byteLength === 0 || responseBuffer.byteLength > (options.maxPayloadSize || MULTIPLAYER_MAX_HTTP_REQUEST_RESPONSE_SIZE)) { // eslint-disable-next-line // @ts-ignore return [2 /*return*/, oldEnd_1.apply(_response_1, restArgs)]; } skipResponseBodyModification = false; if (!isGzip(responseBuffer)) return [3 /*break*/, 4]; if (!options.uncompressPayload) return [3 /*break*/, 2]; return [4 /*yield*/, new Promise(function (resolve) { return zlib .gunzip(responseBuffer, function (err, dezipped) { if (err) { return resolve(Buffer.from('')); } else { return resolve(dezipped); } }); })]; case 1: dezippedBuffer = _a.sent(); responseBody = dezippedBuffer.toString('utf-8'); return [3 /*break*/, 3]; case 2: span.setAttribute(ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY_ENCODING, 'gzip'); skipResponseBodyModification = true; responseBody = responseBuffer.toString('hex'); _a.label = 3; case 3: return [3 /*break*/, 5]; case 4: responseBody = responseBuffer.toString('utf-8'); _a.label = 5; case 5: if (!skipResponseBodyModification) { if (traceId_1.startsWith(MULTIPLAYER_TRACE_DEBUG_PREFIX) && options.maskDebSpanPayload) { responseBody = mask(responseBody); } else if (options.schemifyDocSpanPayload) { responseBody = schemify(responseBody); } else if (typeof responseBody !== 'string') { responseBody = JSON.stringify(responseBody); } } if (responseBody.length) { span.setAttribute(ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY, responseBody); } headers = maskHeaders(_response_1.getHeaders(), options.headersToMask); stringifiedHeaders = JSON.stringify(headers); if (stringifiedHeaders === null || stringifiedHeaders === void 0 ? void 0 : stringifiedHeaders.length) { span.setAttribute(ATTR_MULTIPLAYER_HTTP_RESPONSE_HEADERS, stringifiedHeaders); } // eslint-disable-next-line // @ts-ignore return [2 /*return*/, oldEnd_1.apply(_response_1, restArgs)]; } }); }); }; } catch (error) { // eslint-disable-next-line console.error('An error occured in multiplayer otlp http responseHook', error); } }; }, requestHook: function (options) { if (options === void 0) { options = {}; } return function (span, request) { var _a; try { options = __assign({ maskDebSpanPayload: true, schemifyDocSpanPayload: true }, options); var traceId_2 = span.spanContext().traceId; var _request = request; var contentType = (_a = _request === null || _request === void 0 ? void 0 : _request.headers) === null || _a === void 0 ? void 0 : _a['content-type']; if (!contentType || !(contentType === null || contentType === void 0 ? void 0 : contentType.includes('application/json'))) { return; } var headers = maskHeaders(_request.headers, options.headersToMask); span.setAttribute(ATTR_MULTIPLAYER_HTTP_REQUEST_HEADERS, JSON.stringify(headers)); var body_1 = ''; _request.on('data', function (chunk) { body_1 += chunk; }); _request.on('end', function () { try { var requestBodySizeBytes = Buffer.byteLength(body_1, 'utf8'); if (requestBodySizeBytes === 0 || requestBodySizeBytes > (options.maxPayloadSize || MULTIPLAYER_MAX_HTTP_REQUEST_RESPONSE_SIZE)) { return; } var requestBody = body_1; if (!requestBody) return; if (traceId_2.startsWith(MULTIPLAYER_TRACE_DEBUG_PREFIX) && options.maskDebSpanPayload) { requestBody = mask(requestBody); } else if (options.schemifyDocSpanPayload) { requestBody = schemify(requestBody); } else if (typeof requestBody !== 'string') { requestBody = JSON.stringify(requestBody); } if (requestBody === null || requestBody === void 0 ? void 0 : requestBody.length) { span.setAttribute(ATTR_MULTIPLAYER_HTTP_REQUEST_BODY, requestBody); } } catch (err) { // eslint-disable-next-line console.error('[MULTIPLAYER-HTTP-REQ-HOOK] An error occured in multiplayer otlp http requestHook', err); } }); } catch (error) { // eslint-disable-next-line console.error('An error occured in multiplayer otlp http requestHook', error); } }; }, }; //# sourceMappingURL=MultiplayerHttpInstrumentationHooksNode.js.map