mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Profiling] Show host.name or host.ip when available (#140941)
This commit is contained in:
parent
2404c8bce4
commit
c522506519
7 changed files with 67 additions and 7 deletions
|
@ -13,6 +13,8 @@ export enum ProfilingESField {
|
|||
ProcessThreadName = 'process.thread.name',
|
||||
StacktraceCount = 'Stacktrace.count',
|
||||
HostID = 'host.id',
|
||||
HostName = 'host.name',
|
||||
HostIP = 'host.ip',
|
||||
OrchestratorResourceName = 'orchestrator.resource.name',
|
||||
ServiceName = 'service.name',
|
||||
StacktraceID = 'Stacktrace.id',
|
||||
|
|
|
@ -33,6 +33,7 @@ export interface TopNSamples {
|
|||
export interface TopNResponse extends TopNSamples {
|
||||
TotalCount: number;
|
||||
Metadata: Record<string, StackFrameMetadata[]>;
|
||||
Labels: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface TopNSamplesHistogramResponse {
|
||||
|
@ -65,6 +66,21 @@ export function getTopNAggregationRequest({
|
|||
execution_hint: highCardinality ? ('map' as const) : ('global_ordinals' as const),
|
||||
},
|
||||
aggs: {
|
||||
...(searchField === ProfilingESField.HostID
|
||||
? {
|
||||
sample: {
|
||||
top_metrics: {
|
||||
metrics: [
|
||||
{ field: ProfilingESField.HostName },
|
||||
{ field: ProfilingESField.HostIP },
|
||||
] as [{ field: ProfilingESField.HostName }, { field: ProfilingESField.HostIP }],
|
||||
sort: {
|
||||
'@timestamp': 'desc' as const,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
over_time: {
|
||||
date_histogram: {
|
||||
field: ProfilingESField.Timestamp,
|
||||
|
@ -188,6 +204,7 @@ export function createTopNSamples(
|
|||
|
||||
export interface TopNSubchart {
|
||||
Category: string;
|
||||
Label: string;
|
||||
Percentage: number;
|
||||
Series: CountPerTime[];
|
||||
Color: string;
|
||||
|
@ -199,10 +216,12 @@ export function groupSamplesByCategory({
|
|||
samples,
|
||||
totalCount,
|
||||
metadata,
|
||||
labels,
|
||||
}: {
|
||||
samples: TopNSample[];
|
||||
totalCount: number;
|
||||
metadata: Record<string, StackFrameMetadata[]>;
|
||||
labels: Record<string, string>;
|
||||
}): TopNSubchart[] {
|
||||
const seriesByCategory = new Map<string, CountPerTime[]>();
|
||||
|
||||
|
@ -213,7 +232,10 @@ export function groupSamplesByCategory({
|
|||
seriesByCategory.set(sample.Category, []);
|
||||
}
|
||||
const series = seriesByCategory.get(sample.Category)!;
|
||||
series.push({ Timestamp: sample.Timestamp, Count: sample.Count });
|
||||
series.push({
|
||||
Timestamp: sample.Timestamp,
|
||||
Count: sample.Count,
|
||||
});
|
||||
}
|
||||
|
||||
const subcharts: Array<Omit<TopNSubchart, 'Color' | 'Index'>> = [];
|
||||
|
@ -222,6 +244,7 @@ export function groupSamplesByCategory({
|
|||
const totalPerCategory = series.reduce((sumOf, { Count }) => sumOf + (Count ?? 0), 0);
|
||||
subcharts.push({
|
||||
Category: category,
|
||||
Label: labels[category] || category,
|
||||
Percentage: (totalPerCategory / totalCount) * 100,
|
||||
Series: series,
|
||||
Metadata: metadata[category] ?? [],
|
||||
|
|
|
@ -39,6 +39,7 @@ export const ChartGrid: React.FC<ChartGridProps> = ({ limit, charts, showFrames
|
|||
index={subchart.Index}
|
||||
color={subchart.Color}
|
||||
category={subchart.Category}
|
||||
label={subchart.Label}
|
||||
percentage={subchart.Percentage}
|
||||
metadata={subchart.Metadata}
|
||||
height={200}
|
||||
|
@ -48,6 +49,7 @@ export const ChartGrid: React.FC<ChartGridProps> = ({ limit, charts, showFrames
|
|||
setSelectedSubchart(subchart);
|
||||
}}
|
||||
showFrames={showFrames}
|
||||
padTitle
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
|
@ -64,6 +66,7 @@ export const ChartGrid: React.FC<ChartGridProps> = ({ limit, charts, showFrames
|
|||
index={selectedSubchart.Index}
|
||||
color={selectedSubchart.Color}
|
||||
category={selectedSubchart.Category}
|
||||
label={selectedSubchart.Label}
|
||||
percentage={selectedSubchart.Percentage}
|
||||
metadata={selectedSubchart.Metadata}
|
||||
height={200}
|
||||
|
@ -71,6 +74,7 @@ export const ChartGrid: React.FC<ChartGridProps> = ({ limit, charts, showFrames
|
|||
showAxes
|
||||
onShowMoreClick={null}
|
||||
showFrames={showFrames}
|
||||
padTitle
|
||||
/>
|
||||
</EuiFlyout>
|
||||
)}
|
||||
|
|
|
@ -62,7 +62,12 @@ export function StackTracesView() {
|
|||
}).then((response: TopNResponse) => {
|
||||
const totalCount = response.TotalCount;
|
||||
const samples = response.TopN;
|
||||
const charts = groupSamplesByCategory({ samples, totalCount, metadata: response.Metadata });
|
||||
const charts = groupSamplesByCategory({
|
||||
samples,
|
||||
totalCount,
|
||||
metadata: response.Metadata,
|
||||
labels: response.Labels,
|
||||
});
|
||||
return {
|
||||
charts,
|
||||
};
|
||||
|
|
|
@ -38,6 +38,7 @@ function SubchartTooltip({
|
|||
index={highlightedSubchart.Index}
|
||||
color={highlightedSubchart.Color}
|
||||
category={highlightedSubchart.Category}
|
||||
label={highlightedSubchart.Label}
|
||||
percentage={highlightedSubchart.Percentage}
|
||||
data={highlightedSubchart.Series}
|
||||
showFrames={showFrames}
|
||||
|
@ -47,6 +48,7 @@ function SubchartTooltip({
|
|||
width={width}
|
||||
showAxes={false}
|
||||
onShowMoreClick={null}
|
||||
padTitle={false}
|
||||
/>
|
||||
</EuiPanel>
|
||||
);
|
||||
|
@ -118,7 +120,7 @@ export const StackedBarChart: React.FC<StackedBarChartProps> = ({
|
|||
<HistogramBarSeries
|
||||
key={chart.Category}
|
||||
id={chart.Category}
|
||||
name={chart.Category}
|
||||
name={chart.Label}
|
||||
data={chart.Series}
|
||||
color={chart.Color}
|
||||
xAccessor={'Timestamp'}
|
||||
|
|
|
@ -43,6 +43,7 @@ export interface SubChartProps {
|
|||
height: number;
|
||||
width?: number;
|
||||
category: string;
|
||||
label: string;
|
||||
percentage: number;
|
||||
data: CountPerTime[];
|
||||
showAxes: boolean;
|
||||
|
@ -50,6 +51,7 @@ export interface SubChartProps {
|
|||
onShowMoreClick: (() => void) | null;
|
||||
style?: React.ComponentProps<typeof EuiFlexGroup>['style'];
|
||||
showFrames: boolean;
|
||||
padTitle: boolean;
|
||||
}
|
||||
|
||||
const NUM_DISPLAYED_FRAMES = 5;
|
||||
|
@ -58,6 +60,7 @@ export const SubChart: React.FC<SubChartProps> = ({
|
|||
index,
|
||||
color,
|
||||
category,
|
||||
label,
|
||||
percentage,
|
||||
height,
|
||||
data,
|
||||
|
@ -67,6 +70,7 @@ export const SubChart: React.FC<SubChartProps> = ({
|
|||
onShowMoreClick,
|
||||
style,
|
||||
showFrames,
|
||||
padTitle,
|
||||
}) => {
|
||||
const theme = useEuiTheme();
|
||||
|
||||
|
@ -157,7 +161,11 @@ export const SubChart: React.FC<SubChartProps> = ({
|
|||
<EuiFlexGroup direction="column" gutterSize="s" style={{ ...style, height: '100%' }}>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
style={{ padding: theme.euiTheme.size.l, paddingBottom: theme.euiTheme.size.s }}
|
||||
style={{
|
||||
...(padTitle
|
||||
? { padding: theme.euiTheme.size.l, paddingBottom: theme.euiTheme.size.s }
|
||||
: {}),
|
||||
}}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
direction="row"
|
||||
|
@ -175,11 +183,11 @@ export const SubChart: React.FC<SubChartProps> = ({
|
|||
<EuiFlexItem grow style={{ alignItems: 'flex-start' }}>
|
||||
{showFrames ? (
|
||||
<EuiLink onClick={() => onShowMoreClick?.()}>
|
||||
<EuiText size="s">{category}</EuiText>
|
||||
<EuiText size="s">{label}</EuiText>
|
||||
</EuiLink>
|
||||
) : (
|
||||
<EuiLink href={href}>
|
||||
<EuiText size="s">{category}</EuiText>
|
||||
<EuiText size="s">{label}</EuiText>
|
||||
</EuiLink>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -73,6 +73,7 @@ export async function topNElasticSearchQuery({
|
|||
TotalCount: 0,
|
||||
TopN: [],
|
||||
Metadata: {},
|
||||
Labels: {},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -84,6 +85,20 @@ export async function topNElasticSearchQuery({
|
|||
topN[i].Count = (topN[i].Count ?? 0) / eventsIndex.sampleRate;
|
||||
}
|
||||
|
||||
const groupByBuckets = aggregations.group_by.buckets ?? [];
|
||||
|
||||
const labels: Record<string, string> = {};
|
||||
|
||||
for (const bucket of groupByBuckets) {
|
||||
if (bucket.sample?.top[0]) {
|
||||
labels[String(bucket.key)] = String(
|
||||
bucket.sample.top[0].metrics[ProfilingESField.HostName] ||
|
||||
bucket.sample.top[0].metrics[ProfilingESField.HostIP] ||
|
||||
''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let totalSampledStackTraces = aggregations.total_count.value ?? 0;
|
||||
logger.info('total sampled stacktraces: ' + totalSampledStackTraces);
|
||||
totalSampledStackTraces = Math.floor(totalSampledStackTraces / eventsIndex.sampleRate);
|
||||
|
@ -93,11 +108,11 @@ export async function topNElasticSearchQuery({
|
|||
TotalCount: totalSampledStackTraces,
|
||||
TopN: topN,
|
||||
Metadata: {},
|
||||
Labels: labels,
|
||||
};
|
||||
}
|
||||
|
||||
const stackTraceEvents = new Map<StackTraceID, number>();
|
||||
const groupByBuckets = aggregations.group_by.buckets ?? [];
|
||||
let totalAggregatedStackTraces = 0;
|
||||
|
||||
for (let i = 0; i < groupByBuckets.length; i++) {
|
||||
|
@ -138,6 +153,7 @@ export async function topNElasticSearchQuery({
|
|||
TotalCount: totalSampledStackTraces,
|
||||
TopN: topN,
|
||||
Metadata: metadata,
|
||||
Labels: labels,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue