Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
6 changes: 3 additions & 3 deletions apps/api/src/middlewares/greptime.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Elysia } from "elysia";

import { greptimeSqlClient, type BunSqlClient } from "@hebo/shared-api/db/greptime";
import { getGreptimeSqlClient } from "@hebo/shared-api/db/greptime";
import { auth } from "@hebo/shared-api/middlewares/auth";

export const greptime = new Elysia({
Expand All @@ -9,9 +9,9 @@ export const greptime = new Elysia({
.use(auth)
.resolve(function resolveGreptimeDb() {
return {
greptimeDb: greptimeSqlClient,
greptimeDb: getGreptimeSqlClient(),
};
})
.as("scoped");

export type GreptimeDb = BunSqlClient;
export type GreptimeDb = Bun.SQL;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We don't know this, its completely encapsulated by the shared-api layer. Please revert.

24 changes: 6 additions & 18 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 8 additions & 13 deletions packages/shared-api/db/greptime.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import { getSecret } from "../utils/secret";
import { DEFAULT_DB_IDLE_TIMEOUT_MS, DEFAULT_DB_POOL_MAX } from "./config";

export const getGreptimeConnectionString = async () => {
return `postgres://${(await getSecret("GREPTIME_HOST")) ?? "localhost"}:4003/public`;
};
export const GREPTIME_HOST = (await getSecret("GREPTIME_HOST")) ?? "localhost";

export const createBunSqlClient = (url: string) => {
const { SQL } = require("bun") as typeof Bun;
return new SQL({
url,
let _client: Bun.SQL;

/** Lazily created so BunSqlInstrumentation wraps `bun:sql` before the first `new SQL()` call. */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The previous createBunSqlClient was lazy as well, what exactly is the change here?

export const getGreptimeSqlClient = () =>
(_client ??= new (require("bun") as typeof Bun).SQL({
url: `postgres://${GREPTIME_HOST}:4003/public`,
max: DEFAULT_DB_POOL_MAX,
idleTimeout: DEFAULT_DB_IDLE_TIMEOUT_MS / 1_000,
});
};

export const greptimeSqlClient = createBunSqlClient(await getGreptimeConnectionString());

export type BunSqlClient = ReturnType<typeof createBunSqlClient>;
}));
46 changes: 28 additions & 18 deletions packages/shared-api/lib/otel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type { SeverityNumber } from "@opentelemetry/api-logs";
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-proto";
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-proto";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
import { registerInstrumentations } from "@opentelemetry/instrumentation";
import { PgInstrumentation } from "@opentelemetry/instrumentation-pg";
import { CompressionAlgorithm } from "@opentelemetry/otlp-exporter-base";
import { resourceFromAttributes } from "@opentelemetry/resources";
Expand All @@ -18,8 +17,8 @@ import {
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";

import { GREPTIME_HOST } from "../db/greptime";
import { IS_PRODUCTION } from "../env";
import { getSecret } from "../utils/secret";
import { isRootPathUrl } from "../utils/url";

/**
Expand Down Expand Up @@ -48,7 +47,7 @@ const ALLOWED_RESPONSE_HEADERS = [
"x-request-id",
];

export const GREPTIME_OTLP_ENDPOINT = `http://${(await getSecret("GREPTIME_HOST")) ?? "localhost"}:4000/v1/otlp`;
export const GREPTIME_OTLP_ENDPOINT = `http://${GREPTIME_HOST}:4000/v1/otlp`;

export const createOtelLogger = (serviceName: string, minimumSeverity: SeverityNumber) => {
const loggerProvider = new LoggerProvider({
Expand Down Expand Up @@ -82,24 +81,35 @@ export const createOtelLogger = (serviceName: string, minimumSeverity: SeverityN
return loggerProvider.getLogger(serviceName);
};

registerInstrumentations({
instrumentations: [
new PgInstrumentation({
requireParentSpan: true,
enhancedDatabaseReporting: false,
}),
new BunSqlInstrumentation({
requireParentSpan: true,
ignoreConnectionSpans: true,
// FUTURE: set to true to avoid leaking sensitive information
maskStatement: false,
}),
],
});

export const getOtelConfig = (serviceName: string): ElysiaOpenTelemetryOptions => {
const pgInstrumentation = new PgInstrumentation({
requireParentSpan: true,
enhancedDatabaseReporting: false,
});

// In Bun, pg is already loaded via @prisma/adapter-pg before OTel's module-load
// hooks can patch it. Patch pg.Client directly as a workaround, while still
// passing the instrumentation to NodeSDK so providers are configured correctly.
try {
// oxlint-disable no-unsafe-assignment no-unsafe-call no-unsafe-member-access
const { createRequire } = require("module");
const pg = createRequire(require.resolve("@prisma/adapter-pg"))("pg");
// @ts-expect-error _patchPgClient is a private method on PgInstrumentation
pgInstrumentation._patchPgClient(pg.Client);
// oxlint-enable no-unsafe-assignment no-unsafe-call no-unsafe-member-access
} catch {}

return {
serviceName,
instrumentations: [
pgInstrumentation,
new BunSqlInstrumentation({
requireParentSpan: true,
ignoreConnectionSpans: true,
// FUTURE: set to true to avoid leaking sensitive information
maskStatement: false,
}),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Align coding pattern across pg and bun instrumentation.

],
headersToSpanAttributes: {
requestHeaders: ALLOWED_REQUEST_HEADERS,
responseHeaders: ALLOWED_RESPONSE_HEADERS,
Expand Down