diff --git a/conf/provisioning/datasources/loki_test.yaml b/conf/provisioning/datasources/loki_test.yaml
index 70f43d0ee92..7b561346d54 100644
--- a/conf/provisioning/datasources/loki_test.yaml
+++ b/conf/provisioning/datasources/loki_test.yaml
@@ -10,8 +10,14 @@ datasources:
jsonData:
derivedFields:
- name: "traceID"
- matcherRegex: "traceID=(\\w+)"
+ matcherRegex: "trace_id=(\\w+)"
url: "$${__value.raw}"
- datasourceName: "Jaeger"
+ datasourceUid: jaeger1234
+ - name: jaeger-derived-test
+ type: jaeger
+ uid: jaeger1234
+ access: proxy
+ url: http://localhost:16686
+ editable: false
diff --git a/packages/jaeger-ui-components/src/Theme.tsx b/packages/jaeger-ui-components/src/Theme.tsx
index 8888fc7d6e8..4a6f248d2d5 100644
--- a/packages/jaeger-ui-components/src/Theme.tsx
+++ b/packages/jaeger-ui-components/src/Theme.tsx
@@ -50,18 +50,22 @@ export function ThemeConsumer(props: ThemeConsumerProps) {
return (
{(value: ThemeOptions | undefined) => {
- const mergedTheme: Theme = value
- ? {
- ...defaultTheme,
- ...value,
- }
- : defaultTheme;
- return props.children(mergedTheme);
+ const theme = memoizedThemeMerge(value);
+ return props.children(theme);
}}
);
}
+const memoizedThemeMerge = memoizeOne(value => {
+ return value
+ ? {
+ ...defaultTheme,
+ ...value,
+ }
+ : defaultTheme;
+});
+
type WrappedWithThemeComponent = React.ComponentType> & {
wrapped: React.ComponentType;
};
diff --git a/packages/jaeger-ui-components/src/TracePageHeader/TracePageHeader.tsx b/packages/jaeger-ui-components/src/TracePageHeader/TracePageHeader.tsx
index 55663948b4c..55ded1a4eba 100644
--- a/packages/jaeger-ui-components/src/TracePageHeader/TracePageHeader.tsx
+++ b/packages/jaeger-ui-components/src/TracePageHeader/TracePageHeader.tsx
@@ -34,6 +34,7 @@ import { getTraceLinks } from '../model/link-patterns';
import ExternalLinks from '../common/ExternalLinks';
import { createStyle } from '../Theme';
import { uTxMuted } from '../uberUtilityStyles';
+import { useMemo } from 'react';
const getStyles = createStyle((theme: Theme) => {
const TracePageHeaderOverviewItemValueDetail = css`
@@ -222,7 +223,7 @@ export default function TracePageHeader(props: TracePageHeaderEmbedProps) {
return null;
}
- const links = getTraceLinks(trace);
+ const links = useMemo(() => getTraceLinks(trace), [trace]);
const summaryItems =
!hideSummary &&
diff --git a/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.tsx b/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.tsx
index 22d77ef7c67..d3e923a4e1a 100644
--- a/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.tsx
+++ b/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.tsx
@@ -24,6 +24,7 @@ import { TNil } from '../types';
import { UIButton, UIInputGroup } from '../uiElementsContext';
import { createStyle } from '../Theme';
import { ubFlexAuto, ubJustifyEnd } from '../uberUtilityStyles';
+import { memo } from 'react';
export const getStyles = createStyle(() => {
return {
@@ -71,7 +72,7 @@ type TracePageSearchBarProps = {
hideSearchButtons?: boolean;
};
-export default function TracePageSearchBar(props: TracePageSearchBarProps) {
+export default memo(function TracePageSearchBar(props: TracePageSearchBarProps) {
const {
clearSearch,
focusUiFindMatches,
@@ -141,4 +142,4 @@ export default function TracePageSearchBar(props: TracePageSearchBarProps) {
);
-}
+});
diff --git a/public/app/features/explore/TraceView/TraceView.tsx b/public/app/features/explore/TraceView/TraceView.tsx
index 761664c0595..8828c8a2554 100644
--- a/public/app/features/explore/TraceView/TraceView.tsx
+++ b/public/app/features/explore/TraceView/TraceView.tsx
@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React, { useCallback, useMemo, useState } from 'react';
import {
KeyValuePair,
Link,
@@ -50,27 +50,36 @@ export function TraceView(props: Props) {
*/
const [slim, setSlim] = useState(false);
- const traceProp = transformTraceData(props.trace);
+ const traceProp = useMemo(() => transformTraceData(props.trace), [props.trace]);
const { search, setSearch, spanFindMatches } = useSearch(traceProp?.spans);
+
const theme = useTheme();
+ const traceTheme = useMemo(() => ({ type: theme.isDark ? ThemeType.Dark : ThemeType.Light }), [theme]);
+ const traceTimeline: TTraceTimeline = useMemo(
+ () => ({
+ childrenHiddenIDs,
+ detailStates,
+ hoverIndentGuideIds,
+ shouldScrollToFirstUiFindMatch: false,
+ spanNameColumnWidth,
+ traceID: traceProp.traceID,
+ }),
+ [childrenHiddenIDs, detailStates, hoverIndentGuideIds, spanNameColumnWidth, traceProp.traceID]
+ );
return (
-
+
{}}
- focusUiFindMatches={() => {}}
+ clearSearch={useCallback(() => {}, [])}
+ focusUiFindMatches={useCallback(() => {}, [])}
hideMap={false}
hideSummary={false}
- nextResult={() => {}}
- onSlimViewClicked={() => setSlim(!slim)}
- onTraceGraphViewClicked={() => {}}
- prevResult={() => {}}
+ nextResult={useCallback(() => {}, [])}
+ onSlimViewClicked={useCallback(() => setSlim(!slim), [])}
+ onTraceGraphViewClicked={useCallback(() => {}, [])}
+ prevResult={useCallback(() => {}, [])}
resultCount={0}
slimView={slim}
textFilter={null}
@@ -84,32 +93,23 @@ export function TraceView(props: Props) {
hideSearchButtons={true}
/>
{}}
- scrollToFirstVisibleSpan={() => {}}
+ registerAccessors={useCallback(() => {}, [])}
+ scrollToFirstVisibleSpan={useCallback(() => {}, [])}
findMatchesIDs={spanFindMatches}
trace={traceProp}
- traceTimeline={
- {
- childrenHiddenIDs,
- detailStates,
- hoverIndentGuideIds,
- shouldScrollToFirstUiFindMatch: false,
- spanNameColumnWidth,
- traceID: '50b96206cf81dd64',
- } as TTraceTimeline
- }
+ traceTimeline={traceTimeline}
updateNextViewRangeTime={updateNextViewRangeTime}
updateViewRangeTime={updateViewRangeTime}
viewRange={viewRange}
- focusSpan={() => {}}
- createLinkToExternalSpan={() => ''}
+ focusSpan={useCallback(() => {}, [])}
+ createLinkToExternalSpan={useCallback(() => '', [])}
setSpanNameColumnWidth={setSpanNameColumnWidth}
collapseAll={collapseAll}
collapseOne={collapseOne}
expandAll={expandAll}
expandOne={expandOne}
childrenToggle={childrenToggle}
- clearShouldScrollToFirstUiFindMatch={() => {}}
+ clearShouldScrollToFirstUiFindMatch={useCallback(() => {}, [])}
detailLogItemToggle={detailLogItemToggle}
detailLogsToggle={detailLogsToggle}
detailWarningsToggle={detailWarningsToggle}
@@ -117,10 +117,10 @@ export function TraceView(props: Props) {
detailProcessToggle={detailProcessToggle}
detailTagsToggle={detailTagsToggle}
detailToggle={toggleDetail}
- setTrace={(trace: Trace | null, uiFind: string | null) => {}}
+ setTrace={useCallback((trace: Trace | null, uiFind: string | null) => {}, [])}
addHoverIndentGuideId={addHoverIndentGuideId}
removeHoverIndentGuideId={removeHoverIndentGuideId}
- linksGetter={(span: Span, items: KeyValuePair[], itemIndex: number) => [] as Link[]}
+ linksGetter={useCallback((span: Span, items: KeyValuePair[], itemIndex: number) => [] as Link[], [])}
uiFind={search}
/>
diff --git a/public/app/features/explore/TraceView/useChildrenState.ts b/public/app/features/explore/TraceView/useChildrenState.ts
index 1315682b6f7..c1558182ab6 100644
--- a/public/app/features/explore/TraceView/useChildrenState.ts
+++ b/public/app/features/explore/TraceView/useChildrenState.ts
@@ -1,4 +1,4 @@
-import { useState } from 'react';
+import { useCallback, useState } from 'react';
import { Span } from '@jaegertracing/jaeger-ui-components';
/**
@@ -7,76 +7,88 @@ import { Span } from '@jaegertracing/jaeger-ui-components';
export function useChildrenState() {
const [childrenHiddenIDs, setChildrenHiddenIDs] = useState(new Set());
- function expandOne(spans: Span[]) {
- if (childrenHiddenIDs.size === 0) {
- return;
- }
- let prevExpandedDepth = -1;
- let expandNextHiddenSpan = true;
- const newChildrenHiddenIDs = spans.reduce((res, s) => {
- if (s.depth <= prevExpandedDepth) {
- expandNextHiddenSpan = true;
+ const expandOne = useCallback(
+ function expandOne(spans: Span[]) {
+ if (childrenHiddenIDs.size === 0) {
+ return;
}
- if (expandNextHiddenSpan && res.has(s.spanID)) {
- res.delete(s.spanID);
- expandNextHiddenSpan = false;
- prevExpandedDepth = s.depth;
- }
- return res;
- }, new Set(childrenHiddenIDs));
- setChildrenHiddenIDs(newChildrenHiddenIDs);
- }
+ let prevExpandedDepth = -1;
+ let expandNextHiddenSpan = true;
+ const newChildrenHiddenIDs = spans.reduce((res, s) => {
+ if (s.depth <= prevExpandedDepth) {
+ expandNextHiddenSpan = true;
+ }
+ if (expandNextHiddenSpan && res.has(s.spanID)) {
+ res.delete(s.spanID);
+ expandNextHiddenSpan = false;
+ prevExpandedDepth = s.depth;
+ }
+ return res;
+ }, new Set(childrenHiddenIDs));
+ setChildrenHiddenIDs(newChildrenHiddenIDs);
+ },
+ [childrenHiddenIDs]
+ );
- function collapseOne(spans: Span[]) {
- if (shouldDisableCollapse(spans, childrenHiddenIDs)) {
- return;
- }
- let nearestCollapsedAncestor: Span | undefined;
- const newChildrenHiddenIDs = spans.reduce((res, curSpan) => {
- if (nearestCollapsedAncestor && curSpan.depth <= nearestCollapsedAncestor.depth) {
- res.add(nearestCollapsedAncestor.spanID);
- if (curSpan.hasChildren) {
+ const collapseOne = useCallback(
+ function collapseOne(spans: Span[]) {
+ if (shouldDisableCollapse(spans, childrenHiddenIDs)) {
+ return;
+ }
+ let nearestCollapsedAncestor: Span | undefined;
+ const newChildrenHiddenIDs = spans.reduce((res, curSpan) => {
+ if (nearestCollapsedAncestor && curSpan.depth <= nearestCollapsedAncestor.depth) {
+ res.add(nearestCollapsedAncestor.spanID);
+ if (curSpan.hasChildren) {
+ nearestCollapsedAncestor = curSpan;
+ }
+ } else if (curSpan.hasChildren && !res.has(curSpan.spanID)) {
nearestCollapsedAncestor = curSpan;
}
- } else if (curSpan.hasChildren && !res.has(curSpan.spanID)) {
- nearestCollapsedAncestor = curSpan;
+ return res;
+ }, new Set(childrenHiddenIDs));
+ // The last one
+ if (nearestCollapsedAncestor) {
+ newChildrenHiddenIDs.add(nearestCollapsedAncestor.spanID);
}
- return res;
- }, new Set(childrenHiddenIDs));
- // The last one
- if (nearestCollapsedAncestor) {
- newChildrenHiddenIDs.add(nearestCollapsedAncestor.spanID);
- }
- setChildrenHiddenIDs(newChildrenHiddenIDs);
- }
+ setChildrenHiddenIDs(newChildrenHiddenIDs);
+ },
+ [childrenHiddenIDs]
+ );
- function expandAll() {
+ const expandAll = useCallback(function expandAll() {
setChildrenHiddenIDs(new Set());
- }
+ }, []);
- function collapseAll(spans: Span[]) {
- if (shouldDisableCollapse(spans, childrenHiddenIDs)) {
- return;
- }
- const newChildrenHiddenIDs = spans.reduce((res, s) => {
- if (s.hasChildren) {
- res.add(s.spanID);
+ const collapseAll = useCallback(
+ function collapseAll(spans: Span[]) {
+ if (shouldDisableCollapse(spans, childrenHiddenIDs)) {
+ return;
}
- return res;
- }, new Set());
+ const newChildrenHiddenIDs = spans.reduce((res, s) => {
+ if (s.hasChildren) {
+ res.add(s.spanID);
+ }
+ return res;
+ }, new Set());
- setChildrenHiddenIDs(newChildrenHiddenIDs);
- }
+ setChildrenHiddenIDs(newChildrenHiddenIDs);
+ },
+ [childrenHiddenIDs]
+ );
- function childrenToggle(spanID: string) {
- const newChildrenHiddenIDs = new Set(childrenHiddenIDs);
- if (childrenHiddenIDs.has(spanID)) {
- newChildrenHiddenIDs.delete(spanID);
- } else {
- newChildrenHiddenIDs.add(spanID);
- }
- setChildrenHiddenIDs(newChildrenHiddenIDs);
- }
+ const childrenToggle = useCallback(
+ function childrenToggle(spanID: string) {
+ const newChildrenHiddenIDs = new Set(childrenHiddenIDs);
+ if (childrenHiddenIDs.has(spanID)) {
+ newChildrenHiddenIDs.delete(spanID);
+ } else {
+ newChildrenHiddenIDs.add(spanID);
+ }
+ setChildrenHiddenIDs(newChildrenHiddenIDs);
+ },
+ [childrenHiddenIDs]
+ );
return {
childrenHiddenIDs,
diff --git a/public/app/features/explore/TraceView/useDetailState.ts b/public/app/features/explore/TraceView/useDetailState.ts
index cf725a1f370..4e10874515e 100644
--- a/public/app/features/explore/TraceView/useDetailState.ts
+++ b/public/app/features/explore/TraceView/useDetailState.ts
@@ -1,4 +1,4 @@
-import { useState } from 'react';
+import { useCallback, useState } from 'react';
import { DetailState, Log } from '@jaegertracing/jaeger-ui-components';
/**
@@ -8,36 +8,48 @@ import { DetailState, Log } from '@jaegertracing/jaeger-ui-components';
export function useDetailState() {
const [detailStates, setDetailStates] = useState(new Map());
- function toggleDetail(spanID: string) {
- const newDetailStates = new Map(detailStates);
- if (newDetailStates.has(spanID)) {
- newDetailStates.delete(spanID);
- } else {
- newDetailStates.set(spanID, new DetailState());
- }
- setDetailStates(newDetailStates);
- }
+ const toggleDetail = useCallback(
+ function toggleDetail(spanID: string) {
+ const newDetailStates = new Map(detailStates);
+ if (newDetailStates.has(spanID)) {
+ newDetailStates.delete(spanID);
+ } else {
+ newDetailStates.set(spanID, new DetailState());
+ }
+ setDetailStates(newDetailStates);
+ },
+ [detailStates]
+ );
- function detailLogItemToggle(spanID: string, log: Log) {
- const old = detailStates.get(spanID);
- if (!old) {
- return;
- }
- const detailState = old.toggleLogItem(log);
- const newDetailStates = new Map(detailStates);
- newDetailStates.set(spanID, detailState);
- return setDetailStates(newDetailStates);
- }
+ const detailLogItemToggle = useCallback(
+ function detailLogItemToggle(spanID: string, log: Log) {
+ const old = detailStates.get(spanID);
+ if (!old) {
+ return;
+ }
+ const detailState = old.toggleLogItem(log);
+ const newDetailStates = new Map(detailStates);
+ newDetailStates.set(spanID, detailState);
+ return setDetailStates(newDetailStates);
+ },
+ [detailStates]
+ );
return {
detailStates,
toggleDetail,
detailLogItemToggle,
- detailLogsToggle: makeDetailSubsectionToggle('logs', detailStates, setDetailStates),
- detailWarningsToggle: makeDetailSubsectionToggle('warnings', detailStates, setDetailStates),
- detailReferencesToggle: makeDetailSubsectionToggle('references', detailStates, setDetailStates),
- detailProcessToggle: makeDetailSubsectionToggle('process', detailStates, setDetailStates),
- detailTagsToggle: makeDetailSubsectionToggle('tags', detailStates, setDetailStates),
+ detailLogsToggle: useCallback(makeDetailSubsectionToggle('logs', detailStates, setDetailStates), [detailStates]),
+ detailWarningsToggle: useCallback(makeDetailSubsectionToggle('warnings', detailStates, setDetailStates), [
+ detailStates,
+ ]),
+ detailReferencesToggle: useCallback(makeDetailSubsectionToggle('references', detailStates, setDetailStates), [
+ detailStates,
+ ]),
+ detailProcessToggle: useCallback(makeDetailSubsectionToggle('process', detailStates, setDetailStates), [
+ detailStates,
+ ]),
+ detailTagsToggle: useCallback(makeDetailSubsectionToggle('tags', detailStates, setDetailStates), [detailStates]),
};
}
diff --git a/public/app/features/explore/TraceView/useHoverIndentGuide.ts b/public/app/features/explore/TraceView/useHoverIndentGuide.ts
index d628b779927..0dfb0128358 100644
--- a/public/app/features/explore/TraceView/useHoverIndentGuide.ts
+++ b/public/app/features/explore/TraceView/useHoverIndentGuide.ts
@@ -1,4 +1,4 @@
-import { useState } from 'react';
+import { useCallback, useState } from 'react';
/**
* This is used internally to handle hover state of indent guide. As indent guides are separate
@@ -10,21 +10,21 @@ import { useState } from 'react';
export function useHoverIndentGuide() {
const [hoverIndentGuideIds, setHoverIndentGuideIds] = useState(new Set());
- function addHoverIndentGuideId(spanID: string) {
+ const addHoverIndentGuideId = useCallback(function addHoverIndentGuideId(spanID: string) {
setHoverIndentGuideIds(prevState => {
const newHoverIndentGuideIds = new Set(prevState);
newHoverIndentGuideIds.add(spanID);
return newHoverIndentGuideIds;
});
- }
+ }, []);
- function removeHoverIndentGuideId(spanID: string) {
+ const removeHoverIndentGuideId = useCallback(function removeHoverIndentGuideId(spanID: string) {
setHoverIndentGuideIds(prevState => {
const newHoverIndentGuideIds = new Set(prevState);
newHoverIndentGuideIds.delete(spanID);
return newHoverIndentGuideIds;
});
- }
+ }, []);
return { hoverIndentGuideIds, addHoverIndentGuideId, removeHoverIndentGuideId };
}
diff --git a/public/app/features/explore/TraceView/useSearch.ts b/public/app/features/explore/TraceView/useSearch.ts
index eb15b3ff811..a2f7bd614dd 100644
--- a/public/app/features/explore/TraceView/useSearch.ts
+++ b/public/app/features/explore/TraceView/useSearch.ts
@@ -1,4 +1,4 @@
-import { useState } from 'react';
+import { useMemo, useState } from 'react';
import { Span, filterSpans } from '@jaegertracing/jaeger-ui-components';
/**
@@ -7,9 +7,9 @@ import { Span, filterSpans } from '@jaegertracing/jaeger-ui-components';
*/
export function useSearch(spans?: Span[]) {
const [search, setSearch] = useState('');
- let spanFindMatches: Set | undefined;
- if (search && spans) {
- spanFindMatches = filterSpans(search, spans);
- }
+ const spanFindMatches: Set | undefined = useMemo(() => {
+ return search && spans ? filterSpans(search, spans) : undefined;
+ }, [search, spans]);
+
return { search, setSearch, spanFindMatches };
}
diff --git a/public/app/features/explore/TraceView/useViewRange.ts b/public/app/features/explore/TraceView/useViewRange.ts
index 84254fd11af..82498ae3af7 100644
--- a/public/app/features/explore/TraceView/useViewRange.ts
+++ b/public/app/features/explore/TraceView/useViewRange.ts
@@ -1,4 +1,4 @@
-import { useState } from 'react';
+import { useCallback, useState } from 'react';
import { ViewRangeTimeUpdate, ViewRange } from '@jaegertracing/jaeger-ui-components';
/**
@@ -12,16 +12,16 @@ export function useViewRange() {
},
});
- function updateNextViewRangeTime(update: ViewRangeTimeUpdate) {
+ const updateNextViewRangeTime = useCallback(function updateNextViewRangeTime(update: ViewRangeTimeUpdate) {
setViewRange(
(prevRange): ViewRange => {
const time = { ...prevRange.time, ...update };
return { ...prevRange, time };
}
);
- }
+ }, []);
- function updateViewRangeTime(start: number, end: number) {
+ const updateViewRangeTime = useCallback(function updateViewRangeTime(start: number, end: number) {
const current: [number, number] = [start, end];
const time = { current };
setViewRange(
@@ -29,7 +29,7 @@ export function useViewRange() {
return { ...prevRange, time };
}
);
- }
+ }, []);
return { viewRange, updateViewRangeTime, updateNextViewRangeTime };
}