Compare commits

..

5 Commits

Author SHA1 Message Date
aks07
4ec3754b65 feat: increase limit 2026-02-26 17:45:21 +05:30
aks07
c36f780964 feat: poc flamegraph 3 2026-02-26 15:57:41 +05:30
aks07
e0e0870e23 feat: poc flamegraph 2 2026-02-26 15:41:15 +05:30
aks07
ea406dac52 feat: poc flamegraph 1 2026-02-26 15:40:36 +05:30
aks07
c6152b33e9 feat: poc flamegraph 2026-02-26 15:37:28 +05:30
8 changed files with 59 additions and 207 deletions

View File

@@ -1,5 +1,5 @@
import { ApiV2Instance as axios } from 'api';
import { isUndefined, omit, omitBy } from 'lodash-es';
import { omit } from 'lodash-es';
import { ErrorResponse, SuccessResponse } from 'types/api';
import {
GetTraceFlamegraphPayloadProps,
@@ -11,10 +11,9 @@ const getTraceFlamegraph = async (
): Promise<
SuccessResponse<GetTraceFlamegraphSuccessResponse> | ErrorResponse
> => {
const body = omitBy(omit(props, 'traceId'), isUndefined);
const response = await axios.post<GetTraceFlamegraphSuccessResponse>(
`/traces/flamegraph/${props.traceId}`,
body,
omit(props, 'traceId'),
);
return {

View File

@@ -1,13 +1,12 @@
// @ts-nocheck
/* eslint-disable */
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { useParams } from 'react-router-dom';
import { Progress, Skeleton, Tooltip, Typography } from 'antd';
import { AxiosError } from 'axios';
import Spinner from 'components/Spinner';
import { themeColors } from 'constants/theme';
import useGetTraceFlamegraph from 'hooks/trace/useGetTraceFlamegraph';
import useDebounce from 'hooks/useDebounce';
import useUrlQuery from 'hooks/useUrlQuery';
import { generateColor } from 'lib/uPlotLib/utils/generateColor';
import { TraceDetailFlamegraphURLProps } from 'types/api/trace/getTraceFlamegraph';
@@ -25,12 +24,6 @@ import Success from './TraceFlamegraphStates/Success/Success_zoom';
// import Success from './TraceFlamegraphStates/Success/Success';
import './PaginatedTraceFlamegraph.styles.scss';
interface ViewWindow {
viewStart: number;
viewEnd: number;
topSpanId: string;
}
interface ITraceFlamegraphProps {
serviceExecTime: Record<string, number>;
startTime: number;
@@ -56,87 +49,14 @@ function TraceFlamegraph(props: ITraceFlamegraphProps): JSX.Element {
setFirstSpanAtFetchLevel(urlQuery.get('spanId') || '');
}, [urlQuery]);
// --- Zoom-based API re-fetch orchestration ---
// Raw view window from the canvas child (updated on every zoom/drag frame)
const [rawViewWindow, setRawViewWindow] = useState<ViewWindow | null>(null);
// Debounced view window — settles 300ms after the last zoom/drag interaction
const debouncedViewWindow = useDebounce(rawViewWindow, 300);
// Store trace extents from data in a ref to break the circular dependency
// (apiParams depends on extents, data depends on apiParams)
const traceExtentsRef = useRef({ fullStart: 0, fullEnd: 0 });
// Callback for the canvas child to report its current visible window
const handleViewWindowChange = useCallback(
(viewStart: number, viewEnd: number, topSpanId: string) => {
setRawViewWindow({ viewStart, viewEnd, topSpanId });
},
[],
);
// Derive API params from the debounced view window
const apiParams = useMemo(() => {
const { fullStart, fullEnd } = traceExtentsRef.current;
const fullSpan = fullEnd - fullStart;
if (!debouncedViewWindow || fullSpan <= 0) {
return {
selectedSpanId: firstSpanAtFetchLevel,
boundaryStartTsMilli: undefined,
boundarEndTsMilli: undefined,
};
}
const { viewStart, viewEnd, topSpanId } = debouncedViewWindow;
const viewSpan = viewEnd - viewStart;
const ratio = viewSpan / fullSpan;
// Only send boundaries when zoomed in past 80% threshold
if (ratio < 0.8) {
const padding = viewSpan * 0.5; // 2x fetch width (50% padding each side)
return {
// CRITICAL: always use firstSpanAtFetchLevel (never topSpanId) so the
// backend's lowerLimit/upperLimit stays constant across all zoom fetches.
// Changing selectedSpanId shifts lowerLimit → Spans[i] represents a
// different absolute level → wrong canvas Y-positions → spans don't appear.
selectedSpanId: firstSpanAtFetchLevel,
boundaryStartTsMilli: Math.floor(Math.max(fullStart, viewStart - padding)),
boundarEndTsMilli: Math.ceil(Math.min(fullEnd, viewEnd + padding)),
};
}
// Not zoomed enough — use default params (no boundaries)
return {
selectedSpanId: firstSpanAtFetchLevel,
boundaryStartTsMilli: undefined,
boundarEndTsMilli: undefined,
};
}, [debouncedViewWindow, firstSpanAtFetchLevel]);
// Single query with dynamic params
const { data, isFetching, error } = useGetTraceFlamegraph({
traceId,
selectedSpanId: apiParams.selectedSpanId,
limit: 10001,
boundaryStartTsMilli: apiParams.boundaryStartTsMilli,
boundarEndTsMilli: apiParams.boundarEndTsMilli,
selectedSpanId: firstSpanAtFetchLevel,
limit: 100001,
// boundaryStartTsMilli: 0,
// boundarEndTsMilli: 10000,
});
// Update trace extents ref when data arrives (breaks circular dep)
useEffect(() => {
if (data?.payload) {
traceExtentsRef.current = {
fullStart: data.payload.startTimestampMillis,
fullEnd: data.payload.endTimestampMillis,
};
}
}, [data?.payload]);
// Is this a zoom-triggered fetch (vs initial load)?
const isZoomFetching = isFetching && apiParams.boundaryStartTsMilli !== undefined;
// get the current state of trace flamegraph based on the API lifecycle
const traceFlamegraphState = useMemo(() => {
if (isFetching) {
@@ -195,8 +115,6 @@ function TraceFlamegraph(props: ITraceFlamegraphProps): JSX.Element {
endTime: data?.payload?.endTimestampMillis || 0,
}}
selectedSpan={selectedSpan}
onViewWindowChange={handleViewWindowChange}
isZoomFetching={isZoomFetching}
/>
);
default:
@@ -207,8 +125,6 @@ function TraceFlamegraph(props: ITraceFlamegraphProps): JSX.Element {
data?.payload?.startTimestampMillis,
error,
firstSpanAtFetchLevel,
handleViewWindowChange,
isZoomFetching,
selectedSpan,
spans,
traceFlamegraphState,

View File

@@ -8,23 +8,6 @@
position: relative;
}
.flamegraph-zoom-loading {
position: absolute;
top: 8px;
right: 8px;
z-index: 10;
display: flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
border-radius: 4px;
background-color: var(--bg-ink-300, rgba(0, 0, 0, 0.45));
color: var(--text-vanilla-100, #fff);
font-size: 11px;
opacity: 0.85;
pointer-events: none;
}
.trace-flamegraph-virtuoso {
overflow-x: hidden;

View File

@@ -13,7 +13,7 @@ import {
useState,
} from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import { Button, Spin } from 'antd';
import { Button } from 'antd';
import Color from 'color';
import TimelineV2 from 'components/TimelineV2/TimelineV2';
import { themeColors } from 'constants/theme';
@@ -35,8 +35,6 @@ interface ISuccessProps {
setFirstSpanAtFetchLevel: Dispatch<SetStateAction<string>>;
traceMetadata: ITraceMetadata;
selectedSpan: Span | undefined;
onViewWindowChange?: (viewStart: number, viewEnd: number, topVisibleSpanId: string) => void;
isZoomFetching?: boolean;
}
// // Constants for rendering
@@ -131,8 +129,6 @@ function Success(props: ISuccessProps): JSX.Element {
traceMetadata,
firstSpanAtFetchLevel,
selectedSpan,
onViewWindowChange,
isZoomFetching,
} = props;
const { search } = useLocation();
const history = useHistory();
@@ -179,34 +175,6 @@ function Success(props: ISuccessProps): JSX.Element {
viewEndRef.current = viewEndTs;
}, [viewStartTs, viewEndTs]);
// --- Report view window changes to parent for zoom-based API re-fetch ---
useEffect(() => {
if (!onViewWindowChange) return;
// Find topmost visible span in the current time window
const firstVisibleLevel = Math.max(
0,
Math.floor(scrollTopRef.current / ROW_HEIGHT),
);
const midTs = (viewStartTs + viewEndTs) / 2;
let topSpanId = firstSpanAtFetchLevel;
// Walk from first visible level downward to find a span in the time window
for (
let level = firstVisibleLevel;
level < Math.min(firstVisibleLevel + 5, spans.length);
level++
) {
const span = getClosestSpanAtLevel(spans[level], midTs);
if (span) {
topSpanId = span.spanId;
break;
}
}
onViewWindowChange(viewStartTs, viewEndTs, topSpanId);
}, [viewStartTs, viewEndTs]); // intentionally sparse deps — fire only on view window change
// Drag state in refs to avoid re-renders during drag
const isDraggingRef = useRef(false);
const dragStartRef = useRef<{ x: number; y: number } | null>(null);
@@ -1126,12 +1094,6 @@ function Success(props: ISuccessProps): JSX.Element {
Reset View
</Button>
)}
{isZoomFetching && (
<div className="flamegraph-zoom-loading">
<Spin size="small" />
<span>Loading detail...</span>
</div>
)}
<canvas
ref={canvasRef}
style={{

View File

@@ -18,8 +18,8 @@ const useGetTraceFlamegraph = (
props.traceId,
props.selectedSpanId,
props.limit,
props.boundaryStartTsMilli ?? 'none',
props.boundarEndTsMilli ?? 'none',
props.boundaryStartTsMilli,
props.boundarEndTsMilli,
],
enabled: !!props.traceId,
keepPreviousData: true,

View File

@@ -6,8 +6,8 @@ export interface GetTraceFlamegraphPayloadProps {
traceId: string;
selectedSpanId: string;
limit: number;
boundaryStartTsMilli?: number;
boundarEndTsMilli?: number;
boundaryStartTsMilli: number;
boundarEndTsMilli: number;
}
export interface Event {

View File

@@ -1233,15 +1233,7 @@ func (r *ClickHouseReader) GetFlamegraphSpansForTrace(ctx context.Context, orgID
limit := min(req.Limit, tracedetail.MaxLimitWithoutSampling)
totalSpanCount := tracedetail.GetTotalSpanCount(selectedSpans)
if totalSpanCount > uint64(limit) {
boundaryStart := utils.MilliToNano(req.BoundaryStartTS)
if boundaryStart == 0 {
boundaryStart = startTime // not really required, just to keep previous behaviour exactly same
}
boundaryEnd := utils.MilliToNano(req.BoundaryEndTS)
if boundaryEnd == 0 {
boundaryEnd = endTime
}
fmt.Printf("start: %d, end: %d, old start: %d, old end: %d", boundaryStart, boundaryEnd, startTime, endTime)
boundaryStart, boundaryEnd := utils.MilliToNano(req.BoundaryStartTS), utils.MilliToNano(req.BoundaryEndTS)
selectedSpansForRequest = tracedetail.GetSelectedSpansForFlamegraphForRequest(req.SelectedSpanID, selectedSpans, boundaryStart, boundaryEnd)
}
zap.L().Info("getFlamegraphSpansForTrace: processing post cache", zap.Duration("duration", time.Since(processingPostCache)), zap.String("traceID", traceID),
@@ -3247,8 +3239,8 @@ func (r *ClickHouseReader) GetMetricAggregateAttributes(ctx context.Context, org
// Query all relevant metric names from time_series_v4, but leave metadata retrieval to cache/db
query := fmt.Sprintf(
`SELECT DISTINCT metric_name
FROM %s.%s
`SELECT DISTINCT metric_name
FROM %s.%s
WHERE metric_name ILIKE $1 AND __normalized = $2`,
signozMetricDBName, signozTSTableNameV41Day)
@@ -3320,8 +3312,8 @@ func (r *ClickHouseReader) GetMeterAggregateAttributes(ctx context.Context, orgI
var response v3.AggregateAttributeResponse
// Query all relevant metric names from time_series_v4, but leave metadata retrieval to cache/db
query := fmt.Sprintf(
`SELECT metric_name,type,temporality,is_monotonic
FROM %s.%s
`SELECT metric_name,type,temporality,is_monotonic
FROM %s.%s
WHERE metric_name ILIKE $1
GROUP BY metric_name,type,temporality,is_monotonic`,
signozMeterDBName, signozMeterSamplesName)
@@ -4854,7 +4846,7 @@ func (r *ClickHouseReader) GetOverallStateTransitions(ctx context.Context, ruleI
state,
unix_milli AS firing_time
FROM %s.%s
WHERE overall_state = '` + model.StateFiring.String() + `'
WHERE overall_state = '` + model.StateFiring.String() + `'
AND overall_state_changed = true
AND rule_id IN ('%s')
AND unix_milli >= %d AND unix_milli <= %d
@@ -4865,7 +4857,7 @@ resolution_events AS (
state,
unix_milli AS resolution_time
FROM %s.%s
WHERE overall_state = '` + model.StateInactive.String() + `'
WHERE overall_state = '` + model.StateInactive.String() + `'
AND overall_state_changed = true
AND rule_id IN ('%s')
AND unix_milli >= %d AND unix_milli <= %d
@@ -4982,7 +4974,7 @@ WITH firing_events AS (
state,
unix_milli AS firing_time
FROM %s.%s
WHERE overall_state = '` + model.StateFiring.String() + `'
WHERE overall_state = '` + model.StateFiring.String() + `'
AND overall_state_changed = true
AND rule_id IN ('%s')
AND unix_milli >= %d AND unix_milli <= %d
@@ -4993,7 +4985,7 @@ resolution_events AS (
state,
unix_milli AS resolution_time
FROM %s.%s
WHERE overall_state = '` + model.StateInactive.String() + `'
WHERE overall_state = '` + model.StateInactive.String() + `'
AND overall_state_changed = true
AND rule_id IN ('%s')
AND unix_milli >= %d AND unix_milli <= %d
@@ -5039,7 +5031,7 @@ WITH firing_events AS (
state,
unix_milli AS firing_time
FROM %s.%s
WHERE overall_state = '` + model.StateFiring.String() + `'
WHERE overall_state = '` + model.StateFiring.String() + `'
AND overall_state_changed = true
AND rule_id IN ('%s')
AND unix_milli >= %d AND unix_milli <= %d
@@ -5050,7 +5042,7 @@ resolution_events AS (
state,
unix_milli AS resolution_time
FROM %s.%s
WHERE overall_state = '` + model.StateInactive.String() + `'
WHERE overall_state = '` + model.StateInactive.String() + `'
AND overall_state_changed = true
AND rule_id IN ('%s')
AND unix_milli >= %d AND unix_milli <= %d
@@ -5278,7 +5270,7 @@ func (r *ClickHouseReader) GetAllMetricFilterTypes(ctx context.Context, req *met
}
func (r *ClickHouseReader) GetMetricsDataPoints(ctx context.Context, metricName string) (uint64, *model.ApiError) {
query := fmt.Sprintf(`SELECT
query := fmt.Sprintf(`SELECT
sum(count) as data_points
FROM %s.%s
WHERE metric_name = ?
@@ -5293,7 +5285,7 @@ WHERE metric_name = ?
}
func (r *ClickHouseReader) GetMetricsLastReceived(ctx context.Context, metricName string) (int64, *model.ApiError) {
query := fmt.Sprintf(`SELECT
query := fmt.Sprintf(`SELECT
MAX(unix_milli) AS last_received_time
FROM %s.%s
WHERE metric_name = ?
@@ -5304,7 +5296,7 @@ WHERE metric_name = ?
if err != nil {
return 0, &model.ApiError{Typ: "ClickHouseError", Err: err}
}
query = fmt.Sprintf(`SELECT
query = fmt.Sprintf(`SELECT
MAX(unix_milli) AS last_received_time
FROM %s.%s
WHERE metric_name = ? and unix_milli > ?
@@ -5318,7 +5310,7 @@ WHERE metric_name = ? and unix_milli > ?
}
func (r *ClickHouseReader) GetTotalTimeSeriesForMetricName(ctx context.Context, metricName string) (uint64, *model.ApiError) {
query := fmt.Sprintf(`SELECT
query := fmt.Sprintf(`SELECT
uniq(fingerprint) AS timeSeriesCount
FROM %s.%s
WHERE metric_name = ?;`, signozMetricDBName, signozTSTableNameV41Week)
@@ -5345,7 +5337,7 @@ func (r *ClickHouseReader) GetAttributesForMetricName(ctx context.Context, metri
}
const baseQueryTemplate = `
SELECT
SELECT
kv.1 AS key,
arrayMap(x -> trim(BOTH '"' FROM x), groupUniqArray(1000)(kv.2)) AS values,
length(groupUniqArray(10000)(kv.2)) AS valueCount
@@ -5444,7 +5436,7 @@ func (r *ClickHouseReader) ListSummaryMetrics(ctx context.Context, orgID valuer.
sampleTable, countExp := utils.WhichSampleTableToUse(req.Start, req.End)
metricsQuery := fmt.Sprintf(
`SELECT
`SELECT
t.metric_name AS metric_name,
ANY_VALUE(t.description) AS description,
ANY_VALUE(t.type) AS metric_type,
@@ -5509,11 +5501,11 @@ func (r *ClickHouseReader) ListSummaryMetrics(ctx context.Context, orgID valuer.
if whereClause != "" {
sb.WriteString(fmt.Sprintf(
`SELECT
`SELECT
s.samples,
s.metric_name
FROM (
SELECT
SELECT
dm.metric_name,
%s AS samples
FROM %s.%s AS dm
@@ -5543,11 +5535,11 @@ func (r *ClickHouseReader) ListSummaryMetrics(ctx context.Context, orgID valuer.
} else {
// If no filters, it is a simpler query.
sb.WriteString(fmt.Sprintf(
`SELECT
`SELECT
s.samples,
s.metric_name
FROM (
SELECT
SELECT
metric_name,
%s AS samples
FROM %s.%s
@@ -5647,16 +5639,16 @@ func (r *ClickHouseReader) GetMetricsTimeSeriesPercentage(ctx context.Context, r
// Construct the query without backticks
query := fmt.Sprintf(`
SELECT
SELECT
metric_name,
total_value,
(total_value * 100.0 / total_time_series) AS percentage
FROM (
SELECT
SELECT
metric_name,
uniq(fingerprint) AS total_value,
(SELECT uniq(fingerprint)
FROM %s.%s
(SELECT uniq(fingerprint)
FROM %s.%s
WHERE unix_milli BETWEEN ? AND ? AND __normalized = ?) AS total_time_series
FROM %s.%s
WHERE unix_milli BETWEEN ? AND ? AND NOT startsWith(metric_name, 'signoz') AND __normalized = ? %s
@@ -5727,7 +5719,7 @@ func (r *ClickHouseReader) GetMetricsSamplesPercentage(ctx context.Context, req
queryLimit := 50 + req.Limit
metricsQuery := fmt.Sprintf(
`SELECT
`SELECT
ts.metric_name AS metric_name,
uniq(ts.fingerprint) AS timeSeries
FROM %s.%s AS ts
@@ -5784,13 +5776,13 @@ func (r *ClickHouseReader) GetMetricsSamplesPercentage(ctx context.Context, req
FROM %s.%s
WHERE unix_milli BETWEEN ? AND ?
)
SELECT
SELECT
s.samples,
s.metric_name,
COALESCE((s.samples * 100.0 / t.total_samples), 0) AS percentage
FROM
FROM
(
SELECT
SELECT
dm.metric_name,
%s AS samples
FROM %s.%s AS dm`,
@@ -5811,7 +5803,7 @@ func (r *ClickHouseReader) GetMetricsSamplesPercentage(ctx context.Context, req
if whereClause != "" {
sb.WriteString(fmt.Sprintf(
` AND dm.fingerprint IN (
SELECT ts.fingerprint
SELECT ts.fingerprint
FROM %s.%s AS ts
WHERE ts.metric_name IN (%s)
AND unix_milli BETWEEN ? AND ?
@@ -5877,7 +5869,7 @@ func (r *ClickHouseReader) GetNameSimilarity(ctx context.Context, req *metrics_e
}
query := fmt.Sprintf(`
SELECT
SELECT
metric_name,
any(type) as type,
any(temporality) as temporality,
@@ -5931,7 +5923,7 @@ func (r *ClickHouseReader) GetAttributeSimilarity(ctx context.Context, req *metr
// Get target labels
extractedLabelsQuery := fmt.Sprintf(`
SELECT
SELECT
kv.1 AS label_key,
topK(10)(JSONExtractString(kv.2)) AS label_values
FROM %s.%s
@@ -5975,12 +5967,12 @@ func (r *ClickHouseReader) GetAttributeSimilarity(ctx context.Context, req *metr
priorityListString := strings.Join(priorityList, ", ")
candidateLabelsQuery := fmt.Sprintf(`
WITH
arrayDistinct([%s]) AS filter_keys,
WITH
arrayDistinct([%s]) AS filter_keys,
arrayDistinct([%s]) AS filter_values,
[%s] AS priority_pairs_input,
%d AS priority_multiplier
SELECT
SELECT
metric_name,
any(type) as type,
any(temporality) as temporality,
@@ -6081,17 +6073,17 @@ func (r *ClickHouseReader) GetAttributeSimilarity(ctx context.Context, req *metr
func (r *ClickHouseReader) GetMetricsAllResourceAttributes(ctx context.Context, start int64, end int64) (map[string]uint64, *model.ApiError) {
start, end, attTable, _ := utils.WhichAttributesTableToUse(start, end)
query := fmt.Sprintf(`SELECT
key,
query := fmt.Sprintf(`SELECT
key,
count(distinct value) AS distinct_value_count
FROM (
SELECT key, value
FROM %s.%s
ARRAY JOIN
ARRAY JOIN
arrayConcat(mapKeys(resource_attributes)) AS key,
arrayConcat(mapValues(resource_attributes)) AS value
WHERE unix_milli between ? and ?
)
)
GROUP BY key
ORDER BY distinct_value_count DESC;`, signozMetadataDbName, attTable)
valueCtx := context.WithValue(ctx, "clickhouse_max_threads", constants.MetricsExplorerClickhouseThreads)
@@ -6228,11 +6220,11 @@ func (r *ClickHouseReader) GetInspectMetricsFingerprints(ctx context.Context, at
start, end, tsTable, _ := utils.WhichTSTableToUse(req.Start, req.End)
query := fmt.Sprintf(`
SELECT
SELECT
arrayDistinct(groupArray(toString(fingerprint))) AS fingerprints
FROM
(
SELECT
SELECT
metric_name, labels, fingerprint,
%s
FROM %s.%s
@@ -6388,14 +6380,14 @@ func (r *ClickHouseReader) GetUpdatedMetricsMetadata(ctx context.Context, orgID
var stillMissing []string
if len(missingMetrics) > 0 {
metricList := "'" + strings.Join(missingMetrics, "', '") + "'"
query := fmt.Sprintf(`SELECT
query := fmt.Sprintf(`SELECT
metric_name,
argMax(type, created_at) AS type,
argMax(description, created_at) AS description,
argMax(temporality, created_at) AS temporality,
argMax(is_monotonic, created_at) AS is_monotonic,
argMax(unit, created_at) AS unit
FROM %s.%s
FROM %s.%s
WHERE metric_name IN (%s)
GROUP BY metric_name;`,
signozMetricDBName,
@@ -6443,7 +6435,7 @@ func (r *ClickHouseReader) GetUpdatedMetricsMetadata(ctx context.Context, orgID
if len(stillMissing) > 0 {
metricList := "'" + strings.Join(stillMissing, "', '") + "'"
query := fmt.Sprintf(`SELECT DISTINCT metric_name, type, description, temporality, is_monotonic, unit
FROM %s.%s
FROM %s.%s
WHERE metric_name IN (%s)`, signozMetricDBName, signozTSTableNameV4, metricList)
valueCtx := context.WithValue(ctx, "clickhouse_max_threads", constants.MetricsExplorerClickhouseThreads)
rows, err := r.db.Query(valueCtx, query)

View File

@@ -8,8 +8,8 @@ import (
var (
flamegraphSpanLevelLimit float64 = 50
flamegraphSpanLimitPerLevel int = 100
flamegraphSamplingBucketCount int = 50
flamegraphSpanLimitPerLevel int = 1000
flamegraphSamplingBucketCount int = 500
MaxLimitWithoutSampling uint = 120_000
)
@@ -103,7 +103,7 @@ func getLatencyAndTimestampBucketedSpans(spans []*model.FlamegraphSpan, selected
})
// pick the top 5 latency spans
for idx := range 5 {
for idx := range 100 {
sampledSpans = append(sampledSpans, spans[idx])
}