mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Remove non-essential ES-client stats from /api/stats (#145120)
[PR #141434](https://github.com/elastic/kibana/pull/141434) exposes a bunch of metrics related to the Elasticsearch Client in the `/api/stats` endpoint. While all these stats are interesting, some of them might be less relevant than others right now. Let's start by exposing only those stats that are more critical from a monitoring standpoint. <img width="440" alt="image" src="https://user-images.githubusercontent.com/25349407/201688243-4e33cd88-5fa2-48b7-b8ca-2fd175271adc.png">
This commit is contained in:
parent
e7730f0ab1
commit
46522d76da
6 changed files with 2 additions and 169 deletions
|
@ -62,17 +62,9 @@ const mockedResponse: StatusResponse = {
|
|||
},
|
||||
},
|
||||
elasticsearch_client: {
|
||||
protocol: 'https',
|
||||
connectedNodes: 3,
|
||||
nodesWithActiveSockets: 3,
|
||||
nodesWithIdleSockets: 1,
|
||||
totalActiveSockets: 25,
|
||||
totalIdleSockets: 2,
|
||||
totalQueuedRequests: 0,
|
||||
mostActiveNodeSockets: 15,
|
||||
averageActiveSocketsPerNode: 8,
|
||||
mostIdleNodeSockets: 2,
|
||||
averageIdleSocketsPerNode: 0.5,
|
||||
},
|
||||
process: {
|
||||
pid: 1,
|
||||
|
|
|
@ -32,7 +32,7 @@ describe('getAgentsSocketsStats()', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const agent2 = getHttpAgentMock({
|
||||
const agent2 = getHttpsAgentMock({
|
||||
sockets: {
|
||||
node1: [mockSocket, mockSocket, mockSocket],
|
||||
node4: [mockSocket],
|
||||
|
@ -47,101 +47,9 @@ describe('getAgentsSocketsStats()', () => {
|
|||
|
||||
const stats = getAgentsSocketsStats(new Set<Agent>([agent1, agent2]));
|
||||
expect(stats).toEqual({
|
||||
averageActiveSocketsPerNode: 2.6666666666666665,
|
||||
averageIdleSocketsPerNode: 4.5,
|
||||
connectedNodes: 4,
|
||||
mostActiveNodeSockets: 6,
|
||||
mostIdleNodeSockets: 8,
|
||||
nodesWithActiveSockets: 3,
|
||||
nodesWithIdleSockets: 2,
|
||||
protocol: 'http',
|
||||
totalActiveSockets: 8,
|
||||
totalIdleSockets: 9,
|
||||
totalQueuedRequests: 6,
|
||||
});
|
||||
});
|
||||
|
||||
it('takes into account Agent types to determine the `protocol`', () => {
|
||||
const httpAgent = getHttpAgentMock({
|
||||
sockets: { node1: [mockSocket] },
|
||||
freeSockets: {},
|
||||
requests: {},
|
||||
});
|
||||
|
||||
const httpsAgent = getHttpsAgentMock({
|
||||
sockets: { node1: [mockSocket] },
|
||||
freeSockets: {},
|
||||
requests: {},
|
||||
});
|
||||
|
||||
const noAgents = new Set<Agent>();
|
||||
const httpAgents = new Set<Agent>([httpAgent, httpAgent]);
|
||||
const httpsAgents = new Set<Agent>([httpsAgent, httpsAgent]);
|
||||
const mixedAgents = new Set<Agent>([httpAgent, httpsAgent]);
|
||||
|
||||
expect(getAgentsSocketsStats(noAgents).protocol).toEqual('none');
|
||||
expect(getAgentsSocketsStats(httpAgents).protocol).toEqual('http');
|
||||
expect(getAgentsSocketsStats(httpsAgents).protocol).toEqual('https');
|
||||
expect(getAgentsSocketsStats(mixedAgents).protocol).toEqual('mixed');
|
||||
});
|
||||
|
||||
it('does not take into account those Agents that have not had any connection to any node', () => {
|
||||
const pristineAgentProps = {
|
||||
sockets: {},
|
||||
freeSockets: {},
|
||||
requests: {},
|
||||
};
|
||||
const agent1 = getHttpAgentMock(pristineAgentProps);
|
||||
const agent2 = getHttpAgentMock(pristineAgentProps);
|
||||
const agent3 = getHttpAgentMock(pristineAgentProps);
|
||||
|
||||
const stats = getAgentsSocketsStats(new Set<Agent>([agent1, agent2, agent3]));
|
||||
|
||||
expect(stats).toEqual({
|
||||
averageActiveSocketsPerNode: 0,
|
||||
averageIdleSocketsPerNode: 0,
|
||||
connectedNodes: 0,
|
||||
mostActiveNodeSockets: 0,
|
||||
mostIdleNodeSockets: 0,
|
||||
nodesWithActiveSockets: 0,
|
||||
nodesWithIdleSockets: 0,
|
||||
protocol: 'none',
|
||||
totalActiveSockets: 0,
|
||||
totalIdleSockets: 0,
|
||||
totalQueuedRequests: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it('takes into account those Agents that have hold mappings to one or more nodes, but that do not currently have any pending requests, active connections or idle connections', () => {
|
||||
const emptyAgentProps = {
|
||||
sockets: {
|
||||
node1: [],
|
||||
},
|
||||
freeSockets: {
|
||||
node2: [],
|
||||
},
|
||||
requests: {
|
||||
node3: [],
|
||||
},
|
||||
};
|
||||
|
||||
const agent1 = getHttpAgentMock(emptyAgentProps);
|
||||
const agent2 = getHttpAgentMock(emptyAgentProps);
|
||||
|
||||
const stats = getAgentsSocketsStats(new Set<Agent>([agent1, agent2]));
|
||||
|
||||
expect(stats).toEqual({
|
||||
averageActiveSocketsPerNode: 0,
|
||||
averageIdleSocketsPerNode: 0,
|
||||
connectedNodes: 3,
|
||||
mostActiveNodeSockets: 0,
|
||||
mostIdleNodeSockets: 0,
|
||||
nodesWithActiveSockets: 0,
|
||||
nodesWithIdleSockets: 0,
|
||||
protocol: 'http',
|
||||
totalActiveSockets: 0,
|
||||
totalIdleSockets: 0,
|
||||
totalQueuedRequests: 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,23 +7,13 @@
|
|||
*/
|
||||
|
||||
import { NetworkAgent } from '@kbn/core-elasticsearch-client-server-internal';
|
||||
import { Agent as HttpsAgent } from 'https';
|
||||
import { mean } from 'lodash';
|
||||
import type {
|
||||
ElasticsearchClientProtocol,
|
||||
ElasticsearchClientsMetrics,
|
||||
} from '@kbn/core-metrics-server';
|
||||
import type { ElasticsearchClientsMetrics } from '@kbn/core-metrics-server';
|
||||
|
||||
export const getAgentsSocketsStats = (agents: Set<NetworkAgent>): ElasticsearchClientsMetrics => {
|
||||
const nodes = new Set<string>();
|
||||
let totalActiveSockets = 0;
|
||||
let totalIdleSockets = 0;
|
||||
let totalQueuedRequests = 0;
|
||||
let http: boolean = false;
|
||||
let https: boolean = false;
|
||||
|
||||
const nodesWithActiveSockets: Record<string, number> = {};
|
||||
const nodesWithIdleSockets: Record<string, number> = {};
|
||||
|
||||
agents.forEach((agent) => {
|
||||
const agentRequests = Object.entries(agent.requests) ?? [];
|
||||
|
@ -31,9 +21,6 @@ export const getAgentsSocketsStats = (agents: Set<NetworkAgent>): ElasticsearchC
|
|||
const agentFreeSockets = Object.entries(agent.freeSockets) ?? [];
|
||||
|
||||
if (agentRequests.length || agentSockets.length || agentFreeSockets.length) {
|
||||
if (agent instanceof HttpsAgent) https = true;
|
||||
else http = true;
|
||||
|
||||
agentRequests.forEach(([node, queue]) => {
|
||||
nodes.add(node);
|
||||
totalQueuedRequests += queue?.length ?? 0;
|
||||
|
@ -43,39 +30,19 @@ export const getAgentsSocketsStats = (agents: Set<NetworkAgent>): ElasticsearchC
|
|||
nodes.add(node);
|
||||
const activeSockets = sockets?.length ?? 0;
|
||||
totalActiveSockets += activeSockets;
|
||||
nodesWithActiveSockets[node] = (nodesWithActiveSockets[node] ?? 0) + activeSockets;
|
||||
});
|
||||
|
||||
agentFreeSockets.forEach(([node, freeSockets]) => {
|
||||
nodes.add(node);
|
||||
const idleSockets = freeSockets?.length ?? 0;
|
||||
totalIdleSockets += idleSockets;
|
||||
nodesWithIdleSockets[node] = (nodesWithIdleSockets[node] ?? 0) + idleSockets;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const activeSocketCounters = Object.values(nodesWithActiveSockets);
|
||||
const idleSocketCounters = Object.values(nodesWithIdleSockets);
|
||||
const protocol: ElasticsearchClientProtocol = http
|
||||
? https
|
||||
? 'mixed'
|
||||
: 'http'
|
||||
: https
|
||||
? 'https'
|
||||
: 'none';
|
||||
|
||||
return {
|
||||
protocol,
|
||||
connectedNodes: nodes.size,
|
||||
nodesWithActiveSockets: activeSocketCounters.filter(Boolean).length,
|
||||
nodesWithIdleSockets: idleSocketCounters.filter(Boolean).length,
|
||||
totalActiveSockets,
|
||||
totalIdleSockets,
|
||||
totalQueuedRequests,
|
||||
mostActiveNodeSockets: activeSocketCounters.length ? Math.max(...activeSocketCounters) : 0,
|
||||
averageActiveSocketsPerNode: activeSocketCounters.length ? mean(activeSocketCounters) : 0,
|
||||
mostIdleNodeSockets: idleSocketCounters.length ? Math.max(...idleSocketCounters) : 0,
|
||||
averageIdleSocketsPerNode: idleSocketCounters.length ? mean(idleSocketCounters) : 0,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -24,17 +24,9 @@ import type {
|
|||
} from '@kbn/core-metrics-server';
|
||||
|
||||
export const sampleEsClientMetrics: ElasticsearchClientsMetrics = {
|
||||
protocol: 'https',
|
||||
connectedNodes: 3,
|
||||
nodesWithActiveSockets: 3,
|
||||
nodesWithIdleSockets: 1,
|
||||
totalActiveSockets: 25,
|
||||
totalIdleSockets: 2,
|
||||
totalQueuedRequests: 0,
|
||||
mostActiveNodeSockets: 15,
|
||||
averageActiveSocketsPerNode: 8,
|
||||
mostIdleNodeSockets: 2,
|
||||
averageIdleSocketsPerNode: 0.5,
|
||||
};
|
||||
|
||||
const createInternalSetupContractMock = () => {
|
||||
|
|
|
@ -52,30 +52,12 @@ export type ElasticsearchClientProtocol = 'none' | 'http' | 'https' | 'mixed';
|
|||
* @public
|
||||
*/
|
||||
export interface ElasticsearchClientsMetrics {
|
||||
/** The protocol (or protocols) that these Agents are using */
|
||||
protocol: ElasticsearchClientProtocol;
|
||||
/** Number of ES nodes that ES-js client is connecting to */
|
||||
connectedNodes: number;
|
||||
/** Number of nodes with active connections */
|
||||
nodesWithActiveSockets: number;
|
||||
/** Number of nodes with available connections (alive but idle).
|
||||
* Note that a node can have both active and idle connections at the same time
|
||||
*/
|
||||
nodesWithIdleSockets: number;
|
||||
/** Total number of active sockets (all nodes, all connections) */
|
||||
totalActiveSockets: number;
|
||||
/** Total number of available sockets (alive but idle, all nodes, all connections) */
|
||||
totalIdleSockets: number;
|
||||
/** Total number of queued requests (all nodes, all connections) */
|
||||
totalQueuedRequests: number;
|
||||
/** Number of active connections of the node with most active connections */
|
||||
mostActiveNodeSockets: number;
|
||||
/** Average of active sockets per node (all connections) */
|
||||
averageActiveSocketsPerNode: number;
|
||||
/** Number of idle connections of the node with most idle connections */
|
||||
mostIdleNodeSockets: number;
|
||||
/** Average of available (idle) sockets per node (all connections) */
|
||||
averageIdleSocketsPerNode: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,14 +4,6 @@ exports[`telemetry_ops_stats should return something when there is a metric 1`]
|
|||
Object {
|
||||
"concurrent_connections": 1,
|
||||
"elasticsearch_client": Object {
|
||||
"averageActiveSocketsPerNode": 8,
|
||||
"averageIdleSocketsPerNode": 0.5,
|
||||
"connectedNodes": 3,
|
||||
"mostActiveNodeSockets": 15,
|
||||
"mostIdleNodeSockets": 2,
|
||||
"nodesWithActiveSockets": 3,
|
||||
"nodesWithIdleSockets": 1,
|
||||
"protocol": "https",
|
||||
"totalActiveSockets": 25,
|
||||
"totalIdleSockets": 2,
|
||||
"totalQueuedRequests": 0,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue