Skip to content

Commit

Permalink
fix(client): don't trace if not sampling #15129 (#15311)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel Starns <danielstarns@hotmail.com>
  • Loading branch information
millsp and danstarns committed Sep 21, 2022
1 parent ee48cb0 commit ee83c7e
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 8 deletions.
13 changes: 13 additions & 0 deletions packages/client/tests/functional/tracing-no-sampling/_matrix.ts
@@ -0,0 +1,13 @@
import { defineMatrix } from '../_utils/defineMatrix'
import { allProviders } from '../_utils/providers'
export default defineMatrix(() => [
allProviders,
[
{
previewFeatures: '"tracing", "interactiveTransactions"',
},
{
previewFeatures: '"interactiveTransactions"',
},
],
])
@@ -0,0 +1,20 @@
import { idForProvider } from '../../_utils/idForProvider'
import testMatrix from '../_matrix'

export default testMatrix.setupSchema(({ provider, previewFeatures }) => {
return /* Prisma */ `
generator client {
provider = "prisma-client-js"
previewFeatures = [${previewFeatures}]
}
datasource db {
provider = "${provider}"
url = env("DATABASE_URI_${provider}")
}
model User {
id ${idForProvider(provider)}
}
`
})
94 changes: 94 additions & 0 deletions packages/client/tests/functional/tracing-no-sampling/tests.ts
@@ -0,0 +1,94 @@
import { context } from '@opentelemetry/api'
import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'
import { registerInstrumentations } from '@opentelemetry/instrumentation'
import { Resource } from '@opentelemetry/resources'
import {
BasicTracerProvider,
InMemorySpanExporter,
SimpleSpanProcessor,
TraceIdRatioBasedSampler,
} from '@opentelemetry/sdk-trace-base'
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'
import { PrismaInstrumentation } from '@prisma/instrumentation'

import { NewPrismaClient } from '../_utils/types'
import testMatrix from './_matrix'
// @ts-ignore
import type { PrismaClient } from './node_modules/@prisma/client'

let prisma: PrismaClient<{ log: [{ emit: 'event'; level: 'query' }] }>
declare let newPrismaClient: NewPrismaClient<typeof PrismaClient>

let inMemorySpanExporter: InMemorySpanExporter

beforeAll(() => {
const contextManager = new AsyncHooksContextManager().enable()
context.setGlobalContextManager(contextManager)

inMemorySpanExporter = new InMemorySpanExporter()

const basicTracerProvider = new BasicTracerProvider({
sampler: new TraceIdRatioBasedSampler(0), // 0% sampling!!
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: `test-name`,
[SemanticResourceAttributes.SERVICE_VERSION]: '1.0.0',
}),
})

basicTracerProvider.addSpanProcessor(new SimpleSpanProcessor(inMemorySpanExporter))
basicTracerProvider.register()

registerInstrumentations({
instrumentations: [new PrismaInstrumentation({ middleware: true })],
})
})

afterAll(() => {
context.disable()
})

testMatrix.setupTestSuite(
() => {
const queries: string[] = []

function checkQueriesHaveNotTraceparent() {
const result = !queries.some((q) => q.includes('traceparent'))

queries.length = 0

return result
}

beforeAll(() => {
prisma = newPrismaClient({ log: [{ emit: 'event', level: 'query' }] })

prisma.$on('query', (e) => queries.push(e.query))
})

test('should perform a query and assert that no spans were generated', async () => {
await prisma.user.findMany()

const spans = inMemorySpanExporter.getFinishedSpans()

expect(spans).toHaveLength(0)
expect(checkQueriesHaveNotTraceparent()).toBe(true)
})

testIf(!process.env.DATA_PROXY)(
'should perform a query and assert that no spans were generated via itx',
async () => {
await prisma.$transaction(async (prisma) => {
await prisma.user.findMany()
})

const spans = inMemorySpanExporter.getFinishedSpans()

expect(spans).toHaveLength(0)
expect(checkQueriesHaveNotTraceparent()).toBe(true)
},
)
},
{
skipDefaultClientInstance: true,
},
)
7 changes: 4 additions & 3 deletions packages/engine-core/src/tracing/getTraceParent.ts
Expand Up @@ -16,11 +16,12 @@ export function getTraceParent({
}): string {
const span = trace.getSpanContext(context ?? _context.active())

if (tracingConfig?.enabled && span?.traceFlags === 1) {
return `00-${span.traceId}-${span.spanId}-01`
if (tracingConfig?.enabled && span) {
return `00-${span.traceId}-${span.spanId}-0${span.traceFlags}`
} else {
// https://www.w3.org/TR/trace-context/#examples-of-http-traceparent-headers
// If traceparent ends with -00 this trace will not be sampled
return `00-00-00-00`
// the query engine needs the `10` for the span and trace id otherwise it does not parse this
return `00-10-10-00`
}
}
11 changes: 7 additions & 4 deletions reproductions/tracing/otelSetup.ts
@@ -1,10 +1,14 @@
import * as api from '@opentelemetry/api'
import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'
import { TraceIdRatioBasedSampler } from '@opentelemetry/core'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
import { registerInstrumentations } from '@opentelemetry/instrumentation'
import { Resource } from '@opentelemetry/resources'
import { BasicTracerProvider, ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'
import {
BasicTracerProvider,
ConsoleSpanExporter,
SimpleSpanProcessor,
TraceIdRatioBasedSampler,
} from '@opentelemetry/sdk-trace-base'
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'
import { PrismaInstrumentation } from '@prisma/instrumentation'

Expand All @@ -22,11 +26,10 @@ export function otelSetup() {

// exporter that natively works with jaeger without extras
const otlpTraceExporter = new OTLPTraceExporter()
// docker run --rm -d -p 13133:13133 -p 16686:16686 -p 4317:55680 jaegertracing/opentelemetry-all-in-one:latest
// docker run --rm --name jaeger -d -e COLLECTOR_OTLP_ENABLED=true -p 16686:16686 -p 4318:4318 jaegertracing/all-in-one:latest

// a standard provider that can run on the web and in node
const provider = new BasicTracerProvider({
sampler: new TraceIdRatioBasedSampler(0),
resource: new Resource({
// we can define some metadata about the trace resource
[SemanticResourceAttributes.SERVICE_NAME]: 'basic-service',
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.build.bundle.json
Expand Up @@ -14,7 +14,8 @@
"prisma": ["./packages/cli/src"],
"@prisma/get-platform": ["./packages/get-platform/src"],
"@prisma/fetch-engine": ["./packages/fetch-engine/src"],
"@prisma/engines": ["./packages/engines/src"]
"@prisma/engines": ["./packages/engines/src"],
"@prisma/instrumentation": ["./packages/instrumentation/src"]
}
}
}

0 comments on commit ee83c7e

Please sign in to comment.