diff --git a/packages/jaeger-ui/src/components/Monitor/ServicesView/__snapshots__/index.test.js.snap b/packages/jaeger-ui/src/components/Monitor/ServicesView/__snapshots__/index.test.js.snap index 512a5226cf..498d0c9169 100644 --- a/packages/jaeger-ui/src/components/Monitor/ServicesView/__snapshots__/index.test.js.snap +++ b/packages/jaeger-ui/src/components/Monitor/ServicesView/__snapshots__/index.test.js.snap @@ -12,7 +12,7 @@ exports[` ATM snapshot test 1`] = `

- Choose service + Service

ATM snapshot test 1`] = ` + +

+ Span Kind +

+ + + + + + + + ATM snapshot test with no metrics 1`] = `

- Choose service + Service

ATM snapshot test with no metrics 1`] = ` } /> + +

+ Span Kind +

+ + + + + + + +
render one service latency 1`] = `

- Choose service + Service

render one service latency 1`] = ` } /> + +

+ Span Kind +

+ + + + + + + +
', () => { it('Should track all events', () => { const trackSelectServiceSpy = jest.spyOn(track, 'trackSelectService'); const trackViewAllTracesSpy = jest.spyOn(track, 'trackViewAllTraces'); + const trackSelectSpanKindSpy = jest.spyOn(track, 'trackSelectSpanKind'); const trackSelectTimeframeSpy = jest.spyOn(track, 'trackSelectTimeframe'); const trackSearchOperationSpy = jest.spyOn(track, 'trackSearchOperation'); const newValue = 'newValue'; + const [spanKindOption] = spanKindOptions; const [timeFrameOption] = timeFrameOptions; wrapper.setProps({ @@ -308,6 +311,9 @@ describe('', () => { wrapper.find('Field').first().simulate('change', null, newValue); expect(trackSelectServiceSpy).toHaveBeenCalledWith(newValue); + wrapper.find({ name: 'spanKind' }).simulate('change', null, spanKindOption.value); + expect(trackSelectSpanKindSpy).toHaveBeenCalledWith(spanKindOption.label); + wrapper.find('Field').last().simulate('change', null, timeFrameOption.value); expect(trackSelectTimeframeSpy).toHaveBeenCalledWith(timeFrameOption.label); @@ -316,6 +322,7 @@ describe('', () => { trackSelectServiceSpy.mockReset(); trackViewAllTracesSpy.mockReset(); + trackSelectSpanKindSpy.mockReset(); trackSelectTimeframeSpy.mockReset(); trackSearchOperationSpy.mockReset(); }); @@ -361,6 +368,7 @@ describe('mapStateToProps()', () => { metrics: originInitialState, services: [], selectedService: 's1', + selectedSpanKind: 'server', selectedTimeFrame: 3600000, }); }); diff --git a/packages/jaeger-ui/src/components/Monitor/ServicesView/index.track.test.js b/packages/jaeger-ui/src/components/Monitor/ServicesView/index.track.test.js index 515a7a58f8..c784444f16 100644 --- a/packages/jaeger-ui/src/components/Monitor/ServicesView/index.track.test.js +++ b/packages/jaeger-ui/src/components/Monitor/ServicesView/index.track.test.js @@ -18,7 +18,9 @@ import { CATEGORY_SELECT_SERVICE, CATEGORY_SELECT_TIMEFRAME, CATEGORY_VIEW_ALL_TRACES, + CATEGORY_SELECT_SPAN_KIND, trackSelectService, + trackSelectSpanKind, trackSelectTimeframe, trackViewAllTraces, trackSearchOperation, @@ -46,6 +48,12 @@ describe('ServicesView tracking', () => { expect(trackEvent).toHaveBeenCalledWith(CATEGORY_SELECT_SERVICE, serviceName); }); + it('trackSelectSpanKind calls trackEvent with the match category and show action', () => { + const spanKind = 'producer'; + trackSelectSpanKind(spanKind); + expect(trackEvent).toHaveBeenCalledWith(CATEGORY_SELECT_SPAN_KIND, spanKind); + }); + it('trackSelectTimeframe calls trackEvent with the match category and show action', () => { const timeframe = 'some-timeframe'; trackSelectTimeframe(timeframe); diff --git a/packages/jaeger-ui/src/components/Monitor/ServicesView/index.track.tsx b/packages/jaeger-ui/src/components/Monitor/ServicesView/index.track.tsx index 0ae66ad4b9..680e3aac08 100644 --- a/packages/jaeger-ui/src/components/Monitor/ServicesView/index.track.tsx +++ b/packages/jaeger-ui/src/components/Monitor/ServicesView/index.track.tsx @@ -18,11 +18,13 @@ const SPM_CATEGORY_BASE = 'jaeger/ux/trace/spm'; export const CATEGORY_VIEW_ALL_TRACES = `${SPM_CATEGORY_BASE}/view-all-traces`; export const CATEGORY_SELECT_SERVICE = `${SPM_CATEGORY_BASE}/select-service`; +export const CATEGORY_SELECT_SPAN_KIND = `${SPM_CATEGORY_BASE}/select-span-kind`; export const CATEGORY_SELECT_TIMEFRAME = `${SPM_CATEGORY_BASE}/select-timeframe`; export const CATEGORY_SEARCH_OPERATION = `${SPM_CATEGORY_BASE}/search-operation`; export const trackViewAllTraces = () => trackEvent(CATEGORY_VIEW_ALL_TRACES, 'click'); export const trackSelectService = (service: string) => trackEvent(CATEGORY_SELECT_SERVICE, service); +export const trackSelectSpanKind = (spanKind: string) => trackEvent(CATEGORY_SELECT_SPAN_KIND, spanKind); export const trackSelectTimeframe = (timeframe: string) => trackEvent(CATEGORY_SELECT_TIMEFRAME, timeframe); export const trackSearchOperation = (searchQuery: string) => trackEvent(CATEGORY_SEARCH_OPERATION, searchQuery); diff --git a/packages/jaeger-ui/src/components/Monitor/ServicesView/index.tsx b/packages/jaeger-ui/src/components/Monitor/ServicesView/index.tsx index e22a42bd6f..8ce0b037b6 100644 --- a/packages/jaeger-ui/src/components/Monitor/ServicesView/index.tsx +++ b/packages/jaeger-ui/src/components/Monitor/ServicesView/index.tsx @@ -37,6 +37,7 @@ import { Points, ServiceMetricsObject, ServiceOpsMetrics, + spanKinds, } from '../../../types/metrics'; import prefixUrl from '../../../utils/prefix-url'; import { convertToTimeUnit, convertTimeUnitToShortTerm, getSuitableTimeUnit } from '../../../utils/date'; @@ -46,6 +47,7 @@ import { getConfigValue } from '../../../utils/config/get-config'; import { trackSearchOperation, trackSelectService, + trackSelectSpanKind, trackSelectTimeframe, trackViewAllTraces, } from './index.track'; @@ -64,6 +66,7 @@ type TReduxProps = { servicesLoading: boolean; metrics: MetricsReduxState; selectedService: string; + selectedSpanKind: spanKinds; selectedTimeFrame: number; }; @@ -94,6 +97,13 @@ export const timeFrameOptions = [ { label: 'Last 24 hours', value: 24 * oneHourInMilliSeconds }, { label: 'Last 2 days', value: 48 * oneHourInMilliSeconds }, ]; +export const spanKindOptions = [ + { label: 'Client', value: 'client' }, + { label: 'Server', value: 'server' }, + { label: 'Internal', value: 'internal' }, + { label: 'Producer', value: 'producer' }, + { label: 'Consumer', value: 'consumer' }, +]; // export for tests export const getLoopbackInterval = (interval: number) => { @@ -166,9 +176,13 @@ export class MonitorATMServicesViewImpl extends React.PureComponent -

Choose service

+

Service

trackSelectService(newValue)} name="service" @@ -287,6 +304,31 @@ export class MonitorATMServicesViewImpl extends React.PureComponent + +

Span Kind

+ { + const { label } = spanKindOptions.find(option => option.value === value)!; + trackSelectSpanKind(label); + }} + props={{ + className: 'span-kind-selector', + defaultValue: 'server', + value: selectedSpanKind, + disabled: metrics.operationMetricsLoading, + loading: metrics.operationMetricsLoading, + }} + > + {spanKindOptions.map(option => ( + + ))} + +
@@ -435,6 +477,8 @@ export function mapStateToProps(state: ReduxState): TReduxProps { servicesLoading: services.loading, metrics, selectedService: serviceFormSelector(state, 'service') || store.get('lastAtmSearchService'), + selectedSpanKind: + serviceFormSelector(state, 'spanKind') || store.get('lastAtmSearchSpanKind') || 'server', selectedTimeFrame: serviceFormSelector(state, 'timeframe') || store.get('lastAtmSearchTimeframe') || oneHourInMilliSeconds, }; diff --git a/packages/jaeger-ui/src/types/metrics.tsx b/packages/jaeger-ui/src/types/metrics.tsx index af694cf050..bef57b0d58 100644 --- a/packages/jaeger-ui/src/types/metrics.tsx +++ b/packages/jaeger-ui/src/types/metrics.tsx @@ -23,14 +23,16 @@ export type AvailableOpsMetrics = | 'service_operation_latencies' | 'service_operation_error_rate'; +export type spanKinds = 'unspecified' | 'internal' | 'server' | 'client' | 'producer' | 'consumer'; + export type MetricsAPIQueryParams = { quantile: number; groupByOperation?: boolean; - endTs?: number; - lookback?: number; - step?: number; - ratePer?: number; - spanKind?: 'unspecified' | 'internal' | 'server' | 'client' | 'producer' | 'consumer'; + endTs: number; + lookback: number; + step: number; + ratePer: number; + spanKind: spanKinds; }; export type LableObject = {