From 202b00c4174886e9e098d49216ecd0f1321a4e9e Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Tue, 4 May 2021 16:28:24 +0530 Subject: [PATCH 01/25] feat: fetching log records and showing log icon --- .../distributed-tracing/src/public-api.ts | 1 + .../components/span-detail/span-data.ts | 3 ++ .../trace-waterfall-data-source.model.test.ts | 34 +++++++++++++++++++ .../trace-waterfall-data-source.model.ts | 16 +++++++-- .../span-name/span-name-cell-data.ts | 1 + ...an-name-table-cell-renderer.component.scss | 6 +++- ...name-table-cell-renderer.component.test.ts | 11 ++++++ ...span-name-table-cell-renderer.component.ts | 7 ++++ .../waterfall/waterfall-chart.service.ts | 3 +- .../waterfall/waterfall/waterfall-chart.ts | 10 ++++++ .../trace-graphql-query-handler.service.ts | 22 ++++++++++-- ...-trace-waterfall-data-source.model.test.ts | 34 +++++++++++++++++++ .../api-trace-waterfall-data-source.model.ts | 11 +++++- 13 files changed, 151 insertions(+), 8 deletions(-) diff --git a/projects/distributed-tracing/src/public-api.ts b/projects/distributed-tracing/src/public-api.ts index 523fd1306..327e12e1f 100644 --- a/projects/distributed-tracing/src/public-api.ts +++ b/projects/distributed-tracing/src/public-api.ts @@ -102,6 +102,7 @@ export { WaterfallData } from './shared/dashboard/widgets/waterfall/waterfall/wa export { TraceWaterfallDataSourceModel } from './shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model'; export { traceDetailDashboard } from './pages/trace-detail/trace-detail.dashboard'; export { TraceDetailPageComponent } from './pages/trace-detail/trace-detail.page.component'; +export { LogEvent } from './shared/dashboard/widgets/waterfall/waterfall/waterfall-chart'; // Datasources export * from './shared/dashboard/widgets/trace-detail/data/trace-detail-data-source.model'; diff --git a/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts b/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts index 94100c3e8..1cfbe7686 100644 --- a/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts +++ b/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts @@ -1,4 +1,5 @@ import { Dictionary } from '@hypertrace/common'; +import { LogEvent } from '../../dashboard/widgets/waterfall/waterfall/waterfall-chart'; export interface SpanData { id: string; @@ -12,4 +13,6 @@ export interface SpanData { tags: Dictionary; requestUrl: string; exitCallsBreakup?: Dictionary; + startTime?: number; + logEvents?: LogEvent[]; } diff --git a/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.test.ts b/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.test.ts index db942fc88..6db824d68 100644 --- a/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.test.ts +++ b/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.test.ts @@ -96,6 +96,23 @@ describe('Trace Waterfall data source model', () => { expect.objectContaining({ name: 'errorCount' }) + ], + logEventProperties: [ + expect.objectContaining({ + name: 'traceId' + }), + expect.objectContaining({ + name: 'attributes' + }), + expect.objectContaining({ + name: 'timestamp' + }), + expect.objectContaining({ + name: 'spanId' + }), + expect.objectContaining({ + name: 'summary' + }) ] } }); @@ -156,6 +173,23 @@ describe('Trace Waterfall data source model', () => { expect.objectContaining({ name: 'errorCount' }) + ], + logEventProperties: [ + expect.objectContaining({ + name: 'traceId' + }), + expect.objectContaining({ + name: 'attributes' + }), + expect.objectContaining({ + name: 'timestamp' + }), + expect.objectContaining({ + name: 'spanId' + }), + expect.objectContaining({ + name: 'summary' + }) ] } }); diff --git a/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts b/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts index 1f6c399c1..d25e7448d 100644 --- a/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts +++ b/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts @@ -13,7 +13,7 @@ import { TRACE_GQL_REQUEST } from '../../../../graphql/request/handlers/traces/trace-graphql-query-handler.service'; import { MetadataService } from '../../../../services/metadata/metadata.service'; -import { WaterfallData } from '../../../widgets/waterfall/waterfall/waterfall-chart'; +import { LogEvent, WaterfallData } from '../../../widgets/waterfall/waterfall/waterfall-chart'; import { GraphQlDataSourceModel } from '../graphql-data-source.model'; @Model({ @@ -60,6 +60,14 @@ export class TraceWaterfallDataSourceModel extends GraphQlDataSourceModel { return combineLatest([this.getTraceData(), this.getDurationAttribute()]).pipe( map(combinedData => this.mapResponseObject(combinedData[0], combinedData[1])) @@ -73,7 +81,8 @@ export class TraceWaterfallDataSourceModel extends GraphQlDataSourceModel, - errorCount: span.errorCount as number + errorCount: span.errorCount as number, + logEvents: ((span.logEvents as Dictionary) ?? {}).results })); } } diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-cell-data.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-cell-data.ts index 98d5863ca..79bc000dc 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-cell-data.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-cell-data.ts @@ -4,4 +4,5 @@ export interface SpanNameCellData { apiName?: string; color?: string; hasError?: boolean; + hasLogs?: boolean; } diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-table-cell-renderer.component.scss b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-table-cell-renderer.component.scss index 512260542..874d26418 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-table-cell-renderer.component.scss +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-table-cell-renderer.component.scss @@ -7,7 +7,7 @@ .span-title { display: grid; - grid-template-columns: 3px min-content min-content min-content auto; + grid-template-columns: 3px min-content min-content min-content min-content auto; grid-template-rows: 1fr; column-gap: 4px; @@ -41,6 +41,10 @@ .text { @include ellipsis-overflow(); } + + .log-icon { + margin: auto 0; + } } .clickable { diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-table-cell-renderer.component.test.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-table-cell-renderer.component.test.ts index 626747f60..71b39664a 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-table-cell-renderer.component.test.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-table-cell-renderer.component.test.ts @@ -61,4 +61,15 @@ describe('Span name table cell renderer component', () => { expect(spectator.query('.color-bar')).toExist(); expect(spectator.query('.error-icon')).toExist(); }); + + test('should render log icon ', () => { + const spanNameDataWithColor = { + ...spanNameData, + hasLogs: true + }; + const spectator = buildComponent({ + providers: [tableCellDataProvider(spanNameDataWithColor)] + }); + expect(spectator.query('.log-icon')).toExist(); + }); }); diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-table-cell-renderer.component.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-table-cell-renderer.component.ts index d310aa23b..4b8a61189 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-table-cell-renderer.component.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/span-name/span-name-table-cell-renderer.component.ts @@ -28,6 +28,13 @@ import { WaterfallTableCellType } from './span-name-cell-type'; size="${IconSize.Medium}" color="${Color.Red5}" > + ` }) diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.service.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.service.ts index 142813a93..0d7ae6748 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.service.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.service.ts @@ -42,7 +42,8 @@ export class WaterfallChartService { apiName: datum.apiName, serviceName: datum.serviceName, protocolName: datum.protocolName, - hasError: datum.errorCount > 0 + hasError: datum.errorCount > 0, + hasLogs: datum.logEvents && datum.logEvents.length > 0 }, $$iconType: this.iconLookupService.forSpanType(datum.spanType)!, getChildren: () => of([]), diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts index e05b239ad..4e2d76ca3 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts @@ -23,6 +23,7 @@ export interface WaterfallData { responseBody?: string; tags: Dictionary; errorCount: number; + logEvents?: LogEvent[]; } export interface WaterfallDataNode extends WaterfallData, Omit { @@ -37,3 +38,12 @@ export interface WaterfallChartState { children: WaterfallDataNode[]; expanded: boolean; } + +export interface LogEvent { + [key: string]: unknown; + traceId?: string; + spanId?: string; + attributes?: Dictionary; + timestamp?: string; + summary?: string; +} diff --git a/projects/distributed-tracing/src/shared/graphql/request/handlers/traces/trace-graphql-query-handler.service.ts b/projects/distributed-tracing/src/shared/graphql/request/handlers/traces/trace-graphql-query-handler.service.ts index 0c3a65478..7c4c9aa4d 100644 --- a/projects/distributed-tracing/src/shared/graphql/request/handlers/traces/trace-graphql-query-handler.service.ts +++ b/projects/distributed-tracing/src/shared/graphql/request/handlers/traces/trace-graphql-query-handler.service.ts @@ -73,7 +73,23 @@ export class TraceGraphQlQueryHandlerService implements GraphQlQueryHandler { const span: Span = { - [spanIdKey]: spanRawResult.id as string + [spanIdKey]: spanRawResult.id as string, + ...(!isEmpty(spanRawResult.logEvents) && { logEvents: spanRawResult.logEvents }) }; (request.spanProperties || []).forEach(property => { @@ -175,6 +192,7 @@ export interface GraphQlTraceRequest { spanLimit: number; spanId?: string; spanProperties?: Specification[]; + logEventProperties?: Specification[]; } interface TraceServerResponse { diff --git a/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.test.ts b/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.test.ts index 220d76c55..4e5beb29c 100644 --- a/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.test.ts +++ b/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.test.ts @@ -102,6 +102,23 @@ describe('Api Trace Waterfall data source model', () => { expect.objectContaining({ name: 'errorCount' }) + ], + logEventProperties: [ + expect.objectContaining({ + name: 'traceId' + }), + expect.objectContaining({ + name: 'attributes' + }), + expect.objectContaining({ + name: 'timestamp' + }), + expect.objectContaining({ + name: 'spanId' + }), + expect.objectContaining({ + name: 'summary' + }) ] } }); @@ -163,6 +180,23 @@ describe('Api Trace Waterfall data source model', () => { expect.objectContaining({ name: 'errorCount' }) + ], + logEventProperties: [ + expect.objectContaining({ + name: 'traceId' + }), + expect.objectContaining({ + name: 'attributes' + }), + expect.objectContaining({ + name: 'timestamp' + }), + expect.objectContaining({ + name: 'spanId' + }), + expect.objectContaining({ + name: 'summary' + }) ] } }); diff --git a/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts b/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts index 26789a657..0c0f325a4 100644 --- a/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts +++ b/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts @@ -2,6 +2,7 @@ import { DateCoercer, Dictionary } from '@hypertrace/common'; import { AttributeMetadata, GraphQlDataSourceModel, + LogEvent, MetadataService, Span, spanIdKey, @@ -65,6 +66,10 @@ export class ApiTraceWaterfallDataSourceModel extends GraphQlDataSourceModel { return this.query({ requestType: TRACE_GQL_REQUEST, @@ -75,6 +80,9 @@ export class ApiTraceWaterfallDataSourceModel extends GraphQlDataSourceModel this.specificationBuilder.attributeSpecificationForKey(attribute) + ), + logEventProperties: this.getLogEventAttributes().map(attribute => + this.specificationBuilder.attributeSpecificationForKey(attribute) ) }); } @@ -108,7 +116,8 @@ export class ApiTraceWaterfallDataSourceModel extends GraphQlDataSourceModel, - errorCount: span.errorCount as number + errorCount: span.errorCount as number, + logEvents: ((span.logEvents as Dictionary) ?? {}).results }; } } From 2e7f58b0f915dc970fa37d5dd08a53d7bc68c347 Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Tue, 4 May 2021 16:45:14 +0530 Subject: [PATCH 02/25] feat: log detail widget and log timestamp table cell renderer components --- .../data/log-detail-data-source.model.test.ts | 26 +++++++ .../data/log-detail-data-source.model.ts | 21 ++++++ .../log-detail-widget-renderer.component.scss | 7 ++ .../log-detail-widget-renderer.component.ts | 41 +++++++++++ .../log-detail/log-detail-widget.model.ts | 17 +++++ .../log-detail/log-detail-widget.module.ts | 25 +++++++ .../tracing-dashboard-widgets.module.ts | 3 +- ...mestamp-table-cell-renderer.component.scss | 9 +++ ...tamp-table-cell-renderer.component.test.ts | 42 +++++++++++ ...timestamp-table-cell-renderer.component.ts | 69 +++++++++++++++++++ ...bservability-table-cell-renderer.module.ts | 6 +- .../table/observability-table-cell-type.ts | 3 +- 12 files changed, 265 insertions(+), 4 deletions(-) create mode 100644 projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts create mode 100644 projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.ts create mode 100644 projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.scss create mode 100644 projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts create mode 100644 projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.model.ts create mode 100644 projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.module.ts create mode 100644 projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.scss create mode 100644 projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.test.ts create mode 100644 projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts new file mode 100644 index 000000000..6e36d63a2 --- /dev/null +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts @@ -0,0 +1,26 @@ +import { createModelFactory, SpectatorModel } from '@hypertrace/dashboards/testing'; +import { runFakeRxjs } from '@hypertrace/test-utils'; +import { LogDetailDataSourceModel } from './log-detail-data-source.model'; + +describe('Log Detail data source model', () => { + let spectator!: SpectatorModel; + const buildModel = createModelFactory(); + spectator = buildModel(LogDetailDataSourceModel); + spectator.model.logEvent = { + attributes: { + key1: 'value1', + key2: 'value2' + } + }; + + test('test attribute data', () => { + runFakeRxjs(({ expectObservable }) => { + expectObservable(spectator.model.getData()).toBe('(x|)', { + x: expect.objectContaining({ + key1: 'value1', + key2: 'value2' + }) + }); + }); + }); +}); diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.ts new file mode 100644 index 000000000..45ee55a96 --- /dev/null +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.ts @@ -0,0 +1,21 @@ +import { Dictionary } from '@hypertrace/common'; +import { Model, ModelProperty, PLAIN_OBJECT_PROPERTY } from '@hypertrace/hyperdash'; +import { Observable, of } from 'rxjs'; +import { GraphQlDataSourceModel } from '../../../data/graphql/graphql-data-source.model'; +import { LogEvent } from '../../waterfall/waterfall/waterfall-chart'; + +@Model({ + type: 'log-detail-data-source' +}) +export class LogDetailDataSourceModel extends GraphQlDataSourceModel> { + @ModelProperty({ + key: 'log-event', + required: true, + type: PLAIN_OBJECT_PROPERTY.type + }) + public logEvent?: LogEvent; + + public getData(): Observable> { + return of(this.logEvent?.attributes ?? {}); + } +} diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.scss b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.scss new file mode 100644 index 000000000..a239d0190 --- /dev/null +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.scss @@ -0,0 +1,7 @@ +@import 'font'; + +.content { + @include body-2-regular(); + margin-left: 175px; + margin-top: 15px; +} diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts new file mode 100644 index 000000000..ee12a2afd --- /dev/null +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts @@ -0,0 +1,41 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { Dictionary } from '@hypertrace/common'; +import { ListViewHeader, ListViewRecord } from '@hypertrace/components'; +import { WidgetRenderer } from '@hypertrace/dashboards'; +import { Renderer } from '@hypertrace/hyperdash'; +import { Observable } from 'rxjs'; +import { LogDetailWidgetModel } from './log-detail-widget.model'; + +@Renderer({ modelClass: LogDetailWidgetModel }) +@Component({ + selector: 'ht-log-detail-widget-renderer', + styleUrls: ['./log-detail-widget-renderer.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + template: ` +
+ +
+ ` +}) +export class LogDetailWidgetRendererComponent extends WidgetRenderer> { + public readonly header: ListViewHeader = { keyLabel: 'key', valueLabel: 'value' }; + + protected fetchData(): Observable> { + return this.model.getData(); + } + + public getLogEventAttributeRecords(attributes: Dictionary): ListViewRecord[] { + if (Boolean(attributes)) { + return Object.entries(attributes).map((attribute: [string, unknown]) => ({ + key: attribute[0], + value: attribute[1] as string | number + })); + } + + return []; + } +} diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.model.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.model.ts new file mode 100644 index 000000000..f0653db48 --- /dev/null +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.model.ts @@ -0,0 +1,17 @@ +import { Dictionary } from '@hypertrace/common'; +import { Model, ModelApi } from '@hypertrace/hyperdash'; +import { ModelInject, MODEL_API } from '@hypertrace/hyperdash-angular'; +import { Observable } from 'rxjs'; + +@Model({ + type: 'log-detail-widget', + supportedDataSourceTypes: [] +}) +export class LogDetailWidgetModel { + @ModelInject(MODEL_API) + private readonly api!: ModelApi; + + public getData(): Observable> { + return this.api.getData>(); + } +} diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.module.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.module.ts new file mode 100644 index 000000000..6bd32a7d6 --- /dev/null +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.module.ts @@ -0,0 +1,25 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { ListViewModule, LoadAsyncModule, SummaryValueModule, TitledContentModule } from '@hypertrace/components'; +import { DashboardCoreModule } from '@hypertrace/hyperdash-angular'; +import { SpanDetailModule } from '../../../components/span-detail/span-detail.module'; +import { LogDetailDataSourceModel } from './data/log-detail-data-source.model'; +import { LogDetailWidgetRendererComponent } from './log-detail-widget-renderer.component'; +import { LogDetailWidgetModel } from './log-detail-widget.model'; + +@NgModule({ + declarations: [LogDetailWidgetRendererComponent], + imports: [ + DashboardCoreModule.with({ + models: [LogDetailWidgetModel, LogDetailDataSourceModel], + renderers: [LogDetailWidgetRendererComponent] + }), + CommonModule, + SpanDetailModule, + TitledContentModule, + ListViewModule, + LoadAsyncModule, + SummaryValueModule + ] +}) +export class LogDetailWidgetModule {} diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/tracing-dashboard-widgets.module.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/tracing-dashboard-widgets.module.ts index e48cf5a49..aea045b49 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/tracing-dashboard-widgets.module.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/tracing-dashboard-widgets.module.ts @@ -1,10 +1,11 @@ import { NgModule } from '@angular/core'; +import { LogDetailWidgetModule } from './log-detail/log-detail-widget.module'; import { SpanDetailWidgetModule } from './span-detail/span-detail-widget.module'; import { TableWidgetModule } from './table/table-widget.module'; import { TraceDetailModule } from './trace-detail/trace-detail-widget.module'; import { WaterfallWidgetModule } from './waterfall/waterfall-widget.module'; @NgModule({ - imports: [SpanDetailWidgetModule, TableWidgetModule, TraceDetailModule, WaterfallWidgetModule] + imports: [SpanDetailWidgetModule, LogDetailWidgetModule, TableWidgetModule, TraceDetailModule, WaterfallWidgetModule] }) export class TracingDashboardWidgetsModule {} diff --git a/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.scss b/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.scss new file mode 100644 index 000000000..261cec610 --- /dev/null +++ b/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.scss @@ -0,0 +1,9 @@ +@import 'font'; + +.log-timestamp { + @include ellipsis-overflow(); + + &.first-column { + @include body-1-medium($gray-9); + } +} diff --git a/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.test.ts b/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.test.ts new file mode 100644 index 000000000..bd30457be --- /dev/null +++ b/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.test.ts @@ -0,0 +1,42 @@ +import { + TableCellNoOpParser, + tableCellProviders, + tableCellRowDataProvider, + TooltipDirective +} from '@hypertrace/components'; +import { LogEvent } from '@hypertrace/distributed-tracing'; +import { createComponentFactory } from '@ngneat/spectator/jest'; +import { MockComponent } from 'ng-mocks'; +import { LogTimestampTableCellRendererComponent } from './log-timestamp-table-cell-renderer.component'; + +describe('log timestamp table cell renderer component', () => { + const buildComponent = createComponentFactory({ + component: LogTimestampTableCellRendererComponent, + providers: [ + tableCellProviders( + { + id: 'test' + }, + new TableCellNoOpParser(undefined!) + ) + ], + declarations: [MockComponent(TooltipDirective)], + shallow: true + }); + + test('testing component properties', () => { + const logEvent: LogEvent = { + timestamp: '2021-04-30T12:23:57.889149Z', + spanStartTime: 1619785437887 + }; + const spectator = buildComponent({ + providers: [tableCellRowDataProvider(logEvent)] + }); + + expect(spectator.queryAll('.log-timestamp')[0]).toContainText('2.89 ms'); + expect(spectator.component.spanStartTime).toBe(logEvent.spanStartTime); + expect(spectator.component.timestamp).toBe(logEvent.timestamp); + expect(spectator.component.duration).toBe('2.89 ms'); + expect(spectator.component.readableDateTime).toBe('2021/04/30 12:23:57.889'); + }); +}); diff --git a/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts b/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts new file mode 100644 index 000000000..658e446d2 --- /dev/null +++ b/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts @@ -0,0 +1,69 @@ +import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core'; +import { DateCoercer } from '@hypertrace/common'; +import { + CoreTableCellParserType, + TableCellAlignmentType, + TableCellParserBase, + TableCellRenderer, + TableCellRendererBase, + TableColumnConfig, + TABLE_CELL_DATA, + TABLE_COLUMN_CONFIG, + TABLE_COLUMN_INDEX, + TABLE_DATA_PARSER, + TABLE_ROW_DATA +} from '@hypertrace/components'; +import { LogEvent } from '@hypertrace/distributed-tracing'; +import { ObservabilityTableCellType } from '../../observability-table-cell-type'; + +@Component({ + selector: 'ht-log-timestamp-table-cell-renderer', + styleUrls: ['./log-timestamp-table-cell-renderer.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + template: ` +
+ {{ this.duration }} +
+ {{ this.readableDateTime }} + ` +}) +@TableCellRenderer({ + type: ObservabilityTableCellType.LogTimestamp, + alignment: TableCellAlignmentType.Left, + parser: CoreTableCellParserType.NoOp +}) +export class LogTimestampTableCellRendererComponent extends TableCellRendererBase implements OnInit { + public readonly spanStartTime: number; + public readonly timestamp?: string; + public readonly duration?: string; + public readonly readableDateTime?: string; + + private readonly dateCoercer = new DateCoercer(); + + public constructor( + @Inject(TABLE_COLUMN_CONFIG) columnConfig: TableColumnConfig, + @Inject(TABLE_COLUMN_INDEX) index: number, + @Inject(TABLE_DATA_PARSER) + parser: TableCellParserBase, + @Inject(TABLE_CELL_DATA) cellData: any, + @Inject(TABLE_ROW_DATA) rowData: LogEvent + ) { + super(columnConfig, index, parser, cellData, rowData); + this.spanStartTime = rowData.spanStartTime as number; + this.timestamp = rowData.timestamp; + this.readableDateTime = + this.timestamp + ?.replace('T', ' ') + .replace('Z', ' ') + .replace(/-/g, '/') + .substr(0, this.timestamp.length - 8) + this.getDecimalMilliSeconds(this.timestamp, 3); + + const date: Date = this.dateCoercer.coerce(this.timestamp) ?? new Date(); + const decimalMilliseconds: string = this.getDecimalMilliSeconds(this.timestamp, 2); + this.duration = date.getTime() - this.spanStartTime + decimalMilliseconds + ' ms'; + } + + private getDecimalMilliSeconds(timestamp: string = '', precision: number): string { + return String(Number('0.' + timestamp.substr(timestamp.length - 7, 6)).toFixed(precision)).substring(1); + } +} diff --git a/projects/observability/src/shared/components/table/observability-table-cell-renderer.module.ts b/projects/observability/src/shared/components/table/observability-table-cell-renderer.module.ts index 5f2855f7e..51a82b7bf 100644 --- a/projects/observability/src/shared/components/table/observability-table-cell-renderer.module.ts +++ b/projects/observability/src/shared/components/table/observability-table-cell-renderer.module.ts @@ -8,6 +8,7 @@ import { EntityTableCellParser } from './data-cell/entity/entity-table-cell-pars import { EntityTableCellRendererComponent } from './data-cell/entity/entity-table-cell-renderer.component'; import { EntityTableCellRendererModule } from './data-cell/entity/entity-table-cell-renderer.module'; import { ExitCallsTableCellRendererComponent } from './data-cell/exit-calls/exit-calls-table-cell-renderer.component'; +import { LogTimestampTableCellRendererComponent } from './data-cell/log-timestamp/log-timestamp-table-cell-renderer.component'; @NgModule({ imports: [ @@ -16,13 +17,14 @@ import { ExitCallsTableCellRendererComponent } from './data-cell/exit-calls/exit TableModule.withCellRenderers([ EntityTableCellRendererComponent, BackendIconTableCellRendererComponent, - ExitCallsTableCellRendererComponent + ExitCallsTableCellRendererComponent, + LogTimestampTableCellRendererComponent ]), EntityTableCellRendererModule, BackendIconTableCellRendererModule, TooltipModule ], - declarations: [ExitCallsTableCellRendererComponent], + declarations: [ExitCallsTableCellRendererComponent, LogTimestampTableCellRendererComponent], exports: [ExitCallsTableCellRendererComponent] }) export class ObservabilityTableCellRendererModule {} diff --git a/projects/observability/src/shared/components/table/observability-table-cell-type.ts b/projects/observability/src/shared/components/table/observability-table-cell-type.ts index 3c7f686c0..1253eb45b 100644 --- a/projects/observability/src/shared/components/table/observability-table-cell-type.ts +++ b/projects/observability/src/shared/components/table/observability-table-cell-type.ts @@ -1,5 +1,6 @@ export const enum ObservabilityTableCellType { Entity = 'entity', BackendIcon = 'backend-icon', - ExitCalls = 'exit-calls' + ExitCalls = 'exit-calls', + LogTimestamp = 'log-timestamp' } From 3cb722eb24539456afd53ced96e8297128117df6 Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Tue, 4 May 2021 18:54:24 +0530 Subject: [PATCH 03/25] fix: adding trace start time --- .../log-timestamp-table-cell-renderer.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts b/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts index 658e446d2..50783d573 100644 --- a/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts +++ b/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts @@ -33,7 +33,7 @@ import { ObservabilityTableCellType } from '../../observability-table-cell-type' parser: CoreTableCellParserType.NoOp }) export class LogTimestampTableCellRendererComponent extends TableCellRendererBase implements OnInit { - public readonly spanStartTime: number; + public readonly traceStartTime: number; public readonly timestamp?: string; public readonly duration?: string; public readonly readableDateTime?: string; @@ -49,7 +49,7 @@ export class LogTimestampTableCellRendererComponent extends TableCellRendererBas @Inject(TABLE_ROW_DATA) rowData: LogEvent ) { super(columnConfig, index, parser, cellData, rowData); - this.spanStartTime = rowData.spanStartTime as number; + this.traceStartTime = rowData.traceStartTime as number; this.timestamp = rowData.timestamp; this.readableDateTime = this.timestamp @@ -60,7 +60,7 @@ export class LogTimestampTableCellRendererComponent extends TableCellRendererBas const date: Date = this.dateCoercer.coerce(this.timestamp) ?? new Date(); const decimalMilliseconds: string = this.getDecimalMilliSeconds(this.timestamp, 2); - this.duration = date.getTime() - this.spanStartTime + decimalMilliseconds + ' ms'; + this.duration = date.getTime() - this.traceStartTime + decimalMilliseconds + ' ms'; } private getDecimalMilliSeconds(timestamp: string = '', precision: number): string { From 8f0b5c8eb02fc9e6832cbfbf959be38e8bf5bfd5 Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Tue, 4 May 2021 18:54:53 +0530 Subject: [PATCH 04/25] fix: adding trace start time to span data --- .../src/shared/components/span-detail/span-data.ts | 1 + .../waterfall/trace-waterfall-data-source.model.ts | 1 + .../widgets/waterfall/waterfall/waterfall-chart.ts | 11 ++++++----- .../api-trace-waterfall-data-source.model.ts | 1 + 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts b/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts index 1cfbe7686..f259857ed 100644 --- a/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts +++ b/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts @@ -14,5 +14,6 @@ export interface SpanData { requestUrl: string; exitCallsBreakup?: Dictionary; startTime?: number; + traceStartTime?: number; logEvents?: LogEvent[]; } diff --git a/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts b/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts index d25e7448d..42fc36364 100644 --- a/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts +++ b/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts @@ -112,6 +112,7 @@ export class TraceWaterfallDataSourceModel extends GraphQlDataSourceModel, errorCount: span.errorCount as number, + traceStartTime: this.startTime as number, logEvents: ((span.logEvents as Dictionary) ?? {}).results })); } diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts index 4e2d76ca3..be0668c7c 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts @@ -23,6 +23,7 @@ export interface WaterfallData { responseBody?: string; tags: Dictionary; errorCount: number; + traceStartTime: number; logEvents?: LogEvent[]; } @@ -41,9 +42,9 @@ export interface WaterfallChartState { export interface LogEvent { [key: string]: unknown; - traceId?: string; - spanId?: string; - attributes?: Dictionary; - timestamp?: string; - summary?: string; + traceId: string; + spanId: string; + attributes: Dictionary; + timestamp: string; + summary: string; } diff --git a/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts b/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts index 0c0f325a4..b182e05dd 100644 --- a/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts +++ b/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts @@ -117,6 +117,7 @@ export class ApiTraceWaterfallDataSourceModel extends GraphQlDataSourceModel, errorCount: span.errorCount as number, + traceStartTime: this.startTime as number, logEvents: ((span.logEvents as Dictionary) ?? {}).results }; } From 533c90485e6a40603e21aa6b70aec86202deab85 Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Tue, 4 May 2021 19:36:05 +0530 Subject: [PATCH 05/25] Revert "fix: adding trace start time to span data" This reverts commit 8f0b5c8eb02fc9e6832cbfbf959be38e8bf5bfd5. --- .../src/shared/components/span-detail/span-data.ts | 1 - .../waterfall/trace-waterfall-data-source.model.ts | 1 - .../widgets/waterfall/waterfall/waterfall-chart.ts | 11 +++++------ .../api-trace-waterfall-data-source.model.ts | 1 - 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts b/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts index f259857ed..1cfbe7686 100644 --- a/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts +++ b/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts @@ -14,6 +14,5 @@ export interface SpanData { requestUrl: string; exitCallsBreakup?: Dictionary; startTime?: number; - traceStartTime?: number; logEvents?: LogEvent[]; } diff --git a/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts b/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts index 42fc36364..d25e7448d 100644 --- a/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts +++ b/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts @@ -112,7 +112,6 @@ export class TraceWaterfallDataSourceModel extends GraphQlDataSourceModel, errorCount: span.errorCount as number, - traceStartTime: this.startTime as number, logEvents: ((span.logEvents as Dictionary) ?? {}).results })); } diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts index be0668c7c..4e2d76ca3 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts @@ -23,7 +23,6 @@ export interface WaterfallData { responseBody?: string; tags: Dictionary; errorCount: number; - traceStartTime: number; logEvents?: LogEvent[]; } @@ -42,9 +41,9 @@ export interface WaterfallChartState { export interface LogEvent { [key: string]: unknown; - traceId: string; - spanId: string; - attributes: Dictionary; - timestamp: string; - summary: string; + traceId?: string; + spanId?: string; + attributes?: Dictionary; + timestamp?: string; + summary?: string; } diff --git a/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts b/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts index b182e05dd..0c0f325a4 100644 --- a/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts +++ b/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts @@ -117,7 +117,6 @@ export class ApiTraceWaterfallDataSourceModel extends GraphQlDataSourceModel, errorCount: span.errorCount as number, - traceStartTime: this.startTime as number, logEvents: ((span.logEvents as Dictionary) ?? {}).results }; } From a1d101d3f6a7dbe4ee3bcb4202c4b47c141105a9 Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Tue, 4 May 2021 19:39:40 +0530 Subject: [PATCH 06/25] fix: addressing review comments --- .../widgets/waterfall/waterfall/waterfall-chart.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts index 4e2d76ca3..4b2e5d4e8 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts @@ -41,9 +41,9 @@ export interface WaterfallChartState { export interface LogEvent { [key: string]: unknown; - traceId?: string; - spanId?: string; - attributes?: Dictionary; - timestamp?: string; - summary?: string; + traceId: string; + spanId: string; + attributes: Dictionary; + timestamp: string; + summary: string; } From 8033540d7ceec923fe9af1d94d084575bf50f60a Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Tue, 4 May 2021 19:40:49 +0530 Subject: [PATCH 07/25] Revert "fix: adding trace start time" This reverts commit 3cb722eb24539456afd53ced96e8297128117df6. --- .../log-timestamp-table-cell-renderer.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts b/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts index 50783d573..658e446d2 100644 --- a/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts +++ b/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts @@ -33,7 +33,7 @@ import { ObservabilityTableCellType } from '../../observability-table-cell-type' parser: CoreTableCellParserType.NoOp }) export class LogTimestampTableCellRendererComponent extends TableCellRendererBase implements OnInit { - public readonly traceStartTime: number; + public readonly spanStartTime: number; public readonly timestamp?: string; public readonly duration?: string; public readonly readableDateTime?: string; @@ -49,7 +49,7 @@ export class LogTimestampTableCellRendererComponent extends TableCellRendererBas @Inject(TABLE_ROW_DATA) rowData: LogEvent ) { super(columnConfig, index, parser, cellData, rowData); - this.traceStartTime = rowData.traceStartTime as number; + this.spanStartTime = rowData.spanStartTime as number; this.timestamp = rowData.timestamp; this.readableDateTime = this.timestamp @@ -60,7 +60,7 @@ export class LogTimestampTableCellRendererComponent extends TableCellRendererBas const date: Date = this.dateCoercer.coerce(this.timestamp) ?? new Date(); const decimalMilliseconds: string = this.getDecimalMilliSeconds(this.timestamp, 2); - this.duration = date.getTime() - this.traceStartTime + decimalMilliseconds + ' ms'; + this.duration = date.getTime() - this.spanStartTime + decimalMilliseconds + ' ms'; } private getDecimalMilliSeconds(timestamp: string = '', precision: number): string { From cd1214bac73c499c946841e7b9191e533e53a122 Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Tue, 4 May 2021 19:40:53 +0530 Subject: [PATCH 08/25] Revert "fix: adding trace start time to span data" This reverts commit 8f0b5c8eb02fc9e6832cbfbf959be38e8bf5bfd5. --- .../src/shared/components/span-detail/span-data.ts | 1 - .../waterfall/trace-waterfall-data-source.model.ts | 1 - .../widgets/waterfall/waterfall/waterfall-chart.ts | 11 +++++------ .../api-trace-waterfall-data-source.model.ts | 1 - 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts b/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts index f259857ed..1cfbe7686 100644 --- a/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts +++ b/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts @@ -14,6 +14,5 @@ export interface SpanData { requestUrl: string; exitCallsBreakup?: Dictionary; startTime?: number; - traceStartTime?: number; logEvents?: LogEvent[]; } diff --git a/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts b/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts index 42fc36364..d25e7448d 100644 --- a/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts +++ b/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts @@ -112,7 +112,6 @@ export class TraceWaterfallDataSourceModel extends GraphQlDataSourceModel, errorCount: span.errorCount as number, - traceStartTime: this.startTime as number, logEvents: ((span.logEvents as Dictionary) ?? {}).results })); } diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts index be0668c7c..4e2d76ca3 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts @@ -23,7 +23,6 @@ export interface WaterfallData { responseBody?: string; tags: Dictionary; errorCount: number; - traceStartTime: number; logEvents?: LogEvent[]; } @@ -42,9 +41,9 @@ export interface WaterfallChartState { export interface LogEvent { [key: string]: unknown; - traceId: string; - spanId: string; - attributes: Dictionary; - timestamp: string; - summary: string; + traceId?: string; + spanId?: string; + attributes?: Dictionary; + timestamp?: string; + summary?: string; } diff --git a/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts b/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts index b182e05dd..0c0f325a4 100644 --- a/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts +++ b/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts @@ -117,7 +117,6 @@ export class ApiTraceWaterfallDataSourceModel extends GraphQlDataSourceModel, errorCount: span.errorCount as number, - traceStartTime: this.startTime as number, logEvents: ((span.logEvents as Dictionary) ?? {}).results }; } From e2aef98af0b297db32c8723aba50d0c84013579c Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Wed, 5 May 2021 18:33:19 +0530 Subject: [PATCH 09/25] fix: changing log-timestamp to relative timestamp --- ...estamp-table-cell-renderer.component.scss} | 2 +- ...tamp-table-cell-renderer.component.test.ts | 41 +++++++++++ ...timestamp-table-cell-renderer.component.ts | 63 +++++++++++++++++ .../src/table/cells/table-cells.module.ts | 7 +- .../types/core-table-cell-renderer-type.ts | 1 + ...tamp-table-cell-renderer.component.test.ts | 42 ----------- ...timestamp-table-cell-renderer.component.ts | 69 ------------------- ...bservability-table-cell-renderer.module.ts | 6 +- .../table/observability-table-cell-type.ts | 3 +- 9 files changed, 114 insertions(+), 120 deletions(-) rename projects/{observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.scss => components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.scss} (83%) create mode 100644 projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.test.ts create mode 100644 projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts delete mode 100644 projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.test.ts delete mode 100644 projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts diff --git a/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.scss b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.scss similarity index 83% rename from projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.scss rename to projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.scss index 261cec610..9bea04de3 100644 --- a/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.scss +++ b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.scss @@ -1,6 +1,6 @@ @import 'font'; -.log-timestamp { +.relative-timestamp { @include ellipsis-overflow(); &.first-column { diff --git a/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.test.ts b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.test.ts new file mode 100644 index 000000000..2e2a8d4ef --- /dev/null +++ b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.test.ts @@ -0,0 +1,41 @@ +import { + TableCellNoOpParser, + tableCellProviders, + tableCellRowDataProvider, + TooltipDirective +} from '@hypertrace/components'; +import { createComponentFactory } from '@ngneat/spectator/jest'; +import { MockComponent } from 'ng-mocks'; +import { tableCellDataProvider } from '../../test/cell-providers'; +import { + RelativeTimestampTableCellRendererComponent, + RowData +} from './relative-timestamp-table-cell-renderer.component'; + +describe('log timestamp table cell renderer component', () => { + const buildComponent = createComponentFactory({ + component: RelativeTimestampTableCellRendererComponent, + providers: [ + tableCellProviders( + { + id: 'test' + }, + new TableCellNoOpParser(undefined!) + ) + ], + declarations: [MockComponent(TooltipDirective)], + shallow: true + }); + + test('testing component properties', () => { + const logEvent: RowData = { + baseTimestamp: 1619785437887 + }; + const spectator = buildComponent({ + providers: [tableCellRowDataProvider(logEvent), tableCellDataProvider('2021-04-30T12:23:57.889149Z')] + }); + + expect(spectator.queryAll('.relative-timestamp')[0]).toContainText('2 ms'); + expect(spectator.component.duration).toBe(2); + }); +}); diff --git a/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts new file mode 100644 index 000000000..66dbdba47 --- /dev/null +++ b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts @@ -0,0 +1,63 @@ +import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core'; +import { DateCoercer, DateFormatMode, DateFormatOptions } from '@hypertrace/common'; +import { TableColumnConfig } from '../../../table-api'; +import { + TABLE_CELL_DATA, + TABLE_COLUMN_CONFIG, + TABLE_COLUMN_INDEX, + TABLE_DATA_PARSER, + TABLE_ROW_DATA +} from '../../table-cell-injection'; +import { TableCellParserBase } from '../../table-cell-parser-base'; +import { TableCellRenderer } from '../../table-cell-renderer'; +import { TableCellRendererBase } from '../../table-cell-renderer-base'; +import { CoreTableCellParserType } from '../../types/core-table-cell-parser-type'; +import { CoreTableCellRendererType } from '../../types/core-table-cell-renderer-type'; +import { TableCellAlignmentType } from '../../types/table-cell-alignment-type'; + +export interface RowData { + [key: string]: unknown; + baseTimestamp: DateOrNumber; +} + +type DateOrNumber = Date | number; +@Component({ + selector: 'ht-relative-timestamp-table-cell-renderer', + styleUrls: ['./relative-timestamp-table-cell-renderer.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + template: ` +
+ {{ this.duration }} ms +
+ ` +}) +@TableCellRenderer({ + type: CoreTableCellRendererType.RelativeTimestamp, + alignment: TableCellAlignmentType.Left, + parser: CoreTableCellParserType.NoOp +}) +export class RelativeTimestampTableCellRendererComponent extends TableCellRendererBase implements OnInit { + public readonly dateFormat: DateFormatOptions = { + mode: DateFormatMode.DateAndTimeWithSeconds + }; + public readonly duration: number; + private dateCoercer: DateCoercer = new DateCoercer(); + + public constructor( + @Inject(TABLE_COLUMN_CONFIG) columnConfig: TableColumnConfig, + @Inject(TABLE_COLUMN_INDEX) index: number, + @Inject(TABLE_DATA_PARSER) + parser: TableCellParserBase, + @Inject(TABLE_CELL_DATA) cellData: DateOrNumber, + @Inject(TABLE_ROW_DATA) rowData: RowData + ) { + super(columnConfig, index, parser, cellData, rowData); + this.duration = + (this.dateCoercer.coerce(cellData)?.getTime() ?? NaN) - + (this.dateCoercer.coerce(rowData.baseTimestamp)?.getTime() ?? NaN); + } +} diff --git a/projects/components/src/table/cells/table-cells.module.ts b/projects/components/src/table/cells/table-cells.module.ts index ad7a15e77..4dfed1580 100644 --- a/projects/components/src/table/cells/table-cells.module.ts +++ b/projects/components/src/table/cells/table-cells.module.ts @@ -21,6 +21,7 @@ import { CodeTableCellRendererComponent } from './data-renderers/code/code-table import { StringEnumTableCellRendererComponent } from './data-renderers/enum/string-enum-table-cell-renderer.component'; import { IconTableCellRendererComponent } from './data-renderers/icon/icon-table-cell-renderer.component'; import { NumericTableCellRendererComponent } from './data-renderers/numeric/numeric-table-cell-renderer.component'; +import { RelativeTimestampTableCellRendererComponent } from './data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component'; import { StringArrayTableCellRendererComponent } from './data-renderers/string-array/string-array-table-cell-renderer.component'; import { TableDataCellRendererComponent } from './data-renderers/table-data-cell-renderer.component'; import { TextWithCopyActionTableCellRendererComponent } from './data-renderers/text-with-copy/text-with-copy-table-cell-renderer.component'; @@ -72,7 +73,8 @@ export const TABLE_CELL_PARSERS = new InjectionToken('TABLE_CELL_PA CodeTableCellRendererComponent, StringArrayTableCellRendererComponent, StringEnumTableCellRendererComponent, - TextWithCopyActionTableCellRendererComponent + TextWithCopyActionTableCellRendererComponent, + RelativeTimestampTableCellRendererComponent ], providers: [ { @@ -88,7 +90,8 @@ export const TABLE_CELL_PARSERS = new InjectionToken('TABLE_CELL_PA CodeTableCellRendererComponent, StringArrayTableCellRendererComponent, StringEnumTableCellRendererComponent, - TextWithCopyActionTableCellRendererComponent + TextWithCopyActionTableCellRendererComponent, + RelativeTimestampTableCellRendererComponent ], multi: true }, diff --git a/projects/components/src/table/cells/types/core-table-cell-renderer-type.ts b/projects/components/src/table/cells/types/core-table-cell-renderer-type.ts index 5c5d8a6e6..2917244bc 100644 --- a/projects/components/src/table/cells/types/core-table-cell-renderer-type.ts +++ b/projects/components/src/table/cells/types/core-table-cell-renderer-type.ts @@ -4,6 +4,7 @@ export const enum CoreTableCellRendererType { Icon = 'icon', Number = 'number', RowExpander = 'row-expander', + RelativeTimestamp = 'relative-timestamp', StringArray = 'string-array', StringEnum = 'string-enum', Text = 'text', diff --git a/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.test.ts b/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.test.ts deleted file mode 100644 index bd30457be..000000000 --- a/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { - TableCellNoOpParser, - tableCellProviders, - tableCellRowDataProvider, - TooltipDirective -} from '@hypertrace/components'; -import { LogEvent } from '@hypertrace/distributed-tracing'; -import { createComponentFactory } from '@ngneat/spectator/jest'; -import { MockComponent } from 'ng-mocks'; -import { LogTimestampTableCellRendererComponent } from './log-timestamp-table-cell-renderer.component'; - -describe('log timestamp table cell renderer component', () => { - const buildComponent = createComponentFactory({ - component: LogTimestampTableCellRendererComponent, - providers: [ - tableCellProviders( - { - id: 'test' - }, - new TableCellNoOpParser(undefined!) - ) - ], - declarations: [MockComponent(TooltipDirective)], - shallow: true - }); - - test('testing component properties', () => { - const logEvent: LogEvent = { - timestamp: '2021-04-30T12:23:57.889149Z', - spanStartTime: 1619785437887 - }; - const spectator = buildComponent({ - providers: [tableCellRowDataProvider(logEvent)] - }); - - expect(spectator.queryAll('.log-timestamp')[0]).toContainText('2.89 ms'); - expect(spectator.component.spanStartTime).toBe(logEvent.spanStartTime); - expect(spectator.component.timestamp).toBe(logEvent.timestamp); - expect(spectator.component.duration).toBe('2.89 ms'); - expect(spectator.component.readableDateTime).toBe('2021/04/30 12:23:57.889'); - }); -}); diff --git a/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts b/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts deleted file mode 100644 index 658e446d2..000000000 --- a/projects/observability/src/shared/components/table/data-cell/log-timestamp/log-timestamp-table-cell-renderer.component.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core'; -import { DateCoercer } from '@hypertrace/common'; -import { - CoreTableCellParserType, - TableCellAlignmentType, - TableCellParserBase, - TableCellRenderer, - TableCellRendererBase, - TableColumnConfig, - TABLE_CELL_DATA, - TABLE_COLUMN_CONFIG, - TABLE_COLUMN_INDEX, - TABLE_DATA_PARSER, - TABLE_ROW_DATA -} from '@hypertrace/components'; -import { LogEvent } from '@hypertrace/distributed-tracing'; -import { ObservabilityTableCellType } from '../../observability-table-cell-type'; - -@Component({ - selector: 'ht-log-timestamp-table-cell-renderer', - styleUrls: ['./log-timestamp-table-cell-renderer.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, - template: ` -
- {{ this.duration }} -
- {{ this.readableDateTime }} - ` -}) -@TableCellRenderer({ - type: ObservabilityTableCellType.LogTimestamp, - alignment: TableCellAlignmentType.Left, - parser: CoreTableCellParserType.NoOp -}) -export class LogTimestampTableCellRendererComponent extends TableCellRendererBase implements OnInit { - public readonly spanStartTime: number; - public readonly timestamp?: string; - public readonly duration?: string; - public readonly readableDateTime?: string; - - private readonly dateCoercer = new DateCoercer(); - - public constructor( - @Inject(TABLE_COLUMN_CONFIG) columnConfig: TableColumnConfig, - @Inject(TABLE_COLUMN_INDEX) index: number, - @Inject(TABLE_DATA_PARSER) - parser: TableCellParserBase, - @Inject(TABLE_CELL_DATA) cellData: any, - @Inject(TABLE_ROW_DATA) rowData: LogEvent - ) { - super(columnConfig, index, parser, cellData, rowData); - this.spanStartTime = rowData.spanStartTime as number; - this.timestamp = rowData.timestamp; - this.readableDateTime = - this.timestamp - ?.replace('T', ' ') - .replace('Z', ' ') - .replace(/-/g, '/') - .substr(0, this.timestamp.length - 8) + this.getDecimalMilliSeconds(this.timestamp, 3); - - const date: Date = this.dateCoercer.coerce(this.timestamp) ?? new Date(); - const decimalMilliseconds: string = this.getDecimalMilliSeconds(this.timestamp, 2); - this.duration = date.getTime() - this.spanStartTime + decimalMilliseconds + ' ms'; - } - - private getDecimalMilliSeconds(timestamp: string = '', precision: number): string { - return String(Number('0.' + timestamp.substr(timestamp.length - 7, 6)).toFixed(precision)).substring(1); - } -} diff --git a/projects/observability/src/shared/components/table/observability-table-cell-renderer.module.ts b/projects/observability/src/shared/components/table/observability-table-cell-renderer.module.ts index 51a82b7bf..5f2855f7e 100644 --- a/projects/observability/src/shared/components/table/observability-table-cell-renderer.module.ts +++ b/projects/observability/src/shared/components/table/observability-table-cell-renderer.module.ts @@ -8,7 +8,6 @@ import { EntityTableCellParser } from './data-cell/entity/entity-table-cell-pars import { EntityTableCellRendererComponent } from './data-cell/entity/entity-table-cell-renderer.component'; import { EntityTableCellRendererModule } from './data-cell/entity/entity-table-cell-renderer.module'; import { ExitCallsTableCellRendererComponent } from './data-cell/exit-calls/exit-calls-table-cell-renderer.component'; -import { LogTimestampTableCellRendererComponent } from './data-cell/log-timestamp/log-timestamp-table-cell-renderer.component'; @NgModule({ imports: [ @@ -17,14 +16,13 @@ import { LogTimestampTableCellRendererComponent } from './data-cell/log-timestam TableModule.withCellRenderers([ EntityTableCellRendererComponent, BackendIconTableCellRendererComponent, - ExitCallsTableCellRendererComponent, - LogTimestampTableCellRendererComponent + ExitCallsTableCellRendererComponent ]), EntityTableCellRendererModule, BackendIconTableCellRendererModule, TooltipModule ], - declarations: [ExitCallsTableCellRendererComponent, LogTimestampTableCellRendererComponent], + declarations: [ExitCallsTableCellRendererComponent], exports: [ExitCallsTableCellRendererComponent] }) export class ObservabilityTableCellRendererModule {} diff --git a/projects/observability/src/shared/components/table/observability-table-cell-type.ts b/projects/observability/src/shared/components/table/observability-table-cell-type.ts index 1253eb45b..3c7f686c0 100644 --- a/projects/observability/src/shared/components/table/observability-table-cell-type.ts +++ b/projects/observability/src/shared/components/table/observability-table-cell-type.ts @@ -1,6 +1,5 @@ export const enum ObservabilityTableCellType { Entity = 'entity', BackendIcon = 'backend-icon', - ExitCalls = 'exit-calls', - LogTimestamp = 'log-timestamp' + ExitCalls = 'exit-calls' } From 552f7bcad45af15d606f63759b3989c01232c0e8 Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Wed, 5 May 2021 18:35:45 +0530 Subject: [PATCH 10/25] fix: addressing review comments --- .../widgets/log-detail/log-detail-widget-renderer.component.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts index ee12a2afd..c21ec9859 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts @@ -3,6 +3,7 @@ import { Dictionary } from '@hypertrace/common'; import { ListViewHeader, ListViewRecord } from '@hypertrace/components'; import { WidgetRenderer } from '@hypertrace/dashboards'; import { Renderer } from '@hypertrace/hyperdash'; +import { isEmpty } from 'lodash-es'; import { Observable } from 'rxjs'; import { LogDetailWidgetModel } from './log-detail-widget.model'; @@ -29,7 +30,7 @@ export class LogDetailWidgetRendererComponent extends WidgetRenderer): ListViewRecord[] { - if (Boolean(attributes)) { + if (!isEmpty(attributes)) { return Object.entries(attributes).map((attribute: [string, unknown]) => ({ key: attribute[0], value: attribute[1] as string | number From 2e642b85f067ad6dc5bc7d464e0f6eebc3c3f7f7 Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Wed, 5 May 2021 18:48:56 +0530 Subject: [PATCH 11/25] refactor: removing unwanted changes --- .../widgets/waterfall/waterfall/waterfall-chart.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts index 4e2d76ca3..4b2e5d4e8 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts @@ -41,9 +41,9 @@ export interface WaterfallChartState { export interface LogEvent { [key: string]: unknown; - traceId?: string; - spanId?: string; - attributes?: Dictionary; - timestamp?: string; - summary?: string; + traceId: string; + spanId: string; + attributes: Dictionary; + timestamp: string; + summary: string; } From 2e90a3a0e98a5006e2d44308093e043370a7c19f Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Wed, 5 May 2021 18:51:07 +0530 Subject: [PATCH 12/25] fix: lint errors --- .../relative-timestamp-table-cell-renderer.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts index 66dbdba47..57f4a5ec6 100644 --- a/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts +++ b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts @@ -45,7 +45,7 @@ export class RelativeTimestampTableCellRendererComponent extends TableCellRender mode: DateFormatMode.DateAndTimeWithSeconds }; public readonly duration: number; - private dateCoercer: DateCoercer = new DateCoercer(); + private readonly dateCoercer: DateCoercer = new DateCoercer(); public constructor( @Inject(TABLE_COLUMN_CONFIG) columnConfig: TableColumnConfig, From 171dc8a3b91bdbe06f93b6b29e520ba853da8c64 Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Wed, 5 May 2021 20:38:19 +0530 Subject: [PATCH 13/25] fix: adding and fixing tests --- .../data/log-detail-data-source.model.test.ts | 37 +++++++++++++--- ...g-detail-widget-renderer.component.test.ts | 44 +++++++++++++++++++ 2 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.test.ts diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts index 6e36d63a2..2c006093f 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts @@ -1,17 +1,40 @@ +import { Dictionary } from '@hypertrace/common'; import { createModelFactory, SpectatorModel } from '@hypertrace/dashboards/testing'; +import { LogEvent } from '@hypertrace/distributed-tracing'; +import { GraphQlRequestService } from '@hypertrace/graphql-client'; +import { ModelApi } from '@hypertrace/hyperdash'; import { runFakeRxjs } from '@hypertrace/test-utils'; +import { mockProvider } from '@ngneat/spectator/jest'; +import { of } from 'rxjs'; import { LogDetailDataSourceModel } from './log-detail-data-source.model'; describe('Log Detail data source model', () => { let spectator!: SpectatorModel; - const buildModel = createModelFactory(); - spectator = buildModel(LogDetailDataSourceModel); - spectator.model.logEvent = { - attributes: { - key1: 'value1', - key2: 'value2' - } + const attributes: Dictionary = { + key1: 'value1', + key2: 'value2' }; + const logEvent: LogEvent = { + traceId: 'id1', + attributes: attributes, + spanId: 's-id1', + timestamp: '2021-05-05T00:00:00Z', + summary: 'test log event' + }; + + const buildModel = createModelFactory({ + providers: [ + mockProvider(GraphQlRequestService, { + query: jest.fn().mockReturnValue(of({})) + }) + ] + }); + beforeEach(() => { + const mockApi: Partial = {}; + spectator = buildModel(LogDetailDataSourceModel); + spectator.model.logEvent = logEvent; + spectator.model.api = mockApi as ModelApi; + }); test('test attribute data', () => { runFakeRxjs(({ expectObservable }) => { diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.test.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.test.ts new file mode 100644 index 000000000..d0911c41c --- /dev/null +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.test.ts @@ -0,0 +1,44 @@ +import { Dictionary, FormattingModule } from '@hypertrace/common'; +import { ListViewComponent, LoadAsyncModule } from '@hypertrace/components'; +import { mockDashboardWidgetProviders } from '@hypertrace/dashboards/testing'; +import { createComponentFactory } from '@ngneat/spectator/jest'; +import { MockComponent } from 'ng-mocks'; +import { of } from 'rxjs'; +import { LogDetailWidgetRendererComponent } from './log-detail-widget-renderer.component'; +import { LogDetailWidgetModel } from './log-detail-widget.model'; + +describe('log detail widget renderer component', () => { + let mockModel: Partial = {}; + const buildComponent = createComponentFactory({ + component: LogDetailWidgetRendererComponent, + providers: [], + imports: [FormattingModule, LoadAsyncModule], + declarations: [MockComponent(ListViewComponent)], + shallow: true + }); + const attributes: Dictionary = { + key1: 1, + key2: 2 + }; + + test('should render list view with provided data', () => { + mockModel = { + getData: jest.fn(() => of(attributes)) + }; + const spectator = buildComponent({ + providers: [...mockDashboardWidgetProviders(mockModel)] + }); + expect(spectator.query('.content')).toExist(); + expect(spectator.query(ListViewComponent)!.header).toEqual(spectator.component.header); + expect(spectator.query(ListViewComponent)!.records).toEqual([ + { + key: 'key1', + value: 1 + }, + { + key: 'key2', + value: 2 + } + ]); + }); +}); From 36e8d44ecc5712de3163367f00ad271051e89bae Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Wed, 5 May 2021 21:18:07 +0530 Subject: [PATCH 14/25] fix: address review comment and test fix --- ...elative-timestamp-table-cell-renderer.component.test.ts | 7 ++++--- .../relative-timestamp-table-cell-renderer.component.ts | 5 ++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.test.ts b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.test.ts index 2e2a8d4ef..bf46650ea 100644 --- a/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.test.ts +++ b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.test.ts @@ -1,3 +1,4 @@ +import { DisplayDatePipe } from '@hypertrace/common'; import { TableCellNoOpParser, tableCellProviders, @@ -5,14 +6,14 @@ import { TooltipDirective } from '@hypertrace/components'; import { createComponentFactory } from '@ngneat/spectator/jest'; -import { MockComponent } from 'ng-mocks'; +import { MockComponent, MockPipe } from 'ng-mocks'; import { tableCellDataProvider } from '../../test/cell-providers'; import { RelativeTimestampTableCellRendererComponent, RowData } from './relative-timestamp-table-cell-renderer.component'; -describe('log timestamp table cell renderer component', () => { +describe('relative timestamp table cell renderer component', () => { const buildComponent = createComponentFactory({ component: RelativeTimestampTableCellRendererComponent, providers: [ @@ -23,7 +24,7 @@ describe('log timestamp table cell renderer component', () => { new TableCellNoOpParser(undefined!) ) ], - declarations: [MockComponent(TooltipDirective)], + declarations: [MockComponent(TooltipDirective), MockPipe(DisplayDatePipe)], shallow: true }); diff --git a/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts index 57f4a5ec6..522f40f9f 100644 --- a/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts +++ b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts @@ -1,5 +1,5 @@ import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core'; -import { DateCoercer, DateFormatMode, DateFormatOptions } from '@hypertrace/common'; +import { DateCoercer, DateFormatMode, DateFormatOptions, Dictionary } from '@hypertrace/common'; import { TableColumnConfig } from '../../../table-api'; import { TABLE_CELL_DATA, @@ -15,8 +15,7 @@ import { CoreTableCellParserType } from '../../types/core-table-cell-parser-type import { CoreTableCellRendererType } from '../../types/core-table-cell-renderer-type'; import { TableCellAlignmentType } from '../../types/table-cell-alignment-type'; -export interface RowData { - [key: string]: unknown; +export interface RowData extends Dictionary { baseTimestamp: DateOrNumber; } From 8886ae2f46a4294347f54658dc15753878458ea6 Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Thu, 6 May 2021 10:18:30 +0530 Subject: [PATCH 15/25] fix: addressing review comments --- .../src/shared/components/span-detail/span-data.ts | 4 ++-- .../dashboard/widgets/waterfall/waterfall/waterfall-chart.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts b/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts index 1cfbe7686..21f4af466 100644 --- a/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts +++ b/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts @@ -13,6 +13,6 @@ export interface SpanData { tags: Dictionary; requestUrl: string; exitCallsBreakup?: Dictionary; - startTime?: number; - logEvents?: LogEvent[]; + startTime: number; + logEvents: LogEvent[]; } diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts index 4b2e5d4e8..472389f54 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts @@ -23,7 +23,7 @@ export interface WaterfallData { responseBody?: string; tags: Dictionary; errorCount: number; - logEvents?: LogEvent[]; + logEvents: LogEvent[]; } export interface WaterfallDataNode extends WaterfallData, Omit { From 11bee55467aee64f0125ae94f5b31f2dc2a625e9 Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Thu, 6 May 2021 10:22:57 +0530 Subject: [PATCH 16/25] Revert "fix: addressing review comments" This reverts commit 8886ae2f46a4294347f54658dc15753878458ea6. --- .../src/shared/components/span-detail/span-data.ts | 4 ++-- .../dashboard/widgets/waterfall/waterfall/waterfall-chart.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts b/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts index 21f4af466..1cfbe7686 100644 --- a/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts +++ b/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts @@ -13,6 +13,6 @@ export interface SpanData { tags: Dictionary; requestUrl: string; exitCallsBreakup?: Dictionary; - startTime: number; - logEvents: LogEvent[]; + startTime?: number; + logEvents?: LogEvent[]; } diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts index 472389f54..4b2e5d4e8 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts @@ -23,7 +23,7 @@ export interface WaterfallData { responseBody?: string; tags: Dictionary; errorCount: number; - logEvents: LogEvent[]; + logEvents?: LogEvent[]; } export interface WaterfallDataNode extends WaterfallData, Omit { From 77d168d39651547c2af281a220c98086f40a8ebb Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Thu, 6 May 2021 10:59:17 +0530 Subject: [PATCH 17/25] fix: addressing review comments --- .../src/shared/components/span-detail/span-data.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts b/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts index 1cfbe7686..e12757ee5 100644 --- a/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts +++ b/projects/distributed-tracing/src/shared/components/span-detail/span-data.ts @@ -13,6 +13,6 @@ export interface SpanData { tags: Dictionary; requestUrl: string; exitCallsBreakup?: Dictionary; - startTime?: number; + startTime: number; logEvents?: LogEvent[]; } From 129b6a432f6dab1361459d4cc98ac2d23eff9d6c Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Thu, 6 May 2021 11:32:34 +0530 Subject: [PATCH 18/25] fix: test cases --- .../span-detail/span-detail.component.test.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/projects/distributed-tracing/src/shared/components/span-detail/span-detail.component.test.ts b/projects/distributed-tracing/src/shared/components/span-detail/span-detail.component.test.ts index 00f1d4ed4..430205f59 100644 --- a/projects/distributed-tracing/src/shared/components/span-detail/span-detail.component.test.ts +++ b/projects/distributed-tracing/src/shared/components/span-detail/span-detail.component.test.ts @@ -28,7 +28,8 @@ describe('Span detail component', () => { responseHeaders: { header1: 'value1', header2: 'value2' }, responseBody: '[{"data": 5000}]', tags: { tag1: 'value1', tag2: 'value2' }, - requestUrl: 'test-url' + requestUrl: 'test-url', + startTime: 1604567825671 }; spectator = createHost(``, { @@ -52,7 +53,8 @@ describe('Span detail component', () => { responseHeaders: { header1: 'value1', header2: 'value2' }, responseBody: '[{"data": 5000}]', tags: { tag1: 'value1', tag2: 'value2' }, - requestUrl: 'test-url' + requestUrl: 'test-url', + startTime: 1604567825671 }; spectator = createHost(``, { @@ -77,7 +79,8 @@ describe('Span detail component', () => { responseHeaders: { header1: 'value1', header2: 'value2' }, responseBody: '[{"data": 5000}]', tags: { tag1: 'value1', tag2: 'value2' }, - requestUrl: 'test-url' + requestUrl: 'test-url', + startTime: 1604567825671 }; spectator = createHost(``, { @@ -101,7 +104,8 @@ describe('Span detail component', () => { responseHeaders: {}, responseBody: '', tags: { tag1: 'value1', tag2: 'value2' }, - requestUrl: 'test-url' + requestUrl: 'test-url', + startTime: 1604567825671 }; spectator = createHost(``, { From 10f3d37e30a6bf8d1572f72a580d7cea77e884dc Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Thu, 6 May 2021 15:40:17 +0530 Subject: [PATCH 19/25] fix: test case --- .../log-detail/log-detail-widget-renderer.component.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts index c21ec9859..89ff8163e 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts @@ -1,8 +1,9 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject } from '@angular/core'; import { Dictionary } from '@hypertrace/common'; import { ListViewHeader, ListViewRecord } from '@hypertrace/components'; import { WidgetRenderer } from '@hypertrace/dashboards'; import { Renderer } from '@hypertrace/hyperdash'; +import { RendererApi, RENDERER_API } from '@hypertrace/hyperdash-angular'; import { isEmpty } from 'lodash-es'; import { Observable } from 'rxjs'; import { LogDetailWidgetModel } from './log-detail-widget.model'; @@ -23,6 +24,12 @@ import { LogDetailWidgetModel } from './log-detail-widget.model'; ` }) export class LogDetailWidgetRendererComponent extends WidgetRenderer> { + public constructor( + @Inject(RENDERER_API) public readonly api: RendererApi, + protected readonly changeDetector: ChangeDetectorRef + ) { + super(api, changeDetector); + } public readonly header: ListViewHeader = { keyLabel: 'key', valueLabel: 'value' }; protected fetchData(): Observable> { From b45756d29d95432597725346114baaf5832cd03f Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Thu, 6 May 2021 19:54:16 +0530 Subject: [PATCH 20/25] fix: addressing review comments --- .../trace-waterfall-data-source.model.test.ts | 12 ---------- .../trace-waterfall-data-source.model.ts | 2 -- .../waterfall-chart.component.test.ts | 9 ++++--- .../waterfall/waterfall/waterfall-chart.ts | 5 +--- ...-trace-waterfall-data-source.model.test.ts | 24 +++++++------------ .../api-trace-waterfall-data-source.model.ts | 4 ++-- 6 files changed, 17 insertions(+), 39 deletions(-) diff --git a/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.test.ts b/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.test.ts index 6db824d68..97b1a9b74 100644 --- a/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.test.ts +++ b/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.test.ts @@ -98,18 +98,12 @@ describe('Trace Waterfall data source model', () => { }) ], logEventProperties: [ - expect.objectContaining({ - name: 'traceId' - }), expect.objectContaining({ name: 'attributes' }), expect.objectContaining({ name: 'timestamp' }), - expect.objectContaining({ - name: 'spanId' - }), expect.objectContaining({ name: 'summary' }) @@ -175,18 +169,12 @@ describe('Trace Waterfall data source model', () => { }) ], logEventProperties: [ - expect.objectContaining({ - name: 'traceId' - }), expect.objectContaining({ name: 'attributes' }), expect.objectContaining({ name: 'timestamp' }), - expect.objectContaining({ - name: 'spanId' - }), expect.objectContaining({ name: 'summary' }) diff --git a/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts b/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts index d25e7448d..30fccf333 100644 --- a/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts +++ b/projects/distributed-tracing/src/shared/dashboard/data/graphql/waterfall/trace-waterfall-data-source.model.ts @@ -61,10 +61,8 @@ export class TraceWaterfallDataSourceModel extends GraphQlDataSourceModel { responseHeaders: {}, responseBody: 'Response Body', tags: {}, - errorCount: 0 + errorCount: 0, + logEvents: [] }, { id: 'second-id', @@ -52,7 +53,8 @@ describe('Waterfall Chart component', () => { responseHeaders: {}, responseBody: '', tags: {}, - errorCount: 0 + errorCount: 0, + logEvents: [] }, { id: 'third-id', @@ -73,7 +75,8 @@ describe('Waterfall Chart component', () => { responseHeaders: {}, responseBody: '', tags: {}, - errorCount: 0 + errorCount: 0, + logEvents: [] } ]; diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts index 4b2e5d4e8..c5077dc3a 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.ts @@ -23,7 +23,7 @@ export interface WaterfallData { responseBody?: string; tags: Dictionary; errorCount: number; - logEvents?: LogEvent[]; + logEvents: LogEvent[]; } export interface WaterfallDataNode extends WaterfallData, Omit { @@ -40,9 +40,6 @@ export interface WaterfallChartState { } export interface LogEvent { - [key: string]: unknown; - traceId: string; - spanId: string; attributes: Dictionary; timestamp: string; summary: string; diff --git a/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.test.ts b/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.test.ts index 4e5beb29c..425196294 100644 --- a/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.test.ts +++ b/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.test.ts @@ -104,18 +104,12 @@ describe('Api Trace Waterfall data source model', () => { }) ], logEventProperties: [ - expect.objectContaining({ - name: 'traceId' - }), expect.objectContaining({ name: 'attributes' }), expect.objectContaining({ name: 'timestamp' }), - expect.objectContaining({ - name: 'spanId' - }), expect.objectContaining({ name: 'summary' }) @@ -182,18 +176,12 @@ describe('Api Trace Waterfall data source model', () => { }) ], logEventProperties: [ - expect.objectContaining({ - name: 'traceId' - }), expect.objectContaining({ name: 'attributes' }), expect.objectContaining({ name: 'timestamp' }), - expect.objectContaining({ - name: 'spanId' - }), expect.objectContaining({ name: 'summary' }) @@ -229,7 +217,8 @@ describe('Api Trace Waterfall data source model', () => { displaySpanName: 'Span Name 1', protocolName: 'Protocol Name 1', type: SpanType.Entry, - spanTags: {} + spanTags: {}, + logEvents: [] }, { [spanIdKey]: 'second-id', @@ -241,7 +230,8 @@ describe('Api Trace Waterfall data source model', () => { displaySpanName: 'Span Name 2', protocolName: 'Protocol Name 2', type: SpanType.Exit, - spanTags: {} + spanTags: {}, + logEvents: [] } ] }) @@ -261,7 +251,8 @@ describe('Api Trace Waterfall data source model', () => { apiName: 'Span Name 1', protocolName: 'Protocol Name 1', spanType: SpanType.Entry, - tags: {} + tags: {}, + logEvents: [] }, { id: 'second-id', @@ -277,7 +268,8 @@ describe('Api Trace Waterfall data source model', () => { apiName: 'Span Name 2', protocolName: 'Protocol Name 2', spanType: SpanType.Exit, - tags: {} + tags: {}, + logEvents: [] } ] }); diff --git a/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts b/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts index 0c0f325a4..698263d10 100644 --- a/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts +++ b/projects/observability/src/shared/dashboard/data/graphql/waterfall/api-trace-waterfall-data-source.model.ts @@ -67,7 +67,7 @@ export class ApiTraceWaterfallDataSourceModel extends GraphQlDataSourceModel { @@ -117,7 +117,7 @@ export class ApiTraceWaterfallDataSourceModel extends GraphQlDataSourceModel, errorCount: span.errorCount as number, - logEvents: ((span.logEvents as Dictionary) ?? {}).results + logEvents: ((span.logEvents as Dictionary) ?? {}).results ?? [] }; } } From 01b9bbc9d500674c9b03766e4685f01b8941c90b Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Thu, 6 May 2021 19:57:13 +0530 Subject: [PATCH 21/25] fix: lint errors --- .../widgets/waterfall/waterfall/waterfall-chart.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.service.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.service.ts index 0d7ae6748..e98e18f20 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.service.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/waterfall/waterfall/waterfall-chart.service.ts @@ -43,7 +43,7 @@ export class WaterfallChartService { serviceName: datum.serviceName, protocolName: datum.protocolName, hasError: datum.errorCount > 0, - hasLogs: datum.logEvents && datum.logEvents.length > 0 + hasLogs: datum.logEvents.length > 0 }, $$iconType: this.iconLookupService.forSpanType(datum.spanType)!, getChildren: () => of([]), From 88f233aa096676bcd400dee54b06bca41921799f Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Thu, 6 May 2021 20:18:23 +0530 Subject: [PATCH 22/25] fix: test cases --- .../log-detail/data/log-detail-data-source.model.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts index 2c006093f..a73f0216b 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts @@ -15,9 +15,7 @@ describe('Log Detail data source model', () => { key2: 'value2' }; const logEvent: LogEvent = { - traceId: 'id1', attributes: attributes, - spanId: 's-id1', timestamp: '2021-05-05T00:00:00Z', summary: 'test log event' }; From c5b8a4296875d67bfc428da1a5a22d1b5171b888 Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Fri, 7 May 2021 20:07:48 +0530 Subject: [PATCH 23/25] fix: creating table instead of widget renderer --- ...tamp-table-cell-renderer.component.test.ts | 8 +- ...timestamp-table-cell-renderer.component.ts | 17 +-- .../log-events-table.component.scss} | 4 + .../log-events-table.component.test.ts | 70 ++++++++++ .../log-events/log-events-table.component.ts | 120 ++++++++++++++++++ .../log-events/log-events-table.module.ts | 11 ++ .../data/log-detail-data-source.model.test.ts | 47 ------- .../data/log-detail-data-source.model.ts | 21 --- ...g-detail-widget-renderer.component.test.ts | 44 ------- .../log-detail-widget-renderer.component.ts | 49 ------- .../log-detail/log-detail-widget.model.ts | 17 --- .../log-detail/log-detail-widget.module.ts | 25 ---- .../tracing-dashboard-widgets.module.ts | 3 +- 13 files changed, 216 insertions(+), 220 deletions(-) rename projects/distributed-tracing/src/shared/{dashboard/widgets/log-detail/log-detail-widget-renderer.component.scss => components/log-events/log-events-table.component.scss} (70%) create mode 100644 projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.test.ts create mode 100644 projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.ts create mode 100644 projects/distributed-tracing/src/shared/components/log-events/log-events-table.module.ts delete mode 100644 projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts delete mode 100644 projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.ts delete mode 100644 projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.test.ts delete mode 100644 projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts delete mode 100644 projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.model.ts delete mode 100644 projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.module.ts diff --git a/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.test.ts b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.test.ts index bf46650ea..45b76f090 100644 --- a/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.test.ts +++ b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.test.ts @@ -30,13 +30,13 @@ describe('relative timestamp table cell renderer component', () => { test('testing component properties', () => { const logEvent: RowData = { - baseTimestamp: 1619785437887 + baseTimestamp: new Date(1619785437887) }; const spectator = buildComponent({ - providers: [tableCellRowDataProvider(logEvent), tableCellDataProvider('2021-04-30T12:23:57.889149Z')] + providers: [tableCellRowDataProvider(logEvent), tableCellDataProvider(new Date(1619785437887))] }); - expect(spectator.queryAll('.relative-timestamp')[0]).toContainText('2 ms'); - expect(spectator.component.duration).toBe(2); + expect(spectator.queryAll('.relative-timestamp')[0]).toContainText('0 ms'); + expect(spectator.component.duration).toBe(0); }); }); diff --git a/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts index 522f40f9f..e8862f9ba 100644 --- a/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts +++ b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts @@ -1,5 +1,5 @@ import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core'; -import { DateCoercer, DateFormatMode, DateFormatOptions, Dictionary } from '@hypertrace/common'; +import { DateFormatMode, DateFormatOptions, Dictionary } from '@hypertrace/common'; import { TableColumnConfig } from '../../../table-api'; import { TABLE_CELL_DATA, @@ -16,10 +16,8 @@ import { CoreTableCellRendererType } from '../../types/core-table-cell-renderer- import { TableCellAlignmentType } from '../../types/table-cell-alignment-type'; export interface RowData extends Dictionary { - baseTimestamp: DateOrNumber; + baseTimestamp: Date; } - -type DateOrNumber = Date | number; @Component({ selector: 'ht-relative-timestamp-table-cell-renderer', styleUrls: ['./relative-timestamp-table-cell-renderer.component.scss'], @@ -39,24 +37,21 @@ type DateOrNumber = Date | number; alignment: TableCellAlignmentType.Left, parser: CoreTableCellParserType.NoOp }) -export class RelativeTimestampTableCellRendererComponent extends TableCellRendererBase implements OnInit { +export class RelativeTimestampTableCellRendererComponent extends TableCellRendererBase implements OnInit { public readonly dateFormat: DateFormatOptions = { mode: DateFormatMode.DateAndTimeWithSeconds }; public readonly duration: number; - private readonly dateCoercer: DateCoercer = new DateCoercer(); public constructor( @Inject(TABLE_COLUMN_CONFIG) columnConfig: TableColumnConfig, @Inject(TABLE_COLUMN_INDEX) index: number, @Inject(TABLE_DATA_PARSER) - parser: TableCellParserBase, - @Inject(TABLE_CELL_DATA) cellData: DateOrNumber, + parser: TableCellParserBase, + @Inject(TABLE_CELL_DATA) cellData: Date, @Inject(TABLE_ROW_DATA) rowData: RowData ) { super(columnConfig, index, parser, cellData, rowData); - this.duration = - (this.dateCoercer.coerce(cellData)?.getTime() ?? NaN) - - (this.dateCoercer.coerce(rowData.baseTimestamp)?.getTime() ?? NaN); + this.duration = cellData.getTime() - rowData.baseTimestamp.getTime(); } } diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.scss b/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.scss similarity index 70% rename from projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.scss rename to projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.scss index a239d0190..c44b410dc 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.scss +++ b/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.scss @@ -1,5 +1,9 @@ @import 'font'; +.log-events-table { + margin-top: 25px; +} + .content { @include body-2-regular(); margin-left: 175px; diff --git a/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.test.ts b/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.test.ts new file mode 100644 index 000000000..7c03d7cff --- /dev/null +++ b/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.test.ts @@ -0,0 +1,70 @@ +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { fakeAsync, flush } from '@angular/core/testing'; +import { ActivatedRoute } from '@angular/router'; +import { IconLibraryTestingModule } from '@hypertrace/assets-library'; +import { NavigationService } from '@hypertrace/common'; +import { TableComponent, TableModule } from '@hypertrace/components'; +import { runFakeRxjs } from '@hypertrace/test-utils'; +import { createHostFactory, mockProvider, Spectator } from '@ngneat/spectator/jest'; +import { EMPTY } from 'rxjs'; +import { LogEventsTableComponent, LogEventsTableViewType } from './log-events-table.component'; +import { LogEventsTableModule } from './log-events-table.module'; + +describe('LogEventsTableComponent', () => { + let spectator: Spectator; + + const createHost = createHostFactory({ + component: LogEventsTableComponent, + imports: [LogEventsTableModule, TableModule, HttpClientTestingModule, IconLibraryTestingModule], + declareComponent: false, + providers: [ + mockProvider(ActivatedRoute, { + queryParamMap: EMPTY + }), + mockProvider(NavigationService, { + navigation$: EMPTY + }) + ] + }); + + test('should render data correctly for sheet view', fakeAsync(() => { + spectator = createHost( + ``, + { + hostProps: { + logEvents: [ + { attributes: { attr1: 1, attr2: 2 }, summary: 'test', timestamp: '2021-04-30T12:23:57.889149Z' } + ], + logEventsTableViewType: LogEventsTableViewType.Sheet, + spanStartTime: 1619785437887 + } + } + ); + + expect(spectator.query('.log-events-table')).toExist(); + expect(spectator.query(TableComponent)).toExist(); + expect(spectator.query(TableComponent)!.resizable).toBe(false); + expect(spectator.query(TableComponent)!.columnConfigs).toMatchObject([ + expect.objectContaining({ + id: 'timestamp' + }), + expect.objectContaining({ + id: 'summary' + }) + ]); + expect(spectator.query(TableComponent)!.pageable).toBe(false); + expect(spectator.query(TableComponent)!.detailContent).not.toBeNull(); + + runFakeRxjs(({ expectObservable }) => { + expect(spectator.component.dataSource).toBeDefined(); + expectObservable(spectator.component.dataSource!.getData(undefined!)).toBe('(x|)', { + x: { + data: [expect.objectContaining({ summary: 'test' })], + totalCount: 1 + } + }); + + flush(); + }); + })); +}); diff --git a/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.ts b/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.ts new file mode 100644 index 000000000..22bc70c4d --- /dev/null +++ b/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.ts @@ -0,0 +1,120 @@ +import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; +import { DateCoercer, Dictionary } from '@hypertrace/common'; +import { + CoreTableCellRendererType, + ListViewHeader, + ListViewRecord, + TableColumnConfig, + TableDataResponse, + TableDataSource, + TableMode, + TableRow +} from '@hypertrace/components'; +import { isEmpty } from 'lodash-es'; +import { Observable, of } from 'rxjs'; + +export const enum LogEventsTableViewType { + Sheet = 'sheet', + Page = 'page' +} + +@Component({ + selector: 'ht-log-events-table', + styleUrls: ['./log-events-table.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + template: ` +
+ +
+ +
+ +
+
+ ` +}) +export class LogEventsTableComponent implements OnInit { + @Input() + public logEvents: Dictionary[] = []; + + @Input() + public logEventsTableViewType: LogEventsTableViewType = LogEventsTableViewType.Sheet; + + @Input() + public spanStartTime?: number; + + public readonly header: ListViewHeader = { keyLabel: 'key', valueLabel: 'value' }; + private readonly dateCoercer: DateCoercer = new DateCoercer(); + + public dataSource?: TableDataSource; + public columnConfigs: TableColumnConfig[] = []; + + public ngOnInit(): void { + this.buildDataSource(); + this.columnConfigs = this.getTableColumnConfigs(); + } + + public getLogEventAttributeRecords(attributes: Dictionary): ListViewRecord[] { + if (!isEmpty(attributes)) { + return Object.entries(attributes).map((attribute: [string, unknown]) => ({ + key: attribute[0], + value: attribute[1] as string | number + })); + } + + return []; + } + + private buildDataSource(): void { + this.dataSource = { + getData: (): Observable> => + of({ + data: this.logEvents.map((logEvent: Dictionary) => ({ + ...logEvent, + timestamp: this.dateCoercer.coerce(logEvent.timestamp), + baseTimestamp: this.dateCoercer.coerce(this.spanStartTime) + })), + totalCount: this.logEvents.length + }), + getScope: () => undefined + }; + } + + private getTableColumnConfigs(): TableColumnConfig[] { + if (this.logEventsTableViewType === LogEventsTableViewType.Sheet) { + return [ + { + id: 'timestamp', + name: 'timestamp', + title: 'Timestamp', + display: CoreTableCellRendererType.RelativeTimestamp, + visible: true, + width: '150px', + sortable: false, + filterable: false + }, + { + id: 'summary', + name: 'summary', + title: 'Summary', + visible: true, + sortable: false, + filterable: false + } + ]; + } + + return []; + } +} diff --git a/projects/distributed-tracing/src/shared/components/log-events/log-events-table.module.ts b/projects/distributed-tracing/src/shared/components/log-events/log-events-table.module.ts new file mode 100644 index 000000000..59327818f --- /dev/null +++ b/projects/distributed-tracing/src/shared/components/log-events/log-events-table.module.ts @@ -0,0 +1,11 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { FormattingModule } from '@hypertrace/common'; +import { IconModule, ListViewModule, TableModule, TooltipModule } from '@hypertrace/components'; +import { LogEventsTableComponent } from './log-events-table.component'; +@NgModule({ + imports: [CommonModule, TableModule, IconModule, TooltipModule, FormattingModule, ListViewModule], + declarations: [LogEventsTableComponent], + exports: [LogEventsTableComponent] +}) +export class LogEventsTableModule {} diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts deleted file mode 100644 index a73f0216b..000000000 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Dictionary } from '@hypertrace/common'; -import { createModelFactory, SpectatorModel } from '@hypertrace/dashboards/testing'; -import { LogEvent } from '@hypertrace/distributed-tracing'; -import { GraphQlRequestService } from '@hypertrace/graphql-client'; -import { ModelApi } from '@hypertrace/hyperdash'; -import { runFakeRxjs } from '@hypertrace/test-utils'; -import { mockProvider } from '@ngneat/spectator/jest'; -import { of } from 'rxjs'; -import { LogDetailDataSourceModel } from './log-detail-data-source.model'; - -describe('Log Detail data source model', () => { - let spectator!: SpectatorModel; - const attributes: Dictionary = { - key1: 'value1', - key2: 'value2' - }; - const logEvent: LogEvent = { - attributes: attributes, - timestamp: '2021-05-05T00:00:00Z', - summary: 'test log event' - }; - - const buildModel = createModelFactory({ - providers: [ - mockProvider(GraphQlRequestService, { - query: jest.fn().mockReturnValue(of({})) - }) - ] - }); - beforeEach(() => { - const mockApi: Partial = {}; - spectator = buildModel(LogDetailDataSourceModel); - spectator.model.logEvent = logEvent; - spectator.model.api = mockApi as ModelApi; - }); - - test('test attribute data', () => { - runFakeRxjs(({ expectObservable }) => { - expectObservable(spectator.model.getData()).toBe('(x|)', { - x: expect.objectContaining({ - key1: 'value1', - key2: 'value2' - }) - }); - }); - }); -}); diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.ts deleted file mode 100644 index 45ee55a96..000000000 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/data/log-detail-data-source.model.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Dictionary } from '@hypertrace/common'; -import { Model, ModelProperty, PLAIN_OBJECT_PROPERTY } from '@hypertrace/hyperdash'; -import { Observable, of } from 'rxjs'; -import { GraphQlDataSourceModel } from '../../../data/graphql/graphql-data-source.model'; -import { LogEvent } from '../../waterfall/waterfall/waterfall-chart'; - -@Model({ - type: 'log-detail-data-source' -}) -export class LogDetailDataSourceModel extends GraphQlDataSourceModel> { - @ModelProperty({ - key: 'log-event', - required: true, - type: PLAIN_OBJECT_PROPERTY.type - }) - public logEvent?: LogEvent; - - public getData(): Observable> { - return of(this.logEvent?.attributes ?? {}); - } -} diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.test.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.test.ts deleted file mode 100644 index d0911c41c..000000000 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Dictionary, FormattingModule } from '@hypertrace/common'; -import { ListViewComponent, LoadAsyncModule } from '@hypertrace/components'; -import { mockDashboardWidgetProviders } from '@hypertrace/dashboards/testing'; -import { createComponentFactory } from '@ngneat/spectator/jest'; -import { MockComponent } from 'ng-mocks'; -import { of } from 'rxjs'; -import { LogDetailWidgetRendererComponent } from './log-detail-widget-renderer.component'; -import { LogDetailWidgetModel } from './log-detail-widget.model'; - -describe('log detail widget renderer component', () => { - let mockModel: Partial = {}; - const buildComponent = createComponentFactory({ - component: LogDetailWidgetRendererComponent, - providers: [], - imports: [FormattingModule, LoadAsyncModule], - declarations: [MockComponent(ListViewComponent)], - shallow: true - }); - const attributes: Dictionary = { - key1: 1, - key2: 2 - }; - - test('should render list view with provided data', () => { - mockModel = { - getData: jest.fn(() => of(attributes)) - }; - const spectator = buildComponent({ - providers: [...mockDashboardWidgetProviders(mockModel)] - }); - expect(spectator.query('.content')).toExist(); - expect(spectator.query(ListViewComponent)!.header).toEqual(spectator.component.header); - expect(spectator.query(ListViewComponent)!.records).toEqual([ - { - key: 'key1', - value: 1 - }, - { - key: 'key2', - value: 2 - } - ]); - }); -}); diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts deleted file mode 100644 index 89ff8163e..000000000 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget-renderer.component.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject } from '@angular/core'; -import { Dictionary } from '@hypertrace/common'; -import { ListViewHeader, ListViewRecord } from '@hypertrace/components'; -import { WidgetRenderer } from '@hypertrace/dashboards'; -import { Renderer } from '@hypertrace/hyperdash'; -import { RendererApi, RENDERER_API } from '@hypertrace/hyperdash-angular'; -import { isEmpty } from 'lodash-es'; -import { Observable } from 'rxjs'; -import { LogDetailWidgetModel } from './log-detail-widget.model'; - -@Renderer({ modelClass: LogDetailWidgetModel }) -@Component({ - selector: 'ht-log-detail-widget-renderer', - styleUrls: ['./log-detail-widget-renderer.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, - template: ` -
- -
- ` -}) -export class LogDetailWidgetRendererComponent extends WidgetRenderer> { - public constructor( - @Inject(RENDERER_API) public readonly api: RendererApi, - protected readonly changeDetector: ChangeDetectorRef - ) { - super(api, changeDetector); - } - public readonly header: ListViewHeader = { keyLabel: 'key', valueLabel: 'value' }; - - protected fetchData(): Observable> { - return this.model.getData(); - } - - public getLogEventAttributeRecords(attributes: Dictionary): ListViewRecord[] { - if (!isEmpty(attributes)) { - return Object.entries(attributes).map((attribute: [string, unknown]) => ({ - key: attribute[0], - value: attribute[1] as string | number - })); - } - - return []; - } -} diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.model.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.model.ts deleted file mode 100644 index f0653db48..000000000 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.model.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Dictionary } from '@hypertrace/common'; -import { Model, ModelApi } from '@hypertrace/hyperdash'; -import { ModelInject, MODEL_API } from '@hypertrace/hyperdash-angular'; -import { Observable } from 'rxjs'; - -@Model({ - type: 'log-detail-widget', - supportedDataSourceTypes: [] -}) -export class LogDetailWidgetModel { - @ModelInject(MODEL_API) - private readonly api!: ModelApi; - - public getData(): Observable> { - return this.api.getData>(); - } -} diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.module.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.module.ts deleted file mode 100644 index 6bd32a7d6..000000000 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/log-detail/log-detail-widget.module.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ListViewModule, LoadAsyncModule, SummaryValueModule, TitledContentModule } from '@hypertrace/components'; -import { DashboardCoreModule } from '@hypertrace/hyperdash-angular'; -import { SpanDetailModule } from '../../../components/span-detail/span-detail.module'; -import { LogDetailDataSourceModel } from './data/log-detail-data-source.model'; -import { LogDetailWidgetRendererComponent } from './log-detail-widget-renderer.component'; -import { LogDetailWidgetModel } from './log-detail-widget.model'; - -@NgModule({ - declarations: [LogDetailWidgetRendererComponent], - imports: [ - DashboardCoreModule.with({ - models: [LogDetailWidgetModel, LogDetailDataSourceModel], - renderers: [LogDetailWidgetRendererComponent] - }), - CommonModule, - SpanDetailModule, - TitledContentModule, - ListViewModule, - LoadAsyncModule, - SummaryValueModule - ] -}) -export class LogDetailWidgetModule {} diff --git a/projects/distributed-tracing/src/shared/dashboard/widgets/tracing-dashboard-widgets.module.ts b/projects/distributed-tracing/src/shared/dashboard/widgets/tracing-dashboard-widgets.module.ts index aea045b49..e48cf5a49 100644 --- a/projects/distributed-tracing/src/shared/dashboard/widgets/tracing-dashboard-widgets.module.ts +++ b/projects/distributed-tracing/src/shared/dashboard/widgets/tracing-dashboard-widgets.module.ts @@ -1,11 +1,10 @@ import { NgModule } from '@angular/core'; -import { LogDetailWidgetModule } from './log-detail/log-detail-widget.module'; import { SpanDetailWidgetModule } from './span-detail/span-detail-widget.module'; import { TableWidgetModule } from './table/table-widget.module'; import { TraceDetailModule } from './trace-detail/trace-detail-widget.module'; import { WaterfallWidgetModule } from './waterfall/waterfall-widget.module'; @NgModule({ - imports: [SpanDetailWidgetModule, LogDetailWidgetModule, TableWidgetModule, TraceDetailModule, WaterfallWidgetModule] + imports: [SpanDetailWidgetModule, TableWidgetModule, TraceDetailModule, WaterfallWidgetModule] }) export class TracingDashboardWidgetsModule {} From 29f2bdd1651b50a05b5a6ca68e795a0e4cf30d80 Mon Sep 17 00:00:00 2001 From: Sandeep Sharma <78212931+itssharmasandeep@users.noreply.github.com> Date: Fri, 7 May 2021 20:22:23 +0530 Subject: [PATCH 24/25] feat: log records in the span sheet (#819) * feat: log records in the span sheet --- .../components/span-detail/span-detail.component.ts | 10 ++++++++++ .../components/span-detail/span-detail.module.ts | 4 +++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/projects/distributed-tracing/src/shared/components/span-detail/span-detail.component.ts b/projects/distributed-tracing/src/shared/components/span-detail/span-detail.component.ts index 8c518c2fc..9f54a2901 100644 --- a/projects/distributed-tracing/src/shared/components/span-detail/span-detail.component.ts +++ b/projects/distributed-tracing/src/shared/components/span-detail/span-detail.component.ts @@ -46,6 +46,12 @@ import { SpanDetailLayoutStyle } from './span-detail-layout-style'; + + + ` @@ -66,12 +72,16 @@ export class SpanDetailComponent implements OnChanges { public showRequestTab?: boolean; public showResponseTab?: boolean; public showExitCallsTab?: boolean; + public showLogEventstab?: boolean; + public totalLogEvents?: number; public ngOnChanges(changes: TypedSimpleChanges): void { if (changes.spanData) { this.showRequestTab = !isEmpty(this.spanData?.requestHeaders) || !isEmpty(this.spanData?.requestBody); this.showResponseTab = !isEmpty(this.spanData?.responseHeaders) || !isEmpty(this.spanData?.responseBody); this.showExitCallsTab = !isEmpty(this.spanData?.exitCallsBreakup); + this.showLogEventstab = !isEmpty(this.spanData?.logEvents); + this.totalLogEvents = (this.spanData?.logEvents ?? []).length; } } } diff --git a/projects/distributed-tracing/src/shared/components/span-detail/span-detail.module.ts b/projects/distributed-tracing/src/shared/components/span-detail/span-detail.module.ts index 2bd41a72b..4312d4b1c 100644 --- a/projects/distributed-tracing/src/shared/components/span-detail/span-detail.module.ts +++ b/projects/distributed-tracing/src/shared/components/span-detail/span-detail.module.ts @@ -11,6 +11,7 @@ import { ToggleButtonModule, TooltipModule } from '@hypertrace/components'; +import { LogEventsTableModule } from '../log-events/log-events-table.module'; import { SpanExitCallsModule } from './exit-calls/span-exit-calls.module'; import { SpanDetailTitleHeaderModule } from './headers/title/span-detail-title-header.module'; import { SpanRequestDetailModule } from './request/span-request-detail.module'; @@ -34,7 +35,8 @@ import { SpanTagsDetailModule } from './tags/span-tags-detail.module'; LoadAsyncModule, ListViewModule, SpanDetailTitleHeaderModule, - SpanExitCallsModule + SpanExitCallsModule, + LogEventsTableModule ], declarations: [SpanDetailComponent], exports: [SpanDetailComponent] From e0b2ef41040fcafbea6e54e019e8536e73cfdac1 Mon Sep 17 00:00:00 2001 From: Sandeep Kumar Sharma Date: Tue, 11 May 2021 13:23:28 +0530 Subject: [PATCH 25/25] fix: addressing review comments --- ...timestamp-table-cell-renderer.component.ts | 2 +- .../log-events-table.component.test.ts | 2 +- .../log-events/log-events-table.component.ts | 25 ++++++++++--------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts index e8862f9ba..8e69fbbf1 100644 --- a/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts +++ b/projects/components/src/table/cells/data-renderers/relative-timestamp/relative-timestamp-table-cell-renderer.component.ts @@ -52,6 +52,6 @@ export class RelativeTimestampTableCellRendererComponent extends TableCellRender @Inject(TABLE_ROW_DATA) rowData: RowData ) { super(columnConfig, index, parser, cellData, rowData); - this.duration = cellData.getTime() - rowData.baseTimestamp.getTime(); + this.duration = cellData?.getTime() - rowData?.baseTimestamp?.getTime(); } } diff --git a/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.test.ts b/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.test.ts index 7c03d7cff..f8a5c53ab 100644 --- a/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.test.ts +++ b/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.test.ts @@ -35,7 +35,7 @@ describe('LogEventsTableComponent', () => { logEvents: [ { attributes: { attr1: 1, attr2: 2 }, summary: 'test', timestamp: '2021-04-30T12:23:57.889149Z' } ], - logEventsTableViewType: LogEventsTableViewType.Sheet, + logEventsTableViewType: LogEventsTableViewType.Condensed, spanStartTime: 1619785437887 } } diff --git a/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.ts b/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.ts index 22bc70c4d..0865353b2 100644 --- a/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.ts +++ b/projects/distributed-tracing/src/shared/components/log-events/log-events-table.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core'; import { DateCoercer, Dictionary } from '@hypertrace/common'; import { CoreTableCellRendererType, @@ -10,12 +10,13 @@ import { TableMode, TableRow } from '@hypertrace/components'; +import { LogEvent } from '@hypertrace/distributed-tracing'; import { isEmpty } from 'lodash-es'; import { Observable, of } from 'rxjs'; export const enum LogEventsTableViewType { - Sheet = 'sheet', - Page = 'page' + Condensed = 'condensed', + Detailed = 'detailed' } @Component({ @@ -44,12 +45,12 @@ export const enum LogEventsTableViewType { ` }) -export class LogEventsTableComponent implements OnInit { +export class LogEventsTableComponent implements OnChanges { @Input() - public logEvents: Dictionary[] = []; + public logEvents: LogEvent[] = []; @Input() - public logEventsTableViewType: LogEventsTableViewType = LogEventsTableViewType.Sheet; + public logEventsTableViewType: LogEventsTableViewType = LogEventsTableViewType.Condensed; @Input() public spanStartTime?: number; @@ -60,16 +61,16 @@ export class LogEventsTableComponent implements OnInit { public dataSource?: TableDataSource; public columnConfigs: TableColumnConfig[] = []; - public ngOnInit(): void { + public ngOnChanges(): void { this.buildDataSource(); this.columnConfigs = this.getTableColumnConfigs(); } public getLogEventAttributeRecords(attributes: Dictionary): ListViewRecord[] { if (!isEmpty(attributes)) { - return Object.entries(attributes).map((attribute: [string, unknown]) => ({ - key: attribute[0], - value: attribute[1] as string | number + return Object.entries(attributes).map(([key, value]) => ({ + key: key, + value: value as string | number })); } @@ -80,7 +81,7 @@ export class LogEventsTableComponent implements OnInit { this.dataSource = { getData: (): Observable> => of({ - data: this.logEvents.map((logEvent: Dictionary) => ({ + data: this.logEvents.map((logEvent: LogEvent) => ({ ...logEvent, timestamp: this.dateCoercer.coerce(logEvent.timestamp), baseTimestamp: this.dateCoercer.coerce(this.spanStartTime) @@ -92,7 +93,7 @@ export class LogEventsTableComponent implements OnInit { } private getTableColumnConfigs(): TableColumnConfig[] { - if (this.logEventsTableViewType === LogEventsTableViewType.Sheet) { + if (this.logEventsTableViewType === LogEventsTableViewType.Condensed) { return [ { id: 'timestamp',