UNPKG

@agentscope/studio

Version:

AgentScope Studio is a powerful local monitoring and visualization tool designed to provide real-time insights into your system's performance and behavior.

129 lines (128 loc) 5.73 kB
"use strict"; 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = __importDefault(require("express")); const util_1 = require("util"); const zlib_1 = require("zlib"); const Trace_1 = require("../dao/Trace"); const socket_1 = require("../trpc/socket"); const trace_1 = require("./opentelemetry/proto/trace/v1/trace"); const processor_1 = require("./processor"); const gunzipAsync = (0, util_1.promisify)(zlib_1.gunzip); const inflateAsync = (0, util_1.promisify)(zlib_1.inflate); const otelRouter = express_1.default.Router(); // Request: POST /v1/traces otelRouter.post('/traces', (req, res) => __awaiter(void 0, void 0, void 0, function* () { try { console.debug(`[OTEL] Received OpenTelemetry traces request: ${req.method} ${req.path}`); console.debug(`[OTEL] Content-Type: ${req.get('content-type')}`); console.debug(`[OTEL] Content-Encoding: ${req.get('content-encoding')}`); console.debug(`[OTEL] Content-Length: ${req.get('content-length')}`); const contentType = req.get('content-type') || ''; const contentEncoding = req.get('content-encoding'); // Check content-type if (!contentType || (!contentType.includes('application/x-protobuf') && !contentType.includes('application/json'))) { return res.status(415).json({ error: 'Unsupported Media Type', message: 'Content-Type must be application/x-protobuf or application/json', }); } // Check content-encoding if (contentEncoding && !['gzip', 'deflate'].includes(contentEncoding)) { return res.status(415).json({ error: 'Unsupported Content Encoding', message: `Unsupported content encoding: ${contentEncoding}`, }); } let body = req.body; if (!body || body.length === 0) { console.error('[OTEL] Empty request body'); return res.status(400).json({ error: 'Bad Request', message: 'Empty request body', }); } // Handle compressed data try { if (contentEncoding === 'gzip') { body = yield gunzipAsync(body); } else if (contentEncoding === 'deflate') { body = yield inflateAsync(body); } } catch (error) { console.error('[OTEL] Failed to decompress request body:', error); return res.status(400).json({ error: 'Bad Request', message: 'Failed to decompress request body', }); } let resourceSpans; // Parse the body based on content type if (contentType.includes('application/x-protobuf')) { try { const traceData = trace_1.opentelemetry.proto.trace.v1.TracesData.deserializeBinary(body).toObject(); resourceSpans = traceData.resource_spans; } catch (error) { console.error('[OTEL] Failed to parse protobuf:', error); return res.status(422).json({ error: 'Unprocessable Entity', message: 'Failed to parse OpenTelemetry protobuf data', }); } } else if (contentType.includes('application/json')) { try { const jsonData = JSON.parse(body.toString()); resourceSpans = jsonData.resourceSpans; } catch (error) { console.error('[OTEL] Failed to parse JSON:', error); return res.status(422).json({ error: 'Unprocessable Entity', message: 'Failed to parse JSON data', }); } } if (!resourceSpans || !Array.isArray(resourceSpans)) { return res.status(422).json({ error: 'Invalid or missing resourceSpans data', message: 'Invalid OpenTelemetry data', }); } const spans = processor_1.SpanProcessor.batchProcessOTLPTraces(resourceSpans); // Save spans to the databases yield Trace_1.SpanDao.saveSpans(spans); // Broadcast spans to the run room socket_1.SocketManager.broadcastSpanDataToRunRoom(spans); return res.status(200).json({ message: `Processed traces successfully`, }); } catch (error) { console.error('Error processing OpenTelemetry traces:', error); res.status(500); const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; res.statusMessage = errorMessage; res.json({ error: 'Internal Server Error', message: 'Failed to process traces', }); } })); exports.default = otelRouter;