@livekit/agents 1.0.22 → 1.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/inference/api_protos.cjs +2 -2
- package/dist/inference/api_protos.cjs.map +1 -1
- package/dist/inference/api_protos.d.cts +16 -16
- package/dist/inference/api_protos.d.ts +16 -16
- package/dist/inference/api_protos.js +2 -2
- package/dist/inference/api_protos.js.map +1 -1
- package/dist/ipc/job_proc_lazy_main.cjs +35 -1
- package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
- package/dist/ipc/job_proc_lazy_main.js +13 -1
- package/dist/ipc/job_proc_lazy_main.js.map +1 -1
- package/dist/job.cjs +52 -6
- package/dist/job.cjs.map +1 -1
- package/dist/job.d.cts +2 -0
- package/dist/job.d.ts +2 -0
- package/dist/job.d.ts.map +1 -1
- package/dist/job.js +52 -6
- package/dist/job.js.map +1 -1
- package/dist/llm/llm.cjs +38 -3
- package/dist/llm/llm.cjs.map +1 -1
- package/dist/llm/llm.d.cts +1 -0
- package/dist/llm/llm.d.ts +1 -0
- package/dist/llm/llm.d.ts.map +1 -1
- package/dist/llm/llm.js +38 -3
- package/dist/llm/llm.js.map +1 -1
- package/dist/log.cjs +34 -10
- package/dist/log.cjs.map +1 -1
- package/dist/log.d.cts +7 -0
- package/dist/log.d.ts +7 -0
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +34 -11
- package/dist/log.js.map +1 -1
- package/dist/telemetry/index.cjs +23 -2
- package/dist/telemetry/index.cjs.map +1 -1
- package/dist/telemetry/index.d.cts +4 -1
- package/dist/telemetry/index.d.ts +4 -1
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/index.js +27 -2
- package/dist/telemetry/index.js.map +1 -1
- package/dist/telemetry/logging.cjs +65 -0
- package/dist/telemetry/logging.cjs.map +1 -0
- package/dist/telemetry/logging.d.cts +21 -0
- package/dist/telemetry/logging.d.ts +21 -0
- package/dist/telemetry/logging.d.ts.map +1 -0
- package/dist/telemetry/logging.js +40 -0
- package/dist/telemetry/logging.js.map +1 -0
- package/dist/telemetry/otel_http_exporter.cjs +144 -0
- package/dist/telemetry/otel_http_exporter.cjs.map +1 -0
- package/dist/telemetry/otel_http_exporter.d.cts +62 -0
- package/dist/telemetry/otel_http_exporter.d.ts +62 -0
- package/dist/telemetry/otel_http_exporter.d.ts.map +1 -0
- package/dist/telemetry/otel_http_exporter.js +120 -0
- package/dist/telemetry/otel_http_exporter.js.map +1 -0
- package/dist/telemetry/pino_otel_transport.cjs +217 -0
- package/dist/telemetry/pino_otel_transport.cjs.map +1 -0
- package/dist/telemetry/pino_otel_transport.d.cts +58 -0
- package/dist/telemetry/pino_otel_transport.d.ts +58 -0
- package/dist/telemetry/pino_otel_transport.d.ts.map +1 -0
- package/dist/telemetry/pino_otel_transport.js +189 -0
- package/dist/telemetry/pino_otel_transport.js.map +1 -0
- package/dist/telemetry/traces.cjs +225 -16
- package/dist/telemetry/traces.cjs.map +1 -1
- package/dist/telemetry/traces.d.cts +17 -0
- package/dist/telemetry/traces.d.ts +17 -0
- package/dist/telemetry/traces.d.ts.map +1 -1
- package/dist/telemetry/traces.js +211 -14
- package/dist/telemetry/traces.js.map +1 -1
- package/dist/tts/tts.cjs +62 -5
- package/dist/tts/tts.cjs.map +1 -1
- package/dist/tts/tts.d.cts +2 -0
- package/dist/tts/tts.d.ts +2 -0
- package/dist/tts/tts.d.ts.map +1 -1
- package/dist/tts/tts.js +62 -5
- package/dist/tts/tts.js.map +1 -1
- package/dist/utils.cjs +6 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +5 -0
- package/dist/utils.js.map +1 -1
- package/dist/voice/agent_activity.cjs +93 -7
- package/dist/voice/agent_activity.cjs.map +1 -1
- package/dist/voice/agent_activity.d.cts +3 -0
- package/dist/voice/agent_activity.d.ts +3 -0
- package/dist/voice/agent_activity.d.ts.map +1 -1
- package/dist/voice/agent_activity.js +93 -7
- package/dist/voice/agent_activity.js.map +1 -1
- package/dist/voice/agent_session.cjs +122 -27
- package/dist/voice/agent_session.cjs.map +1 -1
- package/dist/voice/agent_session.d.cts +15 -0
- package/dist/voice/agent_session.d.ts +15 -0
- package/dist/voice/agent_session.d.ts.map +1 -1
- package/dist/voice/agent_session.js +122 -27
- package/dist/voice/agent_session.js.map +1 -1
- package/dist/voice/audio_recognition.cjs +69 -22
- package/dist/voice/audio_recognition.cjs.map +1 -1
- package/dist/voice/audio_recognition.d.cts +5 -0
- package/dist/voice/audio_recognition.d.ts +5 -0
- package/dist/voice/audio_recognition.d.ts.map +1 -1
- package/dist/voice/audio_recognition.js +69 -22
- package/dist/voice/audio_recognition.js.map +1 -1
- package/dist/voice/generation.cjs +43 -3
- package/dist/voice/generation.cjs.map +1 -1
- package/dist/voice/generation.d.ts.map +1 -1
- package/dist/voice/generation.js +43 -3
- package/dist/voice/generation.js.map +1 -1
- package/dist/voice/report.cjs +3 -2
- package/dist/voice/report.cjs.map +1 -1
- package/dist/voice/report.d.cts +7 -1
- package/dist/voice/report.d.ts +7 -1
- package/dist/voice/report.d.ts.map +1 -1
- package/dist/voice/report.js +3 -2
- package/dist/voice/report.js.map +1 -1
- package/package.json +8 -2
- package/src/inference/api_protos.ts +2 -2
- package/src/ipc/job_proc_lazy_main.ts +12 -1
- package/src/job.ts +59 -10
- package/src/llm/llm.ts +48 -5
- package/src/log.ts +52 -15
- package/src/telemetry/index.ts +22 -4
- package/src/telemetry/logging.ts +55 -0
- package/src/telemetry/otel_http_exporter.ts +191 -0
- package/src/telemetry/pino_otel_transport.ts +265 -0
- package/src/telemetry/traces.ts +320 -20
- package/src/tts/tts.ts +71 -9
- package/src/utils.ts +5 -0
- package/src/voice/agent_activity.ts +140 -22
- package/src/voice/agent_session.ts +174 -34
- package/src/voice/audio_recognition.ts +85 -26
- package/src/voice/generation.ts +59 -7
- package/src/voice/report.ts +10 -4
package/dist/log.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/log.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { Logger } from 'pino';\nimport { pino } from 'pino';\n\n/** @internal */\nexport type LoggerOptions = {\n pretty: boolean;\n level?: string;\n};\n\n/** @internal */\nexport let loggerOptions: LoggerOptions;\n\n/** @internal */\nlet logger: Logger | undefined = undefined;\n\n/** @internal */\nexport const log = () => {\n if (!logger) {\n throw new TypeError('logger not initialized. did you forget to run initializeLogger()?');\n }\n return logger;\n};\n\n/** @internal */\nexport const initializeLogger = ({ pretty, level }: LoggerOptions) => {\n loggerOptions = { pretty, level };\n logger = pino(\n pretty\n
|
|
1
|
+
{"version":3,"sources":["../src/log.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Writable } from 'node:stream';\nimport type { DestinationStream, Logger } from 'pino';\nimport { multistream, pino } from 'pino';\nimport { build as pinoPretty } from 'pino-pretty';\nimport { type PinoLogObject, emitToOtel } from './telemetry/pino_otel_transport.js';\n\n/** @internal */\nexport type LoggerOptions = {\n pretty: boolean;\n level?: string;\n};\n\n/** @internal */\nexport let loggerOptions: LoggerOptions;\n\n/** @internal */\nlet logger: Logger | undefined = undefined;\n\n/** @internal */\nlet otelEnabled = false;\n\n/** @internal */\nexport const log = () => {\n if (!logger) {\n throw new TypeError('logger not initialized. did you forget to run initializeLogger()?');\n }\n return logger;\n};\n\n/** @internal */\nexport const initializeLogger = ({ pretty, level }: LoggerOptions) => {\n loggerOptions = { pretty, level };\n logger = pino(\n { level: level || 'info' },\n pretty ? pinoPretty({ colorize: true }) : process.stdout,\n );\n};\n\n/**\n * Custom Pino destination that parses JSON logs and emits to OTEL.\n * This receives the FULL serialized log including msg, level, time, etc.\n */\nclass OtelDestination extends Writable {\n _write(chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void): void {\n try {\n const line = chunk.toString().trim();\n if (line) {\n const logObj = JSON.parse(line) as PinoLogObject;\n emitToOtel(logObj);\n }\n } catch {\n // Ignore parse errors (e.g., non-JSON lines)\n }\n callback();\n }\n}\n\n/**\n * Enable OTEL logging by reconfiguring the logger with multistream.\n * Uses a custom destination that receives full JSON logs (with msg, level, time).\n *\n * @internal\n */\nexport const enableOtelLogging = () => {\n if (otelEnabled || !logger) {\n console.warn('OTEL logging already enabled or logger not initialized');\n return;\n }\n otelEnabled = true;\n\n const { pretty, level } = loggerOptions;\n\n const logLevel = level || 'info';\n const streams: { stream: DestinationStream; level: string }[] = [\n { stream: pretty ? pinoPretty({ colorize: true }) : process.stdout, level: logLevel },\n { stream: new OtelDestination(), level: 'debug' },\n ];\n\n logger = pino({ level: logLevel }, multistream(streams));\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,yBAAyB;AAEzB,kBAAkC;AAClC,yBAAoC;AACpC,iCAA+C;AASxC,IAAI;AAGX,IAAI,SAA6B;AAGjC,IAAI,cAAc;AAGX,MAAM,MAAM,MAAM;AACvB,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,UAAU,mEAAmE;AAAA,EACzF;AACA,SAAO;AACT;AAGO,MAAM,mBAAmB,CAAC,EAAE,QAAQ,MAAM,MAAqB;AACpE,kBAAgB,EAAE,QAAQ,MAAM;AAChC,eAAS;AAAA,IACP,EAAE,OAAO,SAAS,OAAO;AAAA,IACzB,aAAS,mBAAAA,OAAW,EAAE,UAAU,KAAK,CAAC,IAAI,QAAQ;AAAA,EACpD;AACF;AAMA,MAAM,wBAAwB,4BAAS;AAAA,EACrC,OAAO,OAAe,WAAmB,UAAgD;AACvF,QAAI;AACF,YAAM,OAAO,MAAM,SAAS,EAAE,KAAK;AACnC,UAAI,MAAM;AACR,cAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,mDAAW,MAAM;AAAA,MACnB;AAAA,IACF,QAAQ;AAAA,IAER;AACA,aAAS;AAAA,EACX;AACF;AAQO,MAAM,oBAAoB,MAAM;AACrC,MAAI,eAAe,CAAC,QAAQ;AAC1B,YAAQ,KAAK,wDAAwD;AACrE;AAAA,EACF;AACA,gBAAc;AAEd,QAAM,EAAE,QAAQ,MAAM,IAAI;AAE1B,QAAM,WAAW,SAAS;AAC1B,QAAM,UAA0D;AAAA,IAC9D,EAAE,QAAQ,aAAS,mBAAAA,OAAW,EAAE,UAAU,KAAK,CAAC,IAAI,QAAQ,QAAQ,OAAO,SAAS;AAAA,IACpF,EAAE,QAAQ,IAAI,gBAAgB,GAAG,OAAO,QAAQ;AAAA,EAClD;AAEA,eAAS,kBAAK,EAAE,OAAO,SAAS,OAAG,yBAAY,OAAO,CAAC;AACzD;","names":["pinoPretty"]}
|
package/dist/log.d.cts
CHANGED
|
@@ -10,4 +10,11 @@ export declare let loggerOptions: LoggerOptions;
|
|
|
10
10
|
export declare const log: () => Logger;
|
|
11
11
|
/** @internal */
|
|
12
12
|
export declare const initializeLogger: ({ pretty, level }: LoggerOptions) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Enable OTEL logging by reconfiguring the logger with multistream.
|
|
15
|
+
* Uses a custom destination that receives full JSON logs (with msg, level, time).
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export declare const enableOtelLogging: () => void;
|
|
13
20
|
//# sourceMappingURL=log.d.ts.map
|
package/dist/log.d.ts
CHANGED
|
@@ -10,4 +10,11 @@ export declare let loggerOptions: LoggerOptions;
|
|
|
10
10
|
export declare const log: () => Logger;
|
|
11
11
|
/** @internal */
|
|
12
12
|
export declare const initializeLogger: ({ pretty, level }: LoggerOptions) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Enable OTEL logging by reconfiguring the logger with multistream.
|
|
15
|
+
* Uses a custom destination that receives full JSON logs (with msg, level, time).
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export declare const enableOtelLogging: () => void;
|
|
13
20
|
//# sourceMappingURL=log.d.ts.map
|
package/dist/log.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAqB,MAAM,EAAE,MAAM,MAAM,CAAC;AAKtD,gBAAgB;AAChB,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,gBAAgB;AAChB,eAAO,IAAI,aAAa,EAAE,aAAa,CAAC;AAQxC,gBAAgB;AAChB,eAAO,MAAM,GAAG,cAKf,CAAC;AAEF,gBAAgB;AAChB,eAAO,MAAM,gBAAgB,sBAAuB,aAAa,SAMhE,CAAC;AAqBF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,YAgB7B,CAAC"}
|
package/dist/log.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Writable } from "node:stream";
|
|
2
|
+
import { multistream, pino } from "pino";
|
|
3
|
+
import { build as pinoPretty } from "pino-pretty";
|
|
4
|
+
import { emitToOtel } from "./telemetry/pino_otel_transport.js";
|
|
2
5
|
let loggerOptions;
|
|
3
6
|
let logger = void 0;
|
|
7
|
+
let otelEnabled = false;
|
|
4
8
|
const log = () => {
|
|
5
9
|
if (!logger) {
|
|
6
10
|
throw new TypeError("logger not initialized. did you forget to run initializeLogger()?");
|
|
@@ -10,20 +14,39 @@ const log = () => {
|
|
|
10
14
|
const initializeLogger = ({ pretty, level }) => {
|
|
11
15
|
loggerOptions = { pretty, level };
|
|
12
16
|
logger = pino(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
target: "pino-pretty",
|
|
16
|
-
options: {
|
|
17
|
-
colorize: true
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
} : {}
|
|
17
|
+
{ level: level || "info" },
|
|
18
|
+
pretty ? pinoPretty({ colorize: true }) : process.stdout
|
|
21
19
|
);
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
};
|
|
21
|
+
class OtelDestination extends Writable {
|
|
22
|
+
_write(chunk, _encoding, callback) {
|
|
23
|
+
try {
|
|
24
|
+
const line = chunk.toString().trim();
|
|
25
|
+
if (line) {
|
|
26
|
+
const logObj = JSON.parse(line);
|
|
27
|
+
emitToOtel(logObj);
|
|
28
|
+
}
|
|
29
|
+
} catch {
|
|
30
|
+
}
|
|
31
|
+
callback();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const enableOtelLogging = () => {
|
|
35
|
+
if (otelEnabled || !logger) {
|
|
36
|
+
console.warn("OTEL logging already enabled or logger not initialized");
|
|
37
|
+
return;
|
|
24
38
|
}
|
|
39
|
+
otelEnabled = true;
|
|
40
|
+
const { pretty, level } = loggerOptions;
|
|
41
|
+
const logLevel = level || "info";
|
|
42
|
+
const streams = [
|
|
43
|
+
{ stream: pretty ? pinoPretty({ colorize: true }) : process.stdout, level: logLevel },
|
|
44
|
+
{ stream: new OtelDestination(), level: "debug" }
|
|
45
|
+
];
|
|
46
|
+
logger = pino({ level: logLevel }, multistream(streams));
|
|
25
47
|
};
|
|
26
48
|
export {
|
|
49
|
+
enableOtelLogging,
|
|
27
50
|
initializeLogger,
|
|
28
51
|
log,
|
|
29
52
|
loggerOptions
|
package/dist/log.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/log.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { Logger } from 'pino';\nimport { pino } from 'pino';\n\n/** @internal */\nexport type LoggerOptions = {\n pretty: boolean;\n level?: string;\n};\n\n/** @internal */\nexport let loggerOptions: LoggerOptions;\n\n/** @internal */\nlet logger: Logger | undefined = undefined;\n\n/** @internal */\nexport const log = () => {\n if (!logger) {\n throw new TypeError('logger not initialized. did you forget to run initializeLogger()?');\n }\n return logger;\n};\n\n/** @internal */\nexport const initializeLogger = ({ pretty, level }: LoggerOptions) => {\n loggerOptions = { pretty, level };\n logger = pino(\n pretty\n
|
|
1
|
+
{"version":3,"sources":["../src/log.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Writable } from 'node:stream';\nimport type { DestinationStream, Logger } from 'pino';\nimport { multistream, pino } from 'pino';\nimport { build as pinoPretty } from 'pino-pretty';\nimport { type PinoLogObject, emitToOtel } from './telemetry/pino_otel_transport.js';\n\n/** @internal */\nexport type LoggerOptions = {\n pretty: boolean;\n level?: string;\n};\n\n/** @internal */\nexport let loggerOptions: LoggerOptions;\n\n/** @internal */\nlet logger: Logger | undefined = undefined;\n\n/** @internal */\nlet otelEnabled = false;\n\n/** @internal */\nexport const log = () => {\n if (!logger) {\n throw new TypeError('logger not initialized. did you forget to run initializeLogger()?');\n }\n return logger;\n};\n\n/** @internal */\nexport const initializeLogger = ({ pretty, level }: LoggerOptions) => {\n loggerOptions = { pretty, level };\n logger = pino(\n { level: level || 'info' },\n pretty ? pinoPretty({ colorize: true }) : process.stdout,\n );\n};\n\n/**\n * Custom Pino destination that parses JSON logs and emits to OTEL.\n * This receives the FULL serialized log including msg, level, time, etc.\n */\nclass OtelDestination extends Writable {\n _write(chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void): void {\n try {\n const line = chunk.toString().trim();\n if (line) {\n const logObj = JSON.parse(line) as PinoLogObject;\n emitToOtel(logObj);\n }\n } catch {\n // Ignore parse errors (e.g., non-JSON lines)\n }\n callback();\n }\n}\n\n/**\n * Enable OTEL logging by reconfiguring the logger with multistream.\n * Uses a custom destination that receives full JSON logs (with msg, level, time).\n *\n * @internal\n */\nexport const enableOtelLogging = () => {\n if (otelEnabled || !logger) {\n console.warn('OTEL logging already enabled or logger not initialized');\n return;\n }\n otelEnabled = true;\n\n const { pretty, level } = loggerOptions;\n\n const logLevel = level || 'info';\n const streams: { stream: DestinationStream; level: string }[] = [\n { stream: pretty ? pinoPretty({ colorize: true }) : process.stdout, level: logLevel },\n { stream: new OtelDestination(), level: 'debug' },\n ];\n\n logger = pino({ level: logLevel }, multistream(streams));\n};\n"],"mappings":"AAGA,SAAS,gBAAgB;AAEzB,SAAS,aAAa,YAAY;AAClC,SAAS,SAAS,kBAAkB;AACpC,SAA6B,kBAAkB;AASxC,IAAI;AAGX,IAAI,SAA6B;AAGjC,IAAI,cAAc;AAGX,MAAM,MAAM,MAAM;AACvB,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,UAAU,mEAAmE;AAAA,EACzF;AACA,SAAO;AACT;AAGO,MAAM,mBAAmB,CAAC,EAAE,QAAQ,MAAM,MAAqB;AACpE,kBAAgB,EAAE,QAAQ,MAAM;AAChC,WAAS;AAAA,IACP,EAAE,OAAO,SAAS,OAAO;AAAA,IACzB,SAAS,WAAW,EAAE,UAAU,KAAK,CAAC,IAAI,QAAQ;AAAA,EACpD;AACF;AAMA,MAAM,wBAAwB,SAAS;AAAA,EACrC,OAAO,OAAe,WAAmB,UAAgD;AACvF,QAAI;AACF,YAAM,OAAO,MAAM,SAAS,EAAE,KAAK;AACnC,UAAI,MAAM;AACR,cAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,mBAAW,MAAM;AAAA,MACnB;AAAA,IACF,QAAQ;AAAA,IAER;AACA,aAAS;AAAA,EACX;AACF;AAQO,MAAM,oBAAoB,MAAM;AACrC,MAAI,eAAe,CAAC,QAAQ;AAC1B,YAAQ,KAAK,wDAAwD;AACrE;AAAA,EACF;AACA,gBAAc;AAEd,QAAM,EAAE,QAAQ,MAAM,IAAI;AAE1B,QAAM,WAAW,SAAS;AAC1B,QAAM,UAA0D;AAAA,IAC9D,EAAE,QAAQ,SAAS,WAAW,EAAE,UAAU,KAAK,CAAC,IAAI,QAAQ,QAAQ,OAAO,SAAS;AAAA,IACpF,EAAE,QAAQ,IAAI,gBAAgB,GAAG,OAAO,QAAQ;AAAA,EAClD;AAEA,WAAS,KAAK,EAAE,OAAO,SAAS,GAAG,YAAY,OAAO,CAAC;AACzD;","names":[]}
|
package/dist/telemetry/index.cjs
CHANGED
|
@@ -28,24 +28,45 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
var telemetry_exports = {};
|
|
30
30
|
__export(telemetry_exports, {
|
|
31
|
+
ExtraDetailsProcessor: () => import_logging.ExtraDetailsProcessor,
|
|
32
|
+
MetadataLogProcessor: () => import_logging.MetadataLogProcessor,
|
|
33
|
+
PinoCloudExporter: () => import_pino_otel_transport.PinoCloudExporter,
|
|
34
|
+
SimpleOTLPHttpLogExporter: () => import_otel_http_exporter.SimpleOTLPHttpLogExporter,
|
|
35
|
+
emitToOtel: () => import_pino_otel_transport.emitToOtel,
|
|
36
|
+
flushOtelLogs: () => import_traces.flushOtelLogs,
|
|
37
|
+
flushPinoLogs: () => import_pino_otel_transport.flushPinoLogs,
|
|
38
|
+
initPinoCloudExporter: () => import_pino_otel_transport.initPinoCloudExporter,
|
|
31
39
|
recordException: () => import_utils.recordException,
|
|
32
40
|
recordRealtimeMetrics: () => import_utils.recordRealtimeMetrics,
|
|
33
41
|
setTracerProvider: () => import_traces.setTracerProvider,
|
|
34
42
|
setupCloudTracer: () => import_traces.setupCloudTracer,
|
|
35
43
|
traceTypes: () => traceTypes,
|
|
36
|
-
tracer: () => import_traces.tracer
|
|
44
|
+
tracer: () => import_traces.tracer,
|
|
45
|
+
uploadSessionReport: () => import_traces.uploadSessionReport
|
|
37
46
|
});
|
|
38
47
|
module.exports = __toCommonJS(telemetry_exports);
|
|
48
|
+
var import_logging = require("./logging.cjs");
|
|
49
|
+
var import_otel_http_exporter = require("./otel_http_exporter.cjs");
|
|
50
|
+
var import_pino_otel_transport = require("./pino_otel_transport.cjs");
|
|
39
51
|
var traceTypes = __toESM(require("./trace_types.cjs"), 1);
|
|
40
52
|
var import_traces = require("./traces.cjs");
|
|
41
53
|
var import_utils = require("./utils.cjs");
|
|
42
54
|
// Annotate the CommonJS export names for ESM import in node:
|
|
43
55
|
0 && (module.exports = {
|
|
56
|
+
ExtraDetailsProcessor,
|
|
57
|
+
MetadataLogProcessor,
|
|
58
|
+
PinoCloudExporter,
|
|
59
|
+
SimpleOTLPHttpLogExporter,
|
|
60
|
+
emitToOtel,
|
|
61
|
+
flushOtelLogs,
|
|
62
|
+
flushPinoLogs,
|
|
63
|
+
initPinoCloudExporter,
|
|
44
64
|
recordException,
|
|
45
65
|
recordRealtimeMetrics,
|
|
46
66
|
setTracerProvider,
|
|
47
67
|
setupCloudTracer,
|
|
48
68
|
traceTypes,
|
|
49
|
-
tracer
|
|
69
|
+
tracer,
|
|
70
|
+
uploadSessionReport
|
|
50
71
|
});
|
|
51
72
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/telemetry/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\
|
|
1
|
+
{"version":3,"sources":["../../src/telemetry/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\nexport { ExtraDetailsProcessor, MetadataLogProcessor } from './logging.js';\nexport {\n SimpleOTLPHttpLogExporter,\n type SimpleLogRecord,\n type SimpleOTLPHttpLogExporterConfig,\n} from './otel_http_exporter.js';\nexport {\n emitToOtel,\n flushPinoLogs,\n initPinoCloudExporter,\n PinoCloudExporter,\n type PinoCloudExporterConfig,\n type PinoLogObject,\n} from './pino_otel_transport.js';\nexport * as traceTypes from './trace_types.js';\nexport {\n flushOtelLogs,\n setTracerProvider,\n setupCloudTracer,\n tracer,\n uploadSessionReport,\n type StartSpanOptions,\n} from './traces.js';\nexport { recordException, recordRealtimeMetrics } from './utils.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,qBAA4D;AAC5D,gCAIO;AACP,iCAOO;AACP,iBAA4B;AAC5B,oBAOO;AACP,mBAAuD;","names":[]}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
export { ExtraDetailsProcessor, MetadataLogProcessor } from './logging.js';
|
|
2
|
+
export { SimpleOTLPHttpLogExporter, type SimpleLogRecord, type SimpleOTLPHttpLogExporterConfig, } from './otel_http_exporter.js';
|
|
3
|
+
export { emitToOtel, flushPinoLogs, initPinoCloudExporter, PinoCloudExporter, type PinoCloudExporterConfig, type PinoLogObject, } from './pino_otel_transport.js';
|
|
1
4
|
export * as traceTypes from './trace_types.js';
|
|
2
|
-
export { setTracerProvider, setupCloudTracer, tracer, type StartSpanOptions } from './traces.js';
|
|
5
|
+
export { flushOtelLogs, setTracerProvider, setupCloudTracer, tracer, uploadSessionReport, type StartSpanOptions, } from './traces.js';
|
|
3
6
|
export { recordException, recordRealtimeMetrics } from './utils.js';
|
|
4
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
export { ExtraDetailsProcessor, MetadataLogProcessor } from './logging.js';
|
|
2
|
+
export { SimpleOTLPHttpLogExporter, type SimpleLogRecord, type SimpleOTLPHttpLogExporterConfig, } from './otel_http_exporter.js';
|
|
3
|
+
export { emitToOtel, flushPinoLogs, initPinoCloudExporter, PinoCloudExporter, type PinoCloudExporterConfig, type PinoLogObject, } from './pino_otel_transport.js';
|
|
1
4
|
export * as traceTypes from './trace_types.js';
|
|
2
|
-
export { setTracerProvider, setupCloudTracer, tracer, type StartSpanOptions } from './traces.js';
|
|
5
|
+
export { flushOtelLogs, setTracerProvider, setupCloudTracer, tracer, uploadSessionReport, type StartSpanOptions, } from './traces.js';
|
|
3
6
|
export { recordException, recordRealtimeMetrics } from './utils.js';
|
|
4
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EACL,yBAAyB,EACzB,KAAK,eAAe,EACpB,KAAK,+BAA+B,GACrC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,UAAU,EACV,aAAa,EACb,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,uBAAuB,EAC5B,KAAK,aAAa,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,MAAM,EACN,mBAAmB,EACnB,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/telemetry/index.js
CHANGED
|
@@ -1,12 +1,37 @@
|
|
|
1
|
+
import { ExtraDetailsProcessor, MetadataLogProcessor } from "./logging.js";
|
|
2
|
+
import {
|
|
3
|
+
SimpleOTLPHttpLogExporter
|
|
4
|
+
} from "./otel_http_exporter.js";
|
|
5
|
+
import {
|
|
6
|
+
emitToOtel,
|
|
7
|
+
flushPinoLogs,
|
|
8
|
+
initPinoCloudExporter,
|
|
9
|
+
PinoCloudExporter
|
|
10
|
+
} from "./pino_otel_transport.js";
|
|
1
11
|
import * as traceTypes from "./trace_types.js";
|
|
2
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
flushOtelLogs,
|
|
14
|
+
setTracerProvider,
|
|
15
|
+
setupCloudTracer,
|
|
16
|
+
tracer,
|
|
17
|
+
uploadSessionReport
|
|
18
|
+
} from "./traces.js";
|
|
3
19
|
import { recordException, recordRealtimeMetrics } from "./utils.js";
|
|
4
20
|
export {
|
|
21
|
+
ExtraDetailsProcessor,
|
|
22
|
+
MetadataLogProcessor,
|
|
23
|
+
PinoCloudExporter,
|
|
24
|
+
SimpleOTLPHttpLogExporter,
|
|
25
|
+
emitToOtel,
|
|
26
|
+
flushOtelLogs,
|
|
27
|
+
flushPinoLogs,
|
|
28
|
+
initPinoCloudExporter,
|
|
5
29
|
recordException,
|
|
6
30
|
recordRealtimeMetrics,
|
|
7
31
|
setTracerProvider,
|
|
8
32
|
setupCloudTracer,
|
|
9
33
|
traceTypes,
|
|
10
|
-
tracer
|
|
34
|
+
tracer,
|
|
35
|
+
uploadSessionReport
|
|
11
36
|
};
|
|
12
37
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/telemetry/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\
|
|
1
|
+
{"version":3,"sources":["../../src/telemetry/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\nexport { ExtraDetailsProcessor, MetadataLogProcessor } from './logging.js';\nexport {\n SimpleOTLPHttpLogExporter,\n type SimpleLogRecord,\n type SimpleOTLPHttpLogExporterConfig,\n} from './otel_http_exporter.js';\nexport {\n emitToOtel,\n flushPinoLogs,\n initPinoCloudExporter,\n PinoCloudExporter,\n type PinoCloudExporterConfig,\n type PinoLogObject,\n} from './pino_otel_transport.js';\nexport * as traceTypes from './trace_types.js';\nexport {\n flushOtelLogs,\n setTracerProvider,\n setupCloudTracer,\n tracer,\n uploadSessionReport,\n type StartSpanOptions,\n} from './traces.js';\nexport { recordException, recordRealtimeMetrics } from './utils.js';\n"],"mappings":"AAIA,SAAS,uBAAuB,4BAA4B;AAC5D;AAAA,EACE;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,YAAY,gBAAgB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,iBAAiB,6BAA6B;","names":[]}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var logging_exports = {};
|
|
20
|
+
__export(logging_exports, {
|
|
21
|
+
ExtraDetailsProcessor: () => ExtraDetailsProcessor,
|
|
22
|
+
MetadataLogProcessor: () => MetadataLogProcessor
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(logging_exports);
|
|
25
|
+
class MetadataLogProcessor {
|
|
26
|
+
metadata;
|
|
27
|
+
constructor(metadata) {
|
|
28
|
+
this.metadata = metadata;
|
|
29
|
+
}
|
|
30
|
+
onEmit(logRecord) {
|
|
31
|
+
if (logRecord.attributes) {
|
|
32
|
+
Object.assign(logRecord.attributes, this.metadata);
|
|
33
|
+
} else {
|
|
34
|
+
logRecord.attributes = { ...this.metadata };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
shutdown() {
|
|
38
|
+
return Promise.resolve();
|
|
39
|
+
}
|
|
40
|
+
forceFlush() {
|
|
41
|
+
return Promise.resolve();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
class ExtraDetailsProcessor {
|
|
45
|
+
onEmit(logRecord) {
|
|
46
|
+
const loggerName = logRecord.instrumentationScope.name;
|
|
47
|
+
if (logRecord.attributes) {
|
|
48
|
+
logRecord.attributes["logger.name"] = loggerName;
|
|
49
|
+
} else {
|
|
50
|
+
logRecord.attributes = { "logger.name": loggerName };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
shutdown() {
|
|
54
|
+
return Promise.resolve();
|
|
55
|
+
}
|
|
56
|
+
forceFlush() {
|
|
57
|
+
return Promise.resolve();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
61
|
+
0 && (module.exports = {
|
|
62
|
+
ExtraDetailsProcessor,
|
|
63
|
+
MetadataLogProcessor
|
|
64
|
+
});
|
|
65
|
+
//# sourceMappingURL=logging.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/telemetry/logging.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { Attributes } from '@opentelemetry/api';\nimport type { LogRecord, LogRecordProcessor } from '@opentelemetry/sdk-logs';\n\n/**\n * Metadata log processor that injects metadata (room_id, job_id) into all log records.\n */\nexport class MetadataLogProcessor implements LogRecordProcessor {\n private metadata: Attributes;\n\n constructor(metadata: Attributes) {\n this.metadata = metadata;\n }\n\n onEmit(logRecord: LogRecord): void {\n // Add metadata to log record attributes\n if (logRecord.attributes) {\n Object.assign(logRecord.attributes, this.metadata);\n } else {\n (logRecord as any).attributes = { ...this.metadata };\n }\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve();\n }\n\n forceFlush(): Promise<void> {\n return Promise.resolve();\n }\n}\n\n/**\n * Extra details processor that adds logger name to log records.\n */\nexport class ExtraDetailsProcessor implements LogRecordProcessor {\n onEmit(logRecord: LogRecord): void {\n const loggerName = logRecord.instrumentationScope.name;\n if (logRecord.attributes) {\n (logRecord.attributes as any)['logger.name'] = loggerName;\n } else {\n (logRecord as any).attributes = { 'logger.name': loggerName };\n }\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve();\n }\n\n forceFlush(): Promise<void> {\n return Promise.resolve();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASO,MAAM,qBAAmD;AAAA,EACtD;AAAA,EAER,YAAY,UAAsB;AAChC,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,OAAO,WAA4B;AAEjC,QAAI,UAAU,YAAY;AACxB,aAAO,OAAO,UAAU,YAAY,KAAK,QAAQ;AAAA,IACnD,OAAO;AACL,MAAC,UAAkB,aAAa,EAAE,GAAG,KAAK,SAAS;AAAA,IACrD;AAAA,EACF;AAAA,EAEA,WAA0B;AACxB,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EAEA,aAA4B;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;AAKO,MAAM,sBAAoD;AAAA,EAC/D,OAAO,WAA4B;AACjC,UAAM,aAAa,UAAU,qBAAqB;AAClD,QAAI,UAAU,YAAY;AACxB,MAAC,UAAU,WAAmB,aAAa,IAAI;AAAA,IACjD,OAAO;AACL,MAAC,UAAkB,aAAa,EAAE,eAAe,WAAW;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,WAA0B;AACxB,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EAEA,aAA4B;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;","names":[]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Attributes } from '@opentelemetry/api';
|
|
2
|
+
import type { LogRecord, LogRecordProcessor } from '@opentelemetry/sdk-logs';
|
|
3
|
+
/**
|
|
4
|
+
* Metadata log processor that injects metadata (room_id, job_id) into all log records.
|
|
5
|
+
*/
|
|
6
|
+
export declare class MetadataLogProcessor implements LogRecordProcessor {
|
|
7
|
+
private metadata;
|
|
8
|
+
constructor(metadata: Attributes);
|
|
9
|
+
onEmit(logRecord: LogRecord): void;
|
|
10
|
+
shutdown(): Promise<void>;
|
|
11
|
+
forceFlush(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Extra details processor that adds logger name to log records.
|
|
15
|
+
*/
|
|
16
|
+
export declare class ExtraDetailsProcessor implements LogRecordProcessor {
|
|
17
|
+
onEmit(logRecord: LogRecord): void;
|
|
18
|
+
shutdown(): Promise<void>;
|
|
19
|
+
forceFlush(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=logging.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Attributes } from '@opentelemetry/api';
|
|
2
|
+
import type { LogRecord, LogRecordProcessor } from '@opentelemetry/sdk-logs';
|
|
3
|
+
/**
|
|
4
|
+
* Metadata log processor that injects metadata (room_id, job_id) into all log records.
|
|
5
|
+
*/
|
|
6
|
+
export declare class MetadataLogProcessor implements LogRecordProcessor {
|
|
7
|
+
private metadata;
|
|
8
|
+
constructor(metadata: Attributes);
|
|
9
|
+
onEmit(logRecord: LogRecord): void;
|
|
10
|
+
shutdown(): Promise<void>;
|
|
11
|
+
forceFlush(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Extra details processor that adds logger name to log records.
|
|
15
|
+
*/
|
|
16
|
+
export declare class ExtraDetailsProcessor implements LogRecordProcessor {
|
|
17
|
+
onEmit(logRecord: LogRecord): void;
|
|
18
|
+
shutdown(): Promise<void>;
|
|
19
|
+
forceFlush(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=logging.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../src/telemetry/logging.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7E;;GAEG;AACH,qBAAa,oBAAqB,YAAW,kBAAkB;IAC7D,OAAO,CAAC,QAAQ,CAAa;gBAEjB,QAAQ,EAAE,UAAU;IAIhC,MAAM,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IASlC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B;AAED;;GAEG;AACH,qBAAa,qBAAsB,YAAW,kBAAkB;IAC9D,MAAM,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IASlC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class MetadataLogProcessor {
|
|
2
|
+
metadata;
|
|
3
|
+
constructor(metadata) {
|
|
4
|
+
this.metadata = metadata;
|
|
5
|
+
}
|
|
6
|
+
onEmit(logRecord) {
|
|
7
|
+
if (logRecord.attributes) {
|
|
8
|
+
Object.assign(logRecord.attributes, this.metadata);
|
|
9
|
+
} else {
|
|
10
|
+
logRecord.attributes = { ...this.metadata };
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
shutdown() {
|
|
14
|
+
return Promise.resolve();
|
|
15
|
+
}
|
|
16
|
+
forceFlush() {
|
|
17
|
+
return Promise.resolve();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
class ExtraDetailsProcessor {
|
|
21
|
+
onEmit(logRecord) {
|
|
22
|
+
const loggerName = logRecord.instrumentationScope.name;
|
|
23
|
+
if (logRecord.attributes) {
|
|
24
|
+
logRecord.attributes["logger.name"] = loggerName;
|
|
25
|
+
} else {
|
|
26
|
+
logRecord.attributes = { "logger.name": loggerName };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
shutdown() {
|
|
30
|
+
return Promise.resolve();
|
|
31
|
+
}
|
|
32
|
+
forceFlush() {
|
|
33
|
+
return Promise.resolve();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
ExtraDetailsProcessor,
|
|
38
|
+
MetadataLogProcessor
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=logging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/telemetry/logging.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { Attributes } from '@opentelemetry/api';\nimport type { LogRecord, LogRecordProcessor } from '@opentelemetry/sdk-logs';\n\n/**\n * Metadata log processor that injects metadata (room_id, job_id) into all log records.\n */\nexport class MetadataLogProcessor implements LogRecordProcessor {\n private metadata: Attributes;\n\n constructor(metadata: Attributes) {\n this.metadata = metadata;\n }\n\n onEmit(logRecord: LogRecord): void {\n // Add metadata to log record attributes\n if (logRecord.attributes) {\n Object.assign(logRecord.attributes, this.metadata);\n } else {\n (logRecord as any).attributes = { ...this.metadata };\n }\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve();\n }\n\n forceFlush(): Promise<void> {\n return Promise.resolve();\n }\n}\n\n/**\n * Extra details processor that adds logger name to log records.\n */\nexport class ExtraDetailsProcessor implements LogRecordProcessor {\n onEmit(logRecord: LogRecord): void {\n const loggerName = logRecord.instrumentationScope.name;\n if (logRecord.attributes) {\n (logRecord.attributes as any)['logger.name'] = loggerName;\n } else {\n (logRecord as any).attributes = { 'logger.name': loggerName };\n }\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve();\n }\n\n forceFlush(): Promise<void> {\n return Promise.resolve();\n }\n}\n"],"mappings":"AASO,MAAM,qBAAmD;AAAA,EACtD;AAAA,EAER,YAAY,UAAsB;AAChC,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,OAAO,WAA4B;AAEjC,QAAI,UAAU,YAAY;AACxB,aAAO,OAAO,UAAU,YAAY,KAAK,QAAQ;AAAA,IACnD,OAAO;AACL,MAAC,UAAkB,aAAa,EAAE,GAAG,KAAK,SAAS;AAAA,IACrD;AAAA,EACF;AAAA,EAEA,WAA0B;AACxB,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EAEA,aAA4B;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;AAKO,MAAM,sBAAoD;AAAA,EAC/D,OAAO,WAA4B;AACjC,UAAM,aAAa,UAAU,qBAAqB;AAClD,QAAI,UAAU,YAAY;AACxB,MAAC,UAAU,WAAmB,aAAa,IAAI;AAAA,IACjD,OAAO;AACL,MAAC,UAAkB,aAAa,EAAE,eAAe,WAAW;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,WAA0B;AACxB,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EAEA,aAA4B;AAC1B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;","names":[]}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var otel_http_exporter_exports = {};
|
|
20
|
+
__export(otel_http_exporter_exports, {
|
|
21
|
+
SimpleOTLPHttpLogExporter: () => SimpleOTLPHttpLogExporter
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(otel_http_exporter_exports);
|
|
24
|
+
var import_api_logs = require("@opentelemetry/api-logs");
|
|
25
|
+
var import_livekit_server_sdk = require("livekit-server-sdk");
|
|
26
|
+
class SimpleOTLPHttpLogExporter {
|
|
27
|
+
config;
|
|
28
|
+
jwt = null;
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.config = config;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Export simple log records
|
|
34
|
+
*/
|
|
35
|
+
async export(records) {
|
|
36
|
+
if (records.length === 0) return;
|
|
37
|
+
await this.ensureJwt();
|
|
38
|
+
const endpoint = `https://${this.config.cloudHostname}/observability/logs/otlp/v0`;
|
|
39
|
+
const payload = this.buildPayload(records);
|
|
40
|
+
const response = await fetch(endpoint, {
|
|
41
|
+
method: "POST",
|
|
42
|
+
headers: {
|
|
43
|
+
Authorization: `Bearer ${this.jwt}`,
|
|
44
|
+
"Content-Type": "application/json"
|
|
45
|
+
},
|
|
46
|
+
body: JSON.stringify(payload)
|
|
47
|
+
});
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
const text = await response.text();
|
|
50
|
+
throw new Error(
|
|
51
|
+
`OTLP log export failed: ${response.status} ${response.statusText} - ${text}`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async ensureJwt() {
|
|
56
|
+
if (this.jwt) return;
|
|
57
|
+
const apiKey = process.env.LIVEKIT_API_KEY;
|
|
58
|
+
const apiSecret = process.env.LIVEKIT_API_SECRET;
|
|
59
|
+
if (!apiKey || !apiSecret) {
|
|
60
|
+
throw new Error("LIVEKIT_API_KEY and LIVEKIT_API_SECRET must be set");
|
|
61
|
+
}
|
|
62
|
+
const token = new import_livekit_server_sdk.AccessToken(apiKey, apiSecret, { ttl: "6h" });
|
|
63
|
+
token.addObservabilityGrant({ write: true });
|
|
64
|
+
this.jwt = await token.toJwt();
|
|
65
|
+
}
|
|
66
|
+
buildPayload(records) {
|
|
67
|
+
const resourceAttrs = Object.entries(this.config.resourceAttributes).map(([key, value]) => ({
|
|
68
|
+
key,
|
|
69
|
+
value: { stringValue: value }
|
|
70
|
+
}));
|
|
71
|
+
if (!this.config.resourceAttributes["service.name"]) {
|
|
72
|
+
resourceAttrs.push({ key: "service.name", value: { stringValue: "livekit-agents" } });
|
|
73
|
+
}
|
|
74
|
+
const scopeAttrs = this.config.scopeAttributes ? Object.entries(this.config.scopeAttributes).map(([key, value]) => ({
|
|
75
|
+
key,
|
|
76
|
+
value: { stringValue: value }
|
|
77
|
+
})) : [];
|
|
78
|
+
const logRecords = records.map((record) => ({
|
|
79
|
+
timeUnixNano: String(BigInt(Math.floor(record.timestampMs * 1e6))),
|
|
80
|
+
observedTimeUnixNano: String(BigInt(Date.now()) * BigInt(1e6)),
|
|
81
|
+
severityNumber: record.severityNumber ?? import_api_logs.SeverityNumber.UNSPECIFIED,
|
|
82
|
+
severityText: record.severityText ?? "unspecified",
|
|
83
|
+
body: { stringValue: record.body },
|
|
84
|
+
attributes: this.convertAttributes(record.attributes),
|
|
85
|
+
traceId: "",
|
|
86
|
+
spanId: ""
|
|
87
|
+
}));
|
|
88
|
+
return {
|
|
89
|
+
resourceLogs: [
|
|
90
|
+
{
|
|
91
|
+
resource: { attributes: resourceAttrs },
|
|
92
|
+
scopeLogs: [
|
|
93
|
+
{
|
|
94
|
+
scope: {
|
|
95
|
+
name: this.config.scopeName,
|
|
96
|
+
attributes: scopeAttrs
|
|
97
|
+
},
|
|
98
|
+
logRecords
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
convertAttributes(attrs) {
|
|
106
|
+
return Object.entries(attrs).map(([key, value]) => ({
|
|
107
|
+
key,
|
|
108
|
+
value: this.convertValue(value)
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
convertValue(value) {
|
|
112
|
+
if (value === null || value === void 0) {
|
|
113
|
+
return { stringValue: "" };
|
|
114
|
+
}
|
|
115
|
+
if (typeof value === "string") {
|
|
116
|
+
return { stringValue: value };
|
|
117
|
+
}
|
|
118
|
+
if (typeof value === "number") {
|
|
119
|
+
return Number.isInteger(value) ? { intValue: String(value) } : { doubleValue: value };
|
|
120
|
+
}
|
|
121
|
+
if (typeof value === "boolean") {
|
|
122
|
+
return { boolValue: value };
|
|
123
|
+
}
|
|
124
|
+
if (Array.isArray(value)) {
|
|
125
|
+
return { arrayValue: { values: value.map((v) => this.convertValue(v)) } };
|
|
126
|
+
}
|
|
127
|
+
if (typeof value === "object") {
|
|
128
|
+
return {
|
|
129
|
+
kvlistValue: {
|
|
130
|
+
values: Object.entries(value).map(([k, v]) => ({
|
|
131
|
+
key: k,
|
|
132
|
+
value: this.convertValue(v)
|
|
133
|
+
}))
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return { stringValue: String(value) };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
141
|
+
0 && (module.exports = {
|
|
142
|
+
SimpleOTLPHttpLogExporter
|
|
143
|
+
});
|
|
144
|
+
//# sourceMappingURL=otel_http_exporter.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/telemetry/otel_http_exporter.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * OTLP HTTP JSON Log Exporter for LiveKit Cloud\n *\n * This module provides a custom OTLP log exporter that uses HTTP with JSON format\n * instead of the default protobuf format.\n */\nimport { SeverityNumber } from '@opentelemetry/api-logs';\nimport { AccessToken } from 'livekit-server-sdk';\n\nexport interface SimpleLogRecord {\n /** Log message body */\n body: string;\n /** Timestamp in milliseconds since epoch */\n timestampMs: number;\n /** Log attributes */\n attributes: Record<string, unknown>;\n /** Severity number (default: UNSPECIFIED) */\n severityNumber?: SeverityNumber;\n /** Severity text (default: 'unspecified') */\n severityText?: string;\n}\n\nexport interface SimpleOTLPHttpLogExporterConfig {\n /** LiveKit Cloud hostname */\n cloudHostname: string;\n /** Resource attributes (e.g., room_id, job_id) */\n resourceAttributes: Record<string, string>;\n /** Scope name for the logger */\n scopeName: string;\n /** Scope attributes */\n scopeAttributes?: Record<string, string>;\n}\n\n/**\n * Simple OTLP HTTP Log Exporter for direct log export\n *\n * This is a simplified exporter that doesn't require the full SDK infrastructure.\n * Use this when you need to send logs directly without LoggerProvider.\n *\n * @example\n * ```typescript\n * const exporter = new SimpleOTLPHttpLogExporter({\n * cloudHostname: 'cloud.livekit.io',\n * resourceAttributes: { room_id: 'xxx', job_id: 'yyy' },\n * scopeName: 'chat_history',\n * });\n *\n * await exporter.export([\n * { body: 'Hello', timestampMs: Date.now(), attributes: { test: true } },\n * ]);\n * ```\n */\nexport class SimpleOTLPHttpLogExporter {\n private readonly config: SimpleOTLPHttpLogExporterConfig;\n private jwt: string | null = null;\n\n constructor(config: SimpleOTLPHttpLogExporterConfig) {\n this.config = config;\n }\n\n /**\n * Export simple log records\n */\n async export(records: SimpleLogRecord[]): Promise<void> {\n if (records.length === 0) return;\n\n await this.ensureJwt();\n\n const endpoint = `https://${this.config.cloudHostname}/observability/logs/otlp/v0`;\n const payload = this.buildPayload(records);\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.jwt}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(\n `OTLP log export failed: ${response.status} ${response.statusText} - ${text}`,\n );\n }\n }\n\n private async ensureJwt(): Promise<void> {\n if (this.jwt) return;\n\n const apiKey = process.env.LIVEKIT_API_KEY;\n const apiSecret = process.env.LIVEKIT_API_SECRET;\n\n if (!apiKey || !apiSecret) {\n throw new Error('LIVEKIT_API_KEY and LIVEKIT_API_SECRET must be set');\n }\n\n const token = new AccessToken(apiKey, apiSecret, { ttl: '6h' });\n token.addObservabilityGrant({ write: true });\n this.jwt = await token.toJwt();\n }\n\n private buildPayload(records: SimpleLogRecord[]): object {\n const resourceAttrs = Object.entries(this.config.resourceAttributes).map(([key, value]) => ({\n key,\n value: { stringValue: value },\n }));\n\n if (!this.config.resourceAttributes['service.name']) {\n resourceAttrs.push({ key: 'service.name', value: { stringValue: 'livekit-agents' } });\n }\n\n const scopeAttrs = this.config.scopeAttributes\n ? Object.entries(this.config.scopeAttributes).map(([key, value]) => ({\n key,\n value: { stringValue: value },\n }))\n : [];\n\n const logRecords = records.map((record) => ({\n timeUnixNano: String(BigInt(Math.floor(record.timestampMs * 1_000_000))),\n observedTimeUnixNano: String(BigInt(Date.now()) * BigInt(1_000_000)),\n severityNumber: record.severityNumber ?? SeverityNumber.UNSPECIFIED,\n severityText: record.severityText ?? 'unspecified',\n body: { stringValue: record.body },\n attributes: this.convertAttributes(record.attributes),\n traceId: '',\n spanId: '',\n }));\n\n return {\n resourceLogs: [\n {\n resource: { attributes: resourceAttrs },\n scopeLogs: [\n {\n scope: {\n name: this.config.scopeName,\n attributes: scopeAttrs,\n },\n logRecords,\n },\n ],\n },\n ],\n };\n }\n\n private convertAttributes(\n attrs: Record<string, unknown>,\n ): Array<{ key: string; value: unknown }> {\n return Object.entries(attrs).map(([key, value]) => ({\n key,\n value: this.convertValue(value),\n }));\n }\n\n private convertValue(value: unknown): unknown {\n if (value === null || value === undefined) {\n return { stringValue: '' };\n }\n if (typeof value === 'string') {\n return { stringValue: value };\n }\n if (typeof value === 'number') {\n return Number.isInteger(value) ? { intValue: String(value) } : { doubleValue: value };\n }\n if (typeof value === 'boolean') {\n return { boolValue: value };\n }\n if (Array.isArray(value)) {\n return { arrayValue: { values: value.map((v) => this.convertValue(v)) } };\n }\n if (typeof value === 'object') {\n return {\n kvlistValue: {\n values: Object.entries(value as Record<string, unknown>).map(([k, v]) => ({\n key: k,\n value: this.convertValue(v),\n })),\n },\n };\n }\n return { stringValue: String(value) };\n }\n}\n"],"mappings":"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","names":[]}
|