refactor (backend): revise log levels

* Add logging in backend-rs
* Change log levels to 'error', 'warning', 'info', 'debug', 'trace'
* Add `maxLogLevel` config and deprecate `logLevels`
* Move SQL queries to 'trace' level
This commit is contained in:
naskya 2024-04-25 02:18:37 +09:00
parent e67b3e8ad5
commit eac0c1c47c
No known key found for this signature in database
GPG key ID: 712D413B3A9FED5C
43 changed files with 257 additions and 95 deletions

View file

@ -19,10 +19,4 @@ id: 'aid'
# '10.69.1.0/24'
#]
logLevel: [
'error',
'success',
'warning',
'debug',
'info'
]
maxLogLevel: 'debug'

View file

@ -145,16 +145,11 @@ reservedUsernames: [
# IP address family used for outgoing request (ipv4, ipv6 or dual)
#outgoingAddressFamily: ipv4
# Log Option
# Production env: ['error', 'success', 'warning', 'info']
# Debug/Test env or Troubleshooting: ['error', 'success', 'warning', 'debug' ,'info']
# Production env which storage space or IO is tight: ['error', 'warning']
logLevel: [
'error',
'success',
'warning',
'info'
]
# Log level (error, warning, info, debug, trace)
# Production env: info
# Production env whose storage space or IO is tight: warning
# Debug/Test env or Troubleshooting: debug (or trace)
maxLogLevel: info
# Syslog option
#syslog:

91
Cargo.lock generated
View file

@ -171,6 +171,8 @@ dependencies = [
"strum 0.26.2",
"thiserror",
"tokio",
"tracing",
"tracing-subscriber",
"url",
"urlencoding",
]
@ -1128,6 +1130,16 @@ dependencies = [
"minimal-lexical",
]
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
dependencies = [
"overload",
"winapi",
]
[[package]]
name = "num"
version = "0.4.2"
@ -1285,6 +1297,12 @@ dependencies = [
"syn 2.0.58",
]
[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "parking_lot"
version = "0.12.1"
@ -1949,6 +1967,15 @@ dependencies = [
"keccak",
]
[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.1"
@ -2380,6 +2407,16 @@ dependencies = [
"syn 2.0.58",
]
[[package]]
name = "thread_local"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "time"
version = "0.3.36"
@ -2514,6 +2551,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"nu-ansi-term",
"sharded-slab",
"smallvec",
"thread_local",
"tracing-core",
"tracing-log",
]
[[package]]
@ -2593,6 +2656,12 @@ dependencies = [
"serde",
]
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "vcpkg"
version = "0.2.15"
@ -2687,6 +2756,28 @@ dependencies = [
"wasite",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-core"
version = "0.52.0"

View file

@ -33,6 +33,8 @@ strum = "0.26.2"
syn = "2.0.58"
thiserror = "1.0.58"
tokio = "1.37.0"
tracing = "0.1.40"
tracing-subscriber = "0.3.1"
url = "2.5.0"
urlencoding = "2.1.3"

View file

@ -36,6 +36,8 @@ serde_yaml = { workspace = true }
strum = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
tokio = { workspace = true, features = ["full"] }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
url = { workspace = true }
urlencoding = { workspace = true }

View file

@ -38,7 +38,9 @@ export interface ServerConfig {
inboxJobPerSec?: number
deliverJobMaxAttempts?: number
inboxJobMaxAttempts?: number
/** deprecated */
logLevel?: Array<string>
maxLogLevel?: string
syslog?: SysLogConfig
proxyRemoteFiles?: boolean
mediaProxy?: string
@ -148,7 +150,9 @@ export interface Config {
inboxJobPerSec?: number
deliverJobMaxAttempts?: number
inboxJobMaxAttempts?: number
/** deprecated */
logLevel?: Array<string>
maxLogLevel?: string
syslog?: SysLogConfig
proxyRemoteFiles?: boolean
mediaProxy?: string
@ -1122,6 +1126,7 @@ export interface Webhook {
latestSentAt: Date | null
latestStatus: number | null
}
export function initializeRustLogger(): void
export function watchNote(watcherId: string, noteAuthorId: string, noteId: string): Promise<void>
export function unwatchNote(watcherId: string, noteId: string): Promise<void>
export enum ChatEvent {

View file

@ -310,7 +310,7 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`)
}
const { loadEnv, loadConfig, stringToAcct, acctToString, addNoteToAntenna, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getNoteSummary, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, removeOldAttestationChallenges, AntennaSrcEnum, DriveFileUsageHintEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, watchNote, unwatchNote, ChatEvent, publishToChatStream, getTimestamp, genId, genIdAt, secureRndstr } = nativeBinding
const { loadEnv, loadConfig, stringToAcct, acctToString, addNoteToAntenna, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getNoteSummary, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, removeOldAttestationChallenges, AntennaSrcEnum, DriveFileUsageHintEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, initializeRustLogger, watchNote, unwatchNote, ChatEvent, publishToChatStream, getTimestamp, genId, genIdAt, secureRndstr } = nativeBinding
module.exports.loadEnv = loadEnv
module.exports.loadConfig = loadConfig
@ -354,6 +354,7 @@ module.exports.RelayStatusEnum = RelayStatusEnum
module.exports.UserEmojimodpermEnum = UserEmojimodpermEnum
module.exports.UserProfileFfvisibilityEnum = UserProfileFfvisibilityEnum
module.exports.UserProfileMutingnotificationtypesEnum = UserProfileMutingnotificationtypesEnum
module.exports.initializeRustLogger = initializeRustLogger
module.exports.watchNote = watchNote
module.exports.unwatchNote = unwatchNote
module.exports.ChatEvent = ChatEvent

View file

@ -36,8 +36,11 @@ struct ServerConfig {
pub deliver_job_max_attempts: Option<u32>,
pub inbox_job_max_attempts: Option<u32>,
/// deprecated
pub log_level: Option<Vec<String>>,
pub max_log_level: Option<String>,
pub syslog: Option<SysLogConfig>,
pub proxy_remote_files: Option<bool>,
@ -197,7 +200,9 @@ pub struct Config {
pub inbox_job_per_sec: Option<u32>,
pub deliver_job_max_attempts: Option<u32>,
pub inbox_job_max_attempts: Option<u32>,
/// deprecated
pub log_level: Option<Vec<String>>,
pub max_log_level: Option<String>,
pub syslog: Option<SysLogConfig>,
pub proxy_remote_files: Option<bool>,
pub media_proxy: Option<String>,
@ -346,6 +351,7 @@ fn load_config() -> Config {
deliver_job_max_attempts: server_config.deliver_job_max_attempts,
inbox_job_max_attempts: server_config.inbox_job_max_attempts,
log_level: server_config.log_level,
max_log_level: server_config.max_log_level,
syslog: server_config.syslog,
proxy_remote_files: server_config.proxy_remote_files,
media_proxy: server_config.media_proxy,

View file

@ -1,5 +1,6 @@
use crate::config::CONFIG;
use sea_orm::{Database, DbConn, DbErr};
use sea_orm::{ConnectOptions, Database, DbConn, DbErr};
use tracing::log::LevelFilter;
static DB_CONN: once_cell::sync::OnceCell<DbConn> = once_cell::sync::OnceCell::new();
@ -12,7 +13,10 @@ async fn init_database() -> Result<&'static DbConn, DbErr> {
CONFIG.db.port,
CONFIG.db.db,
);
let conn = Database::connect(database_uri).await?;
let option: ConnectOptions = ConnectOptions::new(database_uri)
.sqlx_logging_level(LevelFilter::Trace)
.to_owned();
let conn = Database::connect(option).await?;
Ok(DB_CONN.get_or_init(move || conn))
}

View file

@ -0,0 +1,42 @@
use crate::config::CONFIG;
use tracing::Level;
use tracing_subscriber::FmtSubscriber;
#[crate::export(js_name = "initializeRustLogger")]
pub fn initialize_logger() {
let mut builder = FmtSubscriber::builder();
// Deprecated
if let Some(levels) = &CONFIG.log_level {
if levels.contains(&"error".to_string()) {
builder = builder.with_max_level(Level::ERROR);
}
if levels.contains(&"warning".to_string()) {
builder = builder.with_max_level(Level::WARN);
}
if levels.contains(&"info".to_string()) {
builder = builder.with_max_level(Level::INFO);
}
if levels.contains(&"debug".to_string()) {
builder = builder.with_max_level(Level::DEBUG);
}
if levels.contains(&"trace".to_string()) {
builder = builder.with_max_level(Level::TRACE);
}
} else if let Some(max_level) = &CONFIG.max_log_level {
builder = builder.with_max_level(match max_level.as_str() {
"error" => Level::ERROR,
"warning" => Level::WARN,
"info" => Level::INFO,
"debug" => Level::DEBUG,
"trace" => Level::TRACE,
_ => Level::INFO,
});
} else {
builder = builder.with_max_level(Level::INFO);
};
let subscriber = builder.with_level(true).pretty().finish();
tracing::subscriber::set_global_default(subscriber).expect("Failed to initialize the logger");
}

View file

@ -1,2 +1,3 @@
pub mod log;
pub mod note;
pub mod stream;

View file

@ -9,6 +9,7 @@ import semver from "semver";
import Logger from "@/services/logger.js";
import type { Config } from "backend-rs";
import { initializeRustLogger } from "backend-rs";
import { fetchMeta, removeOldAttestationChallenges } from "backend-rs";
import { config, envOption } from "@/config.js";
import { showMachineInfo } from "@/misc/show-machine-info.js";
@ -94,6 +95,7 @@ export async function masterMain() {
await showMachineInfo(bootLogger);
showNodejsVersion();
await connectDb();
initializeRustLogger();
} catch (e) {
bootLogger.error(
`Fatal error occurred during initialization:\n${inspect(e)}`,
@ -103,13 +105,13 @@ export async function masterMain() {
process.exit(1);
}
bootLogger.succ("Firefish initialized");
bootLogger.info("Firefish initialized");
if (!envOption.disableClustering) {
await spawnWorkers(config.clusterLimits);
}
bootLogger.succ(
bootLogger.info(
`Now listening on port ${config.port} on ${config.url}`,
null,
true,
@ -160,7 +162,7 @@ async function connectDb(): Promise<void> {
const v = await db
.query("SHOW server_version")
.then((x) => x[0].server_version);
dbLogger.succ(`Connected: v${v}`);
dbLogger.info(`Connected: v${v}`);
} catch (e) {
dbLogger.error("Failed to connect to the database", null, true);
dbLogger.error(inspect(e));
@ -196,7 +198,7 @@ async function spawnWorkers(
`Starting ${clusterLimits.web} web workers and ${clusterLimits.queue} queue workers (total ${total})...`,
);
await Promise.all(workers.map((mode) => spawnWorker(mode)));
bootLogger.succ("All workers started");
bootLogger.info("All workers started");
}
function spawnWorker(mode: "web" | "queue"): Promise<void> {

View file

@ -80,7 +80,7 @@ import { dbLogger } from "./logger.js";
const sqlLogger = dbLogger.createSubLogger("sql", "gray", false);
class MyCustomLogger implements Logger {
class DbLogger implements Logger {
private highlight(sql: string) {
return highlight.highlight(sql, {
language: "sql",
@ -89,15 +89,16 @@ class MyCustomLogger implements Logger {
}
public logQuery(query: string, parameters?: any[]) {
sqlLogger.info(this.highlight(query).substring(0, 100));
sqlLogger.trace(this.highlight(query).substring(0, 100));
}
public logQueryError(error: string, query: string, parameters?: any[]) {
sqlLogger.error(error);
sqlLogger.error(this.highlight(query));
}
public logQuerySlow(time: number, query: string, parameters?: any[]) {
sqlLogger.warn(this.highlight(query));
sqlLogger.trace(this.highlight(query));
}
public logSchemaBuild(message: string) {
@ -215,7 +216,7 @@ export const db = new DataSource({
}
: false,
logging: log,
logger: log ? new MyCustomLogger() : undefined,
logger: log ? new DbLogger() : undefined,
maxQueryExecutionTime: 300,
entities: entities,
migrations: ["../../migration/*.js"],

View file

@ -94,7 +94,7 @@ export async function downloadUrl(url: string, path: string): Promise<void> {
}
}
logger.succ(`Download finished: ${chalk.cyan(url)}`);
logger.info(`Download finished: ${chalk.cyan(url)}`);
}
export function isPrivateIp(ip: string): boolean {

View file

@ -564,12 +564,12 @@ export default function () {
export function destroy() {
deliverQueue.once("cleaned", (jobs, status) => {
deliverLogger.succ(`Cleaned ${jobs.length} ${status} jobs`);
deliverLogger.info(`Cleaned ${jobs.length} ${status} jobs`);
});
deliverQueue.clean(0, "delayed");
inboxQueue.once("cleaned", (jobs, status) => {
inboxLogger.succ(`Cleaned ${jobs.length} ${status} jobs`);
inboxLogger.info(`Cleaned ${jobs.length} ${status} jobs`);
});
inboxQueue.clean(0, "delayed");
}

View file

@ -43,7 +43,7 @@ export async function deleteAccount(
await Notes.delete(notes.map((note) => note.id));
}
logger.succ("All of notes deleted");
logger.info("All of notes deleted");
}
{
@ -73,7 +73,7 @@ export async function deleteAccount(
}
}
logger.succ("All of files deleted");
logger.info("All of files deleted");
}
{

View file

@ -54,7 +54,7 @@ export async function deleteDriveFiles(
job.progress(deletedCount / total);
}
logger.succ(
logger.info(
`All drive files (${deletedCount}) of ${user.id} has been deleted.`,
);
done();

View file

@ -83,7 +83,7 @@ export async function exportBlocking(
}
stream.end();
logger.succ(`Exported to: ${path}`);
logger.info(`Exported to: ${path}`);
const fileName = `blocking-${dateFormat(
new Date(),
@ -96,7 +96,7 @@ export async function exportBlocking(
force: true,
});
logger.succ(`Exported to: ${driveFile.id}`);
logger.info(`Exported to: ${driveFile.id}`);
} finally {
cleanup();
}

View file

@ -105,7 +105,7 @@ export async function exportCustomEmojis(
zlib: { level: 0 },
});
archiveStream.on("close", async () => {
logger.succ(`Exported to: ${archivePath}`);
logger.info(`Exported to: ${archivePath}`);
const fileName = `custom-emojis-${dateFormat(
new Date(),
@ -118,7 +118,7 @@ export async function exportCustomEmojis(
force: true,
});
logger.succ(`Exported to: ${driveFile.id}`);
logger.info(`Exported to: ${driveFile.id}`);
cleanup();
archiveCleanup();
done();

View file

@ -91,7 +91,7 @@ export async function exportFollowing(
}
stream.end();
logger.succ(`Exported to: ${path}`);
logger.info(`Exported to: ${path}`);
const fileName = `following-${dateFormat(
new Date(),
@ -104,7 +104,7 @@ export async function exportFollowing(
force: true,
});
logger.succ(`Exported to: ${driveFile.id}`);
logger.info(`Exported to: ${driveFile.id}`);
} finally {
cleanup();
}

View file

@ -84,7 +84,7 @@ export async function exportMute(
}
stream.end();
logger.succ(`Exported to: ${path}`);
logger.info(`Exported to: ${path}`);
const fileName = `mute-${dateFormat(
new Date(),
@ -97,7 +97,7 @@ export async function exportMute(
force: true,
});
logger.succ(`Exported to: ${driveFile.id}`);
logger.info(`Exported to: ${driveFile.id}`);
} finally {
cleanup();
}

View file

@ -91,7 +91,7 @@ export async function exportNotes(
await write("]");
stream.end();
logger.succ(`Exported to: ${path}`);
logger.info(`Exported to: ${path}`);
const fileName = `notes-${dateFormat(
new Date(),
@ -104,7 +104,7 @@ export async function exportNotes(
force: true,
});
logger.succ(`Exported to: ${driveFile.id}`);
logger.info(`Exported to: ${driveFile.id}`);
} finally {
cleanup();
}

View file

@ -59,7 +59,7 @@ export async function exportUserLists(
}
stream.end();
logger.succ(`Exported to: ${path}`);
logger.info(`Exported to: ${path}`);
const fileName = `user-lists-${dateFormat(
new Date(),
@ -72,7 +72,7 @@ export async function exportUserLists(
force: true,
});
logger.succ(`Exported to: ${driveFile.id}`);
logger.info(`Exported to: ${driveFile.id}`);
} finally {
cleanup();
}

View file

@ -74,6 +74,6 @@ export async function importBlocking(
}
}
logger.succ("Imported");
logger.info("Imported");
done();
}

View file

@ -143,8 +143,8 @@ export async function importCustomEmojis(
cleanup();
logger.succ("Imported");
logger.info("Imported");
done();
});
logger.succ(`Unzipping to ${outputPath}`);
logger.info(`Unzipping to ${outputPath}`);
}

View file

@ -94,7 +94,7 @@ export async function importCkPost(
} else {
logger.info(`Note exist`);
}
logger.succ("Imported");
logger.info("Imported");
if (post.childNotes) {
for (const child of post.childNotes) {
createImportCkPostJob(

View file

@ -111,6 +111,6 @@ export async function importFollowing(
}
}
logger.succ("Imported");
logger.info("Imported");
done();
}

View file

@ -125,5 +125,5 @@ export async function importMastoPost(
job.progress(100);
done();
logger.succ("Imported");
logger.info("Imported");
}

View file

@ -74,7 +74,7 @@ export async function importMuting(
}
}
logger.succ("Imported");
logger.info("Imported");
done();
}

View file

@ -47,7 +47,7 @@ export async function importPosts(
// handle error
logger.warn(`Failed to read Mastodon archive:\n${inspect(e)}`);
}
logger.succ("Mastodon archive imported");
logger.info("Mastodon archive imported");
done();
return;
}
@ -73,7 +73,7 @@ export async function importPosts(
logger.warn(`Error occured while reading:\n${inspect(e)}`);
}
logger.succ("Imported");
logger.info("Imported");
done();
}

View file

@ -90,6 +90,6 @@ export async function importUserLists(
}
}
logger.succ("Imported");
logger.info("Imported");
done();
}

View file

@ -48,6 +48,6 @@ export default async function cleanRemoteFiles(
job.progress(deletedCount / total);
}
logger.succ("All cached remote files has been deleted.");
logger.info("All cached remote files has been deleted.");
done();
}

View file

@ -28,6 +28,6 @@ export async function checkExpiredMutings(
}
}
logger.succ("All expired mutings checked.");
logger.info("All expired mutings checked.");
done();
}

View file

@ -11,6 +11,6 @@ export async function cleanCharts(
): Promise<void> {
logger.info("Cleaning active users chart...");
await activeUsersChart.clean();
logger.succ("Active users chart has been cleaned.");
logger.info("Active users chart has been cleaned.");
done();
}

View file

@ -16,6 +16,6 @@ export async function clean(
createdAt: LessThan(new Date(Date.now() - 1000 * 60 * 60 * 24 * 90)),
});
logger.succ("Cleaned.");
logger.info("Cleaned.");
done();
}

View file

@ -34,10 +34,10 @@ export async function setLocalEmojiSizes(
} finally {
// wait for 1sec so that this would not overwhelm the object storage.
await new Promise((resolve) => setTimeout(resolve, 1000));
if (i % 10 === 9) logger.succ(`fetched ${i + 1}/${emojis.length} emojis`);
if (i % 10 === 9) logger.info(`fetched ${i + 1}/${emojis.length} emojis`);
}
}
logger.succ("Done.");
logger.info("Done.");
done();
}

View file

@ -39,6 +39,6 @@ export async function verifyLinks(
}
}
logger.succ("All links successfully verified.");
logger.info("All links successfully verified.");
done();
}

View file

@ -56,7 +56,7 @@ export async function resolveUser(
if (user == null) {
const self = await resolveSelf(acctLower);
logger.succ(`return new remote user: ${chalk.magenta(acctLower)}`);
logger.info(`return new remote user: ${chalk.magenta(acctLower)}`);
return await createPerson(self.href);
}

View file

@ -43,7 +43,7 @@ export const urlPreviewHandler = async (ctx: Koa.Context) => {
lang: lang ?? "en-US",
});
logger.succ(`Got preview of ${url}: ${summary.title}`);
logger.info(`Got preview of ${url}: ${summary.title}`);
if (
summary.url &&

View file

@ -653,7 +653,7 @@ export async function addFile({
);
}
logger.succ(`drive file has been created ${file.id}`);
logger.info(`drive file has been created ${file.id}`);
if (user) {
DriveFiles.pack(file, { self: true }).then((packedFile) => {

View file

@ -86,7 +86,7 @@ export async function uploadFromUrl({
requestHeaders,
usageHint,
});
logger.succ(`Got: ${driveFile.id}`);
logger.info(`Got: ${driveFile.id}`);
return driveFile;
} catch (e) {
logger.error(`Failed to create drive file:\n${inspect(e)}`);

View file

@ -49,7 +49,7 @@ export async function fetchInstanceMetadata(
getDescription(info, dom, manifest).catch(() => null),
]);
logger.succ(`Successfuly fetched metadata of ${instance.host}`);
logger.info(`Successfuly fetched metadata of ${instance.host}`);
const updates = {
infoUpdatedAt: new Date(),
@ -105,7 +105,7 @@ export async function fetchInstanceMetadata(
await Instances.update(instance.id, updates);
logger.succ(`Successfuly updated metadata of ${instance.host}`);
logger.info(`Successfuly updated metadata of ${instance.host}`);
} catch (e) {
logger.error(
`Failed to update metadata of ${instance.host}:\n${inspect(e)}`,
@ -172,7 +172,7 @@ async function fetchNodeinfo(instance: Instance): Promise<NodeInfo> {
throw new Error(inspect(e));
});
logger.succ(`Successfuly fetched nodeinfo of ${instance.host}`);
logger.info(`Successfuly fetched nodeinfo of ${instance.host}`);
return info as NodeInfo;
} catch (e) {

View file

@ -11,7 +11,7 @@ type Domain = {
color?: string;
};
type Level = "error" | "success" | "warning" | "debug" | "info";
type Level = "error" | "warning" | "debug" | "info" | "trace";
export default class Logger {
private domain: Domain;
@ -47,6 +47,23 @@ export default class Logger {
return logger;
}
private showThisLog(logLevel: Level, configLevel: string) {
switch (configLevel) {
case "error":
return ["error"].includes(logLevel);
case "warning":
return ["error", "warning"].includes(logLevel);
case "info":
return ["error", "warning", "info"].includes(logLevel);
case "debug":
return ["error", "warning", "info", "debug"].includes(logLevel);
case "trace":
return true;
default:
return ["error", "warning", "info"].includes(logLevel);
}
}
private log(
level: Level,
message: string,
@ -56,12 +73,13 @@ export default class Logger {
store = true,
): void {
if (
!(typeof config.logLevel === "undefined") &&
!config.logLevel.includes(level)
(config.maxLogLevel != null &&
!this.showThisLog(level, config.maxLogLevel)) ||
(config.logLevel != null && !config.logLevel.includes(level))
)
return;
if (!this.store) store = false;
if (level === "debug") store = false;
if (level === "debug" || level === "trace") store = false;
if (this.parentLogger) {
this.parentLogger.log(
@ -84,14 +102,12 @@ export default class Logger {
: chalk.red("ERR ")
: level === "warning"
? chalk.yellow("WARN")
: level === "success"
? important
? chalk.bgGreen.white("DONE")
: chalk.green("DONE")
: level === "info"
? chalk.green("INFO")
: level === "debug"
? chalk.gray("VERB")
: level === "info"
? chalk.blue("INFO")
? chalk.blue("DEBUG")
: level === "trace"
? chalk.gray("TRACE")
: null;
const domains = [this.domain]
.concat(subDomains)
@ -105,11 +121,11 @@ export default class Logger {
? chalk.red(message)
: level === "warning"
? chalk.yellow(message)
: level === "success"
: level === "info"
? chalk.green(message)
: level === "debug"
? chalk.gray(message)
: level === "info"
? chalk.blue(message)
: level === "trace"
? message
: null;
@ -129,11 +145,11 @@ export default class Logger {
? this.syslogClient.error
: level === "warning"
? this.syslogClient.warning
: level === "success"
: level === "debug"
? this.syslogClient.info
: level === "debug"
: level === "info"
? this.syslogClient.info
: level === "info"
: level === "trace"
? this.syslogClient.info
: (null as never);
@ -144,7 +160,7 @@ export default class Logger {
}
}
// Used when the process can't continue (fatal error)
// Only used when the process can't continue (fatal error)
public error(
x: string | Error,
data?: Record<string, any> | null,
@ -175,16 +191,16 @@ export default class Logger {
this.log("warning", message, data, important);
}
// Used when something is successful
public succ(
// Other generic logs
public info(
message: string,
data?: Record<string, any> | null,
important = false,
): void {
this.log("success", message, data, important);
this.log("info", message, data, important);
}
// Used for debugging (information necessary for developers but unnecessary for users)
// Only used for debugging (information necessary for developers but unnecessary for users)
public debug(
message: string,
data?: Record<string, any> | null,
@ -200,12 +216,12 @@ export default class Logger {
}
}
// Other generic logs
public info(
// Extremely verbose logs for debugging (e.g., SQL Query)
public trace(
message: string,
data?: Record<string, any> | null,
important = false,
): void {
this.log("info", message, data, important);
this.log("trace", message, data, important);
}
}