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:
parent
e67b3e8ad5
commit
eac0c1c47c
43 changed files with 257 additions and 95 deletions
|
@ -19,10 +19,4 @@ id: 'aid'
|
|||
# '10.69.1.0/24'
|
||||
#]
|
||||
|
||||
logLevel: [
|
||||
'error',
|
||||
'success',
|
||||
'warning',
|
||||
'debug',
|
||||
'info'
|
||||
]
|
||||
maxLogLevel: 'debug'
|
||||
|
|
|
@ -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
91
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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 }
|
||||
|
||||
|
|
5
packages/backend-rs/index.d.ts
vendored
5
packages/backend-rs/index.d.ts
vendored
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
42
packages/backend-rs/src/service/log.rs
Normal file
42
packages/backend-rs/src/service/log.rs
Normal 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");
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
pub mod log;
|
||||
pub mod note;
|
||||
pub mod stream;
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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"],
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -74,6 +74,6 @@ export async function importBlocking(
|
|||
}
|
||||
}
|
||||
|
||||
logger.succ("Imported");
|
||||
logger.info("Imported");
|
||||
done();
|
||||
}
|
||||
|
|
|
@ -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}`);
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -111,6 +111,6 @@ export async function importFollowing(
|
|||
}
|
||||
}
|
||||
|
||||
logger.succ("Imported");
|
||||
logger.info("Imported");
|
||||
done();
|
||||
}
|
||||
|
|
|
@ -125,5 +125,5 @@ export async function importMastoPost(
|
|||
job.progress(100);
|
||||
done();
|
||||
|
||||
logger.succ("Imported");
|
||||
logger.info("Imported");
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ export async function importMuting(
|
|||
}
|
||||
}
|
||||
|
||||
logger.succ("Imported");
|
||||
logger.info("Imported");
|
||||
done();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -90,6 +90,6 @@ export async function importUserLists(
|
|||
}
|
||||
}
|
||||
|
||||
logger.succ("Imported");
|
||||
logger.info("Imported");
|
||||
done();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,6 @@ export async function checkExpiredMutings(
|
|||
}
|
||||
}
|
||||
|
||||
logger.succ("All expired mutings checked.");
|
||||
logger.info("All expired mutings checked.");
|
||||
done();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -39,6 +39,6 @@ export async function verifyLinks(
|
|||
}
|
||||
}
|
||||
|
||||
logger.succ("All links successfully verified.");
|
||||
logger.info("All links successfully verified.");
|
||||
done();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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)}`);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 === "debug"
|
||||
? chalk.gray("VERB")
|
||||
: level === "info"
|
||||
? chalk.blue("INFO")
|
||||
? chalk.green("INFO")
|
||||
: level === "debug"
|
||||
? 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"
|
||||
? this.syslogClient.info
|
||||
: level === "debug"
|
||||
? this.syslogClient.info
|
||||
: level === "info"
|
||||
? this.syslogClient.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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue