Skip to content

Commit 9a64662

Browse files
authored
Merge pull request #480 from plotwist-app/chore/add-opentelemetry
chore: add opentelemetry
2 parents ac34129 + d216c8b commit 9a64662

44 files changed

Lines changed: 2204 additions & 50 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/backend/.env.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ ENABLE_CRON_JOBS=false
4747

4848
# OpenAI
4949
OPENAI_API_KEY=
50+
51+
# Monitors
52+
ENABLE_MONITORS=true
53+
MONITOR_CRON_TIME="*/30 * * * *"
54+
55+
# Telemetry
56+
OTEL_EXPORTER_OTLP_ENDPOINT=localhost
57+
OTEL_EXPORTER_OTLP_HEADERS=

apps/backend/docker-compose.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ services:
5656
- localstack_data:/var/lib/localstack
5757
networks:
5858
- plotwist_network
59+
60+
grafana:
61+
image: grafana/otel-lgtm
62+
container_name: plotwist_grafana
63+
ports:
64+
- 12345:3000
65+
- 4317:4317
66+
- 4318:4318
67+
networks:
68+
- plotwist_network
5969

6070
volumes:
6171
redis-data:

apps/backend/package.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,21 @@
3232
"@fastify/cors": "^11.2.0",
3333
"@fastify/jwt": "^10.0.0",
3434
"@fastify/multipart": "^9.3.0",
35+
"@fastify/otel": "^0.16.0",
3536
"@fastify/rate-limit": "^10.3.0",
3637
"@fastify/redis": "^7.1.0",
3738
"@fastify/swagger": "^9.6.1",
3839
"@fastify/swagger-ui": "^5.2.4",
40+
"@kubiks/otel-drizzle": "^2.1.0",
41+
"@opentelemetry/api": "^1.9.0",
42+
"@opentelemetry/exporter-metrics-otlp-proto": "^0.211.0",
43+
"@opentelemetry/exporter-trace-otlp-proto": "^0.211.0",
44+
"@opentelemetry/host-metrics": "^0.38.2",
45+
"@opentelemetry/instrumentation-http": "^0.212.0",
46+
"@opentelemetry/resources": "^2.5.0",
47+
"@opentelemetry/sdk-metrics": "^2.5.0",
48+
"@opentelemetry/sdk-node": "^0.211.0",
49+
"@opentelemetry/semantic-conventions": "^1.39.0",
3950
"@plotwist_app/tmdb": "^0.2.5",
4051
"@react-email/components": "^1.0.3",
4152
"@swc/core": "^1.15.8",
@@ -57,9 +68,9 @@
5768
"fastify-type-provider-zod": "^6.1.0",
5869
"google-auth-library": "^9.14.0",
5970
"https": "^1.0.0",
71+
"ioredis": "^5.8.2",
6072
"jsonwebtoken": "^9.0.2",
6173
"jwks-rsa": "^3.1.0",
62-
"ioredis": "^5.8.2",
6374
"node-cron": "^4.2.1",
6475
"openai": "^6.15.0",
6576
"pino": "^10.1.0",

apps/backend/src/config.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ export const config = {
1212
myAnimeList: loadMALEnvs(),
1313
openai: loadOpenAIEnvs(),
1414
google: loadGoogleEnvs(),
15+
monitors: loadMonitorsEnvs(),
16+
telemetry: loadTelemetryEnvs(),
1517
}
1618

1719
function loadRedisEnvs() {
@@ -121,3 +123,20 @@ function loadGoogleEnvs() {
121123

122124
return schema.parse(process.env)
123125
}
126+
127+
function loadMonitorsEnvs() {
128+
const schema = z.object({
129+
ENABLE_MONITORS: z.string().default('false'),
130+
MONITOR_CRON_TIME: z.string().default('0 0 * * *'),
131+
})
132+
133+
return schema.parse(process.env)
134+
}
135+
136+
function loadTelemetryEnvs() {
137+
const schema = z.object({
138+
OTEL_EXPORTER_OTLP_ENDPOINT: z.string().optional(),
139+
OTEL_EXPORTER_OTLP_HEADERS: z.string().optional(),
140+
})
141+
return schema.parse(process.env)
142+
}

apps/backend/src/domain/services/tmdb/get-tmdb-data.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { FastifyRedis } from '@fastify/redis'
2+
23
import type { Language } from '@plotwist_app/tmdb'
34
import { tmdb } from '@/infra/adapters/tmdb'
45

apps/backend/src/domain/services/users/update-user.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { z } from 'zod'
12
import { NoValidFieldsError } from '@/domain/errors/no-valid-fields'
23
import { UserNotFoundError } from '@/domain/errors/user-not-found'
34
import { UsernameAlreadyRegisteredError } from '@/domain/errors/username-already-registered'
@@ -8,7 +9,7 @@ import {
89
import { isUniqueViolation } from '@/infra/db/utils/postgres-errors'
910
import type { updateUserBodySchema } from '@/infra/http/schemas/users'
1011

11-
export type UpdateUserInput = typeof updateUserBodySchema._type
12+
export type UpdateUserInput = z.infer<typeof updateUserBodySchema>
1213

1314
export async function updateUserService({
1415
userId,

apps/backend/src/infra/adapters/r2-storage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ async function uploadImage({
7676

7777
const R2Storage: CloudStorage = {
7878
deleteOldImages: prefix => deleteOldImages(prefix),
79-
uploadImage: uploadImageInput => uploadImage(uploadImageInput),
79+
uploadImage: input => uploadImage(input),
8080
}
8181

8282
export { R2Storage }

apps/backend/src/infra/db/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { instrumentDrizzleClient } from '@kubiks/otel-drizzle'
12
import { drizzle } from 'drizzle-orm/postgres-js'
23
import postgres from 'postgres'
34
import { config } from '@/config'
@@ -6,3 +7,5 @@ import * as schema from './schema'
67

78
export const client = postgres(config.db.DATABASE_URL)
89
export const db = drizzle(client, { schema })
10+
11+
instrumentDrizzleClient(db, { dbSystem: 'postgresql' })

apps/backend/src/infra/db/repositories/reviews-repository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ export async function selectReviews({
118118
)
119119
.leftJoin(schema.users, eq(schema.reviews.userId, schema.users.id))
120120
.orderBy(...orderCriteria)
121-
.limit(limit + 1) // Fetch one extra to check if there are more
121+
.limit(limit + 1)
122122
.offset(offset)
123123
}
124124

apps/backend/src/infra/db/repositories/user-item-repository.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,6 @@ export async function reorderUserItems(
180180
_status: string,
181181
orderedIds: string[]
182182
) {
183-
// Update position for each item based on array order
184183
const updates = orderedIds.map((id, index) =>
185184
db
186185
.update(schema.userItems)

0 commit comments

Comments
 (0)