Added Log level to background service (#685)
This commit is contained in:
parent
858ad43d3b
commit
e79e92c60f
6 changed files with 89 additions and 37 deletions
|
@ -36,6 +36,11 @@ REDIS_HOSTNAME=immich_redis
|
||||||
UPLOAD_LOCATION=absolute_location_on_your_machine_where_you_want_to_store_the_backup
|
UPLOAD_LOCATION=absolute_location_on_your_machine_where_you_want_to_store_the_backup
|
||||||
|
|
||||||
|
|
||||||
|
###################################################################################
|
||||||
|
# Log message level - [simple|verbose]
|
||||||
|
###################################################################################
|
||||||
|
|
||||||
|
LOG_LEVEL=simple
|
||||||
|
|
||||||
|
|
||||||
###################################################################################
|
###################################################################################
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
} from '@app/job/constants/queue-name.constant';
|
} from '@app/job/constants/queue-name.constant';
|
||||||
import { BullModule } from '@nestjs/bull';
|
import { BullModule } from '@nestjs/bull';
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { ConfigModule } from '@nestjs/config';
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { CommunicationModule } from '../../immich/src/api-v1/communication/communication.module';
|
import { CommunicationModule } from '../../immich/src/api-v1/communication/communication.module';
|
||||||
import { MicroservicesService } from './microservices.service';
|
import { MicroservicesService } from './microservices.service';
|
||||||
|
@ -40,42 +40,48 @@ import { VideoTranscodeProcessor } from './processors/video-transcode.processor'
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
BullModule.registerQueue({
|
BullModule.registerQueue(
|
||||||
name: thumbnailGeneratorQueueName,
|
{
|
||||||
defaultJobOptions: {
|
name: thumbnailGeneratorQueueName,
|
||||||
attempts: 3,
|
defaultJobOptions: {
|
||||||
removeOnComplete: true,
|
attempts: 3,
|
||||||
removeOnFail: false,
|
removeOnComplete: true,
|
||||||
|
removeOnFail: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}, {
|
{
|
||||||
name: assetUploadedQueueName,
|
name: assetUploadedQueueName,
|
||||||
defaultJobOptions: {
|
defaultJobOptions: {
|
||||||
attempts: 3,
|
attempts: 3,
|
||||||
removeOnComplete: true,
|
removeOnComplete: true,
|
||||||
removeOnFail: false,
|
removeOnFail: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}, {
|
{
|
||||||
name: metadataExtractionQueueName,
|
name: metadataExtractionQueueName,
|
||||||
defaultJobOptions: {
|
defaultJobOptions: {
|
||||||
attempts: 3,
|
attempts: 3,
|
||||||
removeOnComplete: true,
|
removeOnComplete: true,
|
||||||
removeOnFail: false,
|
removeOnFail: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}, {
|
{
|
||||||
name: videoConversionQueueName,
|
name: videoConversionQueueName,
|
||||||
defaultJobOptions: {
|
defaultJobOptions: {
|
||||||
attempts: 3,
|
attempts: 3,
|
||||||
removeOnComplete: true,
|
removeOnComplete: true,
|
||||||
removeOnFail: false,
|
removeOnFail: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}, {
|
{
|
||||||
name: generateChecksumQueueName,
|
name: generateChecksumQueueName,
|
||||||
defaultJobOptions: {
|
defaultJobOptions: {
|
||||||
attempts: 3,
|
attempts: 3,
|
||||||
removeOnComplete: true,
|
removeOnComplete: true,
|
||||||
removeOnFail: false,
|
removeOnFail: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
),
|
||||||
CommunicationModule,
|
CommunicationModule,
|
||||||
],
|
],
|
||||||
controllers: [],
|
controllers: [],
|
||||||
|
@ -86,6 +92,7 @@ import { VideoTranscodeProcessor } from './processors/video-transcode.processor'
|
||||||
MetadataExtractionProcessor,
|
MetadataExtractionProcessor,
|
||||||
VideoTranscodeProcessor,
|
VideoTranscodeProcessor,
|
||||||
GenerateChecksumProcessor,
|
GenerateChecksumProcessor,
|
||||||
|
ConfigService,
|
||||||
],
|
],
|
||||||
exports: [],
|
exports: [],
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { ImmichLogLevel } from '@app/common/constants/log-level.constant';
|
||||||
import { AssetEntity } from '@app/database/entities/asset.entity';
|
import { AssetEntity } from '@app/database/entities/asset.entity';
|
||||||
import { ExifEntity } from '@app/database/entities/exif.entity';
|
import { ExifEntity } from '@app/database/entities/exif.entity';
|
||||||
import { SmartInfoEntity } from '@app/database/entities/smart-info.entity';
|
import { SmartInfoEntity } from '@app/database/entities/smart-info.entity';
|
||||||
|
@ -16,6 +17,7 @@ import { MapiResponse } from '@mapbox/mapbox-sdk/lib/classes/mapi-response';
|
||||||
import mapboxGeocoding, { GeocodeService } from '@mapbox/mapbox-sdk/services/geocoding';
|
import mapboxGeocoding, { GeocodeService } from '@mapbox/mapbox-sdk/services/geocoding';
|
||||||
import { Process, Processor } from '@nestjs/bull';
|
import { Process, Processor } from '@nestjs/bull';
|
||||||
import { Logger } from '@nestjs/common';
|
import { Logger } from '@nestjs/common';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Job } from 'bull';
|
import { Job } from 'bull';
|
||||||
|
@ -28,6 +30,7 @@ import { Repository } from 'typeorm/repository/Repository';
|
||||||
@Processor(metadataExtractionQueueName)
|
@Processor(metadataExtractionQueueName)
|
||||||
export class MetadataExtractionProcessor {
|
export class MetadataExtractionProcessor {
|
||||||
private geocodingClient?: GeocodeService;
|
private geocodingClient?: GeocodeService;
|
||||||
|
private logLevel: ImmichLogLevel;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(AssetEntity)
|
@InjectRepository(AssetEntity)
|
||||||
|
@ -38,12 +41,16 @@ export class MetadataExtractionProcessor {
|
||||||
|
|
||||||
@InjectRepository(SmartInfoEntity)
|
@InjectRepository(SmartInfoEntity)
|
||||||
private smartInfoRepository: Repository<SmartInfoEntity>,
|
private smartInfoRepository: Repository<SmartInfoEntity>,
|
||||||
|
|
||||||
|
private configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
if (process.env.ENABLE_MAPBOX == 'true' && process.env.MAPBOX_KEY) {
|
if (process.env.ENABLE_MAPBOX == 'true' && process.env.MAPBOX_KEY) {
|
||||||
this.geocodingClient = mapboxGeocoding({
|
this.geocodingClient = mapboxGeocoding({
|
||||||
accessToken: process.env.MAPBOX_KEY,
|
accessToken: process.env.MAPBOX_KEY,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.logLevel = this.configService.get('LOG_LEVEL') || ImmichLogLevel.SIMPLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Process(exifExtractionProcessorName)
|
@Process(exifExtractionProcessorName)
|
||||||
|
@ -139,6 +146,10 @@ export class MetadataExtractionProcessor {
|
||||||
await this.exifRepository.save(newExif);
|
await this.exifRepository.save(newExif);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error(`Error extracting EXIF ${String(e)}`, 'extractExif');
|
Logger.error(`Error extracting EXIF ${String(e)}`, 'extractExif');
|
||||||
|
|
||||||
|
if (this.logLevel === ImmichLogLevel.VERBOSE) {
|
||||||
|
console.trace('Error extracting EXIF', e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { ImmichLogLevel } from '@app/common/constants/log-level.constant';
|
||||||
import { AssetEntity, AssetType } from '@app/database/entities/asset.entity';
|
import { AssetEntity, AssetType } from '@app/database/entities/asset.entity';
|
||||||
import {
|
import {
|
||||||
WebpGeneratorProcessor,
|
WebpGeneratorProcessor,
|
||||||
|
@ -11,6 +12,7 @@ import {
|
||||||
} from '@app/job';
|
} from '@app/job';
|
||||||
import { InjectQueue, Process, Processor } from '@nestjs/bull';
|
import { InjectQueue, Process, Processor } from '@nestjs/bull';
|
||||||
import { Logger } from '@nestjs/common';
|
import { Logger } from '@nestjs/common';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { mapAsset } from 'apps/immich/src/api-v1/asset/response-dto/asset-response.dto';
|
import { mapAsset } from 'apps/immich/src/api-v1/asset/response-dto/asset-response.dto';
|
||||||
import { Job, Queue } from 'bull';
|
import { Job, Queue } from 'bull';
|
||||||
|
@ -23,6 +25,8 @@ import { CommunicationGateway } from '../../../immich/src/api-v1/communication/c
|
||||||
|
|
||||||
@Processor(thumbnailGeneratorQueueName)
|
@Processor(thumbnailGeneratorQueueName)
|
||||||
export class ThumbnailGeneratorProcessor {
|
export class ThumbnailGeneratorProcessor {
|
||||||
|
private logLevel: ImmichLogLevel;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(AssetEntity)
|
@InjectRepository(AssetEntity)
|
||||||
private assetRepository: Repository<AssetEntity>,
|
private assetRepository: Repository<AssetEntity>,
|
||||||
|
@ -34,7 +38,11 @@ export class ThumbnailGeneratorProcessor {
|
||||||
|
|
||||||
@InjectQueue(metadataExtractionQueueName)
|
@InjectQueue(metadataExtractionQueueName)
|
||||||
private metadataExtractionQueue: Queue,
|
private metadataExtractionQueue: Queue,
|
||||||
) {}
|
|
||||||
|
private configService: ConfigService,
|
||||||
|
) {
|
||||||
|
this.logLevel = this.configService.get('LOG_LEVEL') || ImmichLogLevel.SIMPLE;
|
||||||
|
}
|
||||||
|
|
||||||
@Process({ name: generateJPEGThumbnailProcessorName, concurrency: 3 })
|
@Process({ name: generateJPEGThumbnailProcessorName, concurrency: 3 })
|
||||||
async generateJPEGThumbnail(job: Job<JpegGeneratorProcessor>) {
|
async generateJPEGThumbnail(job: Job<JpegGeneratorProcessor>) {
|
||||||
|
@ -51,8 +59,16 @@ export class ThumbnailGeneratorProcessor {
|
||||||
const jpegThumbnailPath = resizePath + originalFilename + '.jpeg';
|
const jpegThumbnailPath = resizePath + originalFilename + '.jpeg';
|
||||||
|
|
||||||
if (asset.type == AssetType.IMAGE) {
|
if (asset.type == AssetType.IMAGE) {
|
||||||
await sharp(asset.originalPath).resize(1440, 2560, { fit: 'inside' }).jpeg().rotate().toFile(jpegThumbnailPath);
|
try {
|
||||||
await this.assetRepository.update({ id: asset.id }, { resizePath: jpegThumbnailPath });
|
await sharp(asset.originalPath).resize(1440, 2560, { fit: 'inside' }).jpeg().rotate().toFile(jpegThumbnailPath);
|
||||||
|
await this.assetRepository.update({ id: asset.id }, { resizePath: jpegThumbnailPath });
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error('Failed to generate jpeg thumbnail for asset: ' + asset.id);
|
||||||
|
|
||||||
|
if (this.logLevel == ImmichLogLevel.VERBOSE) {
|
||||||
|
console.trace('Failed to generate jpeg thumbnail for asset', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update resize path to send to generate webp queue
|
// Update resize path to send to generate webp queue
|
||||||
asset.resizePath = jpegThumbnailPath;
|
asset.resizePath = jpegThumbnailPath;
|
||||||
|
@ -105,7 +121,15 @@ export class ThumbnailGeneratorProcessor {
|
||||||
|
|
||||||
const webpPath = asset.resizePath.replace('jpeg', 'webp');
|
const webpPath = asset.resizePath.replace('jpeg', 'webp');
|
||||||
|
|
||||||
await sharp(asset.resizePath).resize(250).webp().rotate().toFile(webpPath);
|
try {
|
||||||
await this.assetRepository.update({ id: asset.id }, { webpPath: webpPath });
|
await sharp(asset.resizePath).resize(250).webp().rotate().toFile(webpPath);
|
||||||
|
await this.assetRepository.update({ id: asset.id }, { webpPath: webpPath });
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error('Failed to generate webp thumbnail for asset: ' + asset.id);
|
||||||
|
|
||||||
|
if (this.logLevel == ImmichLogLevel.VERBOSE) {
|
||||||
|
console.trace('Failed to generate webp thumbnail for asset', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,5 +16,6 @@ export const immichAppConfig: ConfigModuleOptions = {
|
||||||
then: Joi.string().optional().allow(null, ''),
|
then: Joi.string().optional().allow(null, ''),
|
||||||
otherwise: Joi.string().required(),
|
otherwise: Joi.string().required(),
|
||||||
}),
|
}),
|
||||||
|
LOG_LEVEL: Joi.string().optional().valid('simple', 'verbose').default('simple'),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
4
server/libs/common/src/constants/log-level.constant.ts
Normal file
4
server/libs/common/src/constants/log-level.constant.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
export enum ImmichLogLevel {
|
||||||
|
SIMPLE = 'simple',
|
||||||
|
VERBOSE = 'verbose',
|
||||||
|
}
|
Loading…
Reference in a new issue