mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-13 20:05:58 +08:00
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:
parent
8aae9f53a9
commit
ab5311caac
@ -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
|
||||||
|
@ -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 =>
|
||||||
|
@ -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;
|
@ -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;
|
@ -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 = {
|
||||||
|
@ -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
|
||||||
|
@ -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 = (
|
||||||
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user