feat(network): add bandwidth-ranked IP and domain activity metrics to network monitoring
This commit is contained in:
@@ -52,7 +52,9 @@ export interface INetworkState {
|
||||
throughputRate: { bytesInPerSecond: number; bytesOutPerSecond: number };
|
||||
totalBytes: { in: number; out: number };
|
||||
topIPs: Array<{ ip: string; count: number }>;
|
||||
topIPsByBandwidth: Array<{ ip: string; count: number; bwIn: number; bwOut: number }>;
|
||||
throughputByIP: Array<{ ip: string; in: number; out: number }>;
|
||||
domainActivity: interfaces.data.IDomainActivity[];
|
||||
throughputHistory: Array<{ timestamp: number; in: number; out: number }>;
|
||||
requestsPerSecond: number;
|
||||
requestsTotal: number;
|
||||
@@ -160,7 +162,9 @@ export const networkStatePart = await appState.getStatePart<INetworkState>(
|
||||
throughputRate: { bytesInPerSecond: 0, bytesOutPerSecond: 0 },
|
||||
totalBytes: { in: 0, out: 0 },
|
||||
topIPs: [],
|
||||
topIPsByBandwidth: [],
|
||||
throughputByIP: [],
|
||||
domainActivity: [],
|
||||
throughputHistory: [],
|
||||
requestsPerSecond: 0,
|
||||
requestsTotal: 0,
|
||||
@@ -552,7 +556,9 @@ export const fetchNetworkStatsAction = networkStatePart.createAction(async (stat
|
||||
? { in: networkStatsResponse.totalDataTransferred.bytesIn, out: networkStatsResponse.totalDataTransferred.bytesOut }
|
||||
: { in: 0, out: 0 },
|
||||
topIPs: networkStatsResponse.topIPs || [],
|
||||
topIPsByBandwidth: networkStatsResponse.topIPsByBandwidth || [],
|
||||
throughputByIP: networkStatsResponse.throughputByIP || [],
|
||||
domainActivity: networkStatsResponse.domainActivity || [],
|
||||
throughputHistory: networkStatsResponse.throughputHistory || [],
|
||||
requestsPerSecond: networkStatsResponse.requestsPerSecond || 0,
|
||||
requestsTotal: networkStatsResponse.requestsTotal || 0,
|
||||
@@ -2649,67 +2655,52 @@ async function dispatchCombinedRefreshActionInner() {
|
||||
if (combinedResponse.metrics.network && currentView === 'network') {
|
||||
const network = combinedResponse.metrics.network;
|
||||
const connectionsByIP: { [ip: string]: number } = {};
|
||||
|
||||
// Convert connection details to IP counts
|
||||
|
||||
// Build connectionsByIP from connectionDetails (now populated with real per-IP data)
|
||||
network.connectionDetails.forEach(conn => {
|
||||
connectionsByIP[conn.remoteAddress] = (connectionsByIP[conn.remoteAddress] || 0) + 1;
|
||||
});
|
||||
|
||||
// Fetch detailed connections for the network view
|
||||
try {
|
||||
const connectionsRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
||||
interfaces.requests.IReq_GetActiveConnections
|
||||
>('/typedrequest', 'getActiveConnections');
|
||||
|
||||
const connectionsResponse = await connectionsRequest.fire({
|
||||
identity: context.identity,
|
||||
});
|
||||
// Build connections from connectionDetails (real per-IP aggregates)
|
||||
const connections: interfaces.data.IConnectionInfo[] = network.connectionDetails.map((conn, i) => ({
|
||||
id: `ip-${conn.remoteAddress}`,
|
||||
remoteAddress: conn.remoteAddress,
|
||||
localAddress: 'server',
|
||||
startTime: conn.startTime,
|
||||
protocol: conn.protocol as any,
|
||||
state: conn.state as any,
|
||||
bytesReceived: conn.bytesIn,
|
||||
bytesSent: conn.bytesOut,
|
||||
}));
|
||||
|
||||
networkStatePart.setState({
|
||||
...networkStatePart.getState()!,
|
||||
connections: connectionsResponse.connections,
|
||||
connectionsByIP,
|
||||
throughputRate: {
|
||||
bytesInPerSecond: network.totalBandwidth.in,
|
||||
bytesOutPerSecond: network.totalBandwidth.out
|
||||
},
|
||||
totalBytes: network.totalBytes || { in: 0, out: 0 },
|
||||
topIPs: network.topEndpoints.map(e => ({ ip: e.endpoint, count: e.requests })),
|
||||
throughputByIP: network.topEndpoints.map(e => ({ ip: e.endpoint, in: e.bandwidth?.in || 0, out: e.bandwidth?.out || 0 })),
|
||||
throughputHistory: network.throughputHistory || [],
|
||||
requestsPerSecond: network.requestsPerSecond || 0,
|
||||
requestsTotal: network.requestsTotal || 0,
|
||||
backends: network.backends || [],
|
||||
frontendProtocols: network.frontendProtocols || null,
|
||||
backendProtocols: network.backendProtocols || null,
|
||||
lastUpdated: Date.now(),
|
||||
isLoading: false,
|
||||
error: null,
|
||||
});
|
||||
} catch (error: unknown) {
|
||||
console.error('Failed to fetch connections:', error);
|
||||
networkStatePart.setState({
|
||||
...networkStatePart.getState()!,
|
||||
connections: [],
|
||||
connectionsByIP,
|
||||
throughputRate: {
|
||||
bytesInPerSecond: network.totalBandwidth.in,
|
||||
bytesOutPerSecond: network.totalBandwidth.out
|
||||
},
|
||||
totalBytes: network.totalBytes || { in: 0, out: 0 },
|
||||
topIPs: network.topEndpoints.map(e => ({ ip: e.endpoint, count: e.requests })),
|
||||
throughputByIP: network.topEndpoints.map(e => ({ ip: e.endpoint, in: e.bandwidth?.in || 0, out: e.bandwidth?.out || 0 })),
|
||||
throughputHistory: network.throughputHistory || [],
|
||||
requestsPerSecond: network.requestsPerSecond || 0,
|
||||
requestsTotal: network.requestsTotal || 0,
|
||||
backends: network.backends || [],
|
||||
frontendProtocols: network.frontendProtocols || null,
|
||||
backendProtocols: network.backendProtocols || null,
|
||||
lastUpdated: Date.now(),
|
||||
isLoading: false,
|
||||
error: null,
|
||||
});
|
||||
}
|
||||
networkStatePart.setState({
|
||||
...networkStatePart.getState()!,
|
||||
connections,
|
||||
connectionsByIP,
|
||||
throughputRate: {
|
||||
bytesInPerSecond: network.totalBandwidth.in,
|
||||
bytesOutPerSecond: network.totalBandwidth.out,
|
||||
},
|
||||
totalBytes: network.totalBytes || { in: 0, out: 0 },
|
||||
topIPs: network.topEndpoints.map(e => ({ ip: e.endpoint, count: e.connections })),
|
||||
topIPsByBandwidth: (network.topEndpointsByBandwidth || []).map(e => ({
|
||||
ip: e.endpoint,
|
||||
count: e.connections,
|
||||
bwIn: e.bandwidth?.in || 0,
|
||||
bwOut: e.bandwidth?.out || 0,
|
||||
})),
|
||||
throughputByIP: network.topEndpoints.map(e => ({ ip: e.endpoint, in: e.bandwidth?.in || 0, out: e.bandwidth?.out || 0 })),
|
||||
domainActivity: network.domainActivity || [],
|
||||
throughputHistory: network.throughputHistory || [],
|
||||
requestsPerSecond: network.requestsPerSecond || 0,
|
||||
requestsTotal: network.requestsTotal || 0,
|
||||
backends: network.backends || [],
|
||||
frontendProtocols: network.frontendProtocols || null,
|
||||
backendProtocols: network.backendProtocols || null,
|
||||
lastUpdated: Date.now(),
|
||||
isLoading: false,
|
||||
error: null,
|
||||
});
|
||||
}
|
||||
|
||||
// Refresh certificate data if on Domains > Certificates subview
|
||||
|
||||
Reference in New Issue
Block a user