Skip to content

Commit ddbe7d2

Browse files
authored
Use pino for logs (#1086)
* Use pino for logs * Use logger for info * Add errorId to the logs
1 parent fc53d26 commit ddbe7d2

File tree

24 files changed

+413
-74
lines changed

24 files changed

+413
-74
lines changed

package-lock.json

Lines changed: 268 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@
6969
"nanoid": "^4.0.2",
7070
"openid-client": "^5.4.2",
7171
"parquetjs": "^0.11.2",
72+
"pino": "^9.0.0",
73+
"pino-pretty": "^11.0.0",
7274
"postcss": "^8.4.31",
7375
"saslprep": "^1.0.3",
7476
"satori": "^0.10.11",

src/app.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ declare global {
1212
sessionId: string;
1313
user?: User;
1414
}
15+
16+
interface Error {
17+
message: string;
18+
errorId?: ReturnType<typeof crypto.randomUUID>;
19+
}
1520
// interface PageData {}
1621
// interface Platform {}
1722
}

src/hooks.server.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
MESSAGES_BEFORE_LOGIN,
77
PARQUET_EXPORT_SECRET,
88
} from "$env/static/private";
9-
import type { Handle } from "@sveltejs/kit";
9+
import type { Handle, HandleServerError } from "@sveltejs/kit";
1010
import {
1111
PUBLIC_GOOGLE_ANALYTICS_ID,
1212
PUBLIC_ORIGIN,
@@ -21,6 +21,7 @@ import { addWeeks } from "date-fns";
2121
import { checkAndRunMigrations } from "$lib/migrations/migrations";
2222
import { building } from "$app/environment";
2323
import { refreshAssistantsCounts } from "$lib/assistantStats/refresh-assistants-counts";
24+
import { logger } from "$lib/server/logger";
2425

2526
if (!building) {
2627
await checkAndRunMigrations();
@@ -29,6 +30,31 @@ if (!building) {
2930
}
3031
}
3132

33+
export const handleError: HandleServerError = async ({ error, event }) => {
34+
// handle 404
35+
if (event.route.id === null) {
36+
return {
37+
message: `Page ${event.url.pathname} not found`,
38+
};
39+
}
40+
41+
const errorId = crypto.randomUUID();
42+
43+
logger.error({
44+
locals: event.locals,
45+
url: event.request.url,
46+
params: event.params,
47+
request: event.request,
48+
error,
49+
errorId,
50+
});
51+
52+
return {
53+
message: "An error occurred",
54+
errorId,
55+
};
56+
};
57+
3258
export const handle: Handle = async ({ event, resolve }) => {
3359
if (event.url.pathname.startsWith(`${base}/api/`) && EXPOSE_API !== "true") {
3460
return new Response("API is disabled", { status: 403 });

src/lib/assistantStats/refresh-assistants-counts.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { client, collections } from "$lib/server/database";
22
import { acquireLock, refreshLock } from "$lib/migrations/lock";
33
import type { ObjectId } from "mongodb";
44
import { subDays } from "date-fns";
5+
import { logger } from "$lib/server/logger";
56

67
const LOCK_KEY = "assistants.count";
78

@@ -53,8 +54,8 @@ async function refreshAssistantsCountsHelper() {
5354
})
5455
);
5556
} catch (e) {
56-
console.log("Refresh assistants counter failed!");
57-
console.error(e);
57+
logger.error("Refresh assistants counter failed!");
58+
logger.error(e);
5859
}
5960
}
6061

src/lib/migrations/migrations.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { client, collections } from "$lib/server/database";
22
import { migrations } from "./routines";
33
import { acquireLock, releaseLock, isDBLocked, refreshLock } from "./lock";
44
import { isHuggingChat } from "$lib/utils/isHuggingChat";
5+
import { logger } from "$lib/server/logger";
56

67
const LOCK_KEY = "migrations";
78

@@ -14,7 +15,7 @@ export async function checkAndRunMigrations() {
1415
// check if all migrations have already been run
1516
const migrationResults = await collections.migrationResults.find().toArray();
1617

17-
console.log("[MIGRATIONS] Begin check...");
18+
logger.info("[MIGRATIONS] Begin check...");
1819

1920
// connect to the database
2021
const connectedClient = await client.connect();
@@ -23,7 +24,7 @@ export async function checkAndRunMigrations() {
2324

2425
if (!lockId) {
2526
// another instance already has the lock, so we exit early
26-
console.log(
27+
logger.info(
2728
"[MIGRATIONS] Another instance already has the lock. Waiting for DB to be unlocked."
2829
);
2930

@@ -50,21 +51,21 @@ export async function checkAndRunMigrations() {
5051

5152
// check if the migration has already been applied
5253
if (!shouldRun) {
53-
console.log(`[MIGRATIONS] "${migration.name}" already applied. Skipping...`);
54+
logger.info(`[MIGRATIONS] "${migration.name}" already applied. Skipping...`);
5455
} else {
5556
// check the modifiers to see if some cases match
5657
if (
5758
(migration.runForHuggingChat === "only" && !isHuggingChat) ||
5859
(migration.runForHuggingChat === "never" && isHuggingChat)
5960
) {
60-
console.log(
61+
logger.info(
6162
`[MIGRATIONS] "${migration.name}" should not be applied for this run. Skipping...`
6263
);
6364
continue;
6465
}
6566

6667
// otherwise all is good and we can run the migration
67-
console.log(
68+
logger.info(
6869
`[MIGRATIONS] "${migration.name}" ${
6970
migration.runEveryTime ? "should run every time" : "not applied yet"
7071
}. Applying...`
@@ -89,8 +90,8 @@ export async function checkAndRunMigrations() {
8990
result = await migration.up(connectedClient);
9091
});
9192
} catch (e) {
92-
console.log(`[MIGRATION[] "${migration.name}" failed!`);
93-
console.error(e);
93+
logger.info(`[MIGRATIONS] "${migration.name}" failed!`);
94+
logger.error(e);
9495
} finally {
9596
await session.endSession();
9697
}
@@ -108,7 +109,7 @@ export async function checkAndRunMigrations() {
108109
}
109110
}
110111

111-
console.log("[MIGRATIONS] All migrations applied. Releasing lock");
112+
logger.info("[MIGRATIONS] All migrations applied. Releasing lock");
112113

113114
clearInterval(refreshInterval);
114115
await releaseLock(LOCK_KEY, lockId);

src/lib/server/abortedGenerations.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { setTimeout } from "node:timers/promises";
44
import { collections } from "./database";
5+
import { logger } from "$lib/server/logger";
56

67
let closed = false;
78
process.on("SIGINT", () => {
@@ -21,7 +22,7 @@ async function maintainAbortedGenerations() {
2122
aborts.map(({ conversationId, createdAt }) => [conversationId.toString(), createdAt])
2223
);
2324
} catch (err) {
24-
console.error(err);
25+
logger.error(err);
2526
}
2627
}
2728
}

src/lib/server/auth.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { dev } from "$app/environment";
1818
import type { Cookies } from "@sveltejs/kit";
1919
import { collections } from "./database";
2020
import JSON5 from "json5";
21+
import { logger } from "$lib/server/logger";
2122

2223
export interface OIDCSettings {
2324
redirectURI: string;
@@ -151,7 +152,7 @@ export async function validateAndParseCsrfToken(
151152
return { redirectUrl: data.redirectUrl };
152153
}
153154
} catch (e) {
154-
console.error(e);
155+
logger.error(e);
155156
}
156157
return null;
157158
}

src/lib/server/database.ts

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type { ConversationStats } from "$lib/types/ConversationStats";
1313
import type { MigrationResult } from "$lib/types/MigrationResult";
1414
import type { Semaphore } from "$lib/types/Semaphore";
1515
import type { AssistantStats } from "$lib/types/AssistantStats";
16+
import { logger } from "$lib/server/logger";
1617

1718
if (!MONGODB_URL) {
1819
throw new Error(
@@ -25,7 +26,7 @@ const client = new MongoClient(MONGODB_URL, {
2526
directConnection: MONGODB_DIRECT_CONNECTION === "true",
2627
});
2728

28-
export const connectPromise = client.connect().catch(console.error);
29+
export const connectPromise = client.connect().catch(logger.error);
2930

3031
export function getCollections(mongoClient: MongoClient) {
3132
const db = mongoClient.db(MONGODB_DB_NAME + (import.meta.env.MODE === "test" ? "-test" : ""));
@@ -89,25 +90,25 @@ client.on("open", () => {
8990
{ sessionId: 1, updatedAt: -1 },
9091
{ partialFilterExpression: { sessionId: { $exists: true } } }
9192
)
92-
.catch(console.error);
93+
.catch(logger.error);
9394
conversations
9495
.createIndex(
9596
{ userId: 1, updatedAt: -1 },
9697
{ partialFilterExpression: { userId: { $exists: true } } }
9798
)
98-
.catch(console.error);
99+
.catch(logger.error);
99100
conversations
100101
.createIndex(
101102
{ "message.id": 1, "message.ancestors": 1 },
102103
{ partialFilterExpression: { userId: { $exists: true } } }
103104
)
104-
.catch(console.error);
105+
.catch(logger.error);
105106
// To do stats on conversations
106-
conversations.createIndex({ updatedAt: 1 }).catch(console.error);
107+
conversations.createIndex({ updatedAt: 1 }).catch(logger.error);
107108
// Not strictly necessary, could use _id, but more convenient. Also for stats
108-
conversations.createIndex({ createdAt: 1 }).catch(console.error);
109+
conversations.createIndex({ createdAt: 1 }).catch(logger.error);
109110
// To do stats on conversation messages
110-
conversations.createIndex({ "messages.createdAt": 1 }, { sparse: true }).catch(console.error);
111+
conversations.createIndex({ "messages.createdAt": 1 }, { sparse: true }).catch(logger.error);
111112
// Unique index for stats
112113
conversationStats
113114
.createIndex(
@@ -120,42 +121,42 @@ client.on("open", () => {
120121
},
121122
{ unique: true }
122123
)
123-
.catch(console.error);
124+
.catch(logger.error);
124125
// Allow easy check of last computed stat for given type/dateField
125126
conversationStats
126127
.createIndex({
127128
type: 1,
128129
"date.field": 1,
129130
"date.at": 1,
130131
})
131-
.catch(console.error);
132-
abortedGenerations.createIndex({ updatedAt: 1 }, { expireAfterSeconds: 30 }).catch(console.error);
133-
abortedGenerations.createIndex({ conversationId: 1 }, { unique: true }).catch(console.error);
134-
sharedConversations.createIndex({ hash: 1 }, { unique: true }).catch(console.error);
135-
settings.createIndex({ sessionId: 1 }, { unique: true, sparse: true }).catch(console.error);
136-
settings.createIndex({ userId: 1 }, { unique: true, sparse: true }).catch(console.error);
137-
settings.createIndex({ assistants: 1 }).catch(console.error);
138-
users.createIndex({ hfUserId: 1 }, { unique: true }).catch(console.error);
139-
users.createIndex({ sessionId: 1 }, { unique: true, sparse: true }).catch(console.error);
132+
.catch(logger.error);
133+
abortedGenerations.createIndex({ updatedAt: 1 }, { expireAfterSeconds: 30 }).catch(logger.error);
134+
abortedGenerations.createIndex({ conversationId: 1 }, { unique: true }).catch(logger.error);
135+
sharedConversations.createIndex({ hash: 1 }, { unique: true }).catch(logger.error);
136+
settings.createIndex({ sessionId: 1 }, { unique: true, sparse: true }).catch(logger.error);
137+
settings.createIndex({ userId: 1 }, { unique: true, sparse: true }).catch(logger.error);
138+
settings.createIndex({ assistants: 1 }).catch(logger.error);
139+
users.createIndex({ hfUserId: 1 }, { unique: true }).catch(logger.error);
140+
users.createIndex({ sessionId: 1 }, { unique: true, sparse: true }).catch(logger.error);
140141
// No unicity because due to renames & outdated info from oauth provider, there may be the same username on different users
141-
users.createIndex({ username: 1 }).catch(console.error);
142-
messageEvents.createIndex({ createdAt: 1 }, { expireAfterSeconds: 60 }).catch(console.error);
143-
sessions.createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 }).catch(console.error);
144-
sessions.createIndex({ sessionId: 1 }, { unique: true }).catch(console.error);
145-
assistants.createIndex({ createdById: 1, userCount: -1 }).catch(console.error);
146-
assistants.createIndex({ userCount: 1 }).catch(console.error);
147-
assistants.createIndex({ featured: 1, userCount: -1 }).catch(console.error);
148-
assistants.createIndex({ modelId: 1, userCount: -1 }).catch(console.error);
149-
assistants.createIndex({ searchTokens: 1 }).catch(console.error);
150-
assistants.createIndex({ last24HoursCount: 1 }).catch(console.error);
142+
users.createIndex({ username: 1 }).catch(logger.error);
143+
messageEvents.createIndex({ createdAt: 1 }, { expireAfterSeconds: 60 }).catch(logger.error);
144+
sessions.createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 }).catch(logger.error);
145+
sessions.createIndex({ sessionId: 1 }, { unique: true }).catch(logger.error);
146+
assistants.createIndex({ createdById: 1, userCount: -1 }).catch(logger.error);
147+
assistants.createIndex({ userCount: 1 }).catch(logger.error);
148+
assistants.createIndex({ featured: 1, userCount: -1 }).catch(logger.error);
149+
assistants.createIndex({ modelId: 1, userCount: -1 }).catch(logger.error);
150+
assistants.createIndex({ searchTokens: 1 }).catch(logger.error);
151+
assistants.createIndex({ last24HoursCount: 1 }).catch(logger.error);
151152
assistantStats
152153
// Order of keys is important for the queries
153154
.createIndex({ "date.span": 1, "date.at": 1, assistantId: 1 }, { unique: true })
154-
.catch(console.error);
155-
reports.createIndex({ assistantId: 1 }).catch(console.error);
156-
reports.createIndex({ createdBy: 1, assistantId: 1 }).catch(console.error);
155+
.catch(logger.error);
156+
reports.createIndex({ assistantId: 1 }).catch(logger.error);
157+
reports.createIndex({ createdBy: 1, assistantId: 1 }).catch(logger.error);
157158

158159
// Unique index for semaphore and migration results
159-
semaphores.createIndex({ key: 1 }, { unique: true }).catch(console.error);
160-
semaphores.createIndex({ createdAt: 1 }, { expireAfterSeconds: 60 }).catch(console.error);
160+
semaphores.createIndex({ key: 1 }, { unique: true }).catch(logger.error);
161+
semaphores.createIndex({ createdAt: 1 }, { expireAfterSeconds: 60 }).catch(logger.error);
161162
});

src/lib/server/embeddingEndpoints/hfApi/embeddingHfApi.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { z } from "zod";
22
import type { EmbeddingEndpoint, Embedding } from "../embeddingEndpoints";
33
import { chunk } from "$lib/utils/chunk";
44
import { HF_TOKEN } from "$env/static/private";
5+
import { logger } from "$lib/server/logger";
56

67
export const embeddingEndpointHfApiSchema = z.object({
78
weight: z.number().int().positive().default(1),
@@ -35,8 +36,8 @@ export async function embeddingEndpointHfApi(
3536
});
3637

3738
if (!response.ok) {
38-
console.log(await response.text());
39-
console.error("Failed to get embeddings from Hugging Face API", response);
39+
logger.error(await response.text());
40+
logger.error("Failed to get embeddings from Hugging Face API", response);
4041
return [];
4142
}
4243

0 commit comments

Comments
 (0)