0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-04-15 03:11:28 -05:00

refactor: logging repository (#15540)

This commit is contained in:
Jason Rasmussen 2025-01-23 08:31:30 -05:00 committed by GitHub
parent b31414af8f
commit d3446f3092
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
53 changed files with 159 additions and 172 deletions

View file

@ -13,7 +13,6 @@ import { entities } from 'src/entities';
import { ImmichWorker } from 'src/enum';
import { IEventRepository } from 'src/interfaces/event.interface';
import { IJobRepository } from 'src/interfaces/job.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ITelemetryRepository } from 'src/interfaces/telemetry.interface';
import { AuthGuard } from 'src/middleware/auth.guard';
import { ErrorInterceptor } from 'src/middleware/error.interceptor';
@ -22,6 +21,7 @@ import { GlobalExceptionFilter } from 'src/middleware/global-exception.filter';
import { LoggingInterceptor } from 'src/middleware/logging.interceptor';
import { providers, repositories } from 'src/repositories';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { teardownTelemetry } from 'src/repositories/telemetry.repository';
import { services } from 'src/services';
import { CliService } from 'src/services/cli.service';
@ -64,7 +64,7 @@ const imports = [
class BaseModule implements OnModuleInit, OnModuleDestroy {
constructor(
@Inject(IWorker) private worker: ImmichWorker,
@Inject(ILoggerRepository) logger: ILoggerRepository,
logger: LoggingRepository,
@Inject(IEventRepository) private eventRepository: IEventRepository,
@Inject(IJobRepository) private jobRepository: IJobRepository,
@Inject(ITelemetryRepository) private telemetryRepository: ITelemetryRepository,

View file

@ -11,10 +11,10 @@ import { join } from 'node:path';
import { format } from 'sql-formatter';
import { GENERATE_SQL_KEY, GenerateSqlQueries } from 'src/decorators';
import { entities } from 'src/entities';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { providers, repositories } from 'src/repositories';
import { AccessRepository } from 'src/repositories/access.repository';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { AuthService } from 'src/services/auth.service';
import { Logger } from 'typeorm';
@ -62,7 +62,7 @@ class SqlGenerator {
...repositories.map((repository) => ({ provide: repository, useClass: repository as any })),
];
for (const repository of targets) {
if (repository.provide === ILoggerRepository) {
if (repository.provide === LoggingRepository) {
continue;
}
await this.process(repository);

View file

@ -4,7 +4,6 @@ import {
Get,
HttpCode,
HttpStatus,
Inject,
Next,
Param,
ParseFilePipe,
@ -34,10 +33,10 @@ import {
} from 'src/dtos/asset-media.dto';
import { AuthDto } from 'src/dtos/auth.dto';
import { ImmichHeader, RouteKey } from 'src/enum';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { AssetUploadInterceptor } from 'src/middleware/asset-upload.interceptor';
import { Auth, Authenticated, FileResponse } from 'src/middleware/auth.guard';
import { FileUploadInterceptor, UploadFiles, getFiles } from 'src/middleware/file-upload.interceptor';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { AssetMediaService } from 'src/services/asset-media.service';
import { sendFile } from 'src/utils/file';
import { FileNotEmptyValidator, UUIDParamDto } from 'src/validation';
@ -46,7 +45,7 @@ import { FileNotEmptyValidator, UUIDParamDto } from 'src/validation';
@Controller(RouteKey.ASSET)
export class AssetMediaController {
constructor(
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
private service: AssetMediaService,
) {}

View file

@ -1,4 +1,4 @@
import { Body, Controller, Get, Inject, Next, Param, Post, Put, Query, Res } from '@nestjs/common';
import { Body, Controller, Get, Next, Param, Post, Put, Query, Res } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { NextFunction, Response } from 'express';
import { BulkIdResponseDto } from 'src/dtos/asset-ids.response.dto';
@ -15,8 +15,8 @@ import {
PersonUpdateDto,
} from 'src/dtos/person.dto';
import { Permission } from 'src/enum';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { Auth, Authenticated, FileResponse } from 'src/middleware/auth.guard';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { PersonService } from 'src/services/person.service';
import { sendFile } from 'src/utils/file';
import { UUIDParamDto } from 'src/validation';
@ -26,7 +26,7 @@ import { UUIDParamDto } from 'src/validation';
export class PersonController {
constructor(
private service: PersonService,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
) {}
@Get()

View file

@ -5,7 +5,6 @@ import {
Get,
HttpCode,
HttpStatus,
Inject,
Next,
Param,
Post,
@ -22,9 +21,9 @@ import { UserPreferencesResponseDto, UserPreferencesUpdateDto } from 'src/dtos/u
import { CreateProfileImageDto, CreateProfileImageResponseDto } from 'src/dtos/user-profile.dto';
import { UserAdminResponseDto, UserResponseDto, UserUpdateMeDto } from 'src/dtos/user.dto';
import { RouteKey } from 'src/enum';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { Auth, Authenticated, FileResponse } from 'src/middleware/auth.guard';
import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { UserService } from 'src/services/user.service';
import { sendFile } from 'src/utils/file';
import { UUIDParamDto } from 'src/validation';
@ -34,7 +33,7 @@ import { UUIDParamDto } from 'src/validation';
export class UserController {
constructor(
private service: UserService,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
) {}
@Get()

View file

@ -6,12 +6,11 @@ import { PersonEntity } from 'src/entities/person.entity';
import { AssetFileType, AssetPathType, ImageFormat, PathType, PersonPathType, StorageFolder } from 'src/enum';
import { IAssetRepository } from 'src/interfaces/asset.interface';
import { ICryptoRepository } from 'src/interfaces/crypto.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IMoveRepository } from 'src/interfaces/move.interface';
import { IPersonRepository } from 'src/interfaces/person.interface';
import { IStorageRepository } from 'src/interfaces/storage.interface';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
import { IConfigRepository } from 'src/types';
import { IConfigRepository, ILoggingRepository } from 'src/types';
import { getAssetFiles } from 'src/utils/asset.util';
import { getConfig } from 'src/utils/config';
@ -40,7 +39,7 @@ export class StorageCore {
private personRepository: IPersonRepository,
private storageRepository: IStorageRepository,
private systemMetadataRepository: ISystemMetadataRepository,
private logger: ILoggerRepository,
private logger: ILoggingRepository,
) {}
static create(
@ -51,7 +50,7 @@ export class StorageCore {
personRepository: IPersonRepository,
storageRepository: IStorageRepository,
systemMetadataRepository: ISystemMetadataRepository,
logger: ILoggerRepository,
logger: ILoggingRepository,
) {
if (!instance) {
instance = new StorageCore(

View file

@ -1,17 +0,0 @@
import { ImmichWorker, LogLevel } from 'src/enum';
export const ILoggerRepository = 'ILoggerRepository';
export interface ILoggerRepository {
setAppName(name: ImmichWorker): void;
setContext(message: string): void;
setLogLevel(level: LogLevel | false): void;
isLevelEnabled(level: LogLevel): boolean;
verbose(message: any, ...args: any): void;
debug(message: any, ...args: any): void;
log(message: any, ...args: any): void;
warn(message: any, ...args: any): void;
error(message: any, ...args: any): void;
fatal(message: any, ...args: any): void;
}

View file

@ -1,7 +1,6 @@
import {
CanActivate,
ExecutionContext,
Inject,
Injectable,
SetMetadata,
applyDecorators,
@ -12,7 +11,7 @@ import { ApiBearerAuth, ApiCookieAuth, ApiOkResponse, ApiQuery, ApiSecurity } fr
import { Request } from 'express';
import { AuthDto } from 'src/dtos/auth.dto';
import { ImmichQuery, MetadataKey, Permission } from 'src/enum';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { AuthService, LoginDetails } from 'src/services/auth.service';
import { UAParser } from 'ua-parser-js';
@ -67,7 +66,7 @@ export interface AuthenticatedRequest extends Request {
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
private reflector: Reflector,
private authService: AuthService,
) {

View file

@ -2,19 +2,18 @@ import {
CallHandler,
ExecutionContext,
HttpException,
Inject,
Injectable,
InternalServerErrorException,
NestInterceptor,
} from '@nestjs/common';
import { Observable, catchError, throwError } from 'rxjs';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { logGlobalError } from 'src/utils/logger';
import { routeToErrorMessage } from 'src/utils/misc';
@Injectable()
export class ErrorInterceptor implements NestInterceptor {
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
constructor(private logger: LoggingRepository) {
this.logger.setContext(ErrorInterceptor.name);
}

View file

@ -1,4 +1,4 @@
import { CallHandler, ExecutionContext, Inject, Injectable, NestInterceptor } from '@nestjs/common';
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { PATH_METADATA } from '@nestjs/common/constants';
import { Reflector } from '@nestjs/core';
import { transformException } from '@nestjs/platform-express/multer/multer/multer.utils';
@ -8,8 +8,8 @@ import { createHash, randomUUID } from 'node:crypto';
import { Observable } from 'rxjs';
import { UploadFieldName } from 'src/dtos/asset-media.dto';
import { RouteKey } from 'src/enum';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { AuthRequest } from 'src/middleware/auth.guard';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { AssetMediaService, UploadFile } from 'src/services/asset-media.service';
import { asRequest, mapToUploadFile } from 'src/utils/asset.util';
@ -64,7 +64,7 @@ export class FileUploadInterceptor implements NestInterceptor {
constructor(
private reflect: Reflector,
private assetService: AssetMediaService,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
) {
this.logger.setContext(FileUploadInterceptor.name);

View file

@ -1,13 +1,13 @@
import { ArgumentsHost, Catch, ExceptionFilter, HttpException, Inject } from '@nestjs/common';
import { ArgumentsHost, Catch, ExceptionFilter, HttpException } from '@nestjs/common';
import { Response } from 'express';
import { ClsService } from 'nestjs-cls';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { logGlobalError } from 'src/utils/logger';
@Catch()
export class GlobalExceptionFilter implements ExceptionFilter<Error> {
constructor(
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
private cls: ClsService,
) {
this.logger.setContext(GlobalExceptionFilter.name);

View file

@ -1,7 +1,7 @@
import { CallHandler, ExecutionContext, Inject, Injectable, NestInterceptor } from '@nestjs/common';
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Request, Response } from 'express';
import { Observable, finalize } from 'rxjs';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
const maxArrayLength = 100;
const replacer = (key: string, value: unknown) => {
@ -18,7 +18,7 @@ const replacer = (key: string, value: unknown) => {
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
constructor(private logger: LoggingRepository) {
this.logger.setContext(LoggingInterceptor.name);
}

View file

@ -1,14 +1,14 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { SchedulerRegistry } from '@nestjs/schedule';
import { CronJob, CronTime } from 'cron';
import { CronCreate, CronUpdate, ICronRepository } from 'src/interfaces/cron.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
@Injectable()
export class CronRepository implements ICronRepository {
constructor(
private schedulerRegistry: SchedulerRegistry,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
) {
this.logger.setContext(CronRepository.name);
}

View file

@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import AsyncLock from 'async-lock';
import { Kysely, sql } from 'kysely';
@ -16,8 +16,8 @@ import {
VectorIndex,
VectorUpdateResult,
} from 'src/interfaces/database.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { UPSERT_COLUMNS } from 'src/utils/database';
import { isValidInteger } from 'src/validation';
import { DataSource, EntityManager, EntityMetadata, QueryRunner } from 'typeorm';
@ -30,7 +30,7 @@ export class DatabaseRepository implements IDatabaseRepository {
constructor(
@InjectKysely() private db: Kysely<DB>,
@InjectDataSource() private dataSource: DataSource,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
configRepository: ConfigRepository,
) {
this.vectorExtension = configRepository.getEnv().database.vectorExtension;

View file

@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { ModuleRef, Reflector } from '@nestjs/core';
import {
OnGatewayConnection,
@ -22,8 +22,8 @@ import {
serverEvents,
ServerEvents,
} from 'src/interfaces/event.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { AuthService } from 'src/services/auth.service';
import { handlePromiseError } from 'src/utils/misc';
@ -52,7 +52,7 @@ export class EventRepository implements OnGatewayConnection, OnGatewayDisconnect
constructor(
private moduleRef: ModuleRef,
private configRepository: ConfigRepository,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
) {
this.logger.setContext(EventRepository.name);
}

View file

@ -7,7 +7,6 @@ import { IDatabaseRepository } from 'src/interfaces/database.interface';
import { IEventRepository } from 'src/interfaces/event.interface';
import { IJobRepository } from 'src/interfaces/job.interface';
import { ILibraryRepository } from 'src/interfaces/library.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IMachineLearningRepository } from 'src/interfaces/machine-learning.interface';
import { IMapRepository } from 'src/interfaces/map.interface';
import { IMetadataRepository } from 'src/interfaces/metadata.interface';
@ -43,7 +42,7 @@ import { DatabaseRepository } from 'src/repositories/database.repository';
import { EventRepository } from 'src/repositories/event.repository';
import { JobRepository } from 'src/repositories/job.repository';
import { LibraryRepository } from 'src/repositories/library.repository';
import { LoggerRepository } from 'src/repositories/logger.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { MachineLearningRepository } from 'src/repositories/machine-learning.repository';
import { MapRepository } from 'src/repositories/map.repository';
import { MediaRepository } from 'src/repositories/media.repository';
@ -70,12 +69,12 @@ import { VersionHistoryRepository } from 'src/repositories/version-history.repos
import { ViewRepository } from 'src/repositories/view-repository';
export const repositories = [
//
AccessRepository,
ActivityRepository,
AuditRepository,
ApiKeyRepository,
ConfigRepository,
LoggingRepository,
MediaRepository,
MemoryRepository,
ViewRepository,
@ -91,7 +90,6 @@ export const providers = [
{ provide: IEventRepository, useClass: EventRepository },
{ provide: IJobRepository, useClass: JobRepository },
{ provide: ILibraryRepository, useClass: LibraryRepository },
{ provide: ILoggerRepository, useClass: LoggerRepository },
{ provide: IMachineLearningRepository, useClass: MachineLearningRepository },
{ provide: IMapRepository, useClass: MapRepository },
{ provide: IMetadataRepository, useClass: MetadataRepository },

View file

@ -19,8 +19,8 @@ import {
QueueName,
QueueStatus,
} from 'src/interfaces/job.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { getKeyByValue, getMethodNames, ImmichStartupError } from 'src/utils/misc';
type JobMapItem = {
@ -39,7 +39,7 @@ export class JobRepository implements IJobRepository {
private moduleRef: ModuleRef,
private configRepository: ConfigRepository,
@Inject(IEventRepository) private eventRepository: IEventRepository,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
) {
this.logger.setContext(JobRepository.name);
}

View file

@ -1,12 +1,12 @@
import { ClsService } from 'nestjs-cls';
import { ImmichWorker } from 'src/enum';
import { LoggerRepository } from 'src/repositories/logger.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { IConfigRepository } from 'src/types';
import { mockEnvData, newConfigRepositoryMock } from 'test/repositories/config.repository.mock';
import { Mocked } from 'vitest';
describe(LoggerRepository.name, () => {
let sut: LoggerRepository;
describe(LoggingRepository.name, () => {
let sut: LoggingRepository;
let configMock: Mocked<IConfigRepository>;
let clsMock: Mocked<ClsService>;
@ -22,7 +22,7 @@ describe(LoggerRepository.name, () => {
it('should use colors', () => {
configMock.getEnv.mockReturnValue(mockEnvData({ noColor: false }));
sut = new LoggerRepository(clsMock, configMock);
sut = new LoggingRepository(clsMock, configMock);
sut.setAppName(ImmichWorker.API);
expect(sut['formatContext']('context')).toBe('\u001B[33m[Api:context]\u001B[39m ');
@ -31,7 +31,7 @@ describe(LoggerRepository.name, () => {
it('should not use colors when noColor is true', () => {
configMock.getEnv.mockReturnValue(mockEnvData({ noColor: true }));
sut = new LoggerRepository(clsMock, configMock);
sut = new LoggingRepository(clsMock, configMock);
sut.setAppName(ImmichWorker.API);
expect(sut['formatContext']('context')).toBe('[Api:context] ');

View file

@ -3,7 +3,6 @@ import { isLogLevelEnabled } from '@nestjs/common/services/utils/is-log-level-en
import { ClsService } from 'nestjs-cls';
import { Telemetry } from 'src/decorators';
import { LogLevel } from 'src/enum';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ConfigRepository } from 'src/repositories/config.repository';
const LOG_LEVELS = [LogLevel.VERBOSE, LogLevel.DEBUG, LogLevel.LOG, LogLevel.WARN, LogLevel.ERROR, LogLevel.FATAL];
@ -19,7 +18,7 @@ enum LogColor {
@Injectable({ scope: Scope.TRANSIENT })
@Telemetry({ enabled: false })
export class LoggerRepository extends ConsoleLogger implements ILoggerRepository {
export class LoggingRepository extends ConsoleLogger {
private static logLevels: LogLevel[] = [LogLevel.LOG, LogLevel.WARN, LogLevel.ERROR, LogLevel.FATAL];
private noColor: boolean;
@ -27,7 +26,7 @@ export class LoggerRepository extends ConsoleLogger implements ILoggerRepository
private cls: ClsService,
configRepository: ConfigRepository,
) {
super(LoggerRepository.name);
super(LoggingRepository.name);
const { noColor } = configRepository.getEnv();
this.noColor = noColor;
@ -36,19 +35,19 @@ export class LoggerRepository extends ConsoleLogger implements ILoggerRepository
private static appName?: string = undefined;
setAppName(name: string): void {
LoggerRepository.appName = name.charAt(0).toUpperCase() + name.slice(1);
LoggingRepository.appName = name.charAt(0).toUpperCase() + name.slice(1);
}
isLevelEnabled(level: LogLevel) {
return isLogLevelEnabled(level, LoggerRepository.logLevels);
return isLogLevelEnabled(level, LoggingRepository.logLevels);
}
setLogLevel(level: LogLevel | false): void {
LoggerRepository.logLevels = level ? LOG_LEVELS.slice(LOG_LEVELS.indexOf(level)) : [];
LoggingRepository.logLevels = level ? LOG_LEVELS.slice(LOG_LEVELS.indexOf(level)) : [];
}
protected formatContext(context: string): string {
let prefix = LoggerRepository.appName || '';
let prefix = LoggingRepository.appName || '';
if (context) {
prefix += (prefix ? ':' : '') + context;
}

View file

@ -1,7 +1,6 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { readFile } from 'node:fs/promises';
import { CLIPConfig } from 'src/dtos/model-config.dto';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import {
ClipTextualResponse,
ClipVisualResponse,
@ -13,10 +12,11 @@ import {
ModelTask,
ModelType,
} from 'src/interfaces/machine-learning.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
@Injectable()
export class MachineLearningRepository implements IMachineLearningRepository {
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
constructor(private logger: LoggingRepository) {
this.logger.setContext(MachineLearningRepository.name);
}

View file

@ -11,7 +11,6 @@ import { DB, GeodataPlaces, NaturalearthCountries } from 'src/db';
import { AssetEntity, withExif } from 'src/entities/asset.entity';
import { NaturalEarthCountriesTempEntity } from 'src/entities/natural-earth-countries.entity';
import { LogLevel, SystemMetadataKey } from 'src/enum';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import {
GeoPoint,
IMapRepository,
@ -21,6 +20,7 @@ import {
} from 'src/interfaces/map.interface';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
interface MapDB extends DB {
geodata_places_tmp: GeodataPlaces;
@ -32,7 +32,7 @@ export class MapRepository implements IMapRepository {
constructor(
private configRepository: ConfigRepository,
@Inject(ISystemMetadataRepository) private metadataRepository: ISystemMetadataRepository,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
@InjectKysely() private db: Kysely<MapDB>,
) {
this.logger.setContext(MapRepository.name);

View file

@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { exiftool } from 'exiftool-vendored';
import ffmpeg, { FfprobeData } from 'fluent-ffmpeg';
import { Duration } from 'luxon';
@ -7,7 +7,7 @@ import { Writable } from 'node:stream';
import sharp from 'sharp';
import { ORIENTATION_TO_SHARP_ROTATION } from 'src/constants';
import { Colorspace, LogLevel } from 'src/enum';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
import {
DecodeToBufferOptions,
GenerateThumbhashOptions,
@ -37,7 +37,7 @@ type ProgressEvent = {
@Injectable()
export class MediaRepository {
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
constructor(private logger: LoggingRepository) {
this.logger.setContext(MediaRepository.name);
}

View file

@ -1,8 +1,8 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { DefaultReadTaskOptions, ExifTool, Tags } from 'exiftool-vendored';
import geotz from 'geo-tz';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IMetadataRepository, ImmichTags } from 'src/interfaces/metadata.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
@Injectable()
export class MetadataRepository implements IMetadataRepository {
@ -20,7 +20,7 @@ export class MetadataRepository implements IMetadataRepository {
writeArgs: ['-api', 'largefilesupport=1', '-overwrite_original'],
});
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
constructor(private logger: LoggingRepository) {
this.logger.setContext(MetadataRepository.name);
}

View file

@ -1,19 +1,18 @@
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { EmailRenderRequest, EmailTemplate } from 'src/interfaces/notification.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { NotificationRepository } from 'src/repositories/notification.repository';
import { ILoggingRepository } from 'src/types';
import { newLoggingRepositoryMock } from 'test/repositories/logger.repository.mock';
import { Mocked } from 'vitest';
describe(NotificationRepository.name, () => {
let sut: NotificationRepository;
let loggerMock: Mocked<ILoggerRepository>;
let loggerMock: Mocked<ILoggingRepository>;
beforeEach(() => {
loggerMock = {
setContext: vitest.fn(),
debug: vitest.fn(),
} as unknown as Mocked<ILoggerRepository>;
loggerMock = newLoggingRepositoryMock();
sut = new NotificationRepository(loggerMock);
sut = new NotificationRepository(loggerMock as ILoggingRepository as LoggingRepository);
});
describe('renderEmail', () => {

View file

@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { render } from '@react-email/render';
import { createTransport } from 'nodemailer';
import React from 'react';
@ -6,7 +6,6 @@ import { AlbumInviteEmail } from 'src/emails/album-invite.email';
import { AlbumUpdateEmail } from 'src/emails/album-update.email';
import { TestEmail } from 'src/emails/test.email';
import { WelcomeEmail } from 'src/emails/welcome.email';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import {
EmailRenderRequest,
EmailTemplate,
@ -15,10 +14,11 @@ import {
SendEmailResponse,
SmtpOptions,
} from 'src/interfaces/notification.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
@Injectable()
export class NotificationRepository implements INotificationRepository {
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
constructor(private logger: LoggingRepository) {
this.logger.setContext(NotificationRepository.name);
}

View file

@ -1,11 +1,11 @@
import { Inject, Injectable, InternalServerErrorException } from '@nestjs/common';
import { Injectable, InternalServerErrorException } from '@nestjs/common';
import { custom, generators, Issuer } from 'openid-client';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IOAuthRepository, OAuthConfig, OAuthProfile } from 'src/interfaces/oauth.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
@Injectable()
export class OAuthRepository implements IOAuthRepository {
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
constructor(private logger: LoggingRepository) {
this.logger.setContext(OAuthRepository.name);
}

View file

@ -1,12 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { ChildProcessWithoutNullStreams, spawn, SpawnOptionsWithoutStdio } from 'node:child_process';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IProcessRepository } from 'src/interfaces/process.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { StorageRepository } from 'src/repositories/storage.repository';
@Injectable()
export class ProcessRepository implements IProcessRepository {
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
constructor(private logger: LoggingRepository) {
this.logger.setContext(StorageRepository.name);
}

View file

@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { Kysely, OrderByDirectionExpression, sql } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { randomUUID } from 'node:crypto';
@ -7,7 +7,6 @@ import { DummyValue, GenerateSql } from 'src/decorators';
import { AssetEntity, searchAssetBuilder } from 'src/entities/asset.entity';
import { GeodataPlacesEntity } from 'src/entities/geodata-places.entity';
import { AssetType } from 'src/enum';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import {
AssetDuplicateSearch,
AssetSearchOptions,
@ -20,6 +19,7 @@ import {
SearchPaginationOptions,
SmartSearchOptions,
} from 'src/interfaces/search.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { anyUuid, asUuid } from 'src/utils/database';
import { Paginated } from 'src/utils/pagination';
import { isValidInteger } from 'src/validation';
@ -27,7 +27,7 @@ import { isValidInteger } from 'src/validation';
@Injectable()
export class SearchRepository implements ISearchRepository {
constructor(
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
@InjectKysely() private db: Kysely<DB>,
) {
this.logger.setContext(SearchRepository.name);

View file

@ -1,12 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { exiftool } from 'exiftool-vendored';
import { exec as execCallback } from 'node:child_process';
import { readFile } from 'node:fs/promises';
import { promisify } from 'node:util';
import sharp from 'sharp';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { GitHubRelease, IServerInfoRepository, ServerBuildVersions } from 'src/interfaces/server-info.interface';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
const exec = promisify(execCallback);
const maybeFirstLine = async (command: string): Promise<string> => {
@ -37,7 +37,7 @@ const getLockfileVersion = (name: string, lockfile?: BuildLockfile) => {
export class ServerInfoRepository implements IServerInfoRepository {
constructor(
private configRepository: ConfigRepository,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
) {
this.logger.setContext(ServerInfoRepository.name);
}

View file

@ -1,8 +1,9 @@
import mockfs from 'mock-fs';
import { CrawlOptionsDto } from 'src/dtos/library.dto';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { StorageRepository } from 'src/repositories/storage.repository';
import { newLoggerRepositoryMock } from 'test/repositories/logger.repository.mock';
import { ILoggingRepository } from 'src/types';
import { newLoggingRepositoryMock } from 'test/repositories/logger.repository.mock';
interface Test {
test: string;
@ -181,11 +182,11 @@ const tests: Test[] = [
describe(StorageRepository.name, () => {
let sut: StorageRepository;
let logger: ILoggerRepository;
let logger: ILoggingRepository;
beforeEach(() => {
logger = newLoggerRepositoryMock();
sut = new StorageRepository(logger);
logger = newLoggingRepositoryMock();
sut = new StorageRepository(logger as LoggingRepository);
});
afterEach(() => {

View file

@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import archiver from 'archiver';
import chokidar, { WatchOptions } from 'chokidar';
import { escapePath, glob, globStream } from 'fast-glob';
@ -7,7 +7,6 @@ import fs from 'node:fs/promises';
import path from 'node:path';
import { Writable } from 'node:stream';
import { CrawlOptionsDto, WalkOptionsDto } from 'src/dtos/library.dto';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import {
DiskUsage,
IStorageRepository,
@ -15,11 +14,12 @@ import {
ImmichZipStream,
WatchEvents,
} from 'src/interfaces/storage.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { mimeTypes } from 'src/utils/mime-types';
@Injectable()
export class StorageRepository implements IStorageRepository {
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
constructor(private logger: LoggingRepository) {
this.logger.setContext(StorageRepository.name);
}

View file

@ -1,18 +1,17 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
import { Chunked, ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
import { TagEntity } from 'src/entities/tag.entity';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { AssetTagItem, ITagRepository } from 'src/interfaces/tag.interface';
import { DataSource, In, Repository, TreeRepository } from 'typeorm';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { DataSource, In, Repository } from 'typeorm';
@Injectable()
export class TagRepository implements ITagRepository {
constructor(
@InjectDataSource() private dataSource: DataSource,
@InjectRepository(TagEntity) private repository: Repository<TagEntity>,
@InjectRepository(TagEntity) private tree: TreeRepository<TagEntity>,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
) {
this.logger.setContext(TagRepository.name);
}

View file

@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { MetricOptions } from '@opentelemetry/api';
import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks';
@ -15,9 +15,9 @@ import { MetricService } from 'nestjs-otel';
import { copyMetadataFromFunctionToFunction } from 'nestjs-otel/lib/opentelemetry.utils';
import { serverVersion } from 'src/constants';
import { ImmichTelemetry, MetadataKey } from 'src/enum';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IMetricGroupRepository, ITelemetryRepository, MetricGroupOptions } from 'src/interfaces/telemetry.interface';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
class MetricGroupRepository implements IMetricGroupRepository {
private enabled = false;
@ -96,7 +96,7 @@ export class TelemetryRepository implements ITelemetryRepository {
private metricService: MetricService,
private reflect: Reflector,
private configRepository: ConfigRepository,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
) {
const { telemetry } = this.configRepository.getEnv();
const { metrics } = telemetry;

View file

@ -1,10 +1,10 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { Cron, CronExpression, Interval } from '@nestjs/schedule';
import { NextFunction, Request, Response } from 'express';
import { readFileSync } from 'node:fs';
import { ONE_HOUR } from 'src/constants';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { AuthService } from 'src/services/auth.service';
import { JobService } from 'src/services/job.service';
import { SharedLinkService } from 'src/services/shared-link.service';
@ -39,7 +39,7 @@ export class ApiService {
private sharedLinkService: SharedLinkService,
private versionService: VersionService,
private configRepository: ConfigRepository,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
private logger: LoggingRepository,
) {
this.logger.setContext(ApiService.name);
}

View file

@ -15,7 +15,6 @@ import { IDatabaseRepository } from 'src/interfaces/database.interface';
import { IEventRepository } from 'src/interfaces/event.interface';
import { IJobRepository } from 'src/interfaces/job.interface';
import { ILibraryRepository } from 'src/interfaces/library.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IMachineLearningRepository } from 'src/interfaces/machine-learning.interface';
import { IMapRepository } from 'src/interfaces/map.interface';
import { IMetadataRepository } from 'src/interfaces/metadata.interface';
@ -42,6 +41,7 @@ import { ActivityRepository } from 'src/repositories/activity.repository';
import { ApiKeyRepository } from 'src/repositories/api-key.repository';
import { AuditRepository } from 'src/repositories/audit.repository';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { MediaRepository } from 'src/repositories/media.repository';
import { MemoryRepository } from 'src/repositories/memory.repository';
import { ViewRepository } from 'src/repositories/view-repository';
@ -52,7 +52,7 @@ export class BaseService {
protected storageCore: StorageCore;
constructor(
@Inject(ILoggerRepository) protected logger: ILoggerRepository,
protected logger: LoggingRepository,
protected accessRepository: AccessRepository,
protected activityRepository: ActivityRepository,
protected auditRepository: AuditRepository,

View file

@ -5,9 +5,8 @@ import {
IDatabaseRepository,
VectorExtension,
} from 'src/interfaces/database.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { DatabaseService } from 'src/services/database.service';
import { IConfigRepository } from 'src/types';
import { IConfigRepository, ILoggingRepository } from 'src/types';
import { mockEnvData } from 'test/repositories/config.repository.mock';
import { newTestService } from 'test/utils';
import { Mocked } from 'vitest';
@ -17,7 +16,7 @@ describe(DatabaseService.name, () => {
let configMock: Mocked<IConfigRepository>;
let databaseMock: Mocked<IDatabaseRepository>;
let loggerMock: Mocked<ILoggerRepository>;
let loggerMock: Mocked<ILoggingRepository>;
let extensionRange: string;
let versionBelowRange: string;
let minVersionInRange: string;

View file

@ -2,9 +2,9 @@ import { BadRequestException } from '@nestjs/common';
import { DownloadResponseDto } from 'src/dtos/download.dto';
import { AssetEntity } from 'src/entities/asset.entity';
import { IAssetRepository } from 'src/interfaces/asset.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IStorageRepository } from 'src/interfaces/storage.interface';
import { DownloadService } from 'src/services/download.service';
import { ILoggingRepository } from 'src/types';
import { assetStub } from 'test/fixtures/asset.stub';
import { authStub } from 'test/fixtures/auth.stub';
import { IAccessRepositoryMock } from 'test/repositories/access.repository.mock';
@ -26,7 +26,7 @@ describe(DownloadService.name, () => {
let sut: DownloadService;
let accessMock: IAccessRepositoryMock;
let assetMock: Mocked<IAssetRepository>;
let loggerMock: Mocked<ILoggerRepository>;
let loggerMock: Mocked<ILoggingRepository>;
let storageMock: Mocked<IStorageRepository>;
it('should work', () => {

View file

@ -1,10 +1,10 @@
import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.interface';
import { IJobRepository, JobName, JobStatus } from 'src/interfaces/job.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ISearchRepository } from 'src/interfaces/search.interface';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
import { DuplicateService } from 'src/services/duplicate.service';
import { SearchService } from 'src/services/search.service';
import { ILoggingRepository } from 'src/types';
import { assetStub } from 'test/fixtures/asset.stub';
import { authStub } from 'test/fixtures/auth.stub';
import { newTestService } from 'test/utils';
@ -17,7 +17,7 @@ describe(SearchService.name, () => {
let assetMock: Mocked<IAssetRepository>;
let jobMock: Mocked<IJobRepository>;
let loggerMock: Mocked<ILoggerRepository>;
let loggerMock: Mocked<ILoggingRepository>;
let searchMock: Mocked<ISearchRepository>;
let systemMock: Mocked<ISystemMetadataRepository>;

View file

@ -3,10 +3,9 @@ import { defaults, SystemConfig } from 'src/config';
import { ImmichWorker } from 'src/enum';
import { IAssetRepository } from 'src/interfaces/asset.interface';
import { IJobRepository, JobCommand, JobItem, JobName, JobStatus, QueueName } from 'src/interfaces/job.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ITelemetryRepository } from 'src/interfaces/telemetry.interface';
import { JobService } from 'src/services/job.service';
import { IConfigRepository } from 'src/types';
import { IConfigRepository, ILoggingRepository } from 'src/types';
import { assetStub } from 'test/fixtures/asset.stub';
import { newTestService } from 'test/utils';
import { Mocked } from 'vitest';
@ -16,7 +15,7 @@ describe(JobService.name, () => {
let assetMock: Mocked<IAssetRepository>;
let configMock: Mocked<IConfigRepository>;
let jobMock: Mocked<IJobRepository>;
let loggerMock: Mocked<ILoggerRepository>;
let loggerMock: Mocked<ILoggingRepository>;
let telemetryMock: Mocked<ITelemetryRepository>;
beforeEach(() => {

View file

@ -15,13 +15,12 @@ import {
} from 'src/enum';
import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.interface';
import { IJobRepository, JobCounts, JobName, JobStatus } from 'src/interfaces/job.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IMoveRepository } from 'src/interfaces/move.interface';
import { IPersonRepository } from 'src/interfaces/person.interface';
import { IStorageRepository } from 'src/interfaces/storage.interface';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
import { MediaService } from 'src/services/media.service';
import { IMediaRepository, RawImageInfo } from 'src/types';
import { ILoggingRepository, IMediaRepository, RawImageInfo } from 'src/types';
import { assetStub } from 'test/fixtures/asset.stub';
import { faceStub } from 'test/fixtures/face.stub';
import { probeStub } from 'test/fixtures/media.stub';
@ -34,7 +33,7 @@ describe(MediaService.name, () => {
let assetMock: Mocked<IAssetRepository>;
let jobMock: Mocked<IJobRepository>;
let loggerMock: Mocked<ILoggerRepository>;
let loggerMock: Mocked<ILoggingRepository>;
let mediaMock: Mocked<IMediaRepository>;
let moveMock: Mocked<IMoveRepository>;
let personMock: Mocked<IPersonRepository>;

View file

@ -1,9 +1,8 @@
import { SystemMetadataKey } from 'src/enum';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IStorageRepository } from 'src/interfaces/storage.interface';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
import { StorageService } from 'src/services/storage.service';
import { IConfigRepository } from 'src/types';
import { IConfigRepository, ILoggingRepository } from 'src/types';
import { ImmichStartupError } from 'src/utils/misc';
import { mockEnvData } from 'test/repositories/config.repository.mock';
import { newTestService } from 'test/utils';
@ -13,7 +12,7 @@ describe(StorageService.name, () => {
let sut: StorageService;
let configMock: Mocked<IConfigRepository>;
let loggerMock: Mocked<ILoggerRepository>;
let loggerMock: Mocked<ILoggingRepository>;
let storageMock: Mocked<IStorageRepository>;
let systemMock: Mocked<ISystemMetadataRepository>;

View file

@ -14,10 +14,9 @@ import {
} from 'src/enum';
import { IEventRepository } from 'src/interfaces/event.interface';
import { QueueName } from 'src/interfaces/job.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
import { SystemConfigService } from 'src/services/system-config.service';
import { DeepPartial, IConfigRepository } from 'src/types';
import { DeepPartial, IConfigRepository, ILoggingRepository } from 'src/types';
import { mockEnvData } from 'test/repositories/config.repository.mock';
import { newTestService } from 'test/utils';
import { Mocked } from 'vitest';
@ -203,7 +202,7 @@ describe(SystemConfigService.name, () => {
let configMock: Mocked<IConfigRepository>;
let eventMock: Mocked<IEventRepository>;
let loggerMock: Mocked<ILoggerRepository>;
let loggerMock: Mocked<ILoggingRepository>;
let systemMock: Mocked<ISystemMetadataRepository>;
beforeEach(() => {

View file

@ -4,12 +4,11 @@ import { serverVersion } from 'src/constants';
import { ImmichEnvironment, SystemMetadataKey } from 'src/enum';
import { IEventRepository } from 'src/interfaces/event.interface';
import { IJobRepository, JobName, JobStatus } from 'src/interfaces/job.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IServerInfoRepository } from 'src/interfaces/server-info.interface';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
import { IVersionHistoryRepository } from 'src/interfaces/version-history.interface';
import { VersionService } from 'src/services/version.service';
import { IConfigRepository } from 'src/types';
import { IConfigRepository, ILoggingRepository } from 'src/types';
import { mockEnvData } from 'test/repositories/config.repository.mock';
import { newTestService } from 'test/utils';
import { Mocked } from 'vitest';
@ -30,7 +29,7 @@ describe(VersionService.name, () => {
let configMock: Mocked<IConfigRepository>;
let eventMock: Mocked<IEventRepository>;
let jobMock: Mocked<IJobRepository>;
let loggerMock: Mocked<ILoggerRepository>;
let loggerMock: Mocked<ILoggingRepository>;
let serverInfoMock: Mocked<IServerInfoRepository>;
let systemMock: Mocked<ISystemMetadataRepository>;
let versionHistoryMock: Mocked<IVersionHistoryRepository>;

View file

@ -5,6 +5,7 @@ import { ActivityRepository } from 'src/repositories/activity.repository';
import { ApiKeyRepository } from 'src/repositories/api-key.repository';
import { AuditRepository } from 'src/repositories/audit.repository';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { MediaRepository } from 'src/repositories/media.repository';
import { MemoryRepository } from 'src/repositories/memory.repository';
import { ViewRepository } from 'src/repositories/view-repository';
@ -25,6 +26,19 @@ export type IAccessRepository = { [K in keyof AccessRepository]: RepositoryInter
export type IApiKeyRepository = RepositoryInterface<ApiKeyRepository>;
export type IAuditRepository = RepositoryInterface<AuditRepository>;
export type IConfigRepository = RepositoryInterface<ConfigRepository>;
export type ILoggingRepository = Pick<
LoggingRepository,
| 'verbose'
| 'log'
| 'debug'
| 'warn'
| 'error'
| 'fatal'
| 'isLevelEnabled'
| 'setLogLevel'
| 'setContext'
| 'setAppName'
>;
export type IMediaRepository = RepositoryInterface<MediaRepository>;
export type IMemoryRepository = RepositoryInterface<MemoryRepository>;
export type IViewRepository = RepositoryInterface<ViewRepository>;

View file

@ -7,9 +7,8 @@ import { SystemConfig, defaults } from 'src/config';
import { SystemConfigDto } from 'src/dtos/system-config.dto';
import { SystemMetadataKey } from 'src/enum';
import { DatabaseLock } from 'src/interfaces/database.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
import { DeepPartial, IConfigRepository } from 'src/types';
import { DeepPartial, IConfigRepository, ILoggingRepository } from 'src/types';
import { getKeysDeep, unsetDeep } from 'src/utils/misc';
export type SystemConfigValidator = (config: SystemConfig, newConfig: SystemConfig) => void | Promise<void>;
@ -17,7 +16,7 @@ export type SystemConfigValidator = (config: SystemConfig, newConfig: SystemConf
type RepoDeps = {
configRepo: IConfigRepository;
metadataRepo: ISystemMetadataRepository;
logger: ILoggerRepository;
logger: ILoggingRepository;
};
const asyncLock = new AsyncLock();

View file

@ -4,8 +4,8 @@ import { access, constants } from 'node:fs/promises';
import { basename, extname, isAbsolute } from 'node:path';
import { promisify } from 'node:util';
import { CacheControl } from 'src/enum';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ImmichReadStream } from 'src/interfaces/storage.interface';
import { ILoggingRepository } from 'src/types';
import { isConnectionAborted } from 'src/utils/misc';
export function getFileNameWithoutExtension(path: string): string {
@ -37,7 +37,7 @@ export const sendFile = async (
res: Response,
next: NextFunction,
handler: () => Promise<ImmichFileResponse>,
logger: ILoggerRepository,
logger: ILoggingRepository,
): Promise<void> => {
const _sendFile = (path: string, options: SendFileOptions) =>
promisify<string, SendFileOptions>(res.sendFile).bind(res)(path, options);

View file

@ -1,8 +1,8 @@
import { HttpException } from '@nestjs/common';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ILoggingRepository } from 'src/types';
import { TypeORMError } from 'typeorm';
export const logGlobalError = (logger: ILoggerRepository, error: Error) => {
export const logGlobalError = (logger: ILoggingRepository, error: Error) => {
if (error instanceof HttpException) {
const status = error.getStatus();
const response = error.getResponse();

View file

@ -13,7 +13,7 @@ import path from 'node:path';
import { SystemConfig } from 'src/config';
import { CLIP_MODEL_INFO, serverVersion } from 'src/constants';
import { ImmichCookie, ImmichHeader, MetadataKey } from 'src/enum';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ILoggingRepository } from 'src/types';
export class ImmichStartupError extends Error {}
export const isStartUpError = (error: unknown): error is ImmichStartupError => error instanceof ImmichStartupError;
@ -96,7 +96,7 @@ export const isFaceImportEnabled = (metadata: SystemConfig['metadata']) => metad
export const isConnectionAborted = (error: Error | any) => error.code === 'ECONNABORTED';
export const handlePromiseError = <T>(promise: Promise<T>, logger: ILoggerRepository): void => {
export const handlePromiseError = <T>(promise: Promise<T>, logger: ILoggingRepository): void => {
promise.catch((error: Error | any) => logger.error(`Promise error: ${error}`, error?.stack));
};

View file

@ -7,9 +7,9 @@ import sirv from 'sirv';
import { ApiModule } from 'src/app.module';
import { excludePaths, serverVersion } from 'src/constants';
import { ImmichEnvironment } from 'src/enum';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { WebSocketAdapter } from 'src/middleware/websocket.adapter';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { bootstrapTelemetry } from 'src/repositories/telemetry.repository';
import { ApiService } from 'src/services/api.service';
import { isStartUpError, useSwagger } from 'src/utils/misc';
@ -23,7 +23,7 @@ async function bootstrap() {
}
const app = await NestFactory.create<NestExpressApplication>(ApiModule, { bufferLogs: true });
const logger = await app.resolve<ILoggerRepository>(ILoggerRepository);
const logger = await app.resolve(LoggingRepository);
const configRepository = app.get(ConfigRepository);
const { environment, host, port, resourcePaths } = configRepository.getEnv();

View file

@ -2,9 +2,9 @@ import { NestFactory } from '@nestjs/core';
import { isMainThread } from 'node:worker_threads';
import { MicroservicesModule } from 'src/app.module';
import { serverVersion } from 'src/constants';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { WebSocketAdapter } from 'src/middleware/websocket.adapter';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { bootstrapTelemetry } from 'src/repositories/telemetry.repository';
import { isStartUpError } from 'src/utils/misc';
@ -15,7 +15,7 @@ export async function bootstrap() {
}
const app = await NestFactory.create(MicroservicesModule, { bufferLogs: true });
const logger = await app.resolve(ILoggerRepository);
const logger = await app.resolve(LoggingRepository);
logger.setContext('Bootstrap');
app.useLogger(logger);
app.useWebSocketAdapter(new WebSocketAdapter(app));

View file

@ -5,13 +5,17 @@ import { join } from 'node:path';
import { AssetEntity } from 'src/entities/asset.entity';
import { IAssetRepository } from 'src/interfaces/asset.interface';
import { IStorageRepository } from 'src/interfaces/storage.interface';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { MetadataRepository } from 'src/repositories/metadata.repository';
import { MetadataService } from 'src/services/metadata.service';
import { newLoggerRepositoryMock } from 'test/repositories/logger.repository.mock';
import { ILoggingRepository } from 'src/types';
import { newLoggingRepositoryMock } from 'test/repositories/logger.repository.mock';
import { newRandomImage, newTestService } from 'test/utils';
import { Mocked } from 'vitest';
const metadataRepository = new MetadataRepository(newLoggerRepositoryMock());
const metadataRepository = new MetadataRepository(
newLoggingRepositoryMock() as ILoggingRepository as LoggingRepository,
);
const createTestFile = async (exifData: Record<string, any>) => {
const data = newRandomImage();

View file

@ -1,7 +1,7 @@
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ILoggingRepository } from 'src/types';
import { Mocked, vitest } from 'vitest';
export const newLoggerRepositoryMock = (): Mocked<ILoggerRepository> => {
export const newLoggingRepositoryMock = (): Mocked<ILoggingRepository> => {
return {
setLogLevel: vitest.fn(),
setContext: vitest.fn(),

View file

@ -7,6 +7,7 @@ import { AccessRepository } from 'src/repositories/access.repository';
import { ActivityRepository } from 'src/repositories/activity.repository';
import { ApiKeyRepository } from 'src/repositories/api-key.repository';
import { AuditRepository } from 'src/repositories/audit.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { MediaRepository } from 'src/repositories/media.repository';
import { MemoryRepository } from 'src/repositories/memory.repository';
import { ViewRepository } from 'src/repositories/view-repository';
@ -16,6 +17,7 @@ import {
IActivityRepository,
IApiKeyRepository,
IAuditRepository,
ILoggingRepository,
IMediaRepository,
IMemoryRepository,
IViewRepository,
@ -34,7 +36,7 @@ import { newDatabaseRepositoryMock } from 'test/repositories/database.repository
import { newEventRepositoryMock } from 'test/repositories/event.repository.mock';
import { newJobRepositoryMock } from 'test/repositories/job.repository.mock';
import { newLibraryRepositoryMock } from 'test/repositories/library.repository.mock';
import { newLoggerRepositoryMock } from 'test/repositories/logger.repository.mock';
import { newLoggingRepositoryMock } from 'test/repositories/logger.repository.mock';
import { newMachineLearningRepositoryMock } from 'test/repositories/machine-learning.repository.mock';
import { newMapRepositoryMock } from 'test/repositories/map.repository.mock';
import { newMediaRepositoryMock } from 'test/repositories/media.repository.mock';
@ -78,7 +80,7 @@ export const newTestService = <T extends BaseService>(
const { metadataRepository } = overrides || {};
const accessMock = newAccessRepositoryMock();
const loggerMock = newLoggerRepositoryMock();
const loggerMock = newLoggingRepositoryMock();
const cronMock = newCronRepositoryMock();
const cryptoMock = newCryptoRepositoryMock();
const activityMock = newActivityRepositoryMock();
@ -118,7 +120,7 @@ export const newTestService = <T extends BaseService>(
const viewMock = newViewRepositoryMock();
const sut = new Service(
loggerMock,
loggerMock as ILoggingRepository as LoggingRepository,
accessMock as IAccessRepository as AccessRepository,
activityMock as IActivityRepository as ActivityRepository,
auditMock as IAuditRepository as AuditRepository,