fix(metrics): fix metrics
This commit is contained in:
@ -43,15 +43,32 @@ export class OpsViewNetwork extends DeesElement {
|
||||
private networkRequests: INetworkRequest[] = [];
|
||||
|
||||
@state()
|
||||
private trafficData: Array<{ x: number; y: number }> = [];
|
||||
private trafficData: Array<{ x: string | number; y: number }> = [];
|
||||
|
||||
@state()
|
||||
private isLoading = false;
|
||||
|
||||
private lastTrafficUpdateTime = 0;
|
||||
private trafficUpdateInterval = 1000; // Update every 1 second
|
||||
private requestCountHistory = new Map<number, number>(); // Track requests per time bucket
|
||||
private trafficUpdateTimer: any = null;
|
||||
|
||||
// Track bytes for calculating true per-second throughput
|
||||
private lastBytesIn = 0;
|
||||
private lastBytesOut = 0;
|
||||
private lastBytesSampleTime = 0;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.subscribeToStateParts();
|
||||
this.initializeTrafficData();
|
||||
this.updateNetworkData();
|
||||
this.startTrafficUpdateTimer();
|
||||
}
|
||||
|
||||
async disconnectedCallback() {
|
||||
await super.disconnectedCallback();
|
||||
this.stopTrafficUpdateTimer();
|
||||
}
|
||||
|
||||
private subscribeToStateParts() {
|
||||
@ -65,6 +82,31 @@ export class OpsViewNetwork extends DeesElement {
|
||||
this.updateNetworkData();
|
||||
});
|
||||
}
|
||||
|
||||
private initializeTrafficData() {
|
||||
const now = Date.now();
|
||||
const timeRanges = {
|
||||
'1m': 60 * 1000,
|
||||
'5m': 5 * 60 * 1000,
|
||||
'15m': 15 * 60 * 1000,
|
||||
'1h': 60 * 60 * 1000,
|
||||
'24h': 24 * 60 * 60 * 1000,
|
||||
};
|
||||
|
||||
const range = timeRanges[this.selectedTimeRange];
|
||||
const bucketSize = range / 60;
|
||||
|
||||
// Initialize with empty data points
|
||||
this.trafficData = Array.from({ length: 60 }, (_, i) => {
|
||||
const time = now - ((59 - i) * bucketSize);
|
||||
return {
|
||||
x: new Date(time).toISOString(),
|
||||
y: 0,
|
||||
};
|
||||
});
|
||||
|
||||
this.lastTrafficUpdateTime = now;
|
||||
}
|
||||
|
||||
public static styles = [
|
||||
cssManager.defaultStyles,
|
||||
@ -181,7 +223,7 @@ export class OpsViewNetwork extends DeesElement {
|
||||
<dees-button-group>
|
||||
${(['1m', '5m', '15m', '1h', '24h'] as const).map(range => html`
|
||||
<dees-button
|
||||
@click=${() => this.selectedTimeRange = range}
|
||||
@click=${() => this.handleTimeRangeChange(range)}
|
||||
.type=${this.selectedTimeRange === range ? 'highlighted' : 'normal'}
|
||||
>
|
||||
${range}
|
||||
@ -223,10 +265,11 @@ export class OpsViewNetwork extends DeesElement {
|
||||
.label=${'Network Traffic'}
|
||||
.series=${[
|
||||
{
|
||||
name: 'Requests/min',
|
||||
name: 'Throughput (Mbps)',
|
||||
data: this.trafficData,
|
||||
}
|
||||
]}
|
||||
.yAxisFormatter=${(val: number) => `${val} Mbps`}
|
||||
></dees-chart-area>
|
||||
|
||||
<!-- Top IPs Section -->
|
||||
@ -394,10 +437,13 @@ export class OpsViewNetwork extends DeesElement {
|
||||
const throughput = this.calculateThroughput();
|
||||
const activeConnections = this.statsState.serverStats?.activeConnections || 0;
|
||||
|
||||
// Generate trend data for requests per second
|
||||
const trendData = Array.from({ length: 20 }, (_, i) =>
|
||||
Math.max(0, reqPerSec + (Math.random() - 0.5) * 10)
|
||||
);
|
||||
// Use actual traffic data for trends (last 20 points)
|
||||
const trendData = this.trafficData.slice(-20).map(point => point.y);
|
||||
|
||||
// If we don't have enough data, pad with the current value
|
||||
while (trendData.length < 20) {
|
||||
trendData.unshift(reqPerSec);
|
||||
}
|
||||
|
||||
const tiles: IStatsTile[] = [
|
||||
{
|
||||
@ -532,25 +578,107 @@ export class OpsViewNetwork extends DeesElement {
|
||||
const range = timeRanges[this.selectedTimeRange];
|
||||
const bucketSize = range / 60; // 60 data points
|
||||
|
||||
// Create buckets for traffic data
|
||||
const buckets = new Map<number, number>();
|
||||
// Check if enough time has passed to add a new data point
|
||||
const timeSinceLastUpdate = now - this.lastTrafficUpdateTime;
|
||||
const shouldAddNewPoint = timeSinceLastUpdate >= this.trafficUpdateInterval;
|
||||
|
||||
// Count requests per bucket
|
||||
this.networkRequests.forEach(req => {
|
||||
if (req.timestamp >= now - range) {
|
||||
const bucketIndex = Math.floor((now - req.timestamp) / bucketSize);
|
||||
const bucketTime = now - (bucketIndex * bucketSize);
|
||||
buckets.set(bucketTime, (buckets.get(bucketTime) || 0) + 1);
|
||||
}
|
||||
console.log('UpdateTrafficData called:', {
|
||||
networkRequestsCount: this.networkRequests.length,
|
||||
timeSinceLastUpdate,
|
||||
shouldAddNewPoint,
|
||||
currentDataPoints: this.trafficData.length
|
||||
});
|
||||
|
||||
// Convert to chart data
|
||||
this.trafficData = Array.from({ length: 60 }, (_, i) => {
|
||||
const time = now - (i * bucketSize);
|
||||
return {
|
||||
x: time,
|
||||
y: buckets.get(time) || 0,
|
||||
if (!shouldAddNewPoint && this.trafficData.length > 0) {
|
||||
// Not enough time has passed, don't update
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate actual per-second throughput by tracking deltas
|
||||
let throughputMbps = 0;
|
||||
|
||||
// Get total bytes from all active connections
|
||||
let currentBytesIn = 0;
|
||||
let currentBytesOut = 0;
|
||||
|
||||
this.networkRequests.forEach(req => {
|
||||
currentBytesIn += req.bytesIn;
|
||||
currentBytesOut += req.bytesOut;
|
||||
});
|
||||
|
||||
// If we have a previous sample, calculate the delta
|
||||
if (this.lastBytesSampleTime > 0) {
|
||||
const timeDelta = (now - this.lastBytesSampleTime) / 1000; // Convert to seconds
|
||||
const bytesInDelta = Math.max(0, currentBytesIn - this.lastBytesIn);
|
||||
const bytesOutDelta = Math.max(0, currentBytesOut - this.lastBytesOut);
|
||||
|
||||
// Calculate bytes per second for this interval
|
||||
const bytesPerSecond = (bytesInDelta + bytesOutDelta) / timeDelta;
|
||||
|
||||
// Convert to Mbps (1 Mbps = 125000 bytes/second)
|
||||
throughputMbps = bytesPerSecond / 125000;
|
||||
|
||||
console.log('Throughput calculation:', {
|
||||
timeDelta,
|
||||
bytesInDelta,
|
||||
bytesOutDelta,
|
||||
bytesPerSecond,
|
||||
throughputMbps
|
||||
});
|
||||
}
|
||||
|
||||
// Update last sample values
|
||||
this.lastBytesIn = currentBytesIn;
|
||||
this.lastBytesOut = currentBytesOut;
|
||||
this.lastBytesSampleTime = now;
|
||||
|
||||
if (this.trafficData.length === 0) {
|
||||
// Initialize if empty
|
||||
this.initializeTrafficData();
|
||||
} else {
|
||||
// Add new data point and remove oldest if we have 60 points
|
||||
const newDataPoint = {
|
||||
x: new Date(now).toISOString(),
|
||||
y: Math.round(throughputMbps * 10) / 10 // Round to 1 decimal place
|
||||
};
|
||||
}).reverse();
|
||||
|
||||
// Create new array with existing data plus new point
|
||||
const newTrafficData = [...this.trafficData, newDataPoint];
|
||||
|
||||
// Keep only the last 60 points
|
||||
if (newTrafficData.length > 60) {
|
||||
newTrafficData.shift(); // Remove oldest point
|
||||
}
|
||||
|
||||
this.trafficData = newTrafficData;
|
||||
this.lastTrafficUpdateTime = now;
|
||||
|
||||
console.log('Added new traffic data point:', {
|
||||
timestamp: newDataPoint.x,
|
||||
throughputMbps: newDataPoint.y,
|
||||
totalPoints: this.trafficData.length
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private startTrafficUpdateTimer() {
|
||||
this.stopTrafficUpdateTimer(); // Clear any existing timer
|
||||
this.trafficUpdateTimer = setInterval(() => {
|
||||
this.updateTrafficData();
|
||||
}, 1000); // Check every second, but only update when interval has passed
|
||||
}
|
||||
|
||||
private stopTrafficUpdateTimer() {
|
||||
if (this.trafficUpdateTimer) {
|
||||
clearInterval(this.trafficUpdateTimer);
|
||||
this.trafficUpdateTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
private handleTimeRangeChange(range: '1m' | '5m' | '15m' | '1h' | '24h') {
|
||||
this.selectedTimeRange = range;
|
||||
// Reinitialize traffic data for new time range
|
||||
this.initializeTrafficData();
|
||||
this.updateNetworkData();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user