Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 2.x] Update custom traces table with filters #2180

Merged
merged 1 commit into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions common/constants/trace_analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,28 @@ export const TRACE_ANALYTICS_DSL_ROUTE = '/api/observability/trace_analytics/que

export const TRACE_CUSTOM_SPAN_INDEX_SETTING = 'observability:traceAnalyticsSpanIndices';
export const TRACE_CUSTOM_SERVICE_INDEX_SETTING = 'observability:traceAnalyticsServiceIndices';

export enum TRACE_TABLE_TITLES {
all_spans = 'All Spans',
root_spans = 'Root Spans',
entry_spans = 'Service Entry Spans',
traces = 'Traces',
}

const getDescription = (key: keyof typeof TRACE_TABLE_TITLES): string => {
const descriptions: Record<keyof typeof TRACE_TABLE_TITLES, string> = {
all_spans: 'Spans representing all activities in all traces across the system',
root_spans: 'Spans marking the root or starting point of each trace',
entry_spans: 'Spans that indicate the entry point of service-side processing',
traces: 'Spans grouped by traceId to show a complete trace lifecycle',
};
return descriptions[key];
};

export const TRACE_TABLE_OPTIONS = Object.entries(TRACE_TABLE_TITLES).map(([key, label]) => ({
label,
key,
'aria-describedby': getDescription(key as keyof typeof TRACE_TABLE_TITLES),
}));

export const TRACE_TABLE_TYPE_KEY = 'TraceAnalyticsTraceTableType';
3 changes: 3 additions & 0 deletions common/types/trace_analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { TRACE_TABLE_TITLES } from '../constants/trace_analytics';

export type SpanField =
| 'SPAN_ID'
| 'PARENT_SPAN_ID'
Expand Down Expand Up @@ -54,3 +56,4 @@ export interface GraphVisEdge {
}

export type TraceAnalyticsMode = 'jaeger' | 'data_prepper' | 'custom_data_prepper';
export type TraceQueryMode = keyof typeof TRACE_TABLE_TITLES;
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
const [serviceFlyoutName, setServiceFlyoutName] = useState<string>('');
const [traceFlyoutId, setTraceFlyoutId] = useState<string>('');
const [spanFlyoutId, setSpanFlyoutId] = useState<string>('');
const [spanDSL, setSpanDSL] = useState<any>({});

Check warning on line 136 in public/components/application_analytics/components/application.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
const [totalSpans, setTotalSpans] = useState<number>(0);
const [editVizId, setEditVizId] = useState<string>('');
const [visWithAvailability, setVisWithAvailability] = useState<EuiSelectOption[]>([]);
Expand All @@ -156,7 +156,7 @@
sessionStorage.setItem(`${application.name}EndTime`, newEndTime);
};

const addSpanFilter = (field: string, value: any) => {

Check warning on line 159 in public/components/application_analytics/components/application.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
const newFilters = [...filters];
const index = newFilters.findIndex(({ field: filterField }) => field === filterField);
if (index === -1) {
Expand Down Expand Up @@ -285,7 +285,7 @@
},
];

const nameColumnAction = (item: any) => openServiceFlyout(item);

Check warning on line 288 in public/components/application_analytics/components/application.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
const traceColumnAction = () => switchToTrace();

const getService = () => {
Expand Down Expand Up @@ -326,6 +326,9 @@
setStartTime={setStartTimeForApp}
setEndTime={setEndTimeForApp}
dataSourceMDSId={[{ id: '', label: '' }]}
setCurrentSelectedService={() => {}}
tracesTableMode="traces"
setTracesTableMode={() => {}}
/>
<EuiPanel>
<PanelTitle title="Spans" totalItems={totalSpans} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -907,10 +907,10 @@ exports[`Added Integration View Test Renders added integration view using dummy
</EuiFlexGroup>
</EuiSearchBar>
<EuiSpacer
size="l"
size="m"
>
<div
className="euiSpacer euiSpacer--l"
className="euiSpacer euiSpacer--m"
/>
</EuiSpacer>
<EuiBasicTable
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import {
EuiButtonIcon,
EuiCopy,
EuiFlexGroup,
EuiFlexItem,
EuiLink,
EuiTableFieldDataColumnType,
EuiText,
EuiToolTip,
} from '@elastic/eui';
import { round } from 'lodash';
import moment from 'moment';
import React from 'react';
import { TRACE_ANALYTICS_DATE_FORMAT } from '../../../../../common/constants/trace_analytics';
import { TraceAnalyticsMode, TraceQueryMode } from '../../../../../common/types/trace_analytics';
import { nanoToMilliSec } from '../common/helper_functions';

export const fetchDynamicColumns = (columnItems: string[]) => {
return columnItems
.filter((col) => col.includes('attributes') || col.includes('instrumentation'))
.map((col) => ({
className: 'attributes-column',
field: col,
name: (
<EuiText className="euiTableCellContent">
<EuiToolTip content={col}>
<p className="euiTableCellContent__text attributes-column-header">{col}</p>
</EuiToolTip>
</EuiText>
),
align: 'right',
sortable: true,
truncateText: true,
render: (item) =>
item ? (
<EuiText>
<EuiToolTip content={item}>
<EuiText size="s" className="attributes-column" title={item}>
{item}
</EuiText>
</EuiToolTip>
</EuiText>
) : (
'-'
),
}));
};

export const getTableColumns = (
showAttributes: boolean,
columnItems: string[],
mode: TraceAnalyticsMode,
tracesTableMode: TraceQueryMode,
getTraceViewUri?: (traceId: string) => string,
openTraceFlyout?: (traceId: string) => void
): Array<EuiTableFieldDataColumnType<any>> => {

Check warning on line 61 in public/components/trace_analytics/components/traces/trace_table_helpers.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
// Helper functions for rendering table fields
const renderIdField = (item: string) =>
item ? (
<EuiText>
<EuiToolTip content={item}>
<EuiText size="s" className="traces-table traces-table-trace-id" title={item}>
{item}
</EuiText>
</EuiToolTip>
</EuiText>
) : (
'-'
);

const renderTraceLinkField = (item: string) => (
<EuiFlexGroup gutterSize="s" alignItems="center">
<EuiFlexItem grow={false}>
<EuiLink
data-test-subj="trace-link"
{...(getTraceViewUri && { href: getTraceViewUri(item) })}
{...(openTraceFlyout && { onClick: () => openTraceFlyout(item) })}
>
<EuiText size="s" className="traces-table traces-table-trace-id" title={item}>
{item}
</EuiText>
</EuiLink>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiCopy textToCopy={item}>
{(copy) => (
<EuiButtonIcon aria-label="Copy trace id" iconType="copyClipboard" onClick={copy} />
)}
</EuiCopy>
</EuiFlexItem>
</EuiFlexGroup>
);

const renderErrorsField = (item: number) =>
item == null ? (
'-'
) : +item > 0 ? (
<EuiText color="danger" size="s">
Yes
</EuiText>
) : (
'No'
);

const renderDurationField = (item: number) =>
item ? <EuiText size="s">{round(nanoToMilliSec(Math.max(0, item)), 2)}</EuiText> : '-';

const renderDateField = (item: number) =>
item === 0 || item ? moment(item).format(TRACE_ANALYTICS_DATE_FORMAT) : '-';

// Columns for custom_data_prepper mode
if (mode === 'custom_data_prepper' && tracesTableMode !== 'traces') {
return [
{
field: 'spanId',
name: 'Span Id',
align: 'left',
sortable: true,
render: renderIdField,
className: 'span-group-column',
},
{
field: 'traceId',
name: 'Trace Id',
align: 'left',
sortable: true,
render: renderTraceLinkField,
},
{
field: 'parentSpanId',
name: 'Parent Span Id',
align: 'left',
sortable: true,
render: renderIdField,
className: 'span-group-column',
},
{
field: 'traceGroup',
name: 'Trace group',
align: 'left',
sortable: true,
truncateText: true,
},
{
field: 'durationInNanos',
name: 'Duration (ms)',
align: 'right',
sortable: true,
render: renderDurationField,
},
{
field: 'status.code',
name: 'Errors',
align: 'right',
sortable: true,
render: renderErrorsField,
},
{
field: 'endTime',
name: 'Last updated',
align: 'right',
sortable: true,
render: renderDateField,
className: 'span-group-column',
},
...(showAttributes ? fetchDynamicColumns(columnItems) : []),
] as Array<EuiTableFieldDataColumnType<any>>;

Check warning on line 172 in public/components/trace_analytics/components/traces/trace_table_helpers.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
}

// Columns for non-jaeger traces mode
if (mode !== 'jaeger' && tracesTableMode === 'traces') {
return [
{
field: 'trace_id',
name: 'Trace ID',
align: 'left',
sortable: true,
render: renderTraceLinkField,
},
{
field: 'trace_group',
name: 'Trace group',
align: 'left',
sortable: true,
truncateText: true,
},
{
field: 'latency',
name: 'Duration (ms)',
align: 'right',
sortable: true,
truncateText: true,
},
{
field: 'percentile_in_trace_group',
name: 'Percentile in trace group',
align: 'right',
sortable: true,
render: (item) => (item ? `${round(item, 2)}th` : '-'),
},
{
field: 'error_count',
name: 'Errors',
align: 'right',
sortable: true,
render: renderErrorsField,
},
{
field: 'last_updated',
name: 'Last updated',
align: 'left',
sortable: true,
className: 'span-group-column',
},
] as Array<EuiTableFieldDataColumnType<any>>;

Check warning on line 220 in public/components/trace_analytics/components/traces/trace_table_helpers.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
}

// Default columns for other modes
return [
{
field: 'trace_id',
name: 'Trace ID',
align: 'left',
sortable: true,
render: renderTraceLinkField,
},
{ field: 'latency', name: 'Latency (ms)', align: 'right', sortable: true },
{
field: 'error_count',
name: 'Errors',
align: 'right',
sortable: true,
render: renderErrorsField,
},
{
field: 'last_updated',
name: 'Last updated',
align: 'left',
sortable: true,
className: 'span-group-column',
},
] as Array<EuiTableFieldDataColumnType<any>>;

Check warning on line 247 in public/components/trace_analytics/components/traces/trace_table_helpers.tsx

View workflow job for this annotation

GitHub Actions / Lint

Unexpected any. Specify a different type
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { EuiBreadcrumb } from '@elastic/eui';
import { Toast } from '@elastic/eui/src/components/toast/global_toast_list';
import React from 'react';
import { DataSourceOption } from '../../../../../../../src/plugins/data_source_management/public/components/data_source_menu/types';
import { TraceQueryMode } from '../../../../../common/types/trace_analytics';
import { TraceAnalyticsComponentDeps } from '../../home';
import { TracesContent } from './traces_content';

Expand All @@ -18,6 +19,8 @@ export interface TracesProps extends TraceAnalyticsComponentDeps {
openTraceFlyout?: (traceId: string) => void;
toasts: Toast[];
dataSourceMDSId: DataSourceOption[];
tracesTableMode: TraceQueryMode;
setTracesTableMode: React.Dispatch<React.SetStateAction<TraceQueryMode>>;
}

export function Traces(props: TracesProps) {
Expand Down
Loading
Loading