diff --git a/packages/entity/src/EntityCompanionProvider.ts b/packages/entity/src/EntityCompanionProvider.ts index b0bc0cd8..7ee52612 100644 --- a/packages/entity/src/EntityCompanionProvider.ts +++ b/packages/entity/src/EntityCompanionProvider.ts @@ -211,7 +211,8 @@ export default class EntityCompanionProvider { > ): EntityCompanion { const tableDataCoordinator = this.getTableDataCoordinatorForEntity( - entityCompanionDefinition.entityConfiguration + entityCompanionDefinition.entityConfiguration, + entityClass.name ); return computeIfAbsent(this.companionMap, entityClass.name, () => { return new EntityCompanion( @@ -226,7 +227,8 @@ export default class EntityCompanionProvider { } private getTableDataCoordinatorForEntity( - entityConfiguration: EntityConfiguration + entityConfiguration: EntityConfiguration, + entityClassName: string ): EntityTableDataCoordinator { return computeIfAbsent(this.tableDataCoordinatorMap, entityConfiguration.tableName, () => { const entityDatabaseAdapterFlavor = this.databaseAdapterFlavors[ @@ -240,7 +242,8 @@ export default class EntityCompanionProvider { entityDatabaseAdapterFlavor.adapterProvider, entityCacheAdapterFlavor.cacheAdapterProvider, entityDatabaseAdapterFlavor.queryContextProvider, - this.metricsAdapter + this.metricsAdapter, + entityClassName ); }); } diff --git a/packages/entity/src/EntityMutator.ts b/packages/entity/src/EntityMutator.ts index cbc8d850..606c31aa 100644 --- a/packages/entity/src/EntityMutator.ts +++ b/packages/entity/src/EntityMutator.ts @@ -146,7 +146,8 @@ export class CreateMutator< async createAsync(): Promise> { return await timeAndLogMutationEventAsync( this.metricsAdapter, - EntityMetricsMutationType.CREATE + EntityMetricsMutationType.CREATE, + this.entityClass.name )(this.createInTransactionAsync()); } @@ -329,7 +330,8 @@ export class UpdateMutator< async updateAsync(): Promise> { return await timeAndLogMutationEventAsync( this.metricsAdapter, - EntityMetricsMutationType.UPDATE + EntityMetricsMutationType.UPDATE, + this.entityClass.name )(this.updateInTransactionAsync()); } @@ -498,7 +500,8 @@ export class DeleteMutator< async deleteAsync(): Promise> { return await timeAndLogMutationEventAsync( this.metricsAdapter, - EntityMetricsMutationType.DELETE + EntityMetricsMutationType.DELETE, + this.entityClass.name )(this.deleteInTransactionAsync()); } diff --git a/packages/entity/src/__tests__/EntityLoader-test.ts b/packages/entity/src/__tests__/EntityLoader-test.ts index 66a67ade..9065036f 100644 --- a/packages/entity/src/__tests__/EntityLoader-test.ts +++ b/packages/entity/src/__tests__/EntityLoader-test.ts @@ -57,7 +57,8 @@ describe(EntityLoader, () => { databaseAdapter, entityCache, StubQueryContextProvider, - instance(mock()) + instance(mock()), + TestEntity.name ); const entityLoader = new EntityLoader( viewerContext, @@ -138,7 +139,8 @@ describe(EntityLoader, () => { databaseAdapter, entityCache, StubQueryContextProvider, - instance(mock()) + instance(mock()), + TestEntity.name ); const entityLoader = new EntityLoader( viewerContext, @@ -200,7 +202,8 @@ describe(EntityLoader, () => { databaseAdapter, entityCache, StubQueryContextProvider, - instance(mock()) + instance(mock()), + TestEntity.name ); const entityLoader = new EntityLoader( viewerContext, diff --git a/packages/entity/src/__tests__/EntityMutator-test.ts b/packages/entity/src/__tests__/EntityMutator-test.ts index 1bff02e0..dccab683 100644 --- a/packages/entity/src/__tests__/EntityMutator-test.ts +++ b/packages/entity/src/__tests__/EntityMutator-test.ts @@ -269,7 +269,8 @@ const createEntityMutatorFactory = ( databaseAdapter, entityCache, StubQueryContextProvider, - metricsAdapter + metricsAdapter, + TestEntity.name ); const entityLoaderFactory = new EntityLoaderFactory( testEntityConfiguration.idField, @@ -930,6 +931,7 @@ describe(EntityMutatorFactory, () => { spiedMetricsAdapter.logMutatorMutationEvent( objectContaining({ type: EntityMetricsMutationType.CREATE, + entityClassName: TestEntity.name, }) ) ).once(); @@ -937,6 +939,7 @@ describe(EntityMutatorFactory, () => { spiedMetricsAdapter.logMutatorMutationEvent( objectContaining({ type: EntityMetricsMutationType.UPDATE, + entityClassName: TestEntity.name, }) ) ).once(); @@ -944,6 +947,7 @@ describe(EntityMutatorFactory, () => { spiedMetricsAdapter.logMutatorMutationEvent( objectContaining({ type: EntityMetricsMutationType.DELETE, + entityClassName: TestEntity.name, }) ) ).once(); diff --git a/packages/entity/src/internal/EntityDataManager.ts b/packages/entity/src/internal/EntityDataManager.ts index 2932e3c2..d418a3bd 100644 --- a/packages/entity/src/internal/EntityDataManager.ts +++ b/packages/entity/src/internal/EntityDataManager.ts @@ -31,7 +31,8 @@ export default class EntityDataManager { private readonly databaseAdapter: EntityDatabaseAdapter, private readonly entityCache: ReadThroughEntityCache, private readonly queryContextProvider: EntityQueryContextProvider, - private readonly metricsAdapter: IEntityMetricsAdapter + private readonly metricsAdapter: IEntityMetricsAdapter, + private readonly entityClassName: string ) {} private getFieldDataLoaderForFieldName( @@ -86,7 +87,8 @@ export default class EntityDataManager { ): Promise, readonly Readonly[]>> { return await timeAndLogLoadMapEventAsync( this.metricsAdapter, - EntityMetricsLoadType.LOAD_MANY + EntityMetricsLoadType.LOAD_MANY, + this.entityClassName )(this.loadManyByFieldEqualingInternalAsync(queryContext, fieldName, fieldValues)); } @@ -127,7 +129,8 @@ export default class EntityDataManager { ): Promise[]> { return await timeAndLogLoadEventAsync( this.metricsAdapter, - EntityMetricsLoadType.LOAD_MANY_EQUALITY_CONJUNCTION + EntityMetricsLoadType.LOAD_MANY_EQUALITY_CONJUNCTION, + this.entityClassName )( this.databaseAdapter.fetchManyByFieldEqualityConjunctionAsync( queryContext, @@ -154,7 +157,8 @@ export default class EntityDataManager { ): Promise[]> { return await timeAndLogLoadEventAsync( this.metricsAdapter, - EntityMetricsLoadType.LOAD_MANY_RAW + EntityMetricsLoadType.LOAD_MANY_RAW, + this.entityClassName )( this.databaseAdapter.fetchManyByRawWhereClauseAsync( queryContext, diff --git a/packages/entity/src/internal/EntityTableDataCoordinator.ts b/packages/entity/src/internal/EntityTableDataCoordinator.ts index e275b135..1ccc07db 100644 --- a/packages/entity/src/internal/EntityTableDataCoordinator.ts +++ b/packages/entity/src/internal/EntityTableDataCoordinator.ts @@ -23,7 +23,8 @@ export default class EntityTableDataCoordinator { databaseAdapterProvider: IEntityDatabaseAdapterProvider, cacheAdapterProvider: IEntityCacheAdapterProvider, private readonly queryContextProvider: EntityQueryContextProvider, - metricsAdapter: IEntityMetricsAdapter + metricsAdapter: IEntityMetricsAdapter, + entityClassName: string ) { this.databaseAdapter = databaseAdapterProvider.getDatabaseAdapter(entityConfiguration); this.cacheAdapter = cacheAdapterProvider.getCacheAdapter(entityConfiguration); @@ -31,7 +32,8 @@ export default class EntityTableDataCoordinator { this.databaseAdapter, new ReadThroughEntityCache(entityConfiguration, this.cacheAdapter), queryContextProvider, - metricsAdapter + metricsAdapter, + entityClassName ); } diff --git a/packages/entity/src/internal/__tests__/EntityDataManager-test.ts b/packages/entity/src/internal/__tests__/EntityDataManager-test.ts index 64c27226..ec837708 100644 --- a/packages/entity/src/internal/__tests__/EntityDataManager-test.ts +++ b/packages/entity/src/internal/__tests__/EntityDataManager-test.ts @@ -14,7 +14,7 @@ import { import EntityDatabaseAdapter from '../../EntityDatabaseAdapter'; import IEntityMetricsAdapter, { EntityMetricsLoadType } from '../../metrics/IEntityMetricsAdapter'; import NoOpEntityMetricsAdapter from '../../metrics/NoOpEntityMetricsAdapter'; -import { testEntityConfiguration, TestFields } from '../../testfixtures/TestEntity'; +import TestEntity, { testEntityConfiguration, TestFields } from '../../testfixtures/TestEntity'; import { NoCacheStubCacheAdapterProvider, InMemoryFullCacheStubCacheAdapterProvider, @@ -69,7 +69,8 @@ describe(EntityDataManager, () => { databaseAdapter, entityCache, StubQueryContextProvider, - new NoOpEntityMetricsAdapter() + new NoOpEntityMetricsAdapter(), + TestEntity.name ); const queryContext = StubQueryContextProvider.getQueryContext(); @@ -116,7 +117,8 @@ describe(EntityDataManager, () => { databaseAdapter, entityCache, StubQueryContextProvider, - new NoOpEntityMetricsAdapter() + new NoOpEntityMetricsAdapter(), + TestEntity.name ); const queryContext = StubQueryContextProvider.getQueryContext(); @@ -163,7 +165,8 @@ describe(EntityDataManager, () => { databaseAdapter, entityCache, StubQueryContextProvider, - new NoOpEntityMetricsAdapter() + new NoOpEntityMetricsAdapter(), + TestEntity.name ); const queryContext = StubQueryContextProvider.getQueryContext(); // use second data manager to ensure that cache is hit instead of data loader @@ -171,7 +174,8 @@ describe(EntityDataManager, () => { databaseAdapter, entityCache, StubQueryContextProvider, - new NoOpEntityMetricsAdapter() + new NoOpEntityMetricsAdapter(), + TestEntity.name ); const dbSpy = jest.spyOn(databaseAdapter, 'fetchManyWhereAsync'); @@ -205,7 +209,8 @@ describe(EntityDataManager, () => { databaseAdapter, entityCache, StubQueryContextProvider, - new NoOpEntityMetricsAdapter() + new NoOpEntityMetricsAdapter(), + TestEntity.name ); const queryContext = StubQueryContextProvider.getQueryContext(); @@ -240,7 +245,8 @@ describe(EntityDataManager, () => { databaseAdapter, entityCache, StubQueryContextProvider, - new NoOpEntityMetricsAdapter() + new NoOpEntityMetricsAdapter(), + TestEntity.name ); const queryContext = StubQueryContextProvider.getQueryContext(); @@ -283,7 +289,8 @@ describe(EntityDataManager, () => { databaseAdapter, entityCache, StubQueryContextProvider, - new NoOpEntityMetricsAdapter() + new NoOpEntityMetricsAdapter(), + TestEntity.name ); const queryContext = StubQueryContextProvider.getQueryContext(); @@ -321,7 +328,8 @@ describe(EntityDataManager, () => { databaseAdapter, entityCache, StubQueryContextProvider, - new NoOpEntityMetricsAdapter() + new NoOpEntityMetricsAdapter(), + TestEntity.name ); const queryContext = StubQueryContextProvider.getQueryContext(); @@ -359,7 +367,8 @@ describe(EntityDataManager, () => { databaseAdapter, entityCache, StubQueryContextProvider, - new NoOpEntityMetricsAdapter() + new NoOpEntityMetricsAdapter(), + TestEntity.name ); const dbSpy = jest.spyOn(databaseAdapter, 'fetchManyWhereAsync'); @@ -396,7 +405,8 @@ describe(EntityDataManager, () => { databaseAdapter, entityCache, StubQueryContextProvider, - new NoOpEntityMetricsAdapter() + new NoOpEntityMetricsAdapter(), + TestEntity.name ); const queryContext = StubQueryContextProvider.getQueryContext(); @@ -441,7 +451,8 @@ describe(EntityDataManager, () => { databaseAdapter, entityCache, StubQueryContextProvider, - new NoOpEntityMetricsAdapter() + new NoOpEntityMetricsAdapter(), + TestEntity.name ); const queryContext = StubQueryContextProvider.getQueryContext(); @@ -467,7 +478,8 @@ describe(EntityDataManager, () => { databaseAdapter, entityCache, StubQueryContextProvider, - metricsAdapter + metricsAdapter, + TestEntity.name ); const queryContext = StubQueryContextProvider.getQueryContext(); @@ -476,6 +488,7 @@ describe(EntityDataManager, () => { metricsAdapterMock.logDataManagerLoadEvent( objectContaining({ type: EntityMetricsLoadType.LOAD_MANY, + entityClassName: TestEntity.name, count: 1, }) ) @@ -495,6 +508,7 @@ describe(EntityDataManager, () => { metricsAdapterMock.logDataManagerLoadEvent( objectContaining({ type: EntityMetricsLoadType.LOAD_MANY_EQUALITY_CONJUNCTION, + entityClassName: TestEntity.name, count: 1, }) ) @@ -520,6 +534,7 @@ describe(EntityDataManager, () => { metricsAdapterMock.logDataManagerLoadEvent( objectContaining({ type: EntityMetricsLoadType.LOAD_MANY_RAW, + entityClassName: TestEntity.name, count: 0, }) ) diff --git a/packages/entity/src/metrics/EntityMetricsUtils.ts b/packages/entity/src/metrics/EntityMetricsUtils.ts index f83208fc..744d00de 100644 --- a/packages/entity/src/metrics/EntityMetricsUtils.ts +++ b/packages/entity/src/metrics/EntityMetricsUtils.ts @@ -6,7 +6,8 @@ import IEntityMetricsAdapter, { export const timeAndLogLoadEventAsync = ( metricsAdapter: IEntityMetricsAdapter, - loadType: EntityMetricsLoadType + loadType: EntityMetricsLoadType, + entityClassName: string ) => async (promise: Promise[]>) => { const startTime = Date.now(); const result = await promise; @@ -14,6 +15,7 @@ export const timeAndLogLoadEventAsync = ( metricsAdapter.logDataManagerLoadEvent({ type: loadType, + entityClassName, duration: endTime - startTime, count: result.length, }); @@ -23,7 +25,8 @@ export const timeAndLogLoadEventAsync = ( export const timeAndLogLoadMapEventAsync = ( metricsAdapter: IEntityMetricsAdapter, - loadType: EntityMetricsLoadType + loadType: EntityMetricsLoadType, + entityClassName: string ) => async ( promise: Promise, readonly Readonly[]>> ) => { @@ -35,6 +38,7 @@ export const timeAndLogLoadMapEventAsync = ( metricsAdapter.logDataManagerLoadEvent({ type: loadType, + entityClassName, duration: endTime - startTime, count, }); @@ -44,7 +48,8 @@ export const timeAndLogLoadMapEventAsync = ( export const timeAndLogMutationEventAsync = ( metricsAdapter: IEntityMetricsAdapter, - mutationType: EntityMetricsMutationType + mutationType: EntityMetricsMutationType, + entityClassName: string ) => async (promise: Promise) => { const startTime = Date.now(); const result = await promise; @@ -52,6 +57,7 @@ export const timeAndLogMutationEventAsync = ( metricsAdapter.logMutatorMutationEvent({ type: mutationType, + entityClassName, duration: endTime - startTime, }); diff --git a/packages/entity/src/metrics/IEntityMetricsAdapter.ts b/packages/entity/src/metrics/IEntityMetricsAdapter.ts index 32dd917a..604dddcc 100644 --- a/packages/entity/src/metrics/IEntityMetricsAdapter.ts +++ b/packages/entity/src/metrics/IEntityMetricsAdapter.ts @@ -6,6 +6,7 @@ export enum EntityMetricsLoadType { export interface EntityMetricsLoadEvent { type: EntityMetricsLoadType; + entityClassName: string; duration: number; count: number; } @@ -18,6 +19,7 @@ export enum EntityMetricsMutationType { export interface EntityMetricsMutationEvent { type: EntityMetricsMutationType; + entityClassName: string; duration: number; }