Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ RUN --mount=type=cache,target=/app/.npm \
COPY --link --chown=1000 . .

RUN --mount=type=secret,id=DOTENV_LOCAL,dst=.env.local \
npm run build
npm run build && npm run build -- --config vite.telemetry.config.ts

FROM node:20-slim

Expand All @@ -29,4 +29,4 @@ COPY --from=builder-production /app/node_modules /app/node_modules
COPY --link --chown=1000 package.json /app/package.json
COPY --from=builder /app/build /app/build

CMD pm2 start /app/build/index.js -i $CPU_CORES --no-daemon
CMD pm2 start /app/build/index.js --node-args="--require /app/build/telemetry.cjs" -i $CPU_CORES --no-daemon
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"packageManager": "[email protected]",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"build": "bash scripts/clean-opentelemetry.sh && vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
Expand Down Expand Up @@ -53,6 +53,12 @@
"@huggingface/hub": "^0.5.1",
"@huggingface/inference": "^2.6.3",
"@iconify-json/bi": "^1.1.21",
"@opentelemetry/api": "^1.8.0",
"@opentelemetry/auto-instrumentations-node": "^0.44.0",
"@opentelemetry/exporter-metrics-otlp-proto": "^0.50.0",
"@opentelemetry/sdk-metrics": "^1.23.0",
"@opentelemetry/sdk-node": "^0.50.0",
"@opentelemetry/sdk-trace-node": "^1.23.0",
"@resvg/resvg-js": "^2.6.0",
"@xenova/transformers": "^2.16.1",
"autoprefixer": "^10.4.14",
Expand Down
7 changes: 7 additions & 0 deletions scripts/clean-opentelemetry.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


packages="./node_modules/@opentelemetry/*/package.json"

for file in ${packages}; do
sed -i '/"module": "build\/esm\/index\.js",/d' ${file}
done
10 changes: 10 additions & 0 deletions src/routes/conversation/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { defaultEmbeddingModel } from "$lib/server/embeddingModels";
import { v4 } from "uuid";
import { authCondition } from "$lib/server/auth";
import { usageLimits } from "$lib/server/usageLimits";
import { metrics } from "@opentelemetry/api";

export const POST: RequestHandler = async ({ locals, request }) => {
const body = await request.text();
Expand Down Expand Up @@ -111,6 +112,15 @@ export const POST: RequestHandler = async ({ locals, request }) => {
...(values.fromShare ? { meta: { fromShareId: values.fromShare } } : {}),
});

const meter = metrics.getMeter("chat-ui");
const counter = meter.createCounter("chat-ui.conversations.count", {
description: "The number of conversations created",
});
counter.add(1, {
"chat-ui.model": values.model,
"user.email": locals.user?.email || undefined,
});

return new Response(
JSON.stringify({
conversationId: res.insertedId.toString(),
Expand Down
10 changes: 10 additions & 0 deletions src/routes/conversation/[id]/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { addSibling } from "$lib/utils/tree/addSibling.js";
import { preprocessMessages } from "$lib/server/preprocessMessages.js";
import { usageLimits } from "$lib/server/usageLimits";
import { isURLLocal } from "$lib/server/isURLLocal.js";
import { metrics } from "@opentelemetry/api";

export async function POST({ request, locals, params, getClientAddress }) {
const id = z.string().parse(params.id);
Expand Down Expand Up @@ -243,6 +244,15 @@ export async function POST({ request, locals, params, getClientAddress }) {
messageId
);

const meter = metrics.getMeter("chat-ui");
const counter = meter.createCounter("chat-ui.conversations.messages.count", {
description: "The number of user messages created",
});
counter.add(1, {
"chat-ui.model": "values.model",
"user.email": locals.user?.email || undefined,
});

messageToWriteToId = addChildren(
conv,
{
Expand Down
77 changes: 77 additions & 0 deletions src/telemetry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// This file is built outside of sveltekit and cannot import from the rest of the application
// or special imports like $env/dynamic/private.
import { NodeSDK } from "@opentelemetry/sdk-node";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-proto";
import { SEMRESATTRS_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
import { AlwaysOnSampler } from "@opentelemetry/sdk-trace-base";
import { Resource } from "@opentelemetry/resources";

const TRACE_URL =
process.env.OTEL_EXPORTER_OTLP_ENDPOINT + "/v1/traces" || "http://localhost:4318/v1/traces";
const METRICS_URL =
process.env.OTEL_EXPORTER_OTLP_ENDPOINT + "/v1/metrics" || "http://localhost:4318/v1/metrics";
const SERVICE_NAME = process.env.OTEL_SERVICE_NAME || "huggingface/chat-ui";

const exporter = new OTLPTraceExporter({
url: TRACE_URL,
headers: {},
});

const otelNodeSdk = new NodeSDK({
autoDetectResources: true,
serviceName: SERVICE_NAME,
traceExporter: exporter,
metricReader: new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter({
url: METRICS_URL,
headers: {},
}),
}),
sampler: new AlwaysOnSampler(),
resource: new Resource({
[SEMRESATTRS_SERVICE_NAME]: SERVICE_NAME,
}),
instrumentations: [
getNodeAutoInstrumentations({
"@opentelemetry/instrumentation-http": {
ignoreIncomingRequestHook: (request) => {
// Don't trace static asset requests
if (
request.url?.endsWith(".js") ||
request.url?.endsWith(".svg") ||
request.url?.endsWith(".css")
) {
return false;
}
return true;
},
},
}),
],
});

export class Telemetry {
private static instance: Telemetry;
private initialized = false;

private constructor() {}

public static getInstance(): Telemetry {
if (!Telemetry.instance) {
Telemetry.instance = new Telemetry();
}
return Telemetry.instance;
}

public start() {
if (!this.initialized) {
this.initialized = true;
otelNodeSdk.start();
}
}
}

Telemetry.getInstance().start();
19 changes: 19 additions & 0 deletions vite.telemetry.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { defineConfig } from "vite";

export default defineConfig({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We unfortunately need a second build step because sveltekit overrides vite's rollupOptions which we need to specify a second entrypoint

build: {
emptyOutDir: false,
ssr: true,
target: "node18",
outDir: "build",
rollupOptions: {
input: {
telemetry: "src/telemetry.ts",
},
},
lib: {
formats: ["cjs"],
entry: "src/telemetry.ts",
},
},
});