ServerCRUD
Observability
Metrics, tracing, and logging for CRUD operations.
Metrics
CRUD emits metrics via MetricsService:
crud_operation_total
Counter incremented on every CRUD execution.
| Label | Description |
|---|---|
model | Prisma model name (e.g., contact) |
operation | Operation type (e.g., createOne, findMany) |
status | success or failure |
# Query success rate by model
sum(rate(crud_operation_total{status="success"}[5m])) by (model)
/ sum(rate(crud_operation_total[5m])) by (model)
# Query latency p95
histogram_quantile(0.95, sum(rate(crud_operation_duration_bucket[5m])) by (le, model))Tracing (OpenTelemetry)
Every operation is wrapped in an OpenTelemetry span:
| Attribute | Value |
|---|---|
span.name | crud.${model}.${op} |
db.system | postgresql |
db.operation | ${op} |
db.model | ${model} |
Trace Example
crud.contact.createOne
├── db:prisma:serialize
├── db:prisma:query
└── crud:hook:beforeLogging
Structured logs using Effect.logInfo and Effect.logError:
Success Log
{
"level": "info",
"message": "CRUD Operation Executed",
"model": "contact",
"op": "createOne",
"duration": 45,
"requestId": "req_abc123",
"org": "acme-corp"
}Error Log
{
"level": "error",
"message": "CRUD Operation Failed",
"model": "contact",
"op": "createOne",
"error": "P2002: Unique constraint failed",
"requestId": "req_abc123"
}Debug Mode
To see raw Prisma queries:
// In your Prisma client setup
const prisma = new PrismaClient({
log: [
{ emit: "event", level: "query" },
],
});
prisma.$on("query", (e) => {
console.log("Query:", e.query);
console.log("Params:", e.params);
});Or set environment variable:
DEBUG=prisma:client:*