Commit 271cc670 by Zoltán Bedi Committed by GitHub

Data: Prefix trace types in data package (#25810)

parent 615b000a
......@@ -17,62 +17,62 @@
*/
// TODO: Everett Tech Debt: Fix KeyValuePair types
export type KeyValuePair = {
export type TraceKeyValuePair = {
key: string;
type?: string;
value: any;
};
export type Link = {
export type TraceLink = {
url: string;
text: string;
};
export type Log = {
export type TraceLog = {
timestamp: number;
fields: KeyValuePair[];
fields: TraceKeyValuePair[];
};
export type Process = {
export type TraceProcess = {
serviceName: string;
tags: KeyValuePair[];
tags: TraceKeyValuePair[];
};
export type SpanReference = {
export type TraceSpanReference = {
refType: 'CHILD_OF' | 'FOLLOWS_FROM';
// eslint-disable-next-line no-use-before-define
span?: Span | null | undefined;
span?: TraceSpan | null | undefined;
spanID: string;
traceID: string;
};
export type SpanData = {
export type TraceSpanData = {
spanID: string;
traceID: string;
processID: string;
operationName: string;
startTime: number;
duration: number;
logs: Log[];
tags?: KeyValuePair[];
references?: SpanReference[];
logs: TraceLog[];
tags?: TraceKeyValuePair[];
references?: TraceSpanReference[];
warnings?: string[] | null;
flags: number;
};
export type Span = SpanData & {
export type TraceSpan = TraceSpanData & {
depth: number;
hasChildren: boolean;
process: Process;
process: TraceProcess;
relativeStartTime: number;
tags: NonNullable<SpanData['tags']>;
references: NonNullable<SpanData['references']>;
warnings: NonNullable<SpanData['warnings']>;
subsidiarilyReferencedBy: SpanReference[];
tags: NonNullable<TraceSpanData['tags']>;
references: NonNullable<TraceSpanData['references']>;
warnings: NonNullable<TraceSpanData['warnings']>;
subsidiarilyReferencedBy: TraceSpanReference[];
};
export type TraceData = {
processes: Record<string, Process>;
processes: Record<string, TraceProcess>;
traceID: string;
warnings?: string[] | null;
};
......@@ -80,7 +80,7 @@ export type TraceData = {
export type Trace = TraceData & {
duration: number;
endTime: number;
spans: Span[];
spans: TraceSpan[];
startTime: number;
traceName: string;
services: Array<{ name: string; numberOfSpans: number }>;
......
......@@ -13,7 +13,7 @@
// limitations under the License.
import { TNil } from './types';
import { Span, SpanReference, Trace } from '@grafana/data';
import { TraceSpan, TraceSpanReference, Trace } from '@grafana/data';
/**
* `Accessors` is necessary because `ScrollManager` needs to be created by
......@@ -37,7 +37,7 @@ export type Accessors = {
mapSpanIndexToRowIndex: (spanIndex: number) => number;
};
interface IScroller {
interface Scroller {
scrollTo: (rowIndex: number) => void;
// TODO arg names throughout
scrollBy: (rowIndex: number, opt?: boolean) => void;
......@@ -47,18 +47,18 @@ interface IScroller {
* Returns `{ isHidden: true, ... }` if one of the parents of `span` is
* collapsed, e.g. has children hidden.
*
* @param {Span} span The Span to check for.
* @param {TraceSpan} span The Span to check for.
* @param {Set<string>} childrenAreHidden The set of Spans known to have hidden
* children, either because it is
* collapsed or has a collapsed parent.
* @param {Map<string, Span | TNil} spansMap Mapping from spanID to Span.
* @param {Map<string, TraceSpan | TNil} spansMap Mapping from spanID to Span.
* @returns {{ isHidden: boolean, parentIds: Set<string> }}
*/
function isSpanHidden(span: Span, childrenAreHidden: Set<string>, spansMap: Map<string, Span | TNil>) {
function isSpanHidden(span: TraceSpan, childrenAreHidden: Set<string>, spansMap: Map<string, TraceSpan | TNil>) {
const parentIDs = new Set<string>();
let { references }: { references: SpanReference[] | TNil } = span;
let { references }: { references: TraceSpanReference[] | TNil } = span;
let parentID: undefined | string;
const checkRef = (ref: SpanReference) => {
const checkRef = (ref: TraceSpanReference) => {
if (ref.refType === 'CHILD_OF' || ref.refType === 'FOLLOWS_FROM') {
parentID = ref.spanID;
parentIDs.add(parentID);
......@@ -87,10 +87,10 @@ function isSpanHidden(span: Span, childrenAreHidden: Set<string>, spansMap: Map<
*/
export default class ScrollManager {
_trace: Trace | TNil;
_scroller: IScroller;
_scroller: Scroller;
_accessors: Accessors | TNil;
constructor(trace: Trace | TNil, scroller: IScroller) {
constructor(trace: Trace | TNil, scroller: Scroller) {
this._trace = trace;
this._scroller = scroller;
this._accessors = undefined;
......@@ -157,8 +157,8 @@ export default class ScrollManager {
const _collapsed = xrs.getCollapsedChildren();
const childrenAreHidden = _collapsed ? new Set(_collapsed) : null;
// use empty Map as fallback to make flow happy
const spansMap: Map<string, Span> = childrenAreHidden
? new Map(spans.map(s => [s.spanID, s] as [string, Span]))
const spansMap: Map<string, TraceSpan> = childrenAreHidden
? new Map(spans.map(s => [s.spanID, s] as [string, TraceSpan]))
: new Map();
const boundary = direction < 0 ? -1 : spans.length;
let nextSpanIndex: number | undefined;
......
......@@ -19,7 +19,7 @@ import CanvasSpanGraph from './CanvasSpanGraph';
import TickLabels from './TickLabels';
import ViewingLayer from './ViewingLayer';
import { TUpdateViewRangeTimeFunction, ViewRange, ViewRangeTimeUpdate } from '../..';
import { Span, Trace } from '@grafana/data';
import { TraceSpan, Trace } from '@grafana/data';
import { ubPb2, ubPx2, ubRelative } from '../../uberUtilityStyles';
const DEFAULT_HEIGHT = 60;
......@@ -45,7 +45,7 @@ type SpanGraphState = {
}>;
};
function getItem(span: Span) {
function getItem(span: TraceSpan) {
return {
valueOffset: span.relativeStartTime,
valueWidth: span.duration,
......
......@@ -15,7 +15,7 @@
import React from 'react';
import { css } from 'emotion';
import NewWindowIcon from '../common/NewWindowIcon';
import { SpanReference } from '@grafana/data';
import { TraceSpanReference } from '@grafana/data';
import { UITooltip, UIDropdown, UIMenuItem, UIMenu, TooltipPlacement } from '../uiElementsContext';
import ReferenceLink from '../url/ReferenceLink';
......@@ -44,14 +44,14 @@ export const getStyles = createStyle(() => {
});
type TReferencesButtonProps = {
references: SpanReference[];
references: TraceSpanReference[];
children: React.ReactNode;
tooltipText: string;
focusSpan: (spanID: string) => void;
};
export default class ReferencesButton extends React.PureComponent<TReferencesButtonProps> {
referencesList = (references: SpanReference[]) => {
referencesList = (references: TraceSpanReference[]) => {
const styles = getStyles();
return (
<UIMenu>
......
......@@ -22,7 +22,7 @@ import AccordianLogs from './SpanDetail/AccordianLogs';
import { ViewedBoundsFunctionType } from './utils';
import { TNil } from '../types';
import { Span } from '@grafana/data';
import { TraceSpan } from '@grafana/data';
import { UIPopover } from '../uiElementsContext';
import { createStyle } from '../Theme';
......@@ -113,7 +113,7 @@ type TCommonProps = {
}
| TNil;
traceStartTime: number;
span: Span;
span: TraceSpan;
className?: string;
labelClassName?: string;
};
......
......@@ -28,7 +28,7 @@ import SpanBar from './SpanBar';
import Ticks from './Ticks';
import { TNil } from '../types';
import { Span } from '@grafana/data';
import { TraceSpan } from '@grafana/data';
import { autoColor, createStyle, Theme, withTheme } from '../Theme';
const getStyles = createStyle((theme: Theme) => {
......@@ -304,7 +304,7 @@ type SpanBarRowProps = {
showErrorIcon: boolean;
getViewedBounds: ViewedBoundsFunctionType;
traceStartTime: number;
span: Span;
span: TraceSpan;
focusSpan: (spanID: string) => void;
hoverIndentGuideIds: Set<string>;
addHoverIndentGuideId: (spanID: string) => void;
......
......@@ -21,7 +21,7 @@ import cx from 'classnames';
import * as markers from './AccordianKeyValues.markers';
import KeyValuesTable from './KeyValuesTable';
import { TNil } from '../../types';
import { KeyValuePair, Link } from '@grafana/data';
import { TraceKeyValuePair, TraceLink } from '@grafana/data';
import { autoColor, createStyle, Theme, useTheme } from '../../Theme';
import { uAlignIcon, uTxEllipsis } from '../../uberUtilityStyles';
......@@ -84,17 +84,17 @@ export const getStyles = createStyle((theme: Theme) => {
type AccordianKeyValuesProps = {
className?: string | TNil;
data: KeyValuePair[];
data: TraceKeyValuePair[];
highContrast?: boolean;
interactive?: boolean;
isOpen: boolean;
label: string;
linksGetter: ((pairs: KeyValuePair[], index: number) => Link[]) | TNil;
linksGetter: ((pairs: TraceKeyValuePair[], index: number) => TraceLink[]) | TNil;
onToggle?: null | (() => void);
};
// export for tests
export function KeyValuesSummary(props: { data?: KeyValuePair[] }) {
export function KeyValuesSummary(props: { data?: TraceKeyValuePair[] }) {
const { data } = props;
if (!Array.isArray(data) || !data.length) {
return null;
......
......@@ -21,7 +21,7 @@ import { css } from 'emotion';
import AccordianKeyValues from './AccordianKeyValues';
import { formatDuration } from '../utils';
import { TNil } from '../../types';
import { Log, KeyValuePair, Link } from '@grafana/data';
import { TraceLog, TraceKeyValuePair, TraceLink } from '@grafana/data';
import { autoColor, createStyle, Theme, useTheme } from '../../Theme';
import { uAlignIcon, ubMb1 } from '../../uberUtilityStyles';
......@@ -59,11 +59,11 @@ const getStyles = createStyle((theme: Theme) => {
type AccordianLogsProps = {
interactive?: boolean;
isOpen: boolean;
linksGetter: ((pairs: KeyValuePair[], index: number) => Link[]) | TNil;
logs: Log[];
onItemToggle?: (log: Log) => void;
linksGetter: ((pairs: TraceKeyValuePair[], index: number) => TraceLink[]) | TNil;
logs: TraceLog[];
onItemToggle?: (log: TraceLog) => void;
onToggle?: () => void;
openedItems?: Set<Log>;
openedItems?: Set<TraceLog>;
timestamp: number;
};
......
......@@ -18,7 +18,7 @@ import cx from 'classnames';
import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down';
import IoIosArrowRight from 'react-icons/lib/io/ios-arrow-right';
import { SpanReference } from '@grafana/data';
import { TraceSpanReference } from '@grafana/data';
import ReferenceLink from '../../url/ReferenceLink';
import { createStyle } from '../../Theme';
......@@ -66,7 +66,7 @@ const getStyles = createStyle(() => {
});
type AccordianReferencesProps = {
data: SpanReference[];
data: TraceSpanReference[];
highContrast?: boolean;
interactive?: boolean;
isOpen: boolean;
......@@ -75,7 +75,7 @@ type AccordianReferencesProps = {
};
type ReferenceItemProps = {
data: SpanReference[];
data: TraceSpanReference[];
focusSpan: (uiFind: string) => void;
};
......
......@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Log } from '@grafana/data';
import { TraceLog } from '@grafana/data';
/**
* Which items of a {@link SpanDetail} component are expanded.
......@@ -20,7 +20,7 @@ import { Log } from '@grafana/data';
export default class DetailState {
isTagsOpen: boolean;
isProcessOpen: boolean;
logs: { isOpen: boolean; openedItems: Set<Log> };
logs: { isOpen: boolean; openedItems: Set<TraceLog> };
isWarningsOpen: boolean;
isReferencesOpen: boolean;
......@@ -72,7 +72,7 @@ export default class DetailState {
return next;
}
toggleLogItem(logItem: Log) {
toggleLogItem(logItem: TraceLog) {
const next = new DetailState(this);
if (next.logs.openedItems.has(logItem)) {
next.logs.openedItems.delete(logItem);
......
......@@ -20,7 +20,7 @@ import cx from 'classnames';
import CopyIcon from '../../common/CopyIcon';
import { TNil } from '../../types';
import { KeyValuePair, Link } from '@grafana/data';
import { TraceKeyValuePair, TraceLink } from '@grafana/data';
import { UIDropdown, UIIcon, UIMenu, UIMenuItem } from '../../uiElementsContext';
import { autoColor, createStyle, Theme, useTheme } from '../../Theme';
import { ubInlineBlock, uWidth100 } from '../../uberUtilityStyles';
......@@ -102,7 +102,7 @@ LinkValue.defaultProps = {
title: '',
};
const linkValueList = (links: Link[]) => (
const linkValueList = (links: TraceLink[]) => (
<UIMenu>
{links.map(({ text, url }, index) => (
// `index` is necessary in the key because url can repeat
......@@ -114,8 +114,8 @@ const linkValueList = (links: Link[]) => (
);
type KeyValuesTableProps = {
data: KeyValuePair[];
linksGetter: ((pairs: KeyValuePair[], index: number) => Link[]) | TNil;
data: TraceKeyValuePair[];
linksGetter: ((pairs: TraceKeyValuePair[], index: number) => TraceLink[]) | TNil;
};
export default function KeyValuesTable(props: KeyValuesTableProps) {
......
......@@ -25,7 +25,7 @@ import CopyIcon from '../../common/CopyIcon';
import LabeledList from '../../common/LabeledList';
import { TNil } from '../../types';
import { KeyValuePair, Link, Log, Span } from '@grafana/data';
import { TraceKeyValuePair, TraceLink, TraceLog, TraceSpan } from '@grafana/data';
import AccordianReferences from './AccordianReferences';
import { autoColor, createStyle, Theme, useTheme } from '../../Theme';
import { UIDivider } from '../../uiElementsContext';
......@@ -99,11 +99,11 @@ const getStyles = createStyle((theme: Theme) => {
type SpanDetailProps = {
detailState: DetailState;
linksGetter: ((links: KeyValuePair[], index: number) => Link[]) | TNil;
logItemToggle: (spanID: string, log: Log) => void;
linksGetter: ((links: TraceKeyValuePair[], index: number) => TraceLink[]) | TNil;
logItemToggle: (spanID: string, log: TraceLog) => void;
logsToggle: (spanID: string) => void;
processToggle: (spanID: string) => void;
span: Span;
span: TraceSpan;
tagsToggle: (spanID: string) => void;
traceStartTime: number;
warningsToggle: (spanID: string) => void;
......
......@@ -21,7 +21,7 @@ import SpanTreeOffset from './SpanTreeOffset';
import TimelineRow from './TimelineRow';
import { autoColor, createStyle, Theme, withTheme } from '../Theme';
import { Log, Span, KeyValuePair, Link } from '@grafana/data';
import { TraceLog, TraceSpan, TraceKeyValuePair, TraceLink } from '@grafana/data';
const getStyles = createStyle((theme: Theme) => {
return {
......@@ -70,13 +70,13 @@ type SpanDetailRowProps = {
columnDivision: number;
detailState: DetailState;
onDetailToggled: (spanID: string) => void;
linksGetter: (span: Span, links: KeyValuePair[], index: number) => Link[];
logItemToggle: (spanID: string, log: Log) => void;
linksGetter: (span: TraceSpan, links: TraceKeyValuePair[], index: number) => TraceLink[];
logItemToggle: (spanID: string, log: TraceLog) => void;
logsToggle: (spanID: string) => void;
processToggle: (spanID: string) => void;
referencesToggle: (spanID: string) => void;
warningsToggle: (spanID: string) => void;
span: Span;
span: TraceSpan;
tagsToggle: (spanID: string) => void;
traceStartTime: number;
focusSpan: (uiFind: string) => void;
......@@ -91,7 +91,7 @@ export class UnthemedSpanDetailRow extends React.PureComponent<SpanDetailRowProp
this.props.onDetailToggled(this.props.span.spanID);
};
_linksGetter = (items: KeyValuePair[], itemIndex: number) => {
_linksGetter = (items: TraceKeyValuePair[], itemIndex: number) => {
const { linksGetter, span } = this.props;
return linksGetter(span, items, itemIndex);
};
......
......@@ -19,7 +19,7 @@ import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down';
import { css } from 'emotion';
import cx from 'classnames';
import { Span } from '@grafana/data';
import { TraceSpan } from '@grafana/data';
import spanAncestorIds from '../utils/span-ancestor-ids';
import { autoColor, createStyle, Theme, withTheme } from '../Theme';
......@@ -72,7 +72,7 @@ export const getStyles = createStyle((theme: Theme) => {
type TProps = {
childrenVisible?: boolean;
onClick?: () => void;
span: Span;
span: TraceSpan;
showChildrenIcon?: boolean;
hoverIndentGuideIds: Set<string>;
......
......@@ -29,7 +29,7 @@ import {
import { Accessors } from '../ScrollManager';
import { getColorByKey } from '../utils/color-generator';
import { TNil } from '../types';
import { Log, Span, Trace, KeyValuePair, Link } from '@grafana/data';
import { TraceLog, TraceSpan, Trace, TraceKeyValuePair, TraceLink } from '@grafana/data';
import TTraceTimeline from '../types/TTraceTimeline';
import { createStyle, Theme, withTheme } from '../Theme';
......@@ -51,7 +51,7 @@ const getStyles = createStyle(() => {
type RowState = {
isDetail: boolean;
span: Span;
span: TraceSpan;
spanIndex: number;
};
......@@ -62,10 +62,10 @@ type TVirtualizedTraceViewOwnProps = {
registerAccessors: (accesors: Accessors) => void;
trace: Trace;
focusSpan: (uiFind: string) => void;
linksGetter: (span: Span, items: KeyValuePair[], itemIndex: number) => Link[];
linksGetter: (span: TraceSpan, items: TraceKeyValuePair[], itemIndex: number) => TraceLink[];
childrenToggle: (spanID: string) => void;
clearShouldScrollToFirstUiFindMatch: () => void;
detailLogItemToggle: (spanID: string, log: Log) => void;
detailLogItemToggle: (spanID: string, log: TraceLog) => void;
detailLogsToggle: (spanID: string) => void;
detailWarningsToggle: (spanID: string) => void;
detailReferencesToggle: (spanID: string) => void;
......@@ -92,7 +92,7 @@ export const DEFAULT_HEIGHTS = {
const NUM_TICKS = 5;
function generateRowStates(
spans: Span[] | TNil,
spans: TraceSpan[] | TNil,
childrenHiddenIDs: Set<string>,
detailStates: Map<string, DetailState | TNil>
): RowState[] {
......@@ -313,7 +313,7 @@ export class UnthemedVirtualizedTraceView extends React.Component<VirtualizedTra
: this.renderSpanBarRow(span, spanIndex, key, style, attrs);
};
renderSpanBarRow(span: Span, spanIndex: number, key: string, style: React.CSSProperties, attrs: {}) {
renderSpanBarRow(span: TraceSpan, spanIndex: number, key: string, style: React.CSSProperties, attrs: {}) {
const { spanID } = span;
const { serviceName } = span.process;
const {
......@@ -383,7 +383,7 @@ export class UnthemedVirtualizedTraceView extends React.Component<VirtualizedTra
);
}
renderSpanDetailRow(span: Span, key: string, style: React.CSSProperties, attrs: {}) {
renderSpanDetailRow(span: TraceSpan, key: string, style: React.CSSProperties, attrs: {}) {
const { spanID } = span;
const { serviceName } = span.process;
const {
......
......@@ -21,7 +21,7 @@ import { merge as mergeShortcuts } from '../keyboard-shortcuts';
import { Accessors } from '../ScrollManager';
import { TUpdateViewRangeTimeFunction, ViewRange, ViewRangeTimeUpdate } from './types';
import { TNil } from '../types';
import { Span, Trace, Log, KeyValuePair, Link } from '@grafana/data';
import { TraceSpan, Trace, TraceLog, TraceKeyValuePair, TraceLink } from '@grafana/data';
import TTraceTimeline from '../types/TTraceTimeline';
import { autoColor, createStyle, Theme, withTheme } from '../Theme';
import ExternalLinkContext from '../url/externalLinkContext';
......@@ -79,14 +79,14 @@ type TProps = TExtractUiFindFromStateReturn & {
createLinkToExternalSpan: (traceID: string, spanID: string) => string;
setSpanNameColumnWidth: (width: number) => void;
collapseAll: (spans: Span[]) => void;
collapseOne: (spans: Span[]) => void;
collapseAll: (spans: TraceSpan[]) => void;
collapseOne: (spans: TraceSpan[]) => void;
expandAll: () => void;
expandOne: (spans: Span[]) => void;
expandOne: (spans: TraceSpan[]) => void;
childrenToggle: (spanID: string) => void;
clearShouldScrollToFirstUiFindMatch: () => void;
detailLogItemToggle: (spanID: string, log: Log) => void;
detailLogItemToggle: (spanID: string, log: TraceLog) => void;
detailLogsToggle: (spanID: string) => void;
detailWarningsToggle: (spanID: string) => void;
detailReferencesToggle: (spanID: string) => void;
......@@ -96,7 +96,7 @@ type TProps = TExtractUiFindFromStateReturn & {
setTrace: (trace: Trace | TNil, uiFind: string | TNil) => void;
addHoverIndentGuideId: (spanID: string) => void;
removeHoverIndentGuideId: (spanID: string) => void;
linksGetter: (span: Span, items: KeyValuePair[], itemIndex: number) => Link[];
linksGetter: (span: TraceSpan, items: TraceKeyValuePair[], itemIndex: number) => TraceLink[];
theme: Theme;
};
......
......@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Span } from '@grafana/data';
import { TraceSpan } from '@grafana/data';
export type ViewedBoundsFunctionType = (start: number, end: number) => { start: number; end: number };
/**
......@@ -57,7 +57,7 @@ export function createViewedBoundsFunc(viewRange: { min: number; max: number; vi
* items.
* @return {boolean} True if a match was found.
*/
export function spanHasTag(key: string, value: any, span: Span) {
export function spanHasTag(key: string, value: any, span: TraceSpan) {
if (!Array.isArray(span.tags) || !span.tags.length) {
return false;
}
......@@ -69,20 +69,20 @@ export const isServerSpan = spanHasTag.bind(null, 'span.kind', 'server');
const isErrorBool = spanHasTag.bind(null, 'error', true);
const isErrorStr = spanHasTag.bind(null, 'error', 'true');
export const isErrorSpan = (span: Span) => isErrorBool(span) || isErrorStr(span);
export const isErrorSpan = (span: TraceSpan) => isErrorBool(span) || isErrorStr(span);
/**
* Returns `true` if at least one of the descendants of the `parentSpanIndex`
* span contains an error tag.
*
* @param {Span[]} spans The spans for a trace - should be
* @param {TraceSpan[]} spans The spans for a trace - should be
* sorted with children following parents.
* @param {number} parentSpanIndex The index of the parent span - only
* subsequent spans with depth less than
* the parent span will be checked.
* @return {boolean} Returns `true` if a descendant contains an error tag.
*/
export function spanContainsErredSpan(spans: Span[], parentSpanIndex: number) {
export function spanContainsErredSpan(spans: TraceSpan[], parentSpanIndex: number) {
const { depth } = spans[parentSpanIndex];
let i = parentSpanIndex + 1;
for (; i < spans.length && spans[i].depth > depth; i++) {
......@@ -96,7 +96,7 @@ export function spanContainsErredSpan(spans: Span[], parentSpanIndex: number) {
/**
* Expects the first span to be the parent span.
*/
export function findServerChildSpan(spans: Span[]) {
export function findServerChildSpan(spans: TraceSpan[]) {
if (spans.length <= 1 || !isClientSpan(spans[0])) {
return false;
}
......
......@@ -17,7 +17,7 @@ import memoize from 'lru-memoize';
import { getConfigValue } from '../utils/config/get-config';
import { getParent } from './span';
import { TNil } from '../types';
import { Span, Link, KeyValuePair, Trace } from '@grafana/data';
import { TraceSpan, TraceLink, TraceKeyValuePair, Trace } from '@grafana/data';
const parameterRegExp = /#\{([^{}]*)\}/g;
......@@ -118,15 +118,15 @@ export function processLinkPattern(pattern: any): ProcessedLinkPattern | TNil {
}
}
export function getParameterInArray(name: string, array: KeyValuePair[]) {
export function getParameterInArray(name: string, array: TraceKeyValuePair[]) {
if (array) {
return array.find(entry => entry.key === name);
}
return undefined;
}
export function getParameterInAncestor(name: string, span: Span) {
let currentSpan: Span | TNil = span;
export function getParameterInAncestor(name: string, span: TraceSpan) {
let currentSpan: TraceSpan | TNil = span;
while (currentSpan) {
const result = getParameterInArray(name, currentSpan.tags) || getParameterInArray(name, currentSpan.process.tags);
if (result) {
......@@ -174,8 +174,8 @@ export function computeTraceLink(linkPatterns: ProcessedLinkPattern[], trace: Tr
export function computeLinks(
linkPatterns: ProcessedLinkPattern[],
span: Span,
items: KeyValuePair[],
span: TraceSpan,
items: TraceKeyValuePair[],
itemIndex: number
) {
const item = items[itemIndex];
......@@ -221,8 +221,8 @@ export function computeLinks(
return result;
}
export function createGetLinks(linkPatterns: ProcessedLinkPattern[], cache: WeakMap<KeyValuePair, Link[]>) {
return (span: Span, items: KeyValuePair[], itemIndex: number) => {
export function createGetLinks(linkPatterns: ProcessedLinkPattern[], cache: WeakMap<TraceKeyValuePair, TraceLink[]>) {
return (span: TraceSpan, items: TraceKeyValuePair[], itemIndex: number) => {
if (linkPatterns.length === 0) {
return [];
}
......
......@@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Span } from '@grafana/data';
import { TraceSpan } from '@grafana/data';
/**
* Searches the span.references to find 'CHILD_OF' reference type or returns null.
* @param {Span} span The span whose parent is to be returned.
* @return {Span|null} The parent span if there is one, null otherwise.
* @param {TraceSpan} span The span whose parent is to be returned.
* @return {TraceSpan|null} The parent span if there is one, null otherwise.
*/
export function getParent(span: Span) {
export function getParent(span: TraceSpan) {
const parentRef = span.references ? span.references.find(ref => ref.refType === 'CHILD_OF') : null;
return parentRef ? parentRef.span : null;
}
......@@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Span } from '@grafana/data';
import { TraceSpan } from '@grafana/data';
export function getTraceName(spans: Span[]): string {
export function getTraceName(spans: TraceSpan[]): string {
const span = spans.filter(sp => !sp.references || !sp.references.length)[0];
return span ? `${span.process.serviceName}: ${span.operationName}` : '';
}
......@@ -17,14 +17,14 @@ import _isEqual from 'lodash/isEqual';
// @ts-ignore
import { getTraceSpanIdsAsTree } from '../selectors/trace';
import { getConfigValue } from '../utils/config/get-config';
import { KeyValuePair, Span, SpanData, Trace, TraceData } from '@grafana/data';
import { TraceKeyValuePair, TraceSpan, TraceSpanData, Trace, TraceData } from '@grafana/data';
// @ts-ignore
import TreeNode from '../utils/TreeNode';
// exported for tests
export function deduplicateTags(spanTags: KeyValuePair[]) {
export function deduplicateTags(spanTags: TraceKeyValuePair[]) {
const warningsHash: Map<string, string> = new Map<string, string>();
const tags: KeyValuePair[] = spanTags.reduce<KeyValuePair[]>((uniqueTags, tag) => {
const tags: TraceKeyValuePair[] = spanTags.reduce<TraceKeyValuePair[]>((uniqueTags, tag) => {
if (!uniqueTags.some(t => t.key === tag.key && t.value === tag.value)) {
uniqueTags.push(tag);
} else {
......@@ -37,8 +37,8 @@ export function deduplicateTags(spanTags: KeyValuePair[]) {
}
// exported for tests
export function orderTags(spanTags: KeyValuePair[], topPrefixes?: string[]) {
const orderedTags: KeyValuePair[] = spanTags.slice();
export function orderTags(spanTags: TraceKeyValuePair[], topPrefixes?: string[]) {
const orderedTags: TraceKeyValuePair[] = spanTags.slice();
const tp = (topPrefixes || []).map((p: string) => p.toLowerCase());
orderedTags.sort((a, b) => {
......@@ -71,7 +71,7 @@ export function orderTags(spanTags: KeyValuePair[], topPrefixes?: string[]) {
* NOTE: Mutates `data` - Transform the HTTP response data into the form the app
* generally requires.
*/
export default function transformTraceData(data: TraceData & { spans: SpanData[] }): Trace | null {
export default function transformTraceData(data: TraceData & { spans: TraceSpanData[] }): Trace | null {
let { traceID } = data;
if (!traceID) {
return null;
......@@ -81,14 +81,14 @@ export default function transformTraceData(data: TraceData & { spans: SpanData[]
let traceEndTime = 0;
let traceStartTime = Number.MAX_SAFE_INTEGER;
const spanIdCounts = new Map();
const spanMap = new Map<string, Span>();
const spanMap = new Map<string, TraceSpan>();
// filter out spans with empty start times
// eslint-disable-next-line no-param-reassign
data.spans = data.spans.filter(span => Boolean(span.startTime));
const max = data.spans.length;
for (let i = 0; i < max; i++) {
const span: Span = data.spans[i] as Span;
const span: TraceSpan = data.spans[i] as TraceSpan;
const { startTime, duration, processID } = span;
//
let spanID = span.spanID;
......@@ -120,7 +120,7 @@ export default function transformTraceData(data: TraceData & { spans: SpanData[]
// tree is necessary to sort the spans, so children follow parents, and
// siblings are sorted by start time
const tree = getTraceSpanIdsAsTree(data);
const spans: Span[] = [];
const spans: TraceSpan[] = [];
const svcCounts: Record<string, number> = {};
let traceName = '';
......@@ -130,7 +130,7 @@ export default function transformTraceData(data: TraceData & { spans: SpanData[]
if (spanID === '__root__') {
return;
}
const span = spanMap.get(spanID) as Span;
const span = spanMap.get(spanID) as TraceSpan;
if (!span) {
return;
}
......@@ -149,7 +149,7 @@ export default function transformTraceData(data: TraceData & { spans: SpanData[]
span.tags = orderTags(tagsInfo.tags, getConfigValue('topTagPrefixes'));
span.warnings = span.warnings.concat(tagsInfo.warnings);
span.references.forEach((ref, index) => {
const refSpan = spanMap.get(ref.spanID) as Span;
const refSpan = spanMap.get(ref.spanID) as TraceSpan;
if (refSpan) {
// eslint-disable-next-line no-param-reassign
ref.span = refSpan;
......
......@@ -13,11 +13,11 @@
// limitations under the License.
import React from 'react';
import { SpanReference } from '@grafana/data';
import { TraceSpanReference } from '@grafana/data';
import ExternalLinkContext from './externalLinkContext';
type ReferenceLinkProps = {
reference: SpanReference;
reference: TraceSpanReference;
children: React.ReactNode;
className?: string;
focusSpan: (spanID: string) => void;
......
......@@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { KeyValuePair, Span } from '@grafana/data';
import { TraceKeyValuePair, TraceSpan } from '@grafana/data';
import { TNil } from '../types';
export default function filterSpans(textFilter: string, spans: Span[] | TNil) {
export default function filterSpans(textFilter: string, spans: TraceSpan[] | TNil) {
if (!spans) {
return null;
}
......@@ -41,7 +41,7 @@ export default function filterSpans(textFilter: string, spans: Span[] | TNil) {
const isTextInFilters = (filters: string[], text: string) =>
filters.some(filter => text.toLowerCase().includes(filter));
const isTextInKeyValues = (kvs: KeyValuePair[]) =>
const isTextInKeyValues = (kvs: TraceKeyValuePair[]) =>
kvs
? kvs.some(kv => {
// ignore checking key and value for a match if key is in excludeKeys
......@@ -53,7 +53,7 @@ export default function filterSpans(textFilter: string, spans: Span[] | TNil) {
})
: false;
const isSpanAMatch = (span: Span) =>
const isSpanAMatch = (span: TraceSpan) =>
isTextInFilters(includeFilters, span.operationName) ||
isTextInFilters(includeFilters, span.process.serviceName) ||
isTextInKeyValues(span.tags) ||
......@@ -62,6 +62,6 @@ export default function filterSpans(textFilter: string, spans: Span[] | TNil) {
includeFilters.some(filter => filter === span.spanID);
// declare as const because need to disambiguate the type
const rv: Set<string> = new Set(spans.filter(isSpanAMatch).map((span: Span) => span.spanID));
const rv: Set<string> = new Set(spans.filter(isSpanAMatch).map((span: TraceSpan) => span.spanID));
return rv;
}
......@@ -16,9 +16,9 @@ import _find from 'lodash/find';
import _get from 'lodash/get';
import { TNil } from '../types';
import { Span } from '@grafana/data';
import { TraceSpan } from '@grafana/data';
function getFirstAncestor(span: Span): Span | TNil {
function getFirstAncestor(span: TraceSpan): TraceSpan | TNil {
return _get(
_find(
span.references,
......@@ -28,7 +28,7 @@ function getFirstAncestor(span: Span): Span | TNil {
);
}
export default function spanAncestorIds(span: Span | TNil): string[] {
export default function spanAncestorIds(span: TraceSpan | TNil): string[] {
const ancestorIDs: string[] = [];
if (!span) {
return ancestorIDs;
......
......@@ -2,7 +2,7 @@ import React from 'react';
import { shallow } from 'enzyme';
import { TraceView } from './TraceView';
import { TracePageHeader, TraceTimelineViewer } from '@jaegertracing/jaeger-ui-components';
import { SpanData, TraceData } from '@grafana/data';
import { TraceSpanData, TraceData } from '@grafana/data';
function renderTraceView() {
const wrapper = shallow(<TraceView trace={response} />);
......@@ -123,7 +123,7 @@ describe('TraceView', () => {
});
});
const response: TraceData & { spans: SpanData[] } = {
const response: TraceData & { spans: TraceSpanData[] } = {
traceID: '1ed38015486087ca',
spans: [
{
......
......@@ -16,10 +16,10 @@ import { useChildrenState } from './useChildrenState';
import { useDetailState } from './useDetailState';
import { useHoverIndentGuide } from './useHoverIndentGuide';
import { colors, useTheme } from '@grafana/ui';
import { TraceData, SpanData, Trace, Span, KeyValuePair, Link } from '@grafana/data';
import { TraceData, TraceSpanData, Trace, TraceSpan, TraceKeyValuePair, TraceLink } from '@grafana/data';
type Props = {
trace: TraceData & { spans: SpanData[] };
trace: TraceData & { spans: TraceSpanData[] };
};
export function TraceView(props: Props) {
......@@ -128,7 +128,10 @@ export function TraceView(props: Props) {
setTrace={useCallback((trace: Trace | null, uiFind: string | null) => {}, [])}
addHoverIndentGuideId={addHoverIndentGuideId}
removeHoverIndentGuideId={removeHoverIndentGuideId}
linksGetter={useCallback((span: Span, items: KeyValuePair[], itemIndex: number) => [] as Link[], [])}
linksGetter={useCallback(
(span: TraceSpan, items: TraceKeyValuePair[], itemIndex: number) => [] as TraceLink[],
[]
)}
uiFind={search}
/>
</UIElementsContext.Provider>
......
import { renderHook, act } from '@testing-library/react-hooks';
import { useChildrenState } from './useChildrenState';
import { Span } from '@grafana/data';
import { TraceSpan } from '@grafana/data';
describe('useChildrenState', () => {
describe('childrenToggle', () => {
......@@ -37,8 +37,8 @@ describe('useChildrenState', () => {
const { result } = renderHook(() => useChildrenState());
act(() =>
result.current.collapseAll([
{ spanID: 'span1', hasChildren: true } as Span,
{ spanID: 'span2', hasChildren: false } as Span,
{ spanID: 'span1', hasChildren: true } as TraceSpan,
{ spanID: 'span2', hasChildren: false } as TraceSpan,
])
);
......@@ -51,8 +51,8 @@ describe('useChildrenState', () => {
act(() => result.current.childrenToggle('span1'));
act(() =>
result.current.collapseAll([
{ spanID: 'span1', hasChildren: true } as Span,
{ spanID: 'span2', hasChildren: false } as Span,
{ spanID: 'span1', hasChildren: true } as TraceSpan,
{ spanID: 'span2', hasChildren: false } as TraceSpan,
])
);
......
import { useCallback, useState } from 'react';
import { Span } from '@grafana/data';
import { TraceSpan } from '@grafana/data';
/**
* Children state means whether spans are collapsed or not. Also provides some functions to manipulate that state.
......@@ -8,7 +8,7 @@ export function useChildrenState() {
const [childrenHiddenIDs, setChildrenHiddenIDs] = useState(new Set<string>());
const expandOne = useCallback(
function expandOne(spans: Span[]) {
function expandOne(spans: TraceSpan[]) {
if (childrenHiddenIDs.size === 0) {
return;
}
......@@ -31,11 +31,11 @@ export function useChildrenState() {
);
const collapseOne = useCallback(
function collapseOne(spans: Span[]) {
function collapseOne(spans: TraceSpan[]) {
if (shouldDisableCollapse(spans, childrenHiddenIDs)) {
return;
}
let nearestCollapsedAncestor: Span | undefined;
let nearestCollapsedAncestor: TraceSpan | undefined;
const newChildrenHiddenIDs = spans.reduce((res, curSpan) => {
if (nearestCollapsedAncestor && curSpan.depth <= nearestCollapsedAncestor.depth) {
res.add(nearestCollapsedAncestor.spanID);
......@@ -61,7 +61,7 @@ export function useChildrenState() {
}, []);
const collapseAll = useCallback(
function collapseAll(spans: Span[]) {
function collapseAll(spans: TraceSpan[]) {
if (shouldDisableCollapse(spans, childrenHiddenIDs)) {
return;
}
......@@ -100,7 +100,7 @@ export function useChildrenState() {
};
}
function shouldDisableCollapse(allSpans: Span[], hiddenSpansIds: Set<string>) {
function shouldDisableCollapse(allSpans: TraceSpan[], hiddenSpansIds: Set<string>) {
const allParentSpans = allSpans.filter(s => s.hasChildren);
return allParentSpans.length === hiddenSpansIds.size;
}
import { act, renderHook } from '@testing-library/react-hooks';
import { Log } from '@grafana/data';
import { TraceLog } from '@grafana/data';
import { useDetailState } from './useDetailState';
describe('useDetailState', () => {
......@@ -21,7 +21,7 @@ describe('useDetailState', () => {
act(() => result.current.detailLogsToggle('span1'));
expect(result.current.detailStates.get('span1')?.logs.isOpen).toBe(true);
const log = { timestamp: 1 } as Log;
const log = { timestamp: 1 } as TraceLog;
act(() => result.current.detailLogItemToggle('span1', log));
expect(result.current.detailStates.get('span1')?.logs.openedItems.has(log)).toBe(true);
});
......
import { useCallback, useState } from 'react';
import { DetailState } from '@jaegertracing/jaeger-ui-components';
import { Log } from '@grafana/data';
import { TraceLog } from '@grafana/data';
/**
* Keeps state of the span detail. This means whether span details are open but also state of each detail subitem
......@@ -23,7 +23,7 @@ export function useDetailState() {
);
const detailLogItemToggle = useCallback(
function detailLogItemToggle(spanID: string, log: Log) {
function detailLogItemToggle(spanID: string, log: TraceLog) {
const old = detailStates.get(spanID);
if (!old) {
return;
......
import { act, renderHook } from '@testing-library/react-hooks';
import { useSearch } from './useSearch';
import { Span } from '@grafana/data';
import { TraceSpan } from '@grafana/data';
describe('useSearch', () => {
it('returns matching span IDs', async () => {
......@@ -15,7 +15,7 @@ describe('useSearch', () => {
},
tags: [],
logs: [],
} as unknown) as Span,
} as unknown) as TraceSpan,
({
spanID: 'span2',
......@@ -26,7 +26,7 @@ describe('useSearch', () => {
},
tags: [],
logs: [],
} as unknown) as Span,
} as unknown) as TraceSpan,
])
);
......
import { useMemo, useState } from 'react';
import { filterSpans } from '@jaegertracing/jaeger-ui-components';
import { Span } from '@grafana/data';
import { TraceSpan } from '@grafana/data';
/**
* Controls the state of search input that highlights spans if they match the search string.
* @param spans
*/
export function useSearch(spans?: Span[]) {
export function useSearch(spans?: TraceSpan[]) {
const [search, setSearch] = useState('');
const spanFindMatches: Set<string> | undefined = useMemo(() => {
return search && spans ? filterSpans(search, spans) : undefined;
......
......@@ -2,7 +2,7 @@ import React from 'react';
import { JaegerDatasource, JaegerQuery } from './datasource';
import { ButtonCascader, CascaderOption } from '@grafana/ui';
import { AppEvents, ExploreQueryFieldProps, Span, TraceData } from '@grafana/data';
import { AppEvents, ExploreQueryFieldProps, TraceSpan, TraceData } from '@grafana/data';
import { appEvents } from '../../../core/core';
const ALL_OPERATIONS_KEY = '__ALL__';
......@@ -13,11 +13,11 @@ interface State {
serviceOptions: CascaderOption[];
}
function findRootSpan(spans: Span[]): Span | undefined {
function findRootSpan(spans: TraceSpan[]): TraceSpan | undefined {
return spans.find(s => !s.references?.length);
}
function getLabelFromTrace(trace: TraceData & { spans: Span[] }): string {
function getLabelFromTrace(trace: TraceData & { spans: TraceSpan[] }): string {
const rootSpan = findRootSpan(trace.spans);
if (rootSpan) {
return `${rootSpan.operationName} [${rootSpan.duration / 1000} ms]`;
......
import { SpanData, TraceData } from '@grafana/data';
import { TraceSpanData, TraceData } from '@grafana/data';
import { ZipkinSpan } from '../types';
export const zipkinResponse: ZipkinSpan[] = [
......@@ -59,7 +59,7 @@ export const zipkinResponse: ZipkinSpan[] = [
},
];
export const jaegerTrace: TraceData & { spans: SpanData[] } = {
export const jaegerTrace: TraceData & { spans: TraceSpanData[] } = {
processes: {
'service 1': {
serviceName: 'service 1',
......
import { identity } from 'lodash';
import { keyBy } from 'lodash';
import { ZipkinAnnotation, ZipkinEndpoint, ZipkinSpan } from '../types';
import { KeyValuePair, Log, Process, SpanData, TraceData } from '@grafana/data';
import { TraceKeyValuePair, TraceLog, TraceProcess, TraceSpanData, TraceData } from '@grafana/data';
/**
* Transforms response to format similar to Jaegers as we use Jaeger ui on the frontend.
*/
export function transformResponse(zSpans: ZipkinSpan[]): TraceData & { spans: SpanData[] } {
export function transformResponse(zSpans: ZipkinSpan[]): TraceData & { spans: TraceSpanData[] } {
return {
processes: gatherProcesses(zSpans),
traceID: zSpans[0].traceId,
......@@ -15,8 +15,8 @@ export function transformResponse(zSpans: ZipkinSpan[]): TraceData & { spans: Sp
};
}
function transformSpan(span: ZipkinSpan): SpanData {
const jaegerSpan: SpanData = {
function transformSpan(span: ZipkinSpan): TraceSpanData {
const jaegerSpan: TraceSpanData = {
duration: span.duration,
// TODO: not sure what this is
flags: 1,
......@@ -63,7 +63,7 @@ function transformSpan(span: ZipkinSpan): SpanData {
* Maps annotations as a Jaeger log as that seems to be the closest thing.
* See https://zipkin.io/zipkin-api/#/default/get_trace__traceId_
*/
function transformAnnotation(annotation: ZipkinAnnotation): Log {
function transformAnnotation(annotation: ZipkinAnnotation): TraceLog {
return {
timestamp: annotation.timestamp,
fields: [
......@@ -76,7 +76,7 @@ function transformAnnotation(annotation: ZipkinAnnotation): Log {
};
}
function gatherProcesses(zSpans: ZipkinSpan[]): Record<string, Process> {
function gatherProcesses(zSpans: ZipkinSpan[]): Record<string, TraceProcess> {
const processes = zSpans.reduce((acc, span) => {
if (span.localEndpoint) {
acc.push(endpointToProcess(span.localEndpoint));
......@@ -85,22 +85,22 @@ function gatherProcesses(zSpans: ZipkinSpan[]): Record<string, Process> {
acc.push(endpointToProcess(span.remoteEndpoint));
}
return acc;
}, [] as Process[]);
}, [] as TraceProcess[]);
return keyBy(processes, 'serviceName');
}
function endpointToProcess(endpoint: ZipkinEndpoint): Process {
function endpointToProcess(endpoint: ZipkinEndpoint): TraceProcess {
return {
serviceName: endpoint.serviceName,
tags: [
valueToTag('ipv4', endpoint.ipv4, 'string'),
valueToTag('ipv6', endpoint.ipv6, 'string'),
valueToTag('port', endpoint.port, 'number'),
].filter(identity) as KeyValuePair[],
].filter(identity) as TraceKeyValuePair[],
};
}
function valueToTag(key: string, value: string | number | undefined, type: string): KeyValuePair | undefined {
function valueToTag(key: string, value: string | number | undefined, type: string): TraceKeyValuePair | undefined {
if (!value) {
return undefined;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment