mirror of
https://github.com/zoriya/drizzle-otel.git
synced 2025-12-06 00:46:09 +00:00
update docs
This commit is contained in:
@@ -42,118 +42,149 @@ Works with any observability platform that supports OpenTelemetry including:
|
||||
|
||||
## Usage
|
||||
|
||||
There are two ways to instrument Drizzle ORM with OpenTelemetry:
|
||||
### Instrument Your Drizzle Database (Recommended)
|
||||
|
||||
### Option 1: Instrument the Connection Pool (Recommended)
|
||||
|
||||
Wrap your database connection pool with `instrumentDrizzle()` before passing it to Drizzle:
|
||||
Use `instrumentDrizzleClient()` to add tracing to your Drizzle database instance. This is the simplest and most straightforward approach:
|
||||
|
||||
```typescript
|
||||
import { drizzle } from "drizzle-orm/node-postgres";
|
||||
import { Pool } from "pg";
|
||||
import { instrumentDrizzle } from "@kubiks/otel-drizzle";
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
import { instrumentDrizzleClient } from "@kubiks/otel-drizzle";
|
||||
|
||||
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
||||
const instrumentedPool = instrumentDrizzle(pool);
|
||||
const db = drizzle(instrumentedPool);
|
||||
// Create your Drizzle database instance as usual
|
||||
const db = drizzle(process.env.DATABASE_URL!);
|
||||
|
||||
// Add instrumentation with a single line
|
||||
instrumentDrizzleClient(db);
|
||||
|
||||
// That's it! All queries are now traced automatically
|
||||
const users = await db.select().from(usersTable);
|
||||
```
|
||||
|
||||
### Option 2: Instrument an Existing Drizzle Client
|
||||
### Database-Specific Examples
|
||||
|
||||
If you already have a Drizzle database instance or don't have access to the underlying pool, use `instrumentDrizzleClient()`. This method instruments the database at the session level, capturing all query operations:
|
||||
#### PostgreSQL
|
||||
|
||||
```typescript
|
||||
// Works with postgres-js (Postgres.js)
|
||||
// PostgreSQL with postgres.js (recommended for serverless)
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
import postgres from "postgres";
|
||||
import { instrumentDrizzleClient } from "@kubiks/otel-drizzle";
|
||||
import * as schema from "./schema";
|
||||
|
||||
const db = drizzle(process.env.DATABASE_URL!, { schema });
|
||||
// Using connection string directly
|
||||
const db = drizzle(process.env.DATABASE_URL!);
|
||||
instrumentDrizzleClient(db, { dbSystem: "postgresql" });
|
||||
|
||||
// Instrument the existing database instance
|
||||
instrumentDrizzleClient(db);
|
||||
|
||||
// All queries are now traced automatically
|
||||
const users = await db.select().from(schema.users);
|
||||
// Direct execute calls are also traced
|
||||
await db.execute("SELECT * FROM users");
|
||||
// Transactions are also traced
|
||||
await db.transaction(async (tx) => {
|
||||
await tx.insert(schema.users).values({ name: "John" });
|
||||
});
|
||||
```
|
||||
|
||||
### Optional Configuration
|
||||
|
||||
Both instrumentation methods accept the same configuration options:
|
||||
|
||||
```typescript
|
||||
// Option 1: Instrument the pool
|
||||
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
||||
const instrumentedPool = instrumentDrizzle(pool, {
|
||||
dbSystem: "postgresql", // Database type (default: 'postgresql')
|
||||
dbName: "myapp", // Database name for spans
|
||||
captureQueryText: true, // Include SQL in traces (default: true)
|
||||
maxQueryTextLength: 1000, // Max SQL length (default: 1000)
|
||||
peerName: "db.example.com", // Database server hostname
|
||||
peerPort: 5432, // Database server port
|
||||
});
|
||||
const db = drizzle(instrumentedPool);
|
||||
|
||||
// Option 2: Instrument the Drizzle client
|
||||
const db = drizzle(pool, { schema });
|
||||
// Or with a client instance
|
||||
const queryClient = postgres(process.env.DATABASE_URL!);
|
||||
const db = drizzle({ client: queryClient });
|
||||
instrumentDrizzleClient(db, {
|
||||
dbSystem: "postgresql",
|
||||
dbName: "myapp",
|
||||
captureQueryText: true,
|
||||
peerName: "db.example.com",
|
||||
peerPort: 5432,
|
||||
});
|
||||
```
|
||||
|
||||
### Works with All Drizzle-Supported Databases
|
||||
|
||||
This package automatically detects and instruments **all databases that Drizzle ORM supports**. It works by detecting whether your database driver uses a `query` or `execute` method and instrumenting it appropriately. This includes:
|
||||
|
||||
- **PostgreSQL** (node-postgres, postgres.js, Neon, Vercel Postgres, etc.)
|
||||
- **MySQL** (mysql2, PlanetScale, TiDB, etc.)
|
||||
- **SQLite** (better-sqlite3, LibSQL/Turso, Cloudflare D1, etc.)
|
||||
- **And any other Drizzle-supported database**
|
||||
|
||||
```typescript
|
||||
// PostgreSQL with postgres-js (Postgres.js) - use instrumentDrizzleClient
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
const db = drizzle(process.env.DATABASE_URL!);
|
||||
instrumentDrizzleClient(db);
|
||||
|
||||
// PostgreSQL with node-postgres (pg) - use instrumentDrizzle on pool
|
||||
// PostgreSQL with node-postgres (pg)
|
||||
import { drizzle } from "drizzle-orm/node-postgres";
|
||||
import { Pool } from "pg";
|
||||
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
||||
const db = drizzle(instrumentDrizzle(pool));
|
||||
import { instrumentDrizzleClient } from "@kubiks/otel-drizzle";
|
||||
|
||||
// MySQL with mysql2 (uses 'execute' or 'query' method)
|
||||
// Using connection string directly
|
||||
const db = drizzle(process.env.DATABASE_URL!);
|
||||
instrumentDrizzleClient(db, { dbSystem: "postgresql" });
|
||||
|
||||
// Or with a pool instance
|
||||
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
||||
const db = drizzle({ client: pool });
|
||||
instrumentDrizzleClient(db, { dbSystem: "postgresql" });
|
||||
```
|
||||
|
||||
#### MySQL
|
||||
|
||||
```typescript
|
||||
// MySQL with mysql2
|
||||
import { drizzle } from "drizzle-orm/mysql2";
|
||||
import mysql from "mysql2/promise";
|
||||
const connection = await mysql.createConnection(process.env.DATABASE_URL);
|
||||
const db = drizzle(instrumentDrizzle(connection, { dbSystem: "mysql" }));
|
||||
import { instrumentDrizzleClient } from "@kubiks/otel-drizzle";
|
||||
|
||||
// Using connection string directly
|
||||
const db = drizzle(process.env.DATABASE_URL!);
|
||||
instrumentDrizzleClient(db, { dbSystem: "mysql" });
|
||||
|
||||
// Or with a connection instance
|
||||
const connection = await mysql.createConnection({
|
||||
host: "localhost",
|
||||
user: "root",
|
||||
database: "mydb",
|
||||
// ... other connection options
|
||||
});
|
||||
const db = drizzle({ client: connection });
|
||||
instrumentDrizzleClient(db, {
|
||||
dbSystem: "mysql",
|
||||
dbName: "mydb",
|
||||
peerName: "localhost",
|
||||
peerPort: 3306,
|
||||
});
|
||||
```
|
||||
|
||||
#### SQLite
|
||||
|
||||
```typescript
|
||||
// SQLite with better-sqlite3
|
||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||
import Database from "better-sqlite3";
|
||||
const sqlite = new Database("database.db");
|
||||
const db = drizzle(instrumentDrizzle(sqlite, { dbSystem: "sqlite" }));
|
||||
import { instrumentDrizzleClient } from "@kubiks/otel-drizzle";
|
||||
|
||||
// LibSQL/Turso (uses 'execute' method)
|
||||
// Using file path directly
|
||||
const db = drizzle("sqlite.db");
|
||||
instrumentDrizzleClient(db, { dbSystem: "sqlite" });
|
||||
|
||||
// Or with a Database instance
|
||||
const sqlite = new Database("sqlite.db");
|
||||
const db = drizzle({ client: sqlite });
|
||||
instrumentDrizzleClient(db, { dbSystem: "sqlite" });
|
||||
```
|
||||
|
||||
```typescript
|
||||
// SQLite with LibSQL/Turso
|
||||
import { drizzle } from "drizzle-orm/libsql";
|
||||
import { createClient } from "@libsql/client";
|
||||
const client = createClient({ url: "...", authToken: "..." });
|
||||
const db = drizzle(instrumentDrizzle(client, { dbSystem: "sqlite" }));
|
||||
import { instrumentDrizzleClient } from "@kubiks/otel-drizzle";
|
||||
|
||||
// Using connection config directly
|
||||
const db = drizzle({
|
||||
connection: {
|
||||
url: process.env.DATABASE_URL!,
|
||||
authToken: process.env.DATABASE_AUTH_TOKEN,
|
||||
}
|
||||
});
|
||||
instrumentDrizzleClient(db, { dbSystem: "sqlite" });
|
||||
|
||||
// Or with a client instance
|
||||
const client = createClient({
|
||||
url: process.env.DATABASE_URL!,
|
||||
authToken: process.env.DATABASE_AUTH_TOKEN,
|
||||
});
|
||||
const db = drizzle({ client });
|
||||
instrumentDrizzleClient(db, { dbSystem: "sqlite" });
|
||||
```
|
||||
|
||||
### Configuration Options
|
||||
|
||||
```typescript
|
||||
instrumentDrizzleClient(db, {
|
||||
dbSystem: "postgresql", // Database type: 'postgresql' | 'mysql' | 'sqlite' (default: 'postgresql')
|
||||
dbName: "myapp", // Database name for spans
|
||||
captureQueryText: true, // Include SQL in traces (default: true)
|
||||
maxQueryTextLength: 1000, // Max SQL length (default: 1000)
|
||||
peerName: "db.example.com", // Database server hostname
|
||||
peerPort: 5432, // Database server port
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## What You Get
|
||||
|
||||
Each database query automatically creates a span with rich telemetry data:
|
||||
|
||||
Reference in New Issue
Block a user