mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Traces: Span bar label (#50931)
* Add SpanBarSettings * Add SpanBarSettings to Jaeger * Add SpanBarSettings to Zipkin * Updated title * Add dropdown to select identifer and make duration a default option * Show duration by default * Add option to hide * Move identifers into constants * Add process * Update text * Update placeholders * Text/meta data updates * Added tests * Added docs * Update find * Merge tag and prcoess options * Update docs * Updated tests * Update betterer results and trace view to match * Updated docs
This commit is contained in:
parent
21591be469
commit
01130f22b7
8325
.betterer.results
8325
.betterer.results
File diff suppressed because it is too large
Load Diff
@ -66,6 +66,16 @@ This is a configuration for the beta Node Graph visualization. The Node Graph is
|
|||||||
|
|
||||||
-- **Enable Node Graph -** Enables the Node Graph visualization.
|
-- **Enable Node Graph -** Enables the Node Graph visualization.
|
||||||
|
|
||||||
|
### Span bar label
|
||||||
|
|
||||||
|
You can configure the span bar label. The span bar label allows you add additional information to the span bar row.
|
||||||
|
|
||||||
|
Select one of the following four options. The default selection is Duration.
|
||||||
|
|
||||||
|
- **None -** Do not show any additional information on the span bar row.
|
||||||
|
- **Duration -** Show the span duration on the span bar row.
|
||||||
|
- **Tag -** Show the span tag on the span bar row. Note: You will also need to specify the tag key to use to get the tag value. For example, `span.kind`.
|
||||||
|
|
||||||
## Query traces
|
## Query traces
|
||||||
|
|
||||||
You can query and display traces from Jaeger via [Explore]({{< relref "../explore/" >}}).
|
You can query and display traces from Jaeger via [Explore]({{< relref "../explore/" >}}).
|
||||||
|
@ -84,6 +84,16 @@ This is a configuration for the Loki search query type.
|
|||||||
|
|
||||||
-- **Data source -** The Loki instance in which you want to search traces. You must configure derived fields in the Loki instance.
|
-- **Data source -** The Loki instance in which you want to search traces. You must configure derived fields in the Loki instance.
|
||||||
|
|
||||||
|
### Span bar label
|
||||||
|
|
||||||
|
You can configure the span bar label. The span bar label allows you add additional information to the span bar row.
|
||||||
|
|
||||||
|
Select one of the following four options. The default selection is Duration.
|
||||||
|
|
||||||
|
- **None -** Do not show any additional information on the span bar row.
|
||||||
|
- **Duration -** Show the span duration on the span bar row.
|
||||||
|
- **Tag -** Show the span tag on the span bar row. Note: You will also need to specify the tag key to use to get the tag value. For example, `span.kind`.
|
||||||
|
|
||||||
## Query traces
|
## Query traces
|
||||||
|
|
||||||
You can query and display traces from Tempo via [Explore]({{< relref "../explore/" >}}).
|
You can query and display traces from Tempo via [Explore]({{< relref "../explore/" >}}).
|
||||||
|
@ -65,6 +65,16 @@ This is a configuration for the beta Node Graph visualization. The Node Graph is
|
|||||||
|
|
||||||
-- **Enable Node Graph -** Enables the Node Graph visualization.
|
-- **Enable Node Graph -** Enables the Node Graph visualization.
|
||||||
|
|
||||||
|
### Span bar label
|
||||||
|
|
||||||
|
You can configure the span bar label. The span bar label allows you add additional information to the span bar row.
|
||||||
|
|
||||||
|
Select one of the following four options. The default selection is Duration.
|
||||||
|
|
||||||
|
- **None -** Do not show any additional information on the span bar row.
|
||||||
|
- **Duration -** Show the span duration on the span bar row.
|
||||||
|
- **Tag -** Show the span tag on the span bar row. Note: You will also need to specify the tag key to use to get the tag value. For example, `span.kind`.
|
||||||
|
|
||||||
## Query traces
|
## Query traces
|
||||||
|
|
||||||
Querying and displaying traces from Zipkin is available via [Explore]({{< relref "../explore/" >}}).
|
Querying and displaying traces from Zipkin is available via [Explore]({{< relref "../explore/" >}}).
|
||||||
|
@ -16,6 +16,8 @@ import { render, screen } from '@testing-library/react';
|
|||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import { NONE, DURATION, TAG } from '../settings/SpanBarSettings';
|
||||||
|
|
||||||
import SpanBarRow from './SpanBarRow';
|
import SpanBarRow from './SpanBarRow';
|
||||||
|
|
||||||
describe('<SpanBarRow>', () => {
|
describe('<SpanBarRow>', () => {
|
||||||
@ -43,11 +45,10 @@ describe('<SpanBarRow>', () => {
|
|||||||
showErrorIcon: false,
|
showErrorIcon: false,
|
||||||
getViewedBounds: () => ({ start: 0, end: 1 }),
|
getViewedBounds: () => ({ start: 0, end: 1 }),
|
||||||
span: {
|
span: {
|
||||||
duration: 'test-duration',
|
duration: 9000,
|
||||||
hasChildren: true,
|
hasChildren: true,
|
||||||
process: {
|
process: {
|
||||||
serviceName: 'service-name',
|
serviceName: 'service-name',
|
||||||
tags: [],
|
|
||||||
},
|
},
|
||||||
spanID,
|
spanID,
|
||||||
logs: [],
|
logs: [],
|
||||||
@ -181,4 +182,89 @@ describe('<SpanBarRow>', () => {
|
|||||||
);
|
);
|
||||||
expect(screen.getAllByTestId('SpanLinksMenu')).toHaveLength(1);
|
expect(screen.getAllByTestId('SpanLinksMenu')).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('render span bar label', () => {
|
||||||
|
it('with default value', () => {
|
||||||
|
render(<SpanBarRow {...props} />);
|
||||||
|
expect(screen.getByText('(9ms)')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with none value', () => {
|
||||||
|
const testProps = Object.assign(
|
||||||
|
{
|
||||||
|
spanBarOptions: {
|
||||||
|
type: NONE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props
|
||||||
|
);
|
||||||
|
render(<SpanBarRow {...testProps} />);
|
||||||
|
expect(screen.queryByText('(9ms)')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with duration value', () => {
|
||||||
|
const testProps = Object.assign(
|
||||||
|
{
|
||||||
|
spanBarOptions: {
|
||||||
|
type: DURATION,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props
|
||||||
|
);
|
||||||
|
render(<SpanBarRow {...testProps} />);
|
||||||
|
expect(screen.getByText('(9ms)')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with tag value', () => {
|
||||||
|
const testProps = Object.assign(
|
||||||
|
{
|
||||||
|
spanBarOptions: {
|
||||||
|
type: TAG,
|
||||||
|
tag: 'tag',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...props,
|
||||||
|
span: {
|
||||||
|
process: {},
|
||||||
|
tags: [
|
||||||
|
{
|
||||||
|
key: 'tag',
|
||||||
|
value: 'tag-value',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
render(<SpanBarRow {...testProps} />);
|
||||||
|
expect(screen.getByText('(tag-value)')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with process value', () => {
|
||||||
|
let testProps = Object.assign(
|
||||||
|
{
|
||||||
|
spanBarOptions: {
|
||||||
|
type: TAG,
|
||||||
|
tag: 'tag',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...props,
|
||||||
|
span: {
|
||||||
|
process: {
|
||||||
|
tags: [
|
||||||
|
{
|
||||||
|
key: 'tag',
|
||||||
|
value: 'process-value',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
tags: [],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
render(<SpanBarRow {...testProps} />);
|
||||||
|
expect(screen.getByText('(process-value)')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -18,11 +18,12 @@ import * as React from 'react';
|
|||||||
import IoAlert from 'react-icons/lib/io/alert';
|
import IoAlert from 'react-icons/lib/io/alert';
|
||||||
import IoArrowRightA from 'react-icons/lib/io/arrow-right-a';
|
import IoArrowRightA from 'react-icons/lib/io/arrow-right-a';
|
||||||
|
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
import { GrafanaTheme2, TraceKeyValuePair } from '@grafana/data';
|
||||||
import { stylesFactory, withTheme2 } from '@grafana/ui';
|
import { stylesFactory, withTheme2 } from '@grafana/ui';
|
||||||
|
|
||||||
import { autoColor } from '../Theme';
|
import { autoColor } from '../Theme';
|
||||||
import { SpanLinkFunc, TNil } from '../types';
|
import { DURATION, NONE, TAG } from '../settings/SpanBarSettings';
|
||||||
|
import { SpanBarOptions, SpanLinkFunc, TNil } from '../types';
|
||||||
import { SpanLinks } from '../types/links';
|
import { SpanLinks } from '../types/links';
|
||||||
import { TraceSpan } from '../types/trace';
|
import { TraceSpan } from '../types/trace';
|
||||||
|
|
||||||
@ -290,6 +291,7 @@ type SpanBarRowProps = {
|
|||||||
className?: string;
|
className?: string;
|
||||||
theme: GrafanaTheme2;
|
theme: GrafanaTheme2;
|
||||||
color: string;
|
color: string;
|
||||||
|
spanBarOptions: SpanBarOptions | undefined;
|
||||||
columnDivision: number;
|
columnDivision: number;
|
||||||
isChildrenExpanded: boolean;
|
isChildrenExpanded: boolean;
|
||||||
isDetailExpanded: boolean;
|
isDetailExpanded: boolean;
|
||||||
@ -352,6 +354,7 @@ export class UnthemedSpanBarRow extends React.PureComponent<SpanBarRowProps> {
|
|||||||
const {
|
const {
|
||||||
className,
|
className,
|
||||||
color,
|
color,
|
||||||
|
spanBarOptions,
|
||||||
columnDivision,
|
columnDivision,
|
||||||
isChildrenExpanded,
|
isChildrenExpanded,
|
||||||
isDetailExpanded,
|
isDetailExpanded,
|
||||||
@ -379,6 +382,7 @@ export class UnthemedSpanBarRow extends React.PureComponent<SpanBarRowProps> {
|
|||||||
process: { serviceName },
|
process: { serviceName },
|
||||||
} = span;
|
} = span;
|
||||||
const label = formatDuration(duration);
|
const label = formatDuration(duration);
|
||||||
|
|
||||||
const viewBounds = getViewedBounds(span.startTime, span.startTime + span.duration);
|
const viewBounds = getViewedBounds(span.startTime, span.startTime + span.duration);
|
||||||
const viewStart = viewBounds.start;
|
const viewStart = viewBounds.start;
|
||||||
const viewEnd = viewBounds.end;
|
const viewEnd = viewBounds.end;
|
||||||
@ -473,7 +477,7 @@ export class UnthemedSpanBarRow extends React.PureComponent<SpanBarRowProps> {
|
|||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
<small className={styles.endpointName}>{rpc ? rpc.operationName : operationName}</small>
|
<small className={styles.endpointName}>{rpc ? rpc.operationName : operationName}</small>
|
||||||
<small className={styles.endpointName}> | {label}</small>
|
<small className={styles.endpointName}> {this.getSpanBarLabel(span, spanBarOptions, label)}</small>
|
||||||
</a>
|
</a>
|
||||||
{createSpanLink &&
|
{createSpanLink &&
|
||||||
(() => {
|
(() => {
|
||||||
@ -542,6 +546,35 @@ export class UnthemedSpanBarRow extends React.PureComponent<SpanBarRowProps> {
|
|||||||
</TimelineRow>
|
</TimelineRow>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSpanBarLabel = (span: TraceSpan, spanBarOptions: SpanBarOptions | undefined, duration: string) => {
|
||||||
|
const type = spanBarOptions?.type ?? '';
|
||||||
|
|
||||||
|
if (type === NONE) {
|
||||||
|
return '';
|
||||||
|
} else if (type === '' || type === DURATION) {
|
||||||
|
return `(${duration})`;
|
||||||
|
} else if (type === TAG) {
|
||||||
|
const tagKey = spanBarOptions?.tag?.trim() ?? '';
|
||||||
|
if (tagKey !== '' && span.tags) {
|
||||||
|
const tag = span.tags?.find((tag: TraceKeyValuePair) => {
|
||||||
|
return tag.key === tagKey;
|
||||||
|
});
|
||||||
|
const process = span.process?.tags?.find((process: TraceKeyValuePair) => {
|
||||||
|
return process.key === tagKey;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (tag) {
|
||||||
|
return `(${tag.value})`;
|
||||||
|
}
|
||||||
|
if (process) {
|
||||||
|
return `(${process.value})`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withTheme2(UnthemedSpanBarRow);
|
export default withTheme2(UnthemedSpanBarRow);
|
||||||
|
@ -23,7 +23,7 @@ import { stylesFactory, withTheme2, ToolbarButton } from '@grafana/ui';
|
|||||||
|
|
||||||
import { Accessors } from '../ScrollManager';
|
import { Accessors } from '../ScrollManager';
|
||||||
import { PEER_SERVICE } from '../constants/tag-keys';
|
import { PEER_SERVICE } from '../constants/tag-keys';
|
||||||
import { SpanLinkFunc, TNil } from '../types';
|
import { SpanBarOptions, SpanLinkFunc, TNil } from '../types';
|
||||||
import TTraceTimeline from '../types/TTraceTimeline';
|
import TTraceTimeline from '../types/TTraceTimeline';
|
||||||
import { TraceLog, TraceSpan, Trace, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace';
|
import { TraceLog, TraceSpan, Trace, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace';
|
||||||
import { getColorByKey } from '../utils/color-generator';
|
import { getColorByKey } from '../utils/color-generator';
|
||||||
@ -89,6 +89,7 @@ type TVirtualizedTraceViewOwnProps = {
|
|||||||
scrollToFirstVisibleSpan: () => void;
|
scrollToFirstVisibleSpan: () => void;
|
||||||
registerAccessors: (accesors: Accessors) => void;
|
registerAccessors: (accesors: Accessors) => void;
|
||||||
trace: Trace;
|
trace: Trace;
|
||||||
|
spanBarOptions: SpanBarOptions | undefined;
|
||||||
linksGetter: (span: TraceSpan, items: TraceKeyValuePair[], itemIndex: number) => TraceLink[];
|
linksGetter: (span: TraceSpan, items: TraceKeyValuePair[], itemIndex: number) => TraceLink[];
|
||||||
childrenToggle: (spanID: string) => void;
|
childrenToggle: (spanID: string) => void;
|
||||||
clearShouldScrollToFirstUiFindMatch: () => void;
|
clearShouldScrollToFirstUiFindMatch: () => void;
|
||||||
@ -387,6 +388,7 @@ export class UnthemedVirtualizedTraceView extends React.Component<VirtualizedTra
|
|||||||
findMatchesIDs,
|
findMatchesIDs,
|
||||||
spanNameColumnWidth,
|
spanNameColumnWidth,
|
||||||
trace,
|
trace,
|
||||||
|
spanBarOptions,
|
||||||
hoverIndentGuideIds,
|
hoverIndentGuideIds,
|
||||||
addHoverIndentGuideId,
|
addHoverIndentGuideId,
|
||||||
removeHoverIndentGuideId,
|
removeHoverIndentGuideId,
|
||||||
@ -440,6 +442,7 @@ export class UnthemedVirtualizedTraceView extends React.Component<VirtualizedTra
|
|||||||
clippingLeft={this.getClipping().left}
|
clippingLeft={this.getClipping().left}
|
||||||
clippingRight={this.getClipping().right}
|
clippingRight={this.getClipping().right}
|
||||||
color={color}
|
color={color}
|
||||||
|
spanBarOptions={spanBarOptions}
|
||||||
columnDivision={spanNameColumnWidth}
|
columnDivision={spanNameColumnWidth}
|
||||||
isChildrenExpanded={!isCollapsed}
|
isChildrenExpanded={!isCollapsed}
|
||||||
isDetailExpanded={isDetailExpanded}
|
isDetailExpanded={isDetailExpanded}
|
||||||
|
@ -21,6 +21,7 @@ import { stylesFactory, withTheme2 } from '@grafana/ui';
|
|||||||
import { Accessors } from '../ScrollManager';
|
import { Accessors } from '../ScrollManager';
|
||||||
import { autoColor } from '../Theme';
|
import { autoColor } from '../Theme';
|
||||||
import { merge as mergeShortcuts } from '../keyboard-shortcuts';
|
import { merge as mergeShortcuts } from '../keyboard-shortcuts';
|
||||||
|
import { SpanBarOptions } from '../settings/SpanBarSettings';
|
||||||
import { SpanLinkFunc, TNil } from '../types';
|
import { SpanLinkFunc, TNil } from '../types';
|
||||||
import TTraceTimeline from '../types/TTraceTimeline';
|
import TTraceTimeline from '../types/TTraceTimeline';
|
||||||
import { TraceSpan, Trace, TraceLog, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace';
|
import { TraceSpan, Trace, TraceLog, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace';
|
||||||
@ -75,6 +76,7 @@ type TProps = TExtractUiFindFromStateReturn & {
|
|||||||
scrollToFirstVisibleSpan: () => void;
|
scrollToFirstVisibleSpan: () => void;
|
||||||
traceTimeline: TTraceTimeline;
|
traceTimeline: TTraceTimeline;
|
||||||
trace: Trace;
|
trace: Trace;
|
||||||
|
spanBarOptions: SpanBarOptions | undefined;
|
||||||
updateNextViewRangeTime: (update: ViewRangeTimeUpdate) => void;
|
updateNextViewRangeTime: (update: ViewRangeTimeUpdate) => void;
|
||||||
updateViewRangeTime: TUpdateViewRangeTimeFunction;
|
updateViewRangeTime: TUpdateViewRangeTimeFunction;
|
||||||
viewRange: ViewRange;
|
viewRange: ViewRange;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
export { default as TraceTimelineViewer } from './TraceTimelineViewer';
|
export { default as TraceTimelineViewer } from './TraceTimelineViewer';
|
||||||
export { default as TracePageHeader } from './TracePageHeader';
|
export { default as TracePageHeader } from './TracePageHeader';
|
||||||
|
export { default as SpanBarSettings } from './settings/SpanBarSettings';
|
||||||
export * from './types';
|
export * from './types';
|
||||||
export * from './TraceTimelineViewer/types';
|
export * from './TraceTimelineViewer/types';
|
||||||
export { default as DetailState } from './TraceTimelineViewer/SpanDetail/DetailState';
|
export { default as DetailState } from './TraceTimelineViewer/SpanDetail/DetailState';
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
import { css } from '@emotion/css';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
DataSourceJsonData,
|
||||||
|
DataSourcePluginOptionsEditorProps,
|
||||||
|
GrafanaTheme,
|
||||||
|
toOption,
|
||||||
|
updateDatasourcePluginJsonDataOption,
|
||||||
|
} from '@grafana/data';
|
||||||
|
import { InlineField, InlineFieldRow, Input, Select, useStyles } from '@grafana/ui';
|
||||||
|
|
||||||
|
export interface SpanBarOptions {
|
||||||
|
type?: string;
|
||||||
|
tag?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SpanBarOptionsData extends DataSourceJsonData {
|
||||||
|
spanBar?: SpanBarOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NONE = 'None';
|
||||||
|
export const DURATION = 'Duration';
|
||||||
|
export const TAG = 'Tag';
|
||||||
|
|
||||||
|
interface Props extends DataSourcePluginOptionsEditorProps<SpanBarOptionsData> {}
|
||||||
|
|
||||||
|
export default function SpanBarSettings({ options, onOptionsChange }: Props) {
|
||||||
|
const styles = useStyles(getStyles);
|
||||||
|
const selectOptions = [NONE, DURATION, TAG].map(toOption);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={css({ width: '100%' })}>
|
||||||
|
<h3 className="page-heading">Span bar label</h3>
|
||||||
|
|
||||||
|
<div className={styles.infoText}>Span bar label lets you add additional info to the span bar row.</div>
|
||||||
|
|
||||||
|
<InlineFieldRow className={styles.row}>
|
||||||
|
<InlineField label="Label" labelWidth={26} grow>
|
||||||
|
<Select
|
||||||
|
inputId="label"
|
||||||
|
options={selectOptions}
|
||||||
|
value={options.jsonData.spanBar?.type || ''}
|
||||||
|
onChange={(v) => {
|
||||||
|
updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'spanBar', {
|
||||||
|
...options.jsonData.spanBar,
|
||||||
|
type: v?.value ?? '',
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
placeholder="Duration"
|
||||||
|
isClearable
|
||||||
|
aria-label={'select-label-name'}
|
||||||
|
width={25}
|
||||||
|
/>
|
||||||
|
</InlineField>
|
||||||
|
</InlineFieldRow>
|
||||||
|
{options.jsonData.spanBar?.type === TAG && (
|
||||||
|
<InlineFieldRow className={styles.row}>
|
||||||
|
<InlineField label="Tag key" labelWidth={26} tooltip="Tag key which will be used to get the tag value">
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter tag key"
|
||||||
|
onChange={(v) =>
|
||||||
|
updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'spanBar', {
|
||||||
|
...options.jsonData.spanBar,
|
||||||
|
tag: v.currentTarget.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
value={options.jsonData.spanBar?.tag || ''}
|
||||||
|
width={25}
|
||||||
|
/>
|
||||||
|
</InlineField>
|
||||||
|
</InlineFieldRow>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getStyles = (theme: GrafanaTheme) => ({
|
||||||
|
infoText: css`
|
||||||
|
label: infoText;
|
||||||
|
padding-bottom: ${theme.spacing.md};
|
||||||
|
color: ${theme.colors.textSemiWeak};
|
||||||
|
`,
|
||||||
|
|
||||||
|
row: css`
|
||||||
|
label: row;
|
||||||
|
align-items: baseline;
|
||||||
|
`,
|
||||||
|
});
|
@ -13,6 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
export { TraceSpan, TraceResponse, Trace, TraceProcess, TraceKeyValuePair, TraceLink } from './trace';
|
export { TraceSpan, TraceResponse, Trace, TraceProcess, TraceKeyValuePair, TraceLink } from './trace';
|
||||||
export { SpanLinkFunc, SpanLinkDef } from './links';
|
export { SpanBarOptions, SpanBarOptionsData } from '../settings/SpanBarSettings';
|
||||||
export { default as TTraceTimeline } from './TTraceTimeline';
|
export { default as TTraceTimeline } from './TTraceTimeline';
|
||||||
export { default as TNil } from './TNil';
|
export { default as TNil } from './TNil';
|
||||||
|
export { SpanLinkFunc, SpanLinkDef } from './links';
|
||||||
|
@ -18,7 +18,13 @@ import {
|
|||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { getTemplateSrv } from '@grafana/runtime';
|
import { getTemplateSrv } from '@grafana/runtime';
|
||||||
import { useStyles2 } from '@grafana/ui';
|
import { useStyles2 } from '@grafana/ui';
|
||||||
import { Trace, TracePageHeader, TraceTimelineViewer, TTraceTimeline } from '@jaegertracing/jaeger-ui-components';
|
import {
|
||||||
|
SpanBarOptionsData,
|
||||||
|
Trace,
|
||||||
|
TracePageHeader,
|
||||||
|
TraceTimelineViewer,
|
||||||
|
TTraceTimeline,
|
||||||
|
} from '@jaegertracing/jaeger-ui-components';
|
||||||
import { TraceToLogsData } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
import { TraceToLogsData } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
||||||
import { TraceToMetricsData } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
import { TraceToMetricsData } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
||||||
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||||
@ -118,6 +124,7 @@ export function TraceView(props: Props) {
|
|||||||
const instanceSettings = getDatasourceSrv().getInstanceSettings(datasource?.name);
|
const instanceSettings = getDatasourceSrv().getInstanceSettings(datasource?.name);
|
||||||
const traceToLogsOptions = (instanceSettings?.jsonData as TraceToLogsData)?.tracesToLogs;
|
const traceToLogsOptions = (instanceSettings?.jsonData as TraceToLogsData)?.tracesToLogs;
|
||||||
const traceToMetricsOptions = (instanceSettings?.jsonData as TraceToMetricsData)?.tracesToMetrics;
|
const traceToMetricsOptions = (instanceSettings?.jsonData as TraceToMetricsData)?.tracesToMetrics;
|
||||||
|
const spanBarOptions: SpanBarOptionsData | undefined = instanceSettings?.jsonData;
|
||||||
|
|
||||||
const createSpanLink = useMemo(
|
const createSpanLink = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@ -155,6 +162,7 @@ export function TraceView(props: Props) {
|
|||||||
scrollToFirstVisibleSpan={noop}
|
scrollToFirstVisibleSpan={noop}
|
||||||
findMatchesIDs={spanFindMatches}
|
findMatchesIDs={spanFindMatches}
|
||||||
trace={traceProp}
|
trace={traceProp}
|
||||||
|
spanBarOptions={spanBarOptions?.spanBar}
|
||||||
traceTimeline={traceTimeline}
|
traceTimeline={traceTimeline}
|
||||||
updateNextViewRangeTime={updateNextViewRangeTime}
|
updateNextViewRangeTime={updateNextViewRangeTime}
|
||||||
updateViewRangeTime={updateViewRangeTime}
|
updateViewRangeTime={updateViewRangeTime}
|
||||||
|
@ -3,6 +3,7 @@ import React from 'react';
|
|||||||
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { DataSourceHttpSettings } from '@grafana/ui';
|
import { DataSourceHttpSettings } from '@grafana/ui';
|
||||||
|
import { SpanBarSettings } from '@jaegertracing/jaeger-ui-components';
|
||||||
import { NodeGraphSettings } from 'app/core/components/NodeGraphSettings';
|
import { NodeGraphSettings } from 'app/core/components/NodeGraphSettings';
|
||||||
import { TraceToLogsSettings } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
import { TraceToLogsSettings } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
||||||
import { TraceToMetricsSettings } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
import { TraceToMetricsSettings } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
||||||
@ -32,6 +33,10 @@ export const ConfigEditor: React.FC<Props> = ({ options, onOptionsChange }) => {
|
|||||||
<div className="gf-form-group">
|
<div className="gf-form-group">
|
||||||
<NodeGraphSettings options={options} onOptionsChange={onOptionsChange} />
|
<NodeGraphSettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="gf-form-group">
|
||||||
|
<SpanBarSettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -15,6 +15,7 @@ import {
|
|||||||
ScopedVars,
|
ScopedVars,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { BackendSrvRequest, getBackendSrv, getTemplateSrv, TemplateSrv } from '@grafana/runtime';
|
import { BackendSrvRequest, getBackendSrv, getTemplateSrv, TemplateSrv } from '@grafana/runtime';
|
||||||
|
import { SpanBarOptions } from '@jaegertracing/jaeger-ui-components';
|
||||||
import { NodeGraphOptions } from 'app/core/components/NodeGraphSettings';
|
import { NodeGraphOptions } from 'app/core/components/NodeGraphSettings';
|
||||||
import { serializeParams } from 'app/core/utils/fetch';
|
import { serializeParams } from 'app/core/utils/fetch';
|
||||||
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
@ -32,6 +33,7 @@ export interface JaegerJsonData extends DataSourceJsonData {
|
|||||||
export class JaegerDatasource extends DataSourceApi<JaegerQuery, JaegerJsonData> {
|
export class JaegerDatasource extends DataSourceApi<JaegerQuery, JaegerJsonData> {
|
||||||
uploadedJson: string | ArrayBuffer | null = null;
|
uploadedJson: string | ArrayBuffer | null = null;
|
||||||
nodeGraph?: NodeGraphOptions;
|
nodeGraph?: NodeGraphOptions;
|
||||||
|
spanBar?: SpanBarOptions;
|
||||||
constructor(
|
constructor(
|
||||||
private instanceSettings: DataSourceInstanceSettings<JaegerJsonData>,
|
private instanceSettings: DataSourceInstanceSettings<JaegerJsonData>,
|
||||||
private readonly timeSrv: TimeSrv = getTimeSrv(),
|
private readonly timeSrv: TimeSrv = getTimeSrv(),
|
||||||
|
@ -3,6 +3,7 @@ import React from 'react';
|
|||||||
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { DataSourceHttpSettings } from '@grafana/ui';
|
import { DataSourceHttpSettings } from '@grafana/ui';
|
||||||
|
import { SpanBarSettings } from '@jaegertracing/jaeger-ui-components';
|
||||||
import { NodeGraphSettings } from 'app/core/components/NodeGraphSettings';
|
import { NodeGraphSettings } from 'app/core/components/NodeGraphSettings';
|
||||||
import { TraceToLogsSettings } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
import { TraceToLogsSettings } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
||||||
import { TraceToMetricsSettings } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
import { TraceToMetricsSettings } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
||||||
@ -50,6 +51,10 @@ export const ConfigEditor: React.FC<Props> = ({ options, onOptionsChange }) => {
|
|||||||
<div className="gf-form-group">
|
<div className="gf-form-group">
|
||||||
<LokiSearchSettings options={options} onOptionsChange={onOptionsChange} />
|
<LokiSearchSettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="gf-form-group">
|
||||||
|
<SpanBarSettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -24,6 +24,7 @@ import {
|
|||||||
TemplateSrv,
|
TemplateSrv,
|
||||||
getTemplateSrv,
|
getTemplateSrv,
|
||||||
} from '@grafana/runtime';
|
} from '@grafana/runtime';
|
||||||
|
import { SpanBarOptions } from '@jaegertracing/jaeger-ui-components';
|
||||||
import { NodeGraphOptions } from 'app/core/components/NodeGraphSettings';
|
import { NodeGraphOptions } from 'app/core/components/NodeGraphSettings';
|
||||||
import { TraceToLogsOptions } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
import { TraceToLogsOptions } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
||||||
import { serializeParams } from 'app/core/utils/fetch';
|
import { serializeParams } from 'app/core/utils/fetch';
|
||||||
@ -65,6 +66,9 @@ export interface TempoJsonData extends DataSourceJsonData {
|
|||||||
lokiSearch?: {
|
lokiSearch?: {
|
||||||
datasourceUid?: string;
|
datasourceUid?: string;
|
||||||
};
|
};
|
||||||
|
spanBar?: {
|
||||||
|
tag: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TempoQuery extends DataQuery {
|
export interface TempoQuery extends DataQuery {
|
||||||
@ -105,6 +109,7 @@ export class TempoDatasource extends DataSourceWithBackend<TempoQuery, TempoJson
|
|||||||
datasourceUid?: string;
|
datasourceUid?: string;
|
||||||
};
|
};
|
||||||
uploadedJson?: string | ArrayBuffer | null = null;
|
uploadedJson?: string | ArrayBuffer | null = null;
|
||||||
|
spanBar?: SpanBarOptions;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private instanceSettings: DataSourceInstanceSettings<TempoJsonData>,
|
private instanceSettings: DataSourceInstanceSettings<TempoJsonData>,
|
||||||
|
@ -3,6 +3,7 @@ import React from 'react';
|
|||||||
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { DataSourceHttpSettings } from '@grafana/ui';
|
import { DataSourceHttpSettings } from '@grafana/ui';
|
||||||
|
import { SpanBarSettings } from '@jaegertracing/jaeger-ui-components';
|
||||||
import { NodeGraphSettings } from 'app/core/components/NodeGraphSettings';
|
import { NodeGraphSettings } from 'app/core/components/NodeGraphSettings';
|
||||||
import { TraceToLogsSettings } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
import { TraceToLogsSettings } from 'app/core/components/TraceToLogs/TraceToLogsSettings';
|
||||||
import { TraceToMetricsSettings } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
import { TraceToMetricsSettings } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';
|
||||||
@ -32,6 +33,10 @@ export const ConfigEditor: React.FC<Props> = ({ options, onOptionsChange }) => {
|
|||||||
<div className="gf-form-group">
|
<div className="gf-form-group">
|
||||||
<NodeGraphSettings options={options} onOptionsChange={onOptionsChange} />
|
<NodeGraphSettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="gf-form-group">
|
||||||
|
<SpanBarSettings options={options} onOptionsChange={onOptionsChange} />
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
MutableDataFrame,
|
MutableDataFrame,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { BackendSrvRequest, FetchResponse, getBackendSrv } from '@grafana/runtime';
|
import { BackendSrvRequest, FetchResponse, getBackendSrv } from '@grafana/runtime';
|
||||||
|
import { SpanBarOptions } from '@jaegertracing/jaeger-ui-components';
|
||||||
import { NodeGraphOptions } from 'app/core/components/NodeGraphSettings';
|
import { NodeGraphOptions } from 'app/core/components/NodeGraphSettings';
|
||||||
|
|
||||||
import { serializeParams } from '../../../core/utils/fetch';
|
import { serializeParams } from '../../../core/utils/fetch';
|
||||||
@ -27,6 +28,7 @@ export interface ZipkinJsonData extends DataSourceJsonData {
|
|||||||
export class ZipkinDatasource extends DataSourceApi<ZipkinQuery, ZipkinJsonData> {
|
export class ZipkinDatasource extends DataSourceApi<ZipkinQuery, ZipkinJsonData> {
|
||||||
uploadedJson: string | ArrayBuffer | null = null;
|
uploadedJson: string | ArrayBuffer | null = null;
|
||||||
nodeGraph?: NodeGraphOptions;
|
nodeGraph?: NodeGraphOptions;
|
||||||
|
spanBar?: SpanBarOptions;
|
||||||
constructor(private instanceSettings: DataSourceInstanceSettings<ZipkinJsonData>) {
|
constructor(private instanceSettings: DataSourceInstanceSettings<ZipkinJsonData>) {
|
||||||
super(instanceSettings);
|
super(instanceSettings);
|
||||||
this.nodeGraph = instanceSettings.jsonData.nodeGraph;
|
this.nodeGraph = instanceSettings.jsonData.nodeGraph;
|
||||||
|
Loading…
Reference in New Issue
Block a user