fix: log noise #284

fix: logs noise
This commit is contained in:
Charles GTE
2026-05-15 22:41:21 +02:00
committed by GitHub
17 changed files with 2124 additions and 1577 deletions
+6
View File
@@ -1,6 +1,12 @@
# Environment
NODE_ENV=development
# Logging
# Controls minimum log level. Options: debug | info | warn | error
# Set to "warn" or "error" in production to suppress health-check ping noise.
# Use "debug" to see all request logs including agent status pings.
LOG_LEVEL=info
# Database
DATABASE_URL=postgresql://devuser:changeme@localhost:5433/devdb?schema=public
+4
View File
@@ -55,3 +55,7 @@ certificates
/playwright/.cache/
/playwright/.auth/
/e2e/local-storage.json
.claude
.codex
/docs
@@ -1,6 +1,7 @@
import {PageParams} from "@/types/next";
import {Page, PageContent, PageHeader, PageTitle} from "@/features/layout/page";
import {db} from "@/db";
import {logger} from "@/lib/logger";
import {notFound} from "next/navigation";
import {SettingsTabs} from "@/components/wrappers/dashboard/admin/settings/settings-tabs";
import {desc, isNull} from "drizzle-orm";
@@ -8,13 +9,15 @@ import * as drizzleDb from "@/db";
import {StorageChannelWith} from "@/db/schema/12_storage-channel";
import {NotificationChannelWith} from "@/db/schema/09_notification-channel";
const log = logger.child({module: "dashboard/admin/settings"});
export default async function RoutePage(props: PageParams<{}>) {
const settings = await db.query.setting.findFirst({
where: (fields, {eq}) => eq(fields.name, "system"),
});
console.log(settings)
log.debug({settings}, "Settings loaded");
const storageChannels = await db.query.storageChannel.findMany({
with: {
@@ -33,7 +36,7 @@ export default async function RoutePage(props: PageParams<{}>) {
}) as NotificationChannelWith[]
if (!settings || !storageChannels || !notificationChannels ) {
if (!settings || !storageChannels || !notificationChannels) {
notFound()
}
@@ -45,7 +48,8 @@ export default async function RoutePage(props: PageParams<{}>) {
</div>
</PageHeader>
<PageContent className="flex flex-col gap-5">
<SettingsTabs storageChannels={storageChannels} notificationChannels={notificationChannels} settings={settings} />
<SettingsTabs storageChannels={storageChannels} notificationChannels={notificationChannels}
settings={settings}/>
</PageContent>
</Page>
);
-4
View File
@@ -9,8 +9,4 @@ export default async function Index() {
redirect(`/dashboard/home`);
}
redirect("/login");
//Do not delete
// return (
// <Home/>
// );
}
+1 -1
View File
@@ -31,7 +31,7 @@ export async function POST(
) {
try {
const agentId = (await params).agentId
log.info(`Agent ID: ${agentId}`)
log.debug(`Agent ID: ${agentId}`)
const body: Body = await request.json();
const lastContact = new Date();
let message: string
+10 -1
View File
@@ -12,7 +12,7 @@ services:
- POSTGRES_USER=devuser
- POSTGRES_PASSWORD=changeme
healthcheck:
test: ["CMD-SHELL", "pg_isready -U devuser -d devdb"]
test: [ "CMD-SHELL", "pg_isready -U devuser -d devdb" ]
interval: 10s
timeout: 5s
retries: 5
@@ -32,5 +32,14 @@ services:
- ./private/uploads/tmp:/data/uploads/tmp
user: "1000:1000"
mailpit:
image: axllent/mailpit:latest
container_name: portabase-mailpit-dev
hostname: mailpit
restart: unless-stopped
ports:
- "8025:8025"
- "1025:1025"
volumes:
postgres-data:
+4 -4
View File
@@ -16,8 +16,8 @@
},
"dependencies": {
"@better-auth/core": "1.6.2",
"@better-auth/passkey": "^1.6.2",
"@better-auth/sso": "^1.6.2",
"@better-auth/passkey": "1.6.2",
"@better-auth/sso": "1.6.2",
"@hookform/resolvers": "^5.2.2",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-alert-dialog": "^1.1.15",
@@ -128,7 +128,7 @@
"eslint-plugin-tailwindcss": "^3.18.2",
"framer-motion": "^12.38.0",
"node-pty": "^1.1.0",
"postcss": "^8.5.9",
"postcss": "8.5.10",
"release-it": "^19.2.4",
"tailwindcss": "^4.2.2",
"tsx": "^4.21.0",
@@ -136,5 +136,5 @@
"typescript": "^5.9.3",
"zenstack": "2.14.2"
},
"packageManager": "pnpm@10.33.0"
"packageManager": "pnpm@11.1.2+sha512.415a1cc25974731e75455c1468371be74c5aa5fb7621b50d4056d222451609f11412f23fd602e6169f1e060466641f798597e1be961a10688836a67b16569499"
}
+2038 -1547
View File
File diff suppressed because it is too large Load Diff
+14
View File
@@ -1,3 +1,17 @@
allowBuilds:
'@prisma/client': true
'@prisma/engines': true
argon2: true
bcrypt: true
cpu-features: true
esbuild: true
node-pty: true
prisma: true
protobufjs: true
sharp: true
ssh2: true
unrs-resolver: true
zenstack: true
ignoredBuiltDependencies:
- node-pty
onlyBuiltDependencies:
@@ -1,13 +1,16 @@
"use server";
import {userAction} from "@/lib/safe-actions/actions";
import { logger } from "@/lib/logger";
import {z} from "zod";
import {v4 as uuidv4} from "uuid";
import {ServerActionResult} from "@/types/action-type";
import {and, eq, inArray} from "drizzle-orm";
import {eq, inArray} from "drizzle-orm";
import {db} from "@/db";
import * as drizzleDb from "@/db";
const log = logger.child({ module: "dashboard/delete-project.action" });
export const deleteProjectAction = userAction.schema(z.string()).action(async ({parsedInput}): Promise<ServerActionResult<typeof drizzleDb.schemas.project.$inferSelect>> => {
try {
const uuid = uuidv4();
@@ -51,7 +54,7 @@ export const deleteProjectAction = userAction.schema(z.string()).action(async ({
},
};
} catch (error) {
console.log(error);
log.error({ error }, "Failed to archive project");
return {
success: false,
actionError: {
+4 -1
View File
@@ -11,6 +11,9 @@ import {StorageChannel} from "@/db/schema/12_storage-channel";
import {
StorageChannelFormType
} from "@/components/wrappers/dashboard/admin/channels/channel/channel-form/channel-form.schema";
import { logger } from "@/lib/logger";
const log = logger.child({ module: "features/storages/dispatch" });
export async function dispatchStorage(
@@ -103,7 +106,7 @@ export async function dispatchStorage(
input,
);
console.log(dispatchResult);
log.debug({ result: dispatchResult }, "Storage dispatch result");
return dispatchResult;
} catch (err: any) {
+4 -3
View File
@@ -1,5 +1,6 @@
"use server";
import {userAction} from "@/lib/safe-actions/actions";
import {logger} from "@/lib/logger";
import {z} from "zod";
import {v4 as uuidv4} from "uuid";
import {db} from "@/db";
@@ -10,6 +11,7 @@ import {dispatchStorage} from "@/features/storages/dispatch";
import {StorageInput} from "@/features/storages/types";
import sharp from "sharp";
const log = logger.child({module: "features/upload/upload.action"});
export const uploadUserImageAction = userAction.schema(
z.instanceof(FormData)
@@ -27,7 +29,7 @@ export const uploadUserImageAction = userAction.schema(
const isWebp = fileFormat === "webp";
const compressedBuffer = await sharp(buffer)
.resize({ width: 1024 })
.resize({width: 1024})
.toFormat(isPng ? "png" : isWebp ? "webp" : "jpeg", {
quality: 80,
compressionLevel: isPng ? 9 : undefined
@@ -35,7 +37,6 @@ export const uploadUserImageAction = userAction.schema(
.toBuffer();
const settings = await db.query.setting.findFirst({
where: eq(drizzleDb.schemas.setting.name, "system"),
with: {
@@ -69,7 +70,7 @@ export const uploadUserImageAction = userAction.schema(
}
const result = await dispatchStorage(input, undefined, settings.storageChannel.id);
console.log(result);
log.debug({result}, "Upload dispatch result");
if (!result.success) {
return {
success: false,
+6 -6
View File
@@ -22,7 +22,9 @@ import {passkey} from "@better-auth/passkey";
import {getOidcProviders} from "./oidc";
import {APIError} from "better-auth/api";
import {getOAuthProviders} from "./oauth";
import { logger } from "@/lib/logger";
const log = logger.child({ module: "lib/auth" });
const oidcProviders = getOidcProviders();
@@ -438,9 +440,7 @@ export const auth = betterAuth({
new Date(user.createdAt).getTime();
if (createdAtDiff < 5000) {
console.log(
`Skipping new login email for freshly created user ${user.email}`,
);
log.debug(`Skipping new login email for freshly created user ${user.email}`);
return;
}
@@ -471,12 +471,12 @@ export const auth = betterAuth({
),
});
} catch (error) {
console.log("sendEmail failed", {
log.error({
userId: user.id,
details: "Please Check your env variables or system config",
email: user.email,
error,
});
}, "sendEmail failed");
}
(await auth.$context).internalAdapter.updateUser(user.id, {
@@ -784,7 +784,7 @@ export const getActiveMember = async () => {
return member as MemberWithUser;
} catch (e) {
console.log("err", e);
log.error({ error: e }, "Auth error");
}
};
+3 -1
View File
@@ -1,6 +1,8 @@
import pino, { type Logger } from "pino";
const isProd = process.env.NODE_ENV === "production";
const defaultLevel = isProd ? "info" : "debug";
const level = (process.env.LOG_LEVEL ?? defaultLevel) as pino.Level;
function getLocalTimestamp() {
const date = new Date();
@@ -19,7 +21,7 @@ function getLocalTimestamp() {
}
export const logger: Logger = pino({
level: isProd ? "info" : "debug",
level,
base: null,
...(isProd
+2 -2
View File
@@ -14,7 +14,7 @@ export const backupCleanTask = async () => {
eq(drizzleDb.schemas.backup.status, "ongoing")
)
});
log.info(`Backups to clean: ${backups.length}`);
log.debug(`Backups to clean: ${backups.length}`);
for (const backup of backups) {
await db.update(drizzleDb.schemas.backup).set(withUpdatedAt({
@@ -24,7 +24,7 @@ export const backupCleanTask = async () => {
}
} catch (e: any) {
log.info({name: "backupCleanTask", error: e},`Backup cleanup failed`);
log.error({name: "backupCleanTask", error: e},`Backup cleanup failed`);
throw e;
}
};
+1 -1
View File
@@ -22,7 +22,7 @@ export const retentionJob = cron.schedule(env.RETENTION_CRON, async () => {
export const cleaningJob = cron.schedule("* * * * *", async () => {
try {
log.info({ job: "cron", action: "start", name: "cleaningJob" }, "Cleaning Job started");
log.debug({ job: "cron", action: "start", name: "cleaningJob" }, "Cleaning Job started");
await backupCleanTask();
} catch (err) {
log.error({ job: "cron", name: "cleaningJob", error: err }, "Cleaning Job Error");
+15 -1
View File
@@ -1,8 +1,22 @@
import { NextRequest, NextResponse } from 'next/server';
const LOG_LEVELS = ["debug", "info", "warn", "error"] as const;
type LogLevel = typeof LOG_LEVELS[number];
const raw = (process.env.LOG_LEVEL ?? "info") as LogLevel;
const _idx = LOG_LEVELS.indexOf(raw);
const LEVEL_INDEX = _idx === -1 ? 1 : _idx;
const STATUS_PATH_RE = /\/api\/agent\/[^/]+\/status\/?$/;
export function loggingMiddleware(request: NextRequest) {
if (request.url.includes('/api')) {
console.log(`[API] Received ${request.method} request : ${request.url} at ${new Date()}`);
const isStatusPing = STATUS_PATH_RE.test(request.nextUrl.pathname);
// Status pings are debug-level; all other API calls are info-level.
const requiredIndex = isStatusPing ? 0 : 1;
if (LEVEL_INDEX <= requiredIndex) {
console.log(`[API] Received ${request.method} request : ${request.url} at ${new Date()}`);
}
}
return NextResponse.next();
}