mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
Code cleanup, add color and pretty dates to LogManagers
This commit is contained in:
parent
327a716b12
commit
bc051ed043
|
|
@ -2,6 +2,12 @@ import { config } from "config-manager";
|
||||||
import { drizzle } from "drizzle-orm/node-postgres";
|
import { drizzle } from "drizzle-orm/node-postgres";
|
||||||
import { Client } from "pg";
|
import { Client } from "pg";
|
||||||
import * as schema from "./schema";
|
import * as schema from "./schema";
|
||||||
|
import {
|
||||||
|
LogLevel,
|
||||||
|
type LogManager,
|
||||||
|
type MultiLogManager,
|
||||||
|
} from "~packages/log-manager";
|
||||||
|
import { migrate } from "drizzle-orm/postgres-js/migrator";
|
||||||
|
|
||||||
export const client = new Client({
|
export const client = new Client({
|
||||||
host: config.database.host,
|
host: config.database.host,
|
||||||
|
|
@ -11,4 +17,38 @@ export const client = new Client({
|
||||||
database: config.database.database,
|
database: config.database.database,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const setupDatabase = async (logger: LogManager | MultiLogManager) => {
|
||||||
|
try {
|
||||||
|
await client.connect();
|
||||||
|
} catch (e) {
|
||||||
|
await logger.logError(LogLevel.CRITICAL, "Database", e as Error);
|
||||||
|
|
||||||
|
await logger.log(
|
||||||
|
LogLevel.CRITICAL,
|
||||||
|
"Database",
|
||||||
|
"Failed to connect to database. Please check your configuration.",
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate the database
|
||||||
|
await logger.log(LogLevel.INFO, "Database", "Migrating database...");
|
||||||
|
|
||||||
|
try {
|
||||||
|
await migrate(db, {
|
||||||
|
migrationsFolder: "./drizzle",
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
await logger.logError(LogLevel.CRITICAL, "Database", e as Error);
|
||||||
|
await logger.log(
|
||||||
|
LogLevel.CRITICAL,
|
||||||
|
"Database",
|
||||||
|
"Failed to migrate database. Please check your configuration.",
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
await logger.log(LogLevel.INFO, "Database", "Database migrated");
|
||||||
|
};
|
||||||
|
|
||||||
export const db = drizzle(client, { schema });
|
export const db = drizzle(client, { schema });
|
||||||
|
|
|
||||||
39
index.ts
39
index.ts
|
|
@ -1,46 +1,31 @@
|
||||||
import { exists, mkdir, writeFile } from "node:fs/promises";
|
|
||||||
import { dirname } from "node:path";
|
|
||||||
import { connectMeili } from "@meilisearch";
|
import { connectMeili } from "@meilisearch";
|
||||||
import { moduleIsEntry } from "@module";
|
|
||||||
import { config } from "config-manager";
|
import { config } from "config-manager";
|
||||||
import { count, sql } from "drizzle-orm";
|
import { count } from "drizzle-orm";
|
||||||
import { migrate } from "drizzle-orm/postgres-js/migrator";
|
|
||||||
import { LogLevel, LogManager, MultiLogManager } from "log-manager";
|
import { LogLevel, LogManager, MultiLogManager } from "log-manager";
|
||||||
import { db, client as pgClient } from "~drizzle/db";
|
import { db, setupDatabase } from "~drizzle/db";
|
||||||
import { status } from "~drizzle/schema";
|
import { status } from "~drizzle/schema";
|
||||||
import { createServer } from "~server";
|
import { createServer } from "~server";
|
||||||
|
|
||||||
await pgClient.connect();
|
|
||||||
await migrate(db, {
|
|
||||||
migrationsFolder: "./drizzle",
|
|
||||||
});
|
|
||||||
const timeAtStart = performance.now();
|
const timeAtStart = performance.now();
|
||||||
|
|
||||||
// Create requests file if it doesnt exist
|
const requests_log = Bun.file(config.logging.storage.requests);
|
||||||
if (
|
const isEntry = import.meta.path === Bun.main;
|
||||||
!(await exists(
|
|
||||||
`${process.cwd()}/${dirname(config.logging.storage.requests)}`,
|
const noColors = process.env.NO_COLORS === "true";
|
||||||
))
|
const noFancyDates = process.env.NO_FANCY_DATES === "true";
|
||||||
) {
|
|
||||||
await mkdir(`${process.cwd()}/${dirname(config.logging.storage.requests)}`);
|
|
||||||
await writeFile(`${process.cwd()}/${config.logging.storage.requests}`, "");
|
|
||||||
}
|
|
||||||
const requests_log = Bun.file(
|
|
||||||
`${process.cwd()}/${config.logging.storage.requests}`,
|
|
||||||
);
|
|
||||||
const isEntry = moduleIsEntry(import.meta.url);
|
|
||||||
// If imported as a module, redirect logs to /dev/null to not pollute console (e.g. in tests)
|
// If imported as a module, redirect logs to /dev/null to not pollute console (e.g. in tests)
|
||||||
const logger = new LogManager(isEntry ? requests_log : Bun.file("/dev/null"));
|
const logger = new LogManager(isEntry ? requests_log : Bun.file("/dev/null"));
|
||||||
const consoleLogger = new LogManager(
|
const consoleLogger = new LogManager(
|
||||||
isEntry ? Bun.stdout : Bun.file("/dev/null"),
|
isEntry ? Bun.stdout : Bun.file("/dev/null"),
|
||||||
|
!noColors,
|
||||||
|
!noFancyDates,
|
||||||
);
|
);
|
||||||
const dualLogger = new MultiLogManager([logger, consoleLogger]);
|
const dualLogger = new MultiLogManager([logger, consoleLogger]);
|
||||||
|
|
||||||
await dualLogger.log(LogLevel.INFO, "Lysand", "Starting Lysand...");
|
await dualLogger.log(LogLevel.INFO, "Lysand", "Starting Lysand...");
|
||||||
|
|
||||||
// NODE_ENV seems to be broken and output `development` even when set to production, so use the flag instead
|
await setupDatabase(dualLogger);
|
||||||
const isProd =
|
|
||||||
process.env.NODE_ENV === "production" || process.argv.includes("--prod");
|
|
||||||
|
|
||||||
if (config.meilisearch.enabled) {
|
if (config.meilisearch.enabled) {
|
||||||
await connectMeili(dualLogger);
|
await connectMeili(dualLogger);
|
||||||
|
|
@ -63,7 +48,7 @@ try {
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const server = createServer(config, dualLogger, isProd);
|
const server = createServer(config, dualLogger, true);
|
||||||
|
|
||||||
await dualLogger.log(
|
await dualLogger.log(
|
||||||
LogLevel.INFO,
|
LogLevel.INFO,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { appendFile, exists, mkdir } from "node:fs/promises";
|
import { appendFile, exists, mkdir } from "node:fs/promises";
|
||||||
import { dirname } from "node:path";
|
import { dirname } from "node:path";
|
||||||
import type { BunFile } from "bun";
|
import type { BunFile } from "bun";
|
||||||
|
import chalk from "chalk";
|
||||||
|
|
||||||
export enum LogLevel {
|
export enum LogLevel {
|
||||||
DEBUG = "debug",
|
DEBUG = "debug",
|
||||||
|
|
@ -15,12 +16,44 @@ export enum LogLevel {
|
||||||
* @param output BunFile of output (can be a normal file or something like Bun.stdout)
|
* @param output BunFile of output (can be a normal file or something like Bun.stdout)
|
||||||
*/
|
*/
|
||||||
export class LogManager {
|
export class LogManager {
|
||||||
constructor(private output: BunFile) {
|
constructor(
|
||||||
|
private output: BunFile,
|
||||||
|
private enableColors = false,
|
||||||
|
private prettyDates = false,
|
||||||
|
) {
|
||||||
void this.write(
|
void this.write(
|
||||||
`--- INIT LogManager at ${new Date().toISOString()} ---`,
|
`--- INIT LogManager at ${new Date().toISOString()} ---`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getLevelColor(level: LogLevel) {
|
||||||
|
switch (level) {
|
||||||
|
case LogLevel.DEBUG:
|
||||||
|
return chalk.blue;
|
||||||
|
case LogLevel.INFO:
|
||||||
|
return chalk.green;
|
||||||
|
case LogLevel.WARNING:
|
||||||
|
return chalk.yellow;
|
||||||
|
case LogLevel.ERROR:
|
||||||
|
return chalk.red;
|
||||||
|
case LogLevel.CRITICAL:
|
||||||
|
return chalk.bgRed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getFormattedDate(date: Date = new Date()) {
|
||||||
|
return this.prettyDates
|
||||||
|
? date.toLocaleString(undefined, {
|
||||||
|
year: "numeric",
|
||||||
|
month: "2-digit",
|
||||||
|
day: "2-digit",
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
second: "2-digit",
|
||||||
|
})
|
||||||
|
: date.toISOString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message to the output
|
* Logs a message to the output
|
||||||
* @param level Importance of the log
|
* @param level Importance of the log
|
||||||
|
|
@ -34,11 +67,23 @@ export class LogManager {
|
||||||
message: string,
|
message: string,
|
||||||
showTimestamp = true,
|
showTimestamp = true,
|
||||||
) {
|
) {
|
||||||
await this.write(
|
if (this.enableColors) {
|
||||||
`${
|
await this.write(
|
||||||
showTimestamp ? `${new Date().toISOString()} ` : ""
|
`${
|
||||||
}[${level.toUpperCase()}] ${entity}: ${message}`,
|
showTimestamp
|
||||||
);
|
? `${chalk.gray(this.getFormattedDate())} `
|
||||||
|
: ""
|
||||||
|
}[${this.getLevelColor(level)(
|
||||||
|
level.toUpperCase(),
|
||||||
|
)}] ${chalk.bold(entity)}: ${message}`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await this.write(
|
||||||
|
`${
|
||||||
|
showTimestamp ? `${this.getFormattedDate()} ` : ""
|
||||||
|
}[${level.toUpperCase()}] ${entity}: ${message}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async write(text: string) {
|
private async write(text: string) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue