feat: events is updated by adding the timestamp (#1802)

* feat: events is updated
* chore: title is updated
* feat: trace detail event timestamp is updated
This commit is contained in:
Palash Gupta 2022-12-02 10:34:06 +05:30 committed by GitHub
parent 8aae9f53a9
commit ab5311caac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 97 additions and 21 deletions

View File

@ -62,6 +62,8 @@ export const legend = (id: string, isLonger: boolean): Plugin<ChartType> => {
li.style.marginTop = '5px'; li.style.marginTop = '5px';
li.onclick = (): void => { li.onclick = (): void => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const { type } = chart.config; const { type } = chart.config;
if (type === 'pie' || type === 'doughnut') { if (type === 'pie' || type === 'doughnut') {
// Pie and doughnut charts only have a single dataset and visibility is per item // Pie and doughnut charts only have a single dataset and visibility is per item

View File

@ -48,9 +48,8 @@ function AddTags({ tags, setTags }: AddTagsProps): JSX.Element {
{tags.map((tag, index) => { {tags.map((tag, index) => {
if (editInputIndex === index) { if (editInputIndex === index) {
return ( return (
<Col lg={4}> <Col key={tag} lg={4}>
<Input <Input
key={tag}
size="small" size="small"
value={editInputValue} value={editInputValue}
onChangeHandler={(event): void => onChangeHandler={(event): void =>

View File

@ -1,12 +1,14 @@
import { Collapse } from 'antd'; import { InfoCircleOutlined } from '@ant-design/icons';
import { Collapse, Popover, Space } from 'antd';
import { convertTimeToRelevantUnit } from 'container/TraceDetail/utils';
import useThemeMode from 'hooks/useThemeMode'; import useThemeMode from 'hooks/useThemeMode';
import keys from 'lodash-es/keys'; import keys from 'lodash-es/keys';
import map from 'lodash-es/map'; import map from 'lodash-es/map';
import React from 'react'; import React from 'react';
import { ITraceTree } from 'types/api/trace/getTraceItem'; import { ITraceTree } from 'types/api/trace/getTraceItem';
import EllipsedButton from './EllipsedButton'; import EllipsedButton from '../EllipsedButton';
import { CustomSubText, CustomSubTitle } from './styles'; import { CustomSubText, CustomSubTitle } from '../styles';
const { Panel } = Collapse; const { Panel } = Collapse;
@ -14,23 +16,42 @@ function ErrorTag({
event, event,
onToggleHandler, onToggleHandler,
setText, setText,
firstSpanStartTime,
}: ErrorTagProps): JSX.Element { }: ErrorTagProps): JSX.Element {
const { isDarkMode } = useThemeMode(); const { isDarkMode } = useThemeMode();
return ( return (
<> <>
{map(event, ({ attributeMap, name }) => { {map(event, ({ attributeMap, name, timeUnixNano }) => {
const attributes = keys(attributeMap); const attributes = keys(attributeMap);
const { time, timeUnitName } = convertTimeToRelevantUnit(
timeUnixNano / 1e6 - firstSpanStartTime,
);
return ( return (
<Collapse <Collapse
key={`${name}${JSON.stringify(attributeMap)}`} key={`${name}${JSON.stringify(attributeMap)}`}
defaultActiveKey={[name || attributeMap.event]} defaultActiveKey={[name || attributeMap.event, 'timestamp']}
expandIconPosition="right" expandIconPosition="right"
> >
<Panel <Panel
header={name || attributeMap?.event} header={name || attributeMap?.event}
key={name || attributeMap.event} key={name || attributeMap.event}
> >
<Space direction="horizontal" align="center">
<CustomSubTitle style={{ margin: 0 }} ellipsis>
Event Start Time
</CustomSubTitle>
<Popover content="Relative to start of the full trace">
<InfoCircleOutlined />
</Popover>
</Space>
<CustomSubText isDarkMode={isDarkMode}>
{`${time.toFixed(2)} ${timeUnitName}`}
</CustomSubText>
{map(attributes, (event) => { {map(attributes, (event) => {
const value = attributeMap[event]; const value = attributeMap[event];
const isEllipsed = value.length > 24; const isEllipsed = value.length > 24;
@ -72,6 +93,7 @@ interface ErrorTagProps {
event: ITraceTree['event']; event: ITraceTree['event'];
onToggleHandler: (isOpen: boolean) => void; onToggleHandler: (isOpen: boolean) => void;
setText: (text: { subText: string; text: string }) => void; setText: (text: { subText: string; text: string }) => void;
firstSpanStartTime: number;
} }
export default ErrorTag; export default ErrorTag;

View File

@ -0,0 +1,38 @@
import { Typography } from 'antd';
import React from 'react';
import { ITraceEvents } from 'types/api/trace/getTraceItem';
import ErrorTag from './Event';
function Events({
events = [],
onToggleHandler,
setText,
firstSpanStartTime,
}: EventsProps): JSX.Element {
if (events.length === 0) {
return <Typography>No events data in selected span</Typography>;
}
return (
<ErrorTag
onToggleHandler={onToggleHandler}
setText={setText}
event={events}
firstSpanStartTime={firstSpanStartTime}
/>
);
}
interface EventsProps {
events?: ITraceEvents[];
onToggleHandler: (event: boolean) => void;
setText: (props: { subText: string; text: string }) => void;
firstSpanStartTime: number;
}
Events.defaultProps = {
events: [],
};
export default Events;

View File

@ -1,11 +1,11 @@
import { Modal, Tabs, Tooltip, Typography } from 'antd'; import { Modal, Tabs, Tooltip } from 'antd';
import Editor from 'components/Editor'; import Editor from 'components/Editor';
import { StyledSpace } from 'components/Styled'; import { StyledSpace } from 'components/Styled';
import useThemeMode from 'hooks/useThemeMode'; import useThemeMode from 'hooks/useThemeMode';
import React, { useMemo, useState } from 'react'; import React, { useMemo, useState } from 'react';
import { ITraceTree } from 'types/api/trace/getTraceItem'; import { ITraceTree } from 'types/api/trace/getTraceItem';
import ErrorTag from './ErrorTag'; import Events from './Events';
import { import {
CardContainer, CardContainer,
CustomSubText, CustomSubText,
@ -18,7 +18,7 @@ import Tags from './Tags';
const { TabPane } = Tabs; const { TabPane } = Tabs;
function SelectedSpanDetails(props: SelectedSpanDetailsProps): JSX.Element { function SelectedSpanDetails(props: SelectedSpanDetailsProps): JSX.Element {
const { tree } = props; const { tree, firstSpanStartTime } = props;
const { isDarkMode } = useThemeMode(); const { isDarkMode } = useThemeMode();
@ -87,15 +87,12 @@ function SelectedSpanDetails(props: SelectedSpanDetailsProps): JSX.Element {
<Tags onToggleHandler={onToggleHandler} setText={setText} tags={tags} /> <Tags onToggleHandler={onToggleHandler} setText={setText} tags={tags} />
</TabPane> </TabPane>
<TabPane tab="Events" key="2"> <TabPane tab="Events" key="2">
{tree.event && Object.keys(tree.event).length !== 0 ? ( <Events
<ErrorTag events={tree.event}
onToggleHandler={onToggleHandler} onToggleHandler={onToggleHandler}
setText={setText} setText={setText}
event={tree.event} firstSpanStartTime={firstSpanStartTime}
/> />
) : (
<Typography>No events data in selected span</Typography>
)}
</TabPane> </TabPane>
</Tabs> </Tabs>
</CardContainer> </CardContainer>
@ -104,6 +101,7 @@ function SelectedSpanDetails(props: SelectedSpanDetailsProps): JSX.Element {
interface SelectedSpanDetailsProps { interface SelectedSpanDetailsProps {
tree?: ITraceTree; tree?: ITraceTree;
firstSpanStartTime: number;
} }
SelectedSpanDetails.defaultProps = { SelectedSpanDetails.defaultProps = {

View File

@ -76,6 +76,8 @@ function TraceDetail({ response }: TraceDetailProps): JSX.Element {
/* eslint-enable */ /* eslint-enable */
}, [treesData, spanServiceColors]); }, [treesData, spanServiceColors]);
const firstSpanStartTime = tree.spanTree[0].startTime;
const [globalTraceMetadata] = useState<ITraceMetaData>({ const [globalTraceMetadata] = useState<ITraceMetaData>({
...traceMetaData, ...traceMetaData,
}); });
@ -255,6 +257,7 @@ function TraceDetail({ response }: TraceDetailProps): JSX.Element {
</Col> </Col>
<StyledCol md={5} sm={5} styledclass={[styles.selectedSpanDetailContainer]}> <StyledCol md={5} sm={5} styledclass={[styles.selectedSpanDetailContainer]}>
<SelectedSpanDetails <SelectedSpanDetails
firstSpanStartTime={firstSpanStartTime}
tree={[ tree={[
...(getSelectedNode.spanTree ? getSelectedNode.spanTree : []), ...(getSelectedNode.spanTree ? getSelectedNode.spanTree : []),
...(getSelectedNode.missingSpanTree ...(getSelectedNode.missingSpanTree

View File

@ -13,7 +13,8 @@ export const filterSpansByString = (
return JSON.stringify(spanWithoutChildren).includes(searchString); return JSON.stringify(spanWithoutChildren).includes(searchString);
}); });
type TTimeUnitName = 'ms' | 's' | 'm'; type TTimeUnitName = 'ms' | 's' | 'm' | 'hr' | 'day' | 'week';
export interface IIntervalUnit { export interface IIntervalUnit {
name: TTimeUnitName; name: TTimeUnitName;
multiplier: number; multiplier: number;
@ -31,6 +32,18 @@ export const INTERVAL_UNITS: IIntervalUnit[] = [
name: 'm', name: 'm',
multiplier: 1 / (1e3 * 60), multiplier: 1 / (1e3 * 60),
}, },
{
name: 'hr',
multiplier: 1 / (1e3 * 60 * 60),
},
{
name: 'day',
multiplier: 1 / (1e3 * 60 * 60 * 24),
},
{
name: 'week',
multiplier: 1 / (1e3 * 60 * 60 * 24 * 7),
},
]; ];
export const resolveTimeFromInterval = ( export const resolveTimeFromInterval = (

View File

@ -56,9 +56,10 @@ export interface ITraceTag {
value: string; value: string;
} }
interface ITraceEvents { export interface ITraceEvents {
attributeMap: { event: string; [key: string]: string }; attributeMap: { event: string; [key: string]: string };
name?: string; name?: string;
timeUnixNano: number;
} }
export interface ITraceForest { export interface ITraceForest {