const { recognizedObject: r = {}, traces = axios.create({ baseURL: opentelemetry_settings.baseUrl, timeout: 16000, }), } = this; function generateIdHex(numBytes = 8) { const bytes = crypto.getRandomValues(new Uint8Array(numBytes)); return Array.from(bytes) .map((b) => b.toString(16).padStart(2, "0")) .join(""); } return { async startSpan(name) { if (name == null) { throw new Error("Span name is required"); } // Initialize telemetry object if it doesn't exist if ("telemetry" in r == false) { r.telemetry = { spans: [] }; if (opentelemetry_settings.trace == "conversation") { r.telemetry.traceId = r.conversationId.replace(/-/gi, ""); } else { r.telemetry.traceId = generateIdHex(16); } } try { const span = { name: name, resourceSpans: [ { resource: { attributes: [ { key: "service.name", value: { stringValue: "ivastudio.verint.live", }, }, { key: "conversationId", value: { stringValue: r.conversationId, }, }, { key: "workspaceId", value: { stringValue: r.workspaceId, }, }, ], }, scopeSpans: [ { spans: [ { traceId: r.telemetry.traceId, spanId: generateIdHex(), name: name, startTimeUnixNano: "" + Date.now() * 1000000, kind: 2, attributes: [ { key: "input", value: { stringValue: r.input, }, }, { key: "channel", value: { stringValue: ( req.body?.metadata?.channel ?? req.body?.channel ?? "web" ).toLowerCase(), }, }, { key: "sessionId", value: { stringValue: ( req.body?.metadata?.sessionId ?? "undefined" ), }, }, ], }, ], }, ], }, ], }; r.telemetry.spans.unshift(span); return span; } catch (e) { throw e; } }, async endSpan(name) { if (name == null) { throw new Error("Span name is required"); } if ("telemetry" in r == false) { // nothing to end return; } try { const spanIndex = r.telemetry.spans.findIndex( (span) => span.name === name ); if (spanIndex == -1) { // nothing to end return; } const span = r.telemetry.spans.splice(spanIndex, 1)[0]; if (r.telemetry.spans.length >= 1) { // Assume span now at index is the parent const parentSpan = r.telemetry.spans[spanIndex]; if (parentSpan) { span.resourceSpans[0].scopeSpans[0].spans[0].parentSpanId = parentSpan.resourceSpans[0].scopeSpans[0].spans[0].spanId; } else { console.debug(name + " has no parentSpan"); } } span.resourceSpans[0].scopeSpans[0].spans[0].endTimeUnixNano = "" + Date.now() * 1000000; span.resourceSpans[0].scopeSpans[0].spans[0].attributes.push({ key: "answers", value: { stringValue: JSON.stringify(r.answers), }, }); const response = await traces.post(`/v1/traces`, span, { headers: { "Content-Type": "application/json", }, }); return response.data; } catch (e) { throw e; } }, };