From db9109a3be4c1297580d2a88b12e456920a051b8 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 5 Jul 2025 14:43:49 -0600 Subject: [PATCH] fix(settings): update readMonitoringConfig to async and improve log reading efficiency --- apps/dokploy/server/api/routers/settings.ts | 8 +-- .../server/src/utils/traefik/application.ts | 49 ++++++++++--------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/apps/dokploy/server/api/routers/settings.ts b/apps/dokploy/server/api/routers/settings.ts index 9bab0622e..9ab142c58 100644 --- a/apps/dokploy/server/api/routers/settings.ts +++ b/apps/dokploy/server/api/routers/settings.ts @@ -609,14 +609,14 @@ export const settingsRouter = createTRPCRouter({ }, }) .input(apiReadStatsLogs) - .query(({ input }) => { + .query(async ({ input }) => { if (IS_CLOUD) { return { data: [], totalCount: 0, }; } - const rawConfig = readMonitoringConfig( + const rawConfig = await readMonitoringConfig( !!input.dateRange?.start && !!input.dateRange?.end, ); @@ -652,11 +652,11 @@ export const settingsRouter = createTRPCRouter({ }) .optional(), ) - .query(({ input }) => { + .query(async ({ input }) => { if (IS_CLOUD) { return []; } - const rawConfig = readMonitoringConfig( + const rawConfig = await readMonitoringConfig( !!input?.dateRange?.start || !!input?.dateRange?.end, ); const processedLogs = processLogs(rawConfig as string, input?.dateRange); diff --git a/packages/server/src/utils/traefik/application.ts b/packages/server/src/utils/traefik/application.ts index 773f2bf64..8e7ca574b 100644 --- a/packages/server/src/utils/traefik/application.ts +++ b/packages/server/src/utils/traefik/application.ts @@ -1,5 +1,7 @@ import fs, { writeFileSync } from "node:fs"; import path from "node:path"; +import { createReadStream } from "node:fs"; +import { createInterface } from "node:readline"; import { paths } from "@dokploy/server/constants"; import type { Domain } from "@dokploy/server/services/domain"; import { dump, load } from "js-yaml"; @@ -137,39 +139,40 @@ export const readRemoteConfig = async (serverId: string, appName: string) => { } }; -export const readMonitoringConfig = (readAll = false) => { +export const readMonitoringConfig = async (readAll = false) => { const { DYNAMIC_TRAEFIK_PATH } = paths(); const configPath = path.join(DYNAMIC_TRAEFIK_PATH, "access.log"); if (fs.existsSync(configPath)) { if (!readAll) { - // Read first 500 lines + // Read first 500 lines using streams let content = ""; - let chunk = ""; let validCount = 0; - for (const char of fs.readFileSync(configPath, "utf8")) { - chunk += char; - if (char === "\n") { - try { - const trimmed = chunk.trim(); - if ( - trimmed !== "" && - trimmed.startsWith("{") && - trimmed.endsWith("}") - ) { - const log = JSON.parse(trimmed); - if (log.ServiceName !== "dokploy-service-app@file") { - content += chunk; - validCount++; - if (validCount >= 500) { - break; - } + const fileStream = createReadStream(configPath, { encoding: "utf8" }); + const readline = createInterface({ + input: fileStream, + crlfDelay: Number.POSITIVE_INFINITY, + }); + + for await (const line of readline) { + try { + const trimmed = line.trim(); + if ( + trimmed !== "" && + trimmed.startsWith("{") && + trimmed.endsWith("}") + ) { + const log = JSON.parse(trimmed); + if (log.ServiceName !== "dokploy-service-app@file") { + content += `${line}\n`; + validCount++; + if (validCount >= 500) { + break; } } - } catch { - // Ignore invalid JSON } - chunk = ""; + } catch { + // Ignore invalid JSON } } return content;