From ce965696d1f8695e96e6b88490fc8ea2f8ab78ae Mon Sep 17 00:00:00 2001 From: Christoph Nakazawa Date: Sat, 17 Oct 2026 06:35:12 +0000 Subject: [PATCH] perf(core): inline OpenTelemetry attribute constants (#11623) Co-authored-by: Taesu --- .../local-instrumentation-attributes.md | 5 +++ packages/core/package.json | 2 +- .../src/instrumentation/attributes.test.ts | 36 +++++++++++++++++++ .../core/src/instrumentation/attributes.ts | 26 +++++++------- pnpm-lock.yaml | 6 ++-- 5 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 .changeset/local-instrumentation-attributes.md create mode 100644 packages/core/src/instrumentation/attributes.test.ts diff --git a/.changeset/local-instrumentation-attributes.md b/.changeset/local-instrumentation-attributes.md new file mode 100644 index 0000000000..3764545ddc --- /dev/null +++ b/.changeset/local-instrumentation-attributes.md @@ -0,0 +1,5 @@ +--- +"@better-auth/core": patch +--- + +Reduce installation size by removing the semantic conventions production dependency while preserving all instrumentation attribute keys. diff --git a/packages/core/package.json b/packages/core/package.json index 901ce2a6b3..4f8f65b3b6 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -164,7 +164,6 @@ } }, "dependencies": { - "@opentelemetry/semantic-conventions": "^1.41.1", "@standard-schema/spec": "^1.1.0", "zod": "catalog:" }, @@ -175,6 +174,7 @@ "@opentelemetry/api": "^1.9.1", "@opentelemetry/sdk-trace-base": "^2.10.0", "@opentelemetry/sdk-trace-node": "^2.10.0", + "@opentelemetry/semantic-conventions": "^1.41.1", "better-call": "catalog:", "jose": "^6.2.3", "kysely": "catalog:", diff --git a/packages/core/src/instrumentation/attributes.test.ts b/packages/core/src/instrumentation/attributes.test.ts new file mode 100644 index 0000000000..2d9754c6bf --- /dev/null +++ b/packages/core/src/instrumentation/attributes.test.ts @@ -0,0 +1,36 @@ +import { readdirSync, readFileSync } from "node:fs"; +import { join } from "node:path"; +import { fileURLToPath } from "node:url"; +import * as semanticConventions from "@opentelemetry/semantic-conventions"; +import { describe, expect, it } from "vitest"; +import * as attributes from "./attributes"; + +const SEMANTIC_CONVENTIONS = "@opentelemetry/semantic-conventions"; + +/** + * @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/db/ + * @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/http/ + */ +describe("instrumentation attributes", () => { + it.for([ + "ATTR_DB_COLLECTION_NAME", + "ATTR_DB_OPERATION_NAME", + "ATTR_HTTP_RESPONSE_STATUS_CODE", + "ATTR_HTTP_ROUTE", + ] as const)("%s matches the OpenTelemetry semantic convention", (name) => { + expect(attributes[name]).toBe(semanticConventions[name]); + }); + + it("keeps the semantic conventions package out of production source", () => { + const srcDir = fileURLToPath(new URL("..", import.meta.url)); + const importers = readdirSync(srcDir, { recursive: true, encoding: "utf8" }) + .filter((file) => file.endsWith(".ts") && !file.endsWith(".test.ts")) + .filter((file) => + readFileSync(join(srcDir, file), "utf8").includes( + `"${SEMANTIC_CONVENTIONS}"`, + ), + ); + + expect(importers).toEqual([]); + }); +}); diff --git a/packages/core/src/instrumentation/attributes.ts b/packages/core/src/instrumentation/attributes.ts index 10bc1fdd89..de4d179622 100644 --- a/packages/core/src/instrumentation/attributes.ts +++ b/packages/core/src/instrumentation/attributes.ts @@ -1,16 +1,18 @@ -import { - ATTR_DB_COLLECTION_NAME, - ATTR_DB_OPERATION_NAME, - ATTR_HTTP_RESPONSE_STATUS_CODE, - ATTR_HTTP_ROUTE, -} from "@opentelemetry/semantic-conventions"; +// Keep these stable OpenTelemetry keys local to avoid installing the full +// semantic conventions registry just for four string constants. -export { - ATTR_DB_COLLECTION_NAME, - ATTR_DB_OPERATION_NAME, - ATTR_HTTP_RESPONSE_STATUS_CODE, - ATTR_HTTP_ROUTE, -}; +/** Database collection accessed by the operation. */ +export const ATTR_DB_COLLECTION_NAME = "db.collection.name" as const; + +/** Database operation performed by the span. */ +export const ATTR_DB_OPERATION_NAME = "db.operation.name" as const; + +/** HTTP response status code. */ +export const ATTR_HTTP_RESPONSE_STATUS_CODE = + "http.response.status_code" as const; + +/** Matched HTTP route template. */ +export const ATTR_HTTP_ROUTE = "http.route" as const; /** Operation identifier (e.g. getSession, signUpWithEmailAndPassword). Uses endpoint operationId when set, otherwise the endpoint key. */ export const ATTR_OPERATION_ID = "better_auth.operation_id" as const; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bede79117e..e382e02acb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1335,9 +1335,6 @@ importers: packages/core: dependencies: - '@opentelemetry/semantic-conventions': - specifier: ^1.41.1 - version: 1.41.1 '@standard-schema/spec': specifier: ^1.1.0 version: 1.1.0 @@ -1363,6 +1360,9 @@ importers: '@opentelemetry/sdk-trace-node': specifier: ^2.10.0 version: 2.10.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': + specifier: ^1.41.1 + version: 1.41.1 better-call: specifier: 'catalog:' version: 1.4.2(zod@4.5.4)