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
53 changed files with 159 additions and 172 deletions

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;