feat(web,server)!: runtime log level (#5672)
* feat: change log level at runtime * chore: open api * chore: prefer env over runtime * chore: remove default env value
This commit is contained in:
@@ -45,6 +45,12 @@ export enum SystemConfigKey {
|
||||
JOB_LIBRARY_CONCURRENCY = 'job.library.concurrency',
|
||||
JOB_MIGRATION_CONCURRENCY = 'job.migration.concurrency',
|
||||
|
||||
LIBRARY_SCAN_ENABLED = 'library.scan.enabled',
|
||||
LIBRARY_SCAN_CRON_EXPRESSION = 'library.scan.cronExpression',
|
||||
|
||||
LOGGING_ENABLED = 'logging.enabled',
|
||||
LOGGING_LEVEL = 'logging.level',
|
||||
|
||||
MACHINE_LEARNING_ENABLED = 'machineLearning.enabled',
|
||||
MACHINE_LEARNING_URL = 'machineLearning.url',
|
||||
|
||||
@@ -94,9 +100,6 @@ export enum SystemConfigKey {
|
||||
TRASH_DAYS = 'trash.days',
|
||||
|
||||
THEME_CUSTOM_CSS = 'theme.customCss',
|
||||
|
||||
LIBRARY_SCAN_ENABLED = 'library.scan.enabled',
|
||||
LIBRARY_SCAN_CRON_EXPRESSION = 'library.scan.cronExpression',
|
||||
}
|
||||
|
||||
export enum TranscodePolicy {
|
||||
@@ -144,6 +147,15 @@ export enum Colorspace {
|
||||
P3 = 'p3',
|
||||
}
|
||||
|
||||
export enum LogLevel {
|
||||
VERBOSE = 'verbose',
|
||||
DEBUG = 'debug',
|
||||
LOG = 'log',
|
||||
WARN = 'warn',
|
||||
ERROR = 'error',
|
||||
FATAL = 'fatal',
|
||||
}
|
||||
|
||||
export interface SystemConfig {
|
||||
ffmpeg: {
|
||||
crf: number;
|
||||
@@ -165,6 +177,10 @@ export interface SystemConfig {
|
||||
tonemap: ToneMapping;
|
||||
};
|
||||
job: Record<QueueName, { concurrency: number }>;
|
||||
logging: {
|
||||
enabled: boolean;
|
||||
level: LogLevel;
|
||||
};
|
||||
machineLearning: {
|
||||
enabled: boolean;
|
||||
url: string;
|
||||
|
||||
21
server/src/infra/logger.ts
Normal file
21
server/src/infra/logger.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { ConsoleLogger } from '@nestjs/common';
|
||||
import { isLogLevelEnabled } from '@nestjs/common/services/utils/is-log-level-enabled.util';
|
||||
import { LogLevel } from './entities';
|
||||
|
||||
const LOG_LEVELS = [LogLevel.VERBOSE, LogLevel.DEBUG, LogLevel.LOG, LogLevel.WARN, LogLevel.ERROR, LogLevel.FATAL];
|
||||
|
||||
export class ImmichLogger extends ConsoleLogger {
|
||||
private static logLevels: LogLevel[] = [];
|
||||
|
||||
constructor(context: string) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
isLevelEnabled(level: LogLevel) {
|
||||
return isLogLevelEnabled(level, ImmichLogger.logLevels);
|
||||
}
|
||||
|
||||
static setLogLevel(level: LogLevel | false): void {
|
||||
ImmichLogger.logLevels = level === false ? [] : LOG_LEVELS.slice(LOG_LEVELS.indexOf(level));
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
OnServerEventCallback,
|
||||
ServerEvent,
|
||||
} from '@app/domain';
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { ImmichLogger } from '@app/infra/logger';
|
||||
import {
|
||||
OnGatewayConnection,
|
||||
OnGatewayDisconnect,
|
||||
@@ -20,7 +20,7 @@ import { Server, Socket } from 'socket.io';
|
||||
export class CommunicationRepository
|
||||
implements OnGatewayConnection, OnGatewayDisconnect, OnGatewayInit, ICommunicationRepository
|
||||
{
|
||||
private logger = new Logger(CommunicationRepository.name);
|
||||
private logger = new ImmichLogger(CommunicationRepository.name);
|
||||
private onConnectCallbacks: OnConnectCallback[] = [];
|
||||
private onServerEventCallbacks: Record<ServerEvent, OnServerEventCallback[]> = {
|
||||
[ServerEvent.CONFIG_UPDATE]: [],
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
IStorageRepository,
|
||||
mimeTypes,
|
||||
} from '@app/domain';
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { ImmichLogger } from '@app/infra/logger';
|
||||
import archiver from 'archiver';
|
||||
import { constants, createReadStream, existsSync, mkdirSync } from 'fs';
|
||||
import fs, { readdir, writeFile } from 'fs/promises';
|
||||
@@ -18,7 +18,7 @@ import path from 'path';
|
||||
const moveFile = promisify<string, string, mv.Options>(mv);
|
||||
|
||||
export class FilesystemProvider implements IStorageRepository {
|
||||
private logger = new Logger(FilesystemProvider.name);
|
||||
private logger = new ImmichLogger(FilesystemProvider.name);
|
||||
|
||||
createZipStream(): ImmichZipStream {
|
||||
const archive = archiver('zip', { store: true });
|
||||
|
||||
@@ -8,8 +8,9 @@ import {
|
||||
QueueName,
|
||||
QueueStatus,
|
||||
} from '@app/domain';
|
||||
import { ImmichLogger } from '@app/infra/logger';
|
||||
import { getQueueToken } from '@nestjs/bullmq';
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ModuleRef } from '@nestjs/core';
|
||||
import { SchedulerRegistry } from '@nestjs/schedule';
|
||||
import { Job, JobsOptions, Processor, Queue, Worker, WorkerOptions } from 'bullmq';
|
||||
@@ -19,7 +20,7 @@ import { bullConfig } from '../infra.config';
|
||||
@Injectable()
|
||||
export class JobRepository implements IJobRepository {
|
||||
private workers: Partial<Record<QueueName, Worker>> = {};
|
||||
private logger = new Logger(JobRepository.name);
|
||||
private logger = new ImmichLogger(JobRepository.name);
|
||||
|
||||
constructor(
|
||||
private moduleRef: ModuleRef,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CropOptions, IMediaRepository, ResizeOptions, TranscodeOptions, VideoInfo } from '@app/domain';
|
||||
import { Colorspace } from '@app/infra/entities';
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { ImmichLogger } from '@app/infra/logger';
|
||||
import ffmpeg, { FfprobeData } from 'fluent-ffmpeg';
|
||||
import fs from 'fs/promises';
|
||||
import sharp from 'sharp';
|
||||
@@ -11,7 +11,7 @@ const probe = promisify<string, FfprobeData>(ffmpeg.ffprobe);
|
||||
sharp.concurrency(0);
|
||||
|
||||
export class MediaRepository implements IMediaRepository {
|
||||
private logger = new Logger(MediaRepository.name);
|
||||
private logger = new ImmichLogger(MediaRepository.name);
|
||||
|
||||
crop(input: string | Buffer, options: CropOptions): Promise<Buffer> {
|
||||
return sharp(input, { failOn: 'none' })
|
||||
|
||||
@@ -7,7 +7,8 @@ import {
|
||||
} from '@app/domain';
|
||||
import { DatabaseLock, RequireLock } from '@app/infra';
|
||||
import { GeodataAdmin1Entity, GeodataAdmin2Entity, GeodataPlacesEntity, SystemMetadataKey } from '@app/infra/entities';
|
||||
import { Inject, Logger } from '@nestjs/common';
|
||||
import { ImmichLogger } from '@app/infra/logger';
|
||||
import { Inject } from '@nestjs/common';
|
||||
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
|
||||
import { DefaultReadTaskOptions, exiftool, Tags } from 'exiftool-vendored';
|
||||
import { createReadStream, existsSync } from 'fs';
|
||||
@@ -31,7 +32,7 @@ export class MetadataRepository implements IMetadataRepository {
|
||||
@InjectDataSource() private dataSource: DataSource,
|
||||
) {}
|
||||
|
||||
private logger = new Logger(MetadataRepository.name);
|
||||
private logger = new ImmichLogger(MetadataRepository.name);
|
||||
|
||||
@RequireLock(DatabaseLock.GeodataImport)
|
||||
async init(): Promise<void> {
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Embedding, EmbeddingSearch, ISmartInfoRepository } from '@app/domain';
|
||||
import { getCLIPModelInfo } from '@app/domain/smart-info/smart-info.constant';
|
||||
import { DatabaseLock, RequireLock, asyncLock } from '@app/infra';
|
||||
import { AssetEntity, AssetFaceEntity, SmartInfoEntity, SmartSearchEntity } from '@app/infra/entities';
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ImmichLogger } from '@app/infra/logger';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { DummyValue, GenerateSql } from '../infra.util';
|
||||
@@ -10,7 +11,7 @@ import { asVector, isValidInteger } from '../infra.utils';
|
||||
|
||||
@Injectable()
|
||||
export class SmartInfoRepository implements ISmartInfoRepository {
|
||||
private logger = new Logger(SmartInfoRepository.name);
|
||||
private logger = new ImmichLogger(SmartInfoRepository.name);
|
||||
private faceColumns: string[];
|
||||
|
||||
constructor(
|
||||
|
||||
Reference in New Issue
Block a user