Skip to content

Commit

Permalink
feat: DataProxy query logs
Browse files Browse the repository at this point in the history
  • Loading branch information
danstarns authored and Sergey Tatarintsev committed Jan 31, 2023
1 parent 3aa7e15 commit 8e7e38e
Show file tree
Hide file tree
Showing 7 changed files with 1,136 additions and 796 deletions.
2 changes: 1 addition & 1 deletion packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
"@prisma/instrumentation": "workspace:*",
"@prisma/internals": "workspace:*",
"@prisma/migrate": "workspace:*",
"@prisma/mini-proxy": "0.3.0",
"@prisma/mini-proxy": "0.6.4",
"@swc-node/register": "1.5.4",
"@swc/core": "1.3.14",
"@swc/jest": "0.2.24",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export async function stopMiniProxyQueryEngine(client: any): Promise<void> {

const response = await nodeFetch(`https://${host}/_mini-proxy/${clientVersion}/${schemaHash}/stop-engine`, {
method: 'POST',
headers: engine.headers,
headers: {
Authorization: `Bearer ${engine.apiKey()}`,
},
})

debug('response status', response.status)
Expand Down
284 changes: 138 additions & 146 deletions packages/client/tests/functional/logging/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,176 +7,168 @@ import type { Prisma, PrismaClient } from './node_modules/@prisma/client'

declare let newPrismaClient: NewPrismaClient<typeof PrismaClient>

testMatrix.setupTestSuite(
(suiteConfig, _suiteMeta, clientMeta) => {
let client: PrismaClient<Prisma.PrismaClientOptions, 'query'>

test('should log queries on a method call', async () => {
client = newPrismaClient({
log: [
{
emit: 'event',
level: 'query',
},
],
})
testMatrix.setupTestSuite((suiteConfig, _suiteMeta, clientMeta) => {
let client: PrismaClient<Prisma.PrismaClientOptions, 'query'>

test('should log queries on a method call', async () => {
client = newPrismaClient({
log: [
{
emit: 'event',
level: 'query',
},
],
})

const queryLogPromise = new Promise<Prisma.QueryEvent>((resolve) => {
client.$on('query', (data) => {
if ('query' in data) {
resolve(data)
}
})
const queryLogPromise = new Promise<Prisma.QueryEvent>((resolve) => {
client.$on('query', (data) => {
if ('query' in data) {
resolve(data)
}
})

await client.user.findMany()

const queryLogEvents = await queryLogPromise
expect(queryLogEvents).toHaveProperty('query')
expect(queryLogEvents).toHaveProperty('duration')
expect(queryLogEvents).toHaveProperty('timestamp')

if (suiteConfig.provider === 'mongodb') {
expect(queryLogEvents.query).toContain('db.User.aggregate')
} else {
expect(queryLogEvents.query).toContain('SELECT')
}

if (!clientMeta.dataProxy) {
expect(queryLogEvents).toHaveProperty('params')
expect(queryLogEvents).toHaveProperty('target')
}
})

test('should log queries inside a ITX', async () => {
client = newPrismaClient({
log: [
{
emit: 'event',
level: 'query',
},
],
})
await client.user.findMany()

const queryLogEvents = await queryLogPromise
expect(queryLogEvents).toHaveProperty('query')
expect(queryLogEvents).toHaveProperty('duration')
expect(queryLogEvents).toHaveProperty('timestamp')

if (suiteConfig.provider === 'mongodb') {
expect(queryLogEvents.query).toContain('db.User.aggregate')
} else {
expect(queryLogEvents.query).toContain('SELECT')
}

if (!clientMeta.dataProxy) {
expect(queryLogEvents).toHaveProperty('params')
expect(queryLogEvents).toHaveProperty('target')
}
})

test('should log queries inside a ITX', async () => {
client = newPrismaClient({
log: [
{
emit: 'event',
level: 'query',
},
],
})

const queryLogs = new Promise<Prisma.QueryEvent[]>((resolve) => {
const logs: Prisma.QueryEvent[] = []
const queryLogs = new Promise<Prisma.QueryEvent[]>((resolve) => {
const logs: Prisma.QueryEvent[] = []

client.$on('query', (data) => {
if ('query' in data) {
logs.push(data)
client.$on('query', (data) => {
if ('query' in data) {
logs.push(data)

if (suiteConfig.provider === 'mongodb' && logs.length === 3) {
resolve(logs)
}
if (suiteConfig.provider === 'mongodb' && logs.length === 3) {
resolve(logs)
}

if (logs.length === 5) {
resolve(logs)
}
if ((data.query as string).includes('COMMIT')) {
resolve(logs)
}
})
}
})
})

await client.$transaction(async (tx) => {
const id = suiteConfig.provider === 'mongodb' ? faker.database.mongodbObjectId() : faker.random.numeric()
await client.$transaction(async (tx) => {
const id = suiteConfig.provider === 'mongodb' ? faker.database.mongodbObjectId() : faker.random.numeric()

await tx.user.create({
data: {
id,
},
})

return tx.user.findMany({
where: {
id,
},
})
await tx.user.create({
data: {
id,
},
})

const logs = await queryLogs

if (suiteConfig.provider === 'mongodb') {
expect(logs).toHaveLength(3)

expect(logs[0].query).toContain('User.insertOne')
expect(logs[1].query).toContain('User.aggregate')
expect(logs[2].query).toContain('User.aggregate')
} else {
expect(logs).toHaveLength(5)

expect(logs[0].query).toContain('BEGIN')
expect(logs[1].query).toContain('INSERT')
expect(logs[2].query).toContain('SELECT')
expect(logs[3].query).toContain('SELECT')
expect(logs[4].query).toContain('COMMIT')
}
return tx.user.findMany({
where: {
id,
},
})
})

test('should log parallel queries inside a ITX', async () => {
client = newPrismaClient({
log: [
{
emit: 'event',
level: 'query',
},
],
})
const logs = await queryLogs

if (suiteConfig.provider === 'mongodb') {
expect(logs).toHaveLength(3)

expect(logs[0].query).toContain('User.insertOne')
expect(logs[1].query).toContain('User.aggregate')
expect(logs[2].query).toContain('User.aggregate')
} else {
expect(logs).toHaveLength(5)

expect(logs[0].query).toContain('BEGIN')
expect(logs[1].query).toContain('INSERT')
expect(logs[2].query).toContain('SELECT')
expect(logs[3].query).toContain('SELECT')
expect(logs[4].query).toContain('COMMIT')
}
})

test('should log parallel queries inside a ITX', async () => {
client = newPrismaClient({
log: [
{
emit: 'event',
level: 'query',
},
],
})

const queryLogs = new Promise<Prisma.QueryEvent[]>((resolve) => {
const logs: Prisma.QueryEvent[] = []
const queryLogs = new Promise<Prisma.QueryEvent[]>((resolve) => {
const logs: Prisma.QueryEvent[] = []

client.$on('query', (data) => {
if ('query' in data) {
logs.push(data)
client.$on('query', (data) => {
if ('query' in data) {
logs.push(data)

if (suiteConfig.provider === 'mongodb' && logs.length === 2) {
resolve(logs)
}
if (suiteConfig.provider === 'mongodb' && logs.length === 2) {
resolve(logs)
}

if (logs.length === 4) {
resolve(logs)
}
if ((data.query as string).includes('COMMIT')) {
resolve(logs)
}
})
}
})
})

await client.$transaction(async (tx) => {
const id = suiteConfig.provider === 'mongodb' ? faker.database.mongodbObjectId() : faker.random.numeric()

await Promise.all([
tx.user.findMany({
where: {
id,
},
}),
tx.user.findMany({
where: {
id,
},
}),
])
})
await client.$transaction(async (tx) => {
const id = suiteConfig.provider === 'mongodb' ? faker.database.mongodbObjectId() : faker.random.numeric()

const logs = await queryLogs
await Promise.all([
tx.user.findMany({
where: {
id,
},
}),
tx.user.findMany({
where: {
id,
},
}),
])
})

if (suiteConfig.provider === 'mongodb') {
expect(logs).toHaveLength(2)
const logs = await queryLogs

expect(logs[0].query).toContain('User.aggregate')
expect(logs[0].query).toContain('User.aggregate')
} else {
expect(logs).toHaveLength(4)
if (suiteConfig.provider === 'mongodb') {
expect(logs).toHaveLength(2)

expect(logs[0].query).toContain('BEGIN')
expect(logs[1].query).toContain('SELECT')
expect(logs[2].query).toContain('SELECT')
expect(logs[3].query).toContain('COMMIT')
}
})
},
{
skipDataProxy: {
reason: 'Not implemented yet',
runtimes: ['edge', 'node'],
},
},
)
expect(logs[0].query).toContain('User.aggregate')
expect(logs[0].query).toContain('User.aggregate')
} else {
expect(logs).toHaveLength(4)

expect(logs[0].query).toContain('BEGIN')
expect(logs[1].query).toContain('SELECT')
expect(logs[2].query).toContain('SELECT')
expect(logs[3].query).toContain('COMMIT')
}
})
})
Loading

0 comments on commit 8e7e38e

Please sign in to comment.