const traces = axios.create({ baseURL: opentelemetry_settings.baseUrl, timeout: 16000, }); return { endSpan(conversationId) { return new Promise(async (resolve, reject) => { try { const latencySpanKey = `latency-span-${conversationId}`; const span = JSON.parse(await redis.get(latencySpanKey)); if (!span) { resolve(); return; } redis.del(latencySpanKey); span.resourceSpans[0].scopeSpans[0].spans[0].endTimeUnixNano = "" + Date.now() * 1000000; console.log("latencySpan span:"); console.log(span); const response = await traces.post(`/v1/traces`, span, { headers: { "Content-Type": "application/json", }, }); resolve(span); } catch (error) { reject(error); } }); }, startSpan(conversationId, startTime) { return new Promise(async (resolve, reject) => { try { const latencySpanKey = `latency-span-${conversationId}`; const traceId = conversationId.replace(/-/gi, ""); const span = { resourceSpans: [ { resource: { attributes: [ { key: "service.name", value: { stringValue: "end-of-utterance-latency", }, }, ], }, scopeSpans: [ { scope: { name: "scope-name", version: "1.0.0", attributes: [ { key: "my.scope.attribute", value: { stringValue: "some scope attribute", }, }, ], }, spans: [ { traceId: traceId, spanId: getIdGenerator(8)(), name: "end-of-utterance-latency", startTimeUnixNano: startTime, kind: 2, }, ], }, ], }, ], }; await redis.set(latencySpanKey, JSON.stringify(span)); await redis.expire(latencySpanKey, 300); resolve(span); } catch (error) { reject(error); } }); }, }; function getIdGenerator(bytes) { return function generateId() { const SHARED_BUFFER = buffer.Buffer.allocUnsafe(16); for (let i = 0; i < bytes / 4; i++) { // unsigned right shift drops decimal part of the number // it is required because if a number between 2**32 and 2**32 - 1 is generated, an out of range error is thrown by writeUInt32BE SHARED_BUFFER.writeUInt32BE((Math.random() * 2 ** 32) >>> 0, i * 4); } // If buffer is all 0, set the last byte to 1 to guarantee a valid w3c id is generated for (let i = 0; i < bytes; i++) { if (SHARED_BUFFER[i] > 0) { break; } else if (i === bytes - 1) { SHARED_BUFFER[bytes - 1] = 1; } } return SHARED_BUFFER.toString("hex", 0, bytes); }; }