feat(logging): add structured server diagnostics
CI / validate (push) Successful in 4m55s
Release / release (push) Successful in 9m46s

This commit is contained in:
dmg
2026-08-01 17:37:52 -04:00
parent 5e693e2cdd
commit 86c87153b4
19 changed files with 331 additions and 13 deletions
+30 -4
View File
@@ -12,6 +12,7 @@ import { ipIntelligence } from "@minecraft-account-manager/database";
import { and, eq, gt } from "drizzle-orm";
import { headers } from "next/headers";
import { db } from "@/lib/database";
import { logger } from "@/lib/logger";
const classifications = new Set<IpClassification>([
"unknown",
@@ -77,6 +78,13 @@ export async function getIpIntelligence(
options: { now?: Date; forceRefresh?: boolean } = {},
): Promise<IpIntelligenceResult> {
if (!isPublicIp(ipAddress)) {
logger.warn(
{
event: "ip_intelligence.skipped",
reason: "non_public_address",
},
"IP intelligence lookup skipped for a non-public client address",
);
return { classification: "unknown", provider: null };
}
@@ -96,14 +104,23 @@ export async function getIpIntelligence(
const result = await provider.classify(ipAddress);
await cacheResult(ipAddress, result, now, cacheHours() * 60 * 60_000);
return result;
} catch {
} catch (error) {
const providerName = process.env.IP_INTELLIGENCE_PROVIDER?.trim().toLowerCase() || null;
const result: IpIntelligenceResult = {
classification: "unknown",
provider: process.env.IP_INTELLIGENCE_PROVIDER?.trim().toLowerCase() || null,
provider: providerName,
lookupError: true,
};
await cacheResult(ipAddress, result, now, 5 * 60_000).catch(() => undefined);
console.error("IP intelligence lookup failed");
await cacheResult(ipAddress, result, now, 5 * 60_000).catch((cacheError) => {
logger.error(
{ err: cacheError, event: "ip_intelligence.cache_failed", provider: providerName },
"Failed to cache an IP intelligence lookup error",
);
});
logger.error(
{ err: error, event: "ip_intelligence.lookup_failed", provider: providerName },
"IP intelligence lookup failed",
);
return result;
}
}
@@ -134,6 +151,15 @@ export async function checkAccountAdditionNetwork() {
const requestHeaders = await headers();
const ipAddress = getClientIp(requestHeaders, process.env.TRUST_PROXY === "true");
if (!ipAddress) {
logger.warn(
{
event: "client_ip.unavailable",
trustProxy: process.env.TRUST_PROXY === "true",
forwardedForPresent: requestHeaders.has("x-forwarded-for"),
realIpPresent: requestHeaders.has("x-real-ip"),
},
"Client IP address was unavailable for account addition",
);
return {
allowed: false as const,
reason: "unavailable" as const,
+3
View File
@@ -0,0 +1,3 @@
import { createLogger } from "@minecraft-account-manager/logging";
export const logger = createLogger("minecraft-account-manager-web");