-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathprisma.service.ts
More file actions
102 lines (90 loc) · 3.1 KB
/
prisma.service.ts
File metadata and controls
102 lines (90 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient, Prisma } from '@prisma/client';
import { LoggerService } from './logger.service';
import { PrismaErrorService } from './prisma-error.service';
@Injectable()
export class PrismaService
extends PrismaClient
implements OnModuleInit, OnModuleDestroy
{
private readonly logger: LoggerService;
constructor(private readonly prismaErrorService?: PrismaErrorService) {
super({
transactionOptions: {
timeout: process.env.GROUPS_SERVICE_PRISMA_TIMEOUT
? parseInt(process.env.GROUPS_SERVICE_PRISMA_TIMEOUT, 10)
: 10000,
},
log: [
{ level: 'query', emit: 'event' },
{ level: 'info', emit: 'event' },
{ level: 'warn', emit: 'event' },
{ level: 'error', emit: 'event' },
],
// Set connection pool configuration
datasources: {
db: {
url: process.env.DATABASE_URL,
},
},
});
this.logger = LoggerService.forRoot('PrismaService');
// Setup logging for Prisma queries and errors
this.$on('query' as never, (e: Prisma.QueryEvent) => {
const queryTime = e.duration;
// Log query details - full query for dev, just time for production
if (process.env.NODE_ENV !== 'production') {
this.logger.debug(
`Query: ${e.query} | Params: ${e.params} | Duration: ${queryTime}ms`,
);
} else if (queryTime > 500) {
// In production, only log slow queries (> 500ms)
this.logger.warn(
`Slow query detected! Duration: ${queryTime}ms | Query: ${e.query}`,
);
}
});
this.$on('info' as never, (e: Prisma.LogEvent) => {
this.logger.log(`Prisma Info: ${e.message}`);
});
this.$on('warn' as never, (e: Prisma.LogEvent) => {
this.logger.warn(`Prisma Warning: ${e.message}`);
});
this.$on('error' as never, (e: Prisma.LogEvent) => {
this.logger.error(`Prisma Error: ${e.message}`, e.target);
});
}
async onModuleInit() {
this.logger.log('Initializing Prisma connection');
try {
await this.$connect();
this.logger.log('Prisma connected successfully');
// Configure query performance
if (process.env.NODE_ENV === 'production') {
try {
// In production, increase the maximum number of connections (NestJS already sets sensible defaults)
await this.$executeRaw`SET max_connections = 100;`;
this.logger.log('Database connection pool configured');
} catch (error) {
this.logger.warn(
`Could not configure database connections: ${error.message}`,
);
}
}
} catch (error) {
const errorMsg = this.prismaErrorService
? this.prismaErrorService.handleError(error, 'connecting to database')
.message
: error.message;
this.logger.error(
`Failed to connect to the database: ${errorMsg}`,
error.stack,
);
throw error;
}
}
async onModuleDestroy() {
this.logger.log('Disconnecting Prisma');
await this.$disconnect();
}
}