|
@@ -11,7 +11,6 @@ import LoadingIndicator from 'sentry/components/loadingIndicator';
|
|
|
import Placeholder from 'sentry/components/placeholder';
|
|
|
import {t, tct} from 'sentry/locale';
|
|
|
import type {Organization, PlatformKey, Project} from 'sentry/types';
|
|
|
-import {getDuration} from 'sentry/utils/formatters';
|
|
|
import type {
|
|
|
TraceError,
|
|
|
TracePerformanceIssue,
|
|
@@ -94,6 +93,29 @@ function decodeScrollQueue(maybePath: unknown): TraceTree.NodePath[] | null {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+const format = (v: number, abbrev: string, precision: number) => {
|
|
|
+ if (v === 0) {
|
|
|
+ return '0' + abbrev;
|
|
|
+ }
|
|
|
+ return v.toFixed(precision) + abbrev;
|
|
|
+};
|
|
|
+
|
|
|
+function getDuration(duration_ms: number) {
|
|
|
+ if (duration_ms >= 24 * 60 * 60 * 1e3) {
|
|
|
+ return format((duration_ms / 24) * 60 * 60e3, 'd', 2);
|
|
|
+ }
|
|
|
+ if (duration_ms >= 60 * 60 * 1e3) {
|
|
|
+ return format((duration_ms / 60) * 60e3, 'h', 2);
|
|
|
+ }
|
|
|
+ if (duration_ms >= 60 * 1e3) {
|
|
|
+ return format(duration_ms / 60e3, 'min', 2);
|
|
|
+ }
|
|
|
+ if (duration_ms >= 1e3) {
|
|
|
+ return format(duration_ms / 1e3, 's', 2);
|
|
|
+ }
|
|
|
+ return format(duration_ms, 'ms', 2);
|
|
|
+}
|
|
|
+
|
|
|
const COUNT_FORMATTER = Intl.NumberFormat(undefined, {notation: 'compact'});
|
|
|
const NO_ERRORS = new Set<TraceError>();
|
|
|
const NO_PERFORMANCE_ISSUES = new Set<TracePerformanceIssue>();
|
|
@@ -130,6 +152,14 @@ function computeNextIndexFromAction(
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+const RIGHT_COLUMN_EVEN_CLASSNAME = `TraceRightColumn`;
|
|
|
+const RIGHT_COLUMN_ODD_CLASSNAME = [RIGHT_COLUMN_EVEN_CLASSNAME, 'Odd'].join(' ');
|
|
|
+const CHILDREN_COUNT_WRAPPER_CLASSNAME = `TraceChildrenCountWrapper`;
|
|
|
+const CHILDREN_COUNT_WRAPPER_ORPHANED_CLASSNAME = [
|
|
|
+ CHILDREN_COUNT_WRAPPER_CLASSNAME,
|
|
|
+ 'Orphaned',
|
|
|
+].join(' ');
|
|
|
+
|
|
|
function maybeFocusRow(
|
|
|
ref: HTMLDivElement | null,
|
|
|
node: TraceTreeNode<TraceTree.NodeValue>,
|
|
@@ -628,11 +658,7 @@ export function Trace({
|
|
|
>
|
|
|
<div className="TraceIndicatorLabel">
|
|
|
{indicatorTimestamp > 0
|
|
|
- ? getDuration(
|
|
|
- (manager.trace_view.x + indicatorTimestamp) / 1000,
|
|
|
- 2,
|
|
|
- true
|
|
|
- )
|
|
|
+ ? getDuration(manager.trace_view.x + indicatorTimestamp)
|
|
|
: '0s'}
|
|
|
</div>
|
|
|
<div className="TraceIndicatorLine" />
|
|
@@ -707,9 +733,6 @@ function RenderRow(props: {
|
|
|
ref={r =>
|
|
|
props.manager.registerColumnRef('list', r, virtualized_index, props.node)
|
|
|
}
|
|
|
- style={{
|
|
|
- width: props.manager.columns.list.width * 100 + '%',
|
|
|
- }}
|
|
|
>
|
|
|
<div
|
|
|
className={`TraceLeftColumnInner`}
|
|
@@ -742,13 +765,14 @@ function RenderRow(props: {
|
|
|
</div>
|
|
|
</div>
|
|
|
<div
|
|
|
- className={`TraceRightColumn ${props.index % 2 === 0 ? 0 : 'Odd'}`}
|
|
|
+ className={
|
|
|
+ props.index % 2 === 0
|
|
|
+ ? RIGHT_COLUMN_ODD_CLASSNAME
|
|
|
+ : RIGHT_COLUMN_EVEN_CLASSNAME
|
|
|
+ }
|
|
|
ref={r =>
|
|
|
props.manager.registerColumnRef('span_list', r, virtualized_index, props.node)
|
|
|
}
|
|
|
- style={{
|
|
|
- width: props.manager.columns.span_list.width * 100 + '%',
|
|
|
- }}
|
|
|
onDoubleClick={e => {
|
|
|
e.stopPropagation();
|
|
|
props.manager.onZoomIntoSpace(props.node.space!);
|
|
@@ -807,9 +831,6 @@ function RenderRow(props: {
|
|
|
ref={r =>
|
|
|
props.manager.registerColumnRef('list', r, virtualized_index, props.node)
|
|
|
}
|
|
|
- style={{
|
|
|
- width: props.manager.columns.list.width * 100 + '%',
|
|
|
- }}
|
|
|
>
|
|
|
<div
|
|
|
className={`TraceLeftColumnInner`}
|
|
@@ -818,10 +839,11 @@ function RenderRow(props: {
|
|
|
}}
|
|
|
>
|
|
|
<div
|
|
|
- className={`TraceChildrenCountWrapper ${
|
|
|
- props.node.isOrphaned ? 'Orphaned' : ''
|
|
|
+ className={
|
|
|
+ props.node.isOrphaned
|
|
|
+ ? CHILDREN_COUNT_WRAPPER_ORPHANED_CLASSNAME
|
|
|
+ : CHILDREN_COUNT_WRAPPER_CLASSNAME
|
|
|
}
|
|
|
- `}
|
|
|
>
|
|
|
<Connectors node={props.node} manager={props.manager} />
|
|
|
{props.node.children.length > 0 || props.node.canFetch ? (
|
|
@@ -862,10 +884,11 @@ function RenderRow(props: {
|
|
|
ref={r =>
|
|
|
props.manager.registerColumnRef('span_list', r, virtualized_index, props.node)
|
|
|
}
|
|
|
- className={`TraceRightColumn ${props.index % 2 === 0 ? 0 : 'Odd'}`}
|
|
|
- style={{
|
|
|
- width: props.manager.columns.span_list.width * 100 + '%',
|
|
|
- }}
|
|
|
+ className={
|
|
|
+ props.index % 2 === 0
|
|
|
+ ? RIGHT_COLUMN_ODD_CLASSNAME
|
|
|
+ : RIGHT_COLUMN_EVEN_CLASSNAME
|
|
|
+ }
|
|
|
onDoubleClick={e => {
|
|
|
e.stopPropagation();
|
|
|
props.manager.onZoomIntoSpace(props.node.space!);
|
|
@@ -920,9 +943,6 @@ function RenderRow(props: {
|
|
|
ref={r =>
|
|
|
props.manager.registerColumnRef('list', r, virtualized_index, props.node)
|
|
|
}
|
|
|
- style={{
|
|
|
- width: props.manager.columns.list.width * 100 + '%',
|
|
|
- }}
|
|
|
>
|
|
|
<div
|
|
|
className={`TraceLeftColumnInner`}
|
|
@@ -931,9 +951,11 @@ function RenderRow(props: {
|
|
|
}}
|
|
|
>
|
|
|
<div
|
|
|
- className={`TraceChildrenCountWrapper ${
|
|
|
- props.node.isOrphaned ? 'Orphaned' : ''
|
|
|
- }`}
|
|
|
+ className={
|
|
|
+ props.node.isOrphaned
|
|
|
+ ? CHILDREN_COUNT_WRAPPER_ORPHANED_CLASSNAME
|
|
|
+ : CHILDREN_COUNT_WRAPPER_CLASSNAME
|
|
|
+ }
|
|
|
>
|
|
|
<Connectors node={props.node} manager={props.manager} />
|
|
|
{props.node.children.length > 0 || props.node.canFetch ? (
|
|
@@ -977,10 +999,11 @@ function RenderRow(props: {
|
|
|
ref={r =>
|
|
|
props.manager.registerColumnRef('span_list', r, virtualized_index, props.node)
|
|
|
}
|
|
|
- className={`TraceRightColumn ${props.index % 2 === 0 ? 0 : 'Odd'}`}
|
|
|
- style={{
|
|
|
- width: props.manager.columns.span_list.width * 100 + '%',
|
|
|
- }}
|
|
|
+ className={
|
|
|
+ props.index % 2 === 0
|
|
|
+ ? RIGHT_COLUMN_ODD_CLASSNAME
|
|
|
+ : RIGHT_COLUMN_EVEN_CLASSNAME
|
|
|
+ }
|
|
|
onDoubleClick={e => {
|
|
|
e.stopPropagation();
|
|
|
props.manager.onZoomIntoSpace(props.node.space!);
|
|
@@ -1034,9 +1057,6 @@ function RenderRow(props: {
|
|
|
ref={r =>
|
|
|
props.manager.registerColumnRef('list', r, virtualized_index, props.node)
|
|
|
}
|
|
|
- style={{
|
|
|
- width: props.manager.columns.list.width * 100 + '%',
|
|
|
- }}
|
|
|
>
|
|
|
<div
|
|
|
className="TraceLeftColumnInner"
|
|
@@ -1054,15 +1074,17 @@ function RenderRow(props: {
|
|
|
ref={r =>
|
|
|
props.manager.registerColumnRef('span_list', r, virtualized_index, props.node)
|
|
|
}
|
|
|
- className={`TraceRightColumn ${props.index % 2 === 0 ? 0 : 'Odd'}`}
|
|
|
- style={{
|
|
|
- width: props.manager.columns.span_list.width * 100 + '%',
|
|
|
- }}
|
|
|
+ className={
|
|
|
+ props.index % 2 === 0
|
|
|
+ ? RIGHT_COLUMN_ODD_CLASSNAME
|
|
|
+ : RIGHT_COLUMN_EVEN_CLASSNAME
|
|
|
+ }
|
|
|
onDoubleClick={e => {
|
|
|
e.stopPropagation();
|
|
|
props.manager.onZoomIntoSpace(props.node.space!);
|
|
|
}}
|
|
|
>
|
|
|
+ {' '}
|
|
|
<TraceBar
|
|
|
virtualized_index={virtualized_index}
|
|
|
manager={props.manager}
|
|
@@ -1111,9 +1133,6 @@ function RenderRow(props: {
|
|
|
ref={r =>
|
|
|
props.manager.registerColumnRef('list', r, virtualized_index, props.node)
|
|
|
}
|
|
|
- style={{
|
|
|
- width: props.manager.columns.list.width * 100 + '%',
|
|
|
- }}
|
|
|
>
|
|
|
<div
|
|
|
className="TraceLeftColumnInner"
|
|
@@ -1141,10 +1160,11 @@ function RenderRow(props: {
|
|
|
ref={r =>
|
|
|
props.manager.registerColumnRef('span_list', r, virtualized_index, props.node)
|
|
|
}
|
|
|
- className={`TraceRightColumn ${props.index % 2 === 0 ? 0 : 'Odd'}`}
|
|
|
- style={{
|
|
|
- width: props.manager.columns.span_list.width * 100 + '%',
|
|
|
- }}
|
|
|
+ className={
|
|
|
+ props.index % 2 === 0
|
|
|
+ ? RIGHT_COLUMN_ODD_CLASSNAME
|
|
|
+ : RIGHT_COLUMN_EVEN_CLASSNAME
|
|
|
+ }
|
|
|
onDoubleClick={e => {
|
|
|
e.stopPropagation();
|
|
|
props.manager.onZoomIntoSpace(props.node.space!);
|
|
@@ -1198,9 +1218,6 @@ function RenderRow(props: {
|
|
|
ref={r =>
|
|
|
props.manager.registerColumnRef('list', r, virtualized_index, props.node)
|
|
|
}
|
|
|
- style={{
|
|
|
- width: props.manager.columns.list.width * 100 + '%',
|
|
|
- }}
|
|
|
>
|
|
|
<div
|
|
|
className="TraceLeftColumnInner"
|
|
@@ -1223,10 +1240,11 @@ function RenderRow(props: {
|
|
|
ref={r =>
|
|
|
props.manager.registerColumnRef('span_list', r, virtualized_index, props.node)
|
|
|
}
|
|
|
- className={`TraceRightColumn ${props.index % 2 === 0 ? 0 : 'Odd'}`}
|
|
|
- style={{
|
|
|
- width: props.manager.columns.span_list.width * 100 + '%',
|
|
|
- }}
|
|
|
+ className={
|
|
|
+ props.index % 2 === 0
|
|
|
+ ? RIGHT_COLUMN_ODD_CLASSNAME
|
|
|
+ : RIGHT_COLUMN_EVEN_CLASSNAME
|
|
|
+ }
|
|
|
onDoubleClick={e => {
|
|
|
e.stopPropagation();
|
|
|
props.manager.onZoomIntoSpace(props.node.space!);
|
|
@@ -1271,9 +1289,6 @@ function RenderRow(props: {
|
|
|
ref={r =>
|
|
|
props.manager.registerColumnRef('list', r, virtualized_index, props.node)
|
|
|
}
|
|
|
- style={{
|
|
|
- width: props.manager.columns.list.width * 100 + '%',
|
|
|
- }}
|
|
|
>
|
|
|
<div
|
|
|
className="TraceLeftColumnInner"
|
|
@@ -1303,10 +1318,11 @@ function RenderRow(props: {
|
|
|
ref={r =>
|
|
|
props.manager.registerColumnRef('span_list', r, virtualized_index, props.node)
|
|
|
}
|
|
|
- className={`TraceRightColumn ${props.index % 2 === 0 ? 0 : 'Odd'}`}
|
|
|
- style={{
|
|
|
- width: props.manager.columns.span_list.width * 100 + '%',
|
|
|
- }}
|
|
|
+ className={
|
|
|
+ props.index % 2 === 0
|
|
|
+ ? RIGHT_COLUMN_ODD_CLASSNAME
|
|
|
+ : RIGHT_COLUMN_EVEN_CLASSNAME
|
|
|
+ }
|
|
|
/>
|
|
|
</div>
|
|
|
);
|
|
@@ -1373,7 +1389,9 @@ function RenderPlaceholderRow(props: {
|
|
|
</div>
|
|
|
</div>
|
|
|
<div
|
|
|
- className={`TraceRightColumn ${props.index % 2 === 0 ? 0 : 'Odd'}`}
|
|
|
+ className={
|
|
|
+ props.index % 2 === 0 ? RIGHT_COLUMN_ODD_CLASSNAME : RIGHT_COLUMN_EVEN_CLASSNAME
|
|
|
+ }
|
|
|
style={{
|
|
|
width: props.manager.columns.span_list.width * 100 + '%',
|
|
|
backgroundColor:
|
|
@@ -1481,7 +1499,7 @@ function TraceBar(props: TraceBarProps) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- const duration = getDuration(props.node_space[1] / 1000, 2, true);
|
|
|
+ const duration = getDuration(props.node_space[1]);
|
|
|
const spanTransform = props.manager.computeSpanCSSMatrixTransform(props.node_space);
|
|
|
const [inside, textTransform] = props.manager.computeSpanTextPlacement(
|
|
|
props.node_space,
|
|
@@ -1748,7 +1766,7 @@ function AutogroupedTraceBar(props: AutogroupedTraceBarProps) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- const duration = getDuration(props.entire_space[1] / 1000, 2, true);
|
|
|
+ const duration = getDuration(props.entire_space[1]);
|
|
|
const spanTransform = props.manager.computeSpanCSSMatrixTransform(props.entire_space);
|
|
|
const [inside, textTransform] = props.manager.computeSpanTextPlacement(
|
|
|
props.entire_space,
|
|
@@ -1903,6 +1921,7 @@ const TraceStylingWrapper = styled('div')`
|
|
|
top: 0;
|
|
|
cursor: col-resize;
|
|
|
z-index: 10;
|
|
|
+ transform: translateX(calc(var(--translate-x) * 1px));
|
|
|
|
|
|
&:before {
|
|
|
content: '';
|
|
@@ -1927,6 +1946,7 @@ const TraceStylingWrapper = styled('div')`
|
|
|
position: absolute;
|
|
|
right: 0;
|
|
|
top: 0;
|
|
|
+ transform: translateX(calc(var(--translate-x) * 1px));
|
|
|
}
|
|
|
|
|
|
.TraceIndicator {
|
|
@@ -2170,6 +2190,7 @@ const TraceStylingWrapper = styled('div')`
|
|
|
will-change: width;
|
|
|
box-shadow: inset 1px 0 0px 0px transparent;
|
|
|
cursor: pointer;
|
|
|
+ width: calc(var(--width) * 100%);
|
|
|
|
|
|
.TraceLeftColumnInner {
|
|
|
height: 100%;
|
|
@@ -2195,6 +2216,7 @@ const TraceStylingWrapper = styled('div')`
|
|
|
will-change: width;
|
|
|
z-index: 1;
|
|
|
cursor: pointer;
|
|
|
+ width: calc(var(--width) * 100%);
|
|
|
|
|
|
&:hover {
|
|
|
.TraceArrow.Visible {
|