refactor(api): 🔊 Move HTTP logs to logtape/hono
Some checks failed
CodeQL Scan / Analyze (javascript-typescript) (push) Failing after 1s
Build Docker Images / lint (push) Failing after 7s
Build Docker Images / check (push) Failing after 6s
Build Docker Images / tests (push) Failing after 6s
Build Docker Images / detect-circular (push) Failing after 6s
Deploy Docs to GitHub Pages / build (push) Failing after 0s
Build Docker Images / build (server, Dockerfile, ${{ github.repository_owner }}/server) (push) Has been skipped
Build Docker Images / build (worker, Worker.Dockerfile, ${{ github.repository_owner }}/worker) (push) Has been skipped
Deploy Docs to GitHub Pages / Deploy (push) Has been skipped
Mirror to Codeberg / Mirror (push) Failing after 0s
Nix Build / check (push) Failing after 1s
Test Publish / build (client) (push) Failing after 0s
Test Publish / build (sdk) (push) Failing after 0s

This commit is contained in:
Jesse Wierzbinski 2025-12-18 22:22:03 +01:00
parent a2d7c323f6
commit de69f27877
No known key found for this signature in database
9 changed files with 15 additions and 50 deletions

View file

@ -181,6 +181,7 @@
"version": "0.0.1", "version": "0.0.1",
"dependencies": { "dependencies": {
"@logtape/file": "catalog:", "@logtape/file": "catalog:",
"@logtape/hono": "catalog:",
"@logtape/logtape": "catalog:", "@logtape/logtape": "catalog:",
"@logtape/otel": "catalog:", "@logtape/otel": "catalog:",
"@logtape/sentry": "catalog:", "@logtape/sentry": "catalog:",
@ -241,6 +242,7 @@
"@hono/standard-validator": "~0.2.1", "@hono/standard-validator": "~0.2.1",
"@inquirer/confirm": "~6.0.3", "@inquirer/confirm": "~6.0.3",
"@logtape/file": "~1.3.4", "@logtape/file": "~1.3.4",
"@logtape/hono": "~1.3.4",
"@logtape/logtape": "~1.3.4", "@logtape/logtape": "~1.3.4",
"@logtape/otel": "~1.3.4", "@logtape/otel": "~1.3.4",
"@logtape/sentry": "~1.3.4", "@logtape/sentry": "~1.3.4",
@ -560,6 +562,8 @@
"@logtape/file": ["@logtape/file@1.3.4", "", { "peerDependencies": { "@logtape/logtape": "^1.3.4" } }, "sha512-tIE9T/WR3iqnsacN/el0DdvScNeofpZr54M6AP+Pw7kE7tDOTMnzK2JMd7dcx1mrsF3ZVqUkxToolE70u68blg=="], "@logtape/file": ["@logtape/file@1.3.4", "", { "peerDependencies": { "@logtape/logtape": "^1.3.4" } }, "sha512-tIE9T/WR3iqnsacN/el0DdvScNeofpZr54M6AP+Pw7kE7tDOTMnzK2JMd7dcx1mrsF3ZVqUkxToolE70u68blg=="],
"@logtape/hono": ["@logtape/hono@1.3.4", "", { "peerDependencies": { "@logtape/logtape": "^1.3.4", "hono": "^4.0.0" } }, "sha512-+usxX/6b9I6rZaZWPCv/BvI8vdn1rTWeE4JGfwOLKNAVhSuQ/gb0w1r3tRQcCv+Z17jlIVsbqA7qfaBF8V5UTQ=="],
"@logtape/logtape": ["@logtape/logtape@1.3.4", "", {}, "sha512-zFdMXSvyFp3R9FzjxKD9hP+MGdTlOTOutxL9Kg2qLvIUrZ4+q4KvvQC4Zo7LTGWdR2Z5RlzjwSBjyANhsntriw=="], "@logtape/logtape": ["@logtape/logtape@1.3.4", "", {}, "sha512-zFdMXSvyFp3R9FzjxKD9hP+MGdTlOTOutxL9Kg2qLvIUrZ4+q4KvvQC4Zo7LTGWdR2Z5RlzjwSBjyANhsntriw=="],
"@logtape/otel": ["@logtape/otel@1.3.4", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/api-logs": "^0.208.0", "@opentelemetry/exporter-logs-otlp-grpc": "^0.208.0", "@opentelemetry/exporter-logs-otlp-http": "^0.208.0", "@opentelemetry/exporter-logs-otlp-proto": "^0.208.0", "@opentelemetry/otlp-exporter-base": "^0.208.0", "@opentelemetry/resources": "^2.2.0", "@opentelemetry/sdk-logs": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.38.0" }, "peerDependencies": { "@logtape/logtape": "^1.3.4" } }, "sha512-88vmByhJ2LYxYdzWtvNxFOAdaVGlwCDpc+8iIQUAB3OmpbvcOot1fRRZcDPg4iA7gLTkYs0pbXb718F/LLafzQ=="], "@logtape/otel": ["@logtape/otel@1.3.4", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/api-logs": "^0.208.0", "@opentelemetry/exporter-logs-otlp-grpc": "^0.208.0", "@opentelemetry/exporter-logs-otlp-http": "^0.208.0", "@opentelemetry/exporter-logs-otlp-proto": "^0.208.0", "@opentelemetry/otlp-exporter-base": "^0.208.0", "@opentelemetry/resources": "^2.2.0", "@opentelemetry/sdk-logs": "^0.208.0", "@opentelemetry/semantic-conventions": "^1.38.0" }, "peerDependencies": { "@logtape/logtape": "^1.3.4" } }, "sha512-88vmByhJ2LYxYdzWtvNxFOAdaVGlwCDpc+8iIQUAB3OmpbvcOot1fRRZcDPg4iA7gLTkYs0pbXb718F/LLafzQ=="],

View file

@ -54,7 +54,7 @@ in
# Required else we get errors that our fixed-output derivation references store paths # Required else we get errors that our fixed-output derivation references store paths
dontFixup = true; dontFixup = true;
outputHash = "sha256-Ope/mLjhzNkoU9FIPO+kF4mlnZEqqLHzFvZmnrtvue4="; outputHash = "sha256-vCqJXbmC03p/4o2p9ou6COEmyPn7znm1LVYJapyexvI=";
outputHashAlgo = "sha256"; outputHashAlgo = "sha256";
outputHashMode = "recursive"; outputHashMode = "recursive";
}; };

View file

@ -69,6 +69,7 @@
"@inquirer/confirm": "~6.0.3", "@inquirer/confirm": "~6.0.3",
"@logtape/file": "~1.3.4", "@logtape/file": "~1.3.4",
"@logtape/logtape": "~1.3.4", "@logtape/logtape": "~1.3.4",
"@logtape/hono": "~1.3.4",
"@logtape/sentry": "~1.3.4", "@logtape/sentry": "~1.3.4",
"@logtape/otel": "~1.3.4", "@logtape/otel": "~1.3.4",
"@scalar/hono-api-reference": "~0.9.30", "@scalar/hono-api-reference": "~0.9.30",

View file

@ -1,6 +1,7 @@
import { Scalar } from "@scalar/hono-api-reference"; import { Scalar } from "@scalar/hono-api-reference";
import { config } from "@versia-server/config"; import { config } from "@versia-server/config";
import { ApiError } from "@versia-server/kit"; import { ApiError } from "@versia-server/kit";
import { honoLogger } from "@versia-server/logging";
import { Hono } from "hono"; import { Hono } from "hono";
import { serveStatic } from "hono/bun"; import { serveStatic } from "hono/bun";
import { cors } from "hono/cors"; import { cors } from "hono/cors";
@ -15,7 +16,6 @@ import type { ApiRouteExports, HonoEnv } from "../../types/api.ts";
import { agentBans } from "./middlewares/agent-bans.ts"; import { agentBans } from "./middlewares/agent-bans.ts";
import { boundaryCheck } from "./middlewares/boundary-check.ts"; import { boundaryCheck } from "./middlewares/boundary-check.ts";
import { ipBans } from "./middlewares/ip-bans.ts"; import { ipBans } from "./middlewares/ip-bans.ts";
import { logger } from "./middlewares/logger.ts";
import { rateLimit } from "./middlewares/rate-limit.ts"; import { rateLimit } from "./middlewares/rate-limit.ts";
import { routes } from "./routes.ts"; import { routes } from "./routes.ts";
@ -26,7 +26,7 @@ export const appFactory = async (): Promise<Hono<HonoEnv>> => {
app.use(ipBans); app.use(ipBans);
app.use(agentBans); app.use(agentBans);
app.use(logger); app.use(honoLogger);
app.use(boundaryCheck); app.use(boundaryCheck);
app.use( app.use(
"/api/*", "/api/*",

View file

@ -1,26 +0,0 @@
import { serverLogger } from "@versia-server/logging";
import { SHA256 } from "bun";
import chalk from "chalk";
import { createMiddleware } from "hono/factory";
export const logger = createMiddleware(async (context, next) => {
const body = await context.req.raw.clone().text();
const urlAndMethod = `${chalk.green(context.req.method)} ${chalk.blue(context.req.url)}`;
const hash = `${chalk.bold("Hash")}: ${chalk.yellow(
new SHA256().update(body).digest("hex"),
)}`;
const headers = `${chalk.bold("Headers")}:\n${Array.from(
context.req.raw.headers.entries(),
)
.map(([key, value]) => ` - ${chalk.cyan(key)}: ${chalk.white(value)}`)
.join("\n")}`;
const bodyLog = `${chalk.bold("Body")}: ${chalk.gray(body)}`;
serverLogger.debug`${urlAndMethod}\n${hash}\n${headers}\n${bodyLog}`;
await next();
});

View file

@ -1,9 +1,7 @@
import type { Hook } from "@hono/standard-validator"; import type { Hook } from "@hono/standard-validator";
import type { RolePermission } from "@versia/client/schemas"; import type { RolePermission } from "@versia/client/schemas";
import { config } from "@versia-server/config"; import { config } from "@versia-server/config";
import { serverLogger } from "@versia-server/logging";
import { extractParams, verifySolution } from "altcha-lib"; import { extractParams, verifySolution } from "altcha-lib";
import chalk from "chalk";
import { eq, type SQL } from "drizzle-orm"; import { eq, type SQL } from "drizzle-orm";
import type { Context, Hono, MiddlewareHandler, ValidationTargets } from "hono"; import type { Context, Hono, MiddlewareHandler, ValidationTargets } from "hono";
import { every } from "hono/combine"; import { every } from "hono/combine";
@ -417,19 +415,3 @@ export const jsonOrForm = (): MiddlewareHandler<HonoEnv> => {
await next(); await next();
}); });
}; };
export const debugResponse = async (res: Response): Promise<void> => {
const body = await res.clone().text();
const status = `${chalk.bold("Status")}: ${chalk.green(res.status)}`;
const headers = `${chalk.bold("Headers")}:\n${Array.from(
res.headers.entries(),
)
.map(([key, value]) => ` - ${chalk.cyan(key)}: ${chalk.white(value)}`)
.join("\n")}`;
const bodyLog = `${chalk.bold("Body")}: ${chalk.gray(body)}`;
serverLogger.debug`${status}\n${headers}\n${bodyLog}`;
};

View file

@ -1,6 +1,7 @@
import { mkdir } from "node:fs/promises"; import { mkdir } from "node:fs/promises";
import { dirname } from "node:path"; import { dirname } from "node:path";
import { getFileSink, getRotatingFileSink } from "@logtape/file"; import { getFileSink, getRotatingFileSink } from "@logtape/file";
import { honoLogger as logtapeHonoLogger } from "@logtape/hono";
import { import {
configure, configure,
getConsoleSink, getConsoleSink,
@ -100,6 +101,7 @@ await configure({
category: "server", category: "server",
sinks: getSinkNames(), sinks: getSinkNames(),
}, },
{ category: ["http"], sinks: getSinkNames() },
{ {
category: ["federation", "inbox"], category: ["federation", "inbox"],
sinks: getSinkNames(), sinks: getSinkNames(),
@ -148,3 +150,7 @@ export const federationMessagingLogger = getLogger(["federation", "messaging"]);
export const databaseLogger = getLogger("database"); export const databaseLogger = getLogger("database");
export const webfingerLogger = getLogger("webfinger"); export const webfingerLogger = getLogger("webfinger");
export const sonicLogger = getLogger("sonic"); export const sonicLogger = getLogger("sonic");
export const honoLogger = logtapeHonoLogger({
category: "http",
level: "debug",
});

View file

@ -18,6 +18,7 @@
"@logtape/file": "catalog:", "@logtape/file": "catalog:",
"@logtape/sentry": "catalog:", "@logtape/sentry": "catalog:",
"@logtape/otel": "catalog:", "@logtape/otel": "catalog:",
"@logtape/hono": "catalog:",
"@sentry/bun": "catalog:", "@sentry/bun": "catalog:",
"chalk": "catalog:" "chalk": "catalog:"
} }

View file

@ -1,5 +1,4 @@
import type { ConfigSchema } from "@versia-server/config"; import type { ConfigSchema } from "@versia-server/config";
import { debugResponse } from "@versia-server/kit/api";
import { type Server, serve } from "bun"; import { type Server, serve } from "bun";
import type { Hono } from "hono"; import type { Hono } from "hono";
import { matches } from "ip-matching"; import { matches } from "ip-matching";
@ -52,8 +51,6 @@ export const createServer = (
const output = await app.fetch(new Request(url, req), { ip }); const output = await app.fetch(new Request(url, req), { ip });
await debugResponse(output.clone());
return output; return output;
}, },
}); });