feat(remoteingress): add remote ingress performance configuration and expose tunnel transport metrics
This commit is contained in:
@@ -125,6 +125,18 @@ export class OpsViewRemoteIngress extends DeesElement {
|
||||
color: ${cssManager.bdTheme('#047857', '#34d399')};
|
||||
border: 1px dashed ${cssManager.bdTheme('#6ee7b7', '#065f46')};
|
||||
}
|
||||
|
||||
.metricStack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
font-size: 12px;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.metricMuted {
|
||||
color: var(--text-muted, #6b7280);
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
@@ -226,9 +238,13 @@ export class OpsViewRemoteIngress extends DeesElement {
|
||||
.displayFunction=${(edge: interfaces.data.IRemoteIngress) => ({
|
||||
name: edge.name,
|
||||
status: this.getEdgeStatusHtml(edge),
|
||||
transport: this.getTransportHtml(edge.id),
|
||||
publicIp: this.getEdgePublicIp(edge.id),
|
||||
ports: this.getPortsHtml(edge),
|
||||
tunnels: this.getEdgeTunnelCount(edge.id),
|
||||
window: this.getWindowHtml(edge.id),
|
||||
queues: this.getQueuesHtml(edge.id),
|
||||
traffic: this.getTrafficHtml(edge.id),
|
||||
lastHeartbeat: this.getLastHeartbeat(edge.id),
|
||||
})}
|
||||
.dataActions=${[
|
||||
@@ -459,6 +475,46 @@ export class OpsViewRemoteIngress extends DeesElement {
|
||||
return status?.activeTunnels || 0;
|
||||
}
|
||||
|
||||
private getTransportHtml(edgeId: string): TemplateResult | string {
|
||||
const status = this.getEdgeStatus(edgeId);
|
||||
if (!status?.connected) return '-';
|
||||
const mode = status.transportMode || 'unknown';
|
||||
const label = mode === 'quic' ? 'QUIC' : mode === 'tcpTls' ? 'TCP/TLS' : mode;
|
||||
return html`<div class="metricStack"><strong>${label}</strong><span class="metricMuted">${status.fallbackUsed ? 'fallback' : status.performance?.profile || 'default'}</span></div>`;
|
||||
}
|
||||
|
||||
private getWindowHtml(edgeId: string): TemplateResult | string {
|
||||
const status = this.getEdgeStatus(edgeId);
|
||||
if (!status?.connected || !status.flowControl) return '-';
|
||||
if (!status.flowControl.applies) {
|
||||
return html`<div class="metricStack"><span>native QUIC</span><span class="metricMuted">max ${status.performance?.maxStreamsPerEdge || '-'} streams</span></div>`;
|
||||
}
|
||||
return html`
|
||||
<div class="metricStack">
|
||||
<span>${this.formatBytes(status.flowControl.currentWindowBytes)} window</span>
|
||||
<span class="metricMuted">${this.formatBytes(status.flowControl.estimatedInFlightBytes)} est. in-flight</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private getQueuesHtml(edgeId: string): TemplateResult | string {
|
||||
const status = this.getEdgeStatus(edgeId);
|
||||
if (!status?.connected || !status.queues) return '-';
|
||||
return html`<div class="metricStack"><span>C ${status.queues.ctrlQueueDepth} / D ${status.queues.dataQueueDepth}</span><span class="metricMuted">S ${status.queues.sustainedQueueDepth}</span></div>`;
|
||||
}
|
||||
|
||||
private getTrafficHtml(edgeId: string): TemplateResult | string {
|
||||
const status = this.getEdgeStatus(edgeId);
|
||||
if (!status?.connected || !status.traffic) return '-';
|
||||
const drops = (status.traffic.rejectedStreams || 0) + (status.udp?.droppedDatagrams || 0);
|
||||
return html`
|
||||
<div class="metricStack">
|
||||
<span>${this.formatBytes(status.traffic.bytesIn)} in / ${this.formatBytes(status.traffic.bytesOut)} out</span>
|
||||
<span class="metricMuted">${drops} rejected/dropped</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private getLastHeartbeat(edgeId: string): string {
|
||||
const status = this.getEdgeStatus(edgeId);
|
||||
if (!status?.lastHeartbeat) return '-';
|
||||
@@ -467,4 +523,16 @@ export class OpsViewRemoteIngress extends DeesElement {
|
||||
if (ago < 3600000) return `${Math.floor(ago / 60000)}m ago`;
|
||||
return `${Math.floor(ago / 3600000)}h ago`;
|
||||
}
|
||||
|
||||
private formatBytes(bytes: number): string {
|
||||
if (!Number.isFinite(bytes) || bytes <= 0) return '0 B';
|
||||
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
let value = bytes;
|
||||
let unitIndex = 0;
|
||||
while (value >= 1024 && unitIndex < units.length - 1) {
|
||||
value = value / 1024;
|
||||
unitIndex++;
|
||||
}
|
||||
return `${value >= 10 || unitIndex === 0 ? value.toFixed(0) : value.toFixed(1)} ${units[unitIndex]}`;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user