add invalid captcha and messageChannel sync status health monitoring (#10029)

Context : 
We want to implement some counters to monitor server health. First
counters will track : messageChannel sync status during job execution
and invalid captcha.

How : 
Counters are stored in cache and grouped by one-minute windows.
Controllers are created for each metric, aggregating counter over a
five-minutes window.
Endpoints are public and will be queried by Prometheus.

closes https://github.com/twentyhq/core-team-issues/issues/55
This commit is contained in:
Etienne
2025-02-10 12:24:42 +01:00
committed by GitHub
parent e70e69cf94
commit d4ffd52988
12 changed files with 213 additions and 4 deletions

View File

@ -2,6 +2,7 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { HealthModule } from 'src/engine/core-modules/health/health.module';
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
import { ConnectedAccountModule } from 'src/modules/connected-account/connected-account.module';
import { MessageChannelSyncStatusService } from 'src/modules/messaging/common/services/message-channel-sync-status.service';
@ -11,6 +12,7 @@ import { MessageChannelSyncStatusService } from 'src/modules/messaging/common/se
WorkspaceDataSourceModule,
TypeOrmModule.forFeature([FeatureFlag], 'core'),
ConnectedAccountModule,
HealthModule,
],
providers: [MessageChannelSyncStatusService],
exports: [MessageChannelSyncStatusService],

View File

@ -5,6 +5,7 @@ import { Any } from 'typeorm';
import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator';
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
import { HealthCacheService } from 'src/engine/core-modules/health/health-cache.service';
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
import { AccountsToReconnectService } from 'src/modules/connected-account/services/accounts-to-reconnect.service';
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
@ -22,6 +23,7 @@ export class MessageChannelSyncStatusService {
private readonly cacheStorage: CacheStorageService,
private readonly twentyORMManager: TwentyORMManager,
private readonly accountsToReconnectService: AccountsToReconnectService,
private readonly healthCacheService: HealthCacheService,
) {}
public async scheduleFullMessageListFetch(messageChannelIds: string[]) {
@ -127,6 +129,11 @@ export class MessageChannelSyncStatusService {
syncStatus: MessageChannelSyncStatus.ONGOING,
syncStageStartedAt: new Date().toISOString(),
});
await this.healthCacheService.incrementMessageChannelSyncJobByStatusCounter(
MessageChannelSyncStatus.ONGOING,
messageChannelIds.length,
);
}
public async markAsCompletedAndSchedulePartialMessageListFetch(
@ -148,6 +155,11 @@ export class MessageChannelSyncStatusService {
syncStageStartedAt: null,
syncedAt: new Date().toISOString(),
});
await this.healthCacheService.incrementMessageChannelSyncJobByStatusCounter(
MessageChannelSyncStatus.ACTIVE,
messageChannelIds.length,
);
}
public async markAsMessagesImportOngoing(messageChannelIds: string[]) {
@ -189,6 +201,11 @@ export class MessageChannelSyncStatusService {
syncStage: MessageChannelSyncStage.FAILED,
syncStatus: MessageChannelSyncStatus.FAILED_UNKNOWN,
});
await this.healthCacheService.incrementMessageChannelSyncJobByStatusCounter(
MessageChannelSyncStatus.FAILED_UNKNOWN,
messageChannelIds.length,
);
}
public async markAsFailedInsufficientPermissionsAndFlushMessagesToImport(
@ -215,6 +232,11 @@ export class MessageChannelSyncStatusService {
syncStatus: MessageChannelSyncStatus.FAILED_INSUFFICIENT_PERMISSIONS,
});
await this.healthCacheService.incrementMessageChannelSyncJobByStatusCounter(
MessageChannelSyncStatus.FAILED_INSUFFICIENT_PERMISSIONS,
messageChannelIds.length,
);
const connectedAccountRepository =
await this.twentyORMManager.getRepository<ConnectedAccountWorkspaceEntity>(
'connectedAccount',