1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2024-12-28 22:51:59 +00:00

fix(server): otel not working due to port conflicts after combining containers (#10078)

fix: otel not working due to port conflicts after combining containers

Fixes #9759
This commit is contained in:
Zack Pollard 2024-06-10 17:01:04 +01:00 committed by GitHub
parent 20efd82461
commit 2f2aecfb47
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 44 additions and 26 deletions

View file

@ -3,10 +3,10 @@ global:
evaluation_interval: 15s evaluation_interval: 15s
scrape_configs: scrape_configs:
- job_name: immich_server - job_name: immich_api
static_configs: static_configs:
- targets: ['immich-server:8081'] - targets: ['immich-server:8081']
- job_name: immich_microservices - job_name: immich_microservices
static_configs: static_configs:
- targets: ['immich-microservices:8081'] - targets: ['immich-server:8082']

View file

@ -374,7 +374,8 @@ export const immichAppConfig: ConfigModuleOptions = {
DB_SKIP_MIGRATIONS: Joi.boolean().optional().default(false), DB_SKIP_MIGRATIONS: Joi.boolean().optional().default(false),
IMMICH_PORT: Joi.number().optional(), IMMICH_PORT: Joi.number().optional(),
IMMICH_METRICS_PORT: Joi.number().optional(), IMMICH_API_METRICS_PORT: Joi.number().optional(),
IMMICH_MICROSERVICES_METRICS_PORT: Joi.number().optional(),
IMMICH_METRICS: Joi.boolean().optional().default(false), IMMICH_METRICS: Joi.boolean().optional().default(false),
IMMICH_HOST_METRICS: Joi.boolean().optional().default(false), IMMICH_HOST_METRICS: Joi.boolean().optional().default(false),

View file

@ -17,7 +17,7 @@ import { StorageService } from 'src/services/storage.service';
import { SystemConfigService } from 'src/services/system-config.service'; import { SystemConfigService } from 'src/services/system-config.service';
import { UserService } from 'src/services/user.service'; import { UserService } from 'src/services/user.service';
import { VersionService } from 'src/services/version.service'; import { VersionService } from 'src/services/version.service';
import { otelSDK } from 'src/utils/instrumentation'; import { otelShutdown } from 'src/utils/instrumentation';
@Injectable() @Injectable()
export class MicroservicesService { export class MicroservicesService {
@ -102,6 +102,6 @@ export class MicroservicesService {
async teardown() { async teardown() {
await this.libraryService.teardown(); await this.libraryService.teardown();
await this.metadataService.teardown(); await this.metadataService.teardown();
await otelSDK.shutdown(); await otelShutdown();
} }
} }

View file

@ -33,23 +33,36 @@ const aggregation = new metrics.ExplicitBucketHistogramAggregation(
true, true,
); );
const metricsPort = Number.parseInt(process.env.IMMICH_METRICS_PORT ?? '8081'); let otelSingleton: NodeSDK | undefined;
export const otelSDK = new NodeSDK({ export const otelStart = (port: number) => {
resource: new resources.Resource({ if (otelSingleton) {
[SemanticResourceAttributes.SERVICE_NAME]: `immich`, throw new Error('OpenTelemetry SDK already started');
[SemanticResourceAttributes.SERVICE_VERSION]: serverVersion.toString(), }
}), otelSingleton = new NodeSDK({
metricReader: new PrometheusExporter({ port: metricsPort }), resource: new resources.Resource({
contextManager: new AsyncLocalStorageContextManager(), [SemanticResourceAttributes.SERVICE_NAME]: `immich`,
instrumentations: [ [SemanticResourceAttributes.SERVICE_VERSION]: serverVersion.toString(),
new HttpInstrumentation(), }),
new IORedisInstrumentation(), metricReader: new PrometheusExporter({ port }),
new NestInstrumentation(), contextManager: new AsyncLocalStorageContextManager(),
new PgInstrumentation(), instrumentations: [
], new HttpInstrumentation(),
views: [new metrics.View({ aggregation, instrumentName: '*', instrumentUnit: 'ms' })], new IORedisInstrumentation(),
}); new NestInstrumentation(),
new PgInstrumentation(),
],
views: [new metrics.View({ aggregation, instrumentName: '*', instrumentUnit: 'ms' })],
});
otelSingleton.start();
};
export const otelShutdown = async () => {
if (otelSingleton) {
await otelSingleton.shutdown();
otelSingleton = undefined;
}
};
export const otelConfig: OpenTelemetryModuleOptions = { export const otelConfig: OpenTelemetryModuleOptions = {
metrics: { metrics: {

View file

@ -9,14 +9,16 @@ import { envName, excludePaths, isDev, serverVersion, WEB_ROOT } from 'src/const
import { ILoggerRepository } from 'src/interfaces/logger.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { WebSocketAdapter } from 'src/middleware/websocket.adapter'; import { WebSocketAdapter } from 'src/middleware/websocket.adapter';
import { ApiService } from 'src/services/api.service'; import { ApiService } from 'src/services/api.service';
import { otelSDK } from 'src/utils/instrumentation'; import { otelStart } from 'src/utils/instrumentation';
import { useSwagger } from 'src/utils/misc'; import { useSwagger } from 'src/utils/misc';
const host = process.env.HOST; const host = process.env.HOST;
async function bootstrap() { async function bootstrap() {
process.title = 'immich-api'; process.title = 'immich-api';
otelSDK.start(); const otelPort = Number.parseInt(process.env.IMMICH_API_METRICS_PORT ?? '8081');
otelStart(otelPort);
const port = Number(process.env.IMMICH_PORT) || 3001; const port = Number(process.env.IMMICH_PORT) || 3001;
const app = await NestFactory.create<NestExpressApplication>(ApiModule, { bufferLogs: true }); const app = await NestFactory.create<NestExpressApplication>(ApiModule, { bufferLogs: true });

View file

@ -4,10 +4,12 @@ import { MicroservicesModule } from 'src/app.module';
import { envName, serverVersion } from 'src/constants'; import { envName, serverVersion } from 'src/constants';
import { ILoggerRepository } from 'src/interfaces/logger.interface'; import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { WebSocketAdapter } from 'src/middleware/websocket.adapter'; import { WebSocketAdapter } from 'src/middleware/websocket.adapter';
import { otelSDK } from 'src/utils/instrumentation'; import { otelStart } from 'src/utils/instrumentation';
export async function bootstrap() { export async function bootstrap() {
otelSDK.start(); const otelPort = Number.parseInt(process.env.IMMICH_MICROSERVICES_METRICS_PORT ?? '8082');
otelStart(otelPort);
const app = await NestFactory.create(MicroservicesModule, { bufferLogs: true }); const app = await NestFactory.create(MicroservicesModule, { bufferLogs: true });
const logger = await app.resolve(ILoggerRepository); const logger = await app.resolve(ILoggerRepository);