feat: use ILoggerRepository (#8855)

* Migrate ImmichLogger over to injected ILoggerRepository

* chore: cleanup and tests

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
AmAn Sharma
2024-04-17 03:00:31 +05:30
committed by GitHub
parent 877207a2e6
commit 6e6deec40c
59 changed files with 352 additions and 191 deletions

View File

@@ -1,3 +1,4 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
import { ActivityEntity } from 'src/entities/activity.entity';
@@ -25,6 +26,7 @@ type IPersonAccess = IAccessRepository['person'];
type IPartnerAccess = IAccessRepository['partner'];
@Instrumentation()
@Injectable()
class ActivityAccess implements IActivityAccess {
constructor(
private activityRepository: Repository<ActivityEntity>,

View File

@@ -1,3 +1,4 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { AuditEntity } from 'src/entities/audit.entity';
import { AuditSearch, IAuditRepository } from 'src/interfaces/audit.interface';
@@ -5,6 +6,7 @@ import { Instrumentation } from 'src/utils/instrumentation';
import { In, LessThan, MoreThan, Repository } from 'typeorm';
@Instrumentation()
@Injectable()
export class AuditRepository implements IAuditRepository {
constructor(@InjectRepository(AuditEntity) private repository: Repository<AuditEntity>) {}

View File

@@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import AsyncLock from 'async-lock';
import { vectorExt } from 'src/database.config';
@@ -11,8 +11,8 @@ import {
VectorUpdateResult,
extName,
} from 'src/interfaces/database.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { Instrumentation } from 'src/utils/instrumentation';
import { ImmichLogger } from 'src/utils/logger';
import { Version, VersionType } from 'src/utils/version';
import { isValidInteger } from 'src/validation';
import { DataSource, EntityManager, QueryRunner } from 'typeorm';
@@ -20,10 +20,14 @@ import { DataSource, EntityManager, QueryRunner } from 'typeorm';
@Instrumentation()
@Injectable()
export class DatabaseRepository implements IDatabaseRepository {
private logger = new ImmichLogger(DatabaseRepository.name);
readonly asyncLock = new AsyncLock();
constructor(@InjectDataSource() private dataSource: DataSource) {}
constructor(
@InjectDataSource() private dataSource: DataSource,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
) {
this.logger.setContext(DatabaseRepository.name);
}
async getExtensionVersion(extension: DatabaseExtension): Promise<Version | null> {
const res = await this.dataSource.query(`SELECT extversion FROM pg_extension WHERE extname = $1`, [extension]);

View File

@@ -1,3 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
import {
OnGatewayConnection,
@@ -14,9 +15,9 @@ import {
ServerEvent,
ServerEventMap,
} from 'src/interfaces/event.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { AuthService } from 'src/services/auth.service';
import { Instrumentation } from 'src/utils/instrumentation';
import { ImmichLogger } from 'src/utils/logger';
@Instrumentation()
@WebSocketGateway({
@@ -24,16 +25,18 @@ import { ImmichLogger } from 'src/utils/logger';
path: '/api/socket.io',
transports: ['websocket'],
})
@Injectable()
export class EventRepository implements OnGatewayConnection, OnGatewayDisconnect, OnGatewayInit, IEventRepository {
private logger = new ImmichLogger(EventRepository.name);
@WebSocketServer()
private server?: Server;
constructor(
private authService: AuthService,
private eventEmitter: EventEmitter2,
) {}
@Inject(ILoggerRepository) private logger: ILoggerRepository,
) {
this.logger.setContext(EventRepository.name);
}
afterInit(server: Server) {
this.logger.log('Initialized websocket server');

View File

@@ -1,5 +1,5 @@
import { getQueueToken } from '@nestjs/bullmq';
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { SchedulerRegistry } from '@nestjs/schedule';
import { Job, JobsOptions, Processor, Queue, Worker, WorkerOptions } from 'bullmq';
@@ -15,8 +15,8 @@ import {
QueueName,
QueueStatus,
} from 'src/interfaces/job.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { Instrumentation } from 'src/utils/instrumentation';
import { ImmichLogger } from 'src/utils/logger';
export const JOBS_TO_QUEUE: Record<JobName, QueueName> = {
// misc
@@ -83,12 +83,14 @@ export const JOBS_TO_QUEUE: Record<JobName, QueueName> = {
@Injectable()
export class JobRepository implements IJobRepository {
private workers: Partial<Record<QueueName, Worker>> = {};
private logger = new ImmichLogger(JobRepository.name);
constructor(
private moduleReference: ModuleRef,
private schedulerReqistry: SchedulerRegistry,
) {}
@Inject(ILoggerRepository) private logger: ILoggerRepository,
) {
this.logger.setContext(JobRepository.name);
}
addHandler(queueName: QueueName, concurrency: number, handler: (item: JobItem) => Promise<void>) {
const workerHandler: Processor = async (job: Job) => handler(job as JobItem);

View File

@@ -1,10 +1,10 @@
import { Injectable } from '@nestjs/common';
import { Injectable, Scope } from '@nestjs/common';
import { ClsService } from 'nestjs-cls';
import { LogLevel } from 'src/entities/system-config.entity';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ImmichLogger } from 'src/utils/logger';
@Injectable()
@Injectable({ scope: Scope.TRANSIENT })
export class LoggerRepository extends ImmichLogger implements ILoggerRepository {
constructor(private cls: ClsService) {
super(LoggerRepository.name);

View File

@@ -1,9 +1,11 @@
import { Inject, Injectable } from '@nestjs/common';
import ffmpeg, { FfprobeData } from 'fluent-ffmpeg';
import fs from 'node:fs/promises';
import { Writable } from 'node:stream';
import { promisify } from 'node:util';
import sharp from 'sharp';
import { Colorspace } from 'src/entities/system-config.entity';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import {
CropOptions,
IMediaRepository,
@@ -12,7 +14,6 @@ import {
VideoInfo,
} from 'src/interfaces/media.interface';
import { Instrumentation } from 'src/utils/instrumentation';
import { ImmichLogger } from 'src/utils/logger';
import { handlePromiseError } from 'src/utils/misc';
const probe = promisify<string, FfprobeData>(ffmpeg.ffprobe);
@@ -20,9 +21,11 @@ sharp.concurrency(0);
sharp.cache({ files: 0 });
@Instrumentation()
@Injectable()
export class MediaRepository implements IMediaRepository {
private logger = new ImmichLogger(MediaRepository.name);
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
this.logger.setContext(MediaRepository.name);
}
crop(input: string | Buffer, options: CropOptions): Promise<Buffer> {
return sharp(input, { failOn: 'none' })
.pipelineColorspace('rgb16')

View File

@@ -1,4 +1,4 @@
import { Inject } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
import { DefaultReadTaskOptions, Tags, exiftool } from 'exiftool-vendored';
import geotz from 'geo-tz';
@@ -11,24 +11,26 @@ import { DummyValue, GenerateSql } from 'src/decorators';
import { ExifEntity } from 'src/entities/exif.entity';
import { GeodataPlacesEntity } from 'src/entities/geodata-places.entity';
import { SystemMetadataKey } from 'src/entities/system-metadata.entity';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { GeoPoint, IMetadataRepository, ImmichTags, ReverseGeocodeResult } from 'src/interfaces/metadata.interface';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
import { Instrumentation } from 'src/utils/instrumentation';
import { ImmichLogger } from 'src/utils/logger';
import { DataSource, QueryRunner, Repository } from 'typeorm';
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity.js';
@Instrumentation()
@Injectable()
export class MetadataRepository implements IMetadataRepository {
constructor(
@InjectRepository(ExifEntity) private exifRepository: Repository<ExifEntity>,
@InjectRepository(GeodataPlacesEntity) private readonly geodataPlacesRepository: Repository<GeodataPlacesEntity>,
@InjectRepository(GeodataPlacesEntity) private geodataPlacesRepository: Repository<GeodataPlacesEntity>,
@Inject(ISystemMetadataRepository)
private readonly systemMetadataRepository: ISystemMetadataRepository,
private systemMetadataRepository: ISystemMetadataRepository,
@InjectDataSource() private dataSource: DataSource,
) {}
private logger = new ImmichLogger(MetadataRepository.name);
@Inject(ILoggerRepository) private logger: ILoggerRepository,
) {
this.logger.setContext(MetadataRepository.name);
}
async init(): Promise<void> {
this.logger.log('Initializing metadata repository');

View File

@@ -6,7 +6,7 @@ import { apiMetrics, hostMetrics, jobMetrics, repoMetrics } from 'src/utils/inst
class MetricGroupRepository implements IMetricGroupRepository {
private enabled = false;
constructor(private readonly metricService: MetricService) {}
constructor(private metricService: MetricService) {}
addToCounter(name: string, value: number, options?: MetricOptions): void {
if (this.enabled) {

View File

@@ -8,7 +8,7 @@ import { DeepPartial, Repository } from 'typeorm';
@Instrumentation()
@Injectable()
export class PartnerRepository implements IPartnerRepository {
constructor(@InjectRepository(PartnerEntity) private readonly repository: Repository<PartnerEntity>) {}
constructor(@InjectRepository(PartnerEntity) private repository: Repository<PartnerEntity>) {}
getAll(userId: string): Promise<PartnerEntity[]> {
return this.repository.find({ where: [{ sharedWithId: userId }, { sharedById: userId }] });

View File

@@ -1,3 +1,4 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import _ from 'lodash';
import { ChunkedArray, DummyValue, GenerateSql } from 'src/decorators';
@@ -19,6 +20,7 @@ import { Paginated, PaginationOptions, paginate } from 'src/utils/pagination';
import { FindManyOptions, FindOptionsRelations, FindOptionsSelect, In, Repository } from 'typeorm';
@Instrumentation()
@Injectable()
export class PersonRepository implements IPersonRepository {
constructor(
@InjectRepository(AssetEntity) private assetRepository: Repository<AssetEntity>,

View File

@@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { vectorExt } from 'src/database.config';
import { DummyValue, GenerateSql } from 'src/decorators';
@@ -8,6 +8,7 @@ import { GeodataPlacesEntity } from 'src/entities/geodata-places.entity';
import { SmartInfoEntity } from 'src/entities/smart-info.entity';
import { SmartSearchEntity } from 'src/entities/smart-search.entity';
import { DatabaseExtension } from 'src/interfaces/database.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import {
AssetSearchOptions,
FaceEmbeddingSearch,
@@ -18,7 +19,6 @@ import {
} from 'src/interfaces/search.interface';
import { asVector, searchAssetBuilder } from 'src/utils/database';
import { Instrumentation } from 'src/utils/instrumentation';
import { ImmichLogger } from 'src/utils/logger';
import { getCLIPModelInfo } from 'src/utils/misc';
import { Paginated, PaginationMode, PaginationResult, paginatedBuilder } from 'src/utils/pagination';
import { isValidInteger } from 'src/validation';
@@ -27,7 +27,6 @@ import { Repository, SelectQueryBuilder } from 'typeorm';
@Instrumentation()
@Injectable()
export class SearchRepository implements ISearchRepository {
private logger = new ImmichLogger(SearchRepository.name);
private faceColumns: string[];
private assetsByCityQuery: string;
@@ -36,8 +35,10 @@ export class SearchRepository implements ISearchRepository {
@InjectRepository(AssetEntity) private assetRepository: Repository<AssetEntity>,
@InjectRepository(AssetFaceEntity) private assetFaceRepository: Repository<AssetFaceEntity>,
@InjectRepository(SmartSearchEntity) private smartSearchRepository: Repository<SmartSearchEntity>,
@InjectRepository(GeodataPlacesEntity) private readonly geodataPlacesRepository: Repository<GeodataPlacesEntity>,
@InjectRepository(GeodataPlacesEntity) private geodataPlacesRepository: Repository<GeodataPlacesEntity>,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
) {
this.logger.setContext(SearchRepository.name);
this.faceColumns = this.assetFaceRepository.manager.connection
.getMetadata(AssetFaceEntity)
.ownColumns.map((column) => column.propertyName)

View File

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

View File

@@ -1,3 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import archiver from 'archiver';
import chokidar, { WatchOptions } from 'chokidar';
import { glob, globStream } from 'fast-glob';
@@ -5,6 +6,7 @@ import { constants, createReadStream, existsSync, mkdirSync } from 'node:fs';
import fs from 'node:fs/promises';
import path from 'node:path';
import { CrawlOptionsDto } from 'src/dtos/library.dto';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import {
DiskUsage,
IStorageRepository,
@@ -13,12 +15,14 @@ import {
WatchEvents,
} from 'src/interfaces/storage.interface';
import { Instrumentation } from 'src/utils/instrumentation';
import { ImmichLogger } from 'src/utils/logger';
import { mimeTypes } from 'src/utils/mime-types';
@Instrumentation()
@Injectable()
export class StorageRepository implements IStorageRepository {
private logger = new ImmichLogger(StorageRepository.name);
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
this.logger.setContext(StorageRepository.name);
}
readdir(folder: string): Promise<string[]> {
return fs.readdir(folder);

View File

@@ -1,3 +1,4 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { readFile } from 'node:fs/promises';
import { Chunked, DummyValue, GenerateSql } from 'src/decorators';
@@ -7,6 +8,7 @@ import { Instrumentation } from 'src/utils/instrumentation';
import { In, Repository } from 'typeorm';
@Instrumentation()
@Injectable()
export class SystemConfigRepository implements ISystemConfigRepository {
constructor(
@InjectRepository(SystemConfigEntity)

View File

@@ -1,3 +1,4 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { SystemMetadata, SystemMetadataEntity } from 'src/entities/system-metadata.entity';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
@@ -5,6 +6,7 @@ import { Instrumentation } from 'src/utils/instrumentation';
import { Repository } from 'typeorm';
@Instrumentation()
@Injectable()
export class SystemMetadataRepository implements ISystemMetadataRepository {
constructor(
@InjectRepository(SystemMetadataEntity)