mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2026-01-11 19:44:53 +01:00
fix(container): Fix Podman 5.x Network Traffic Statistics Not Displaying (#991)
* fix(container): Added version parameter to accommodate Podman 5.x network statistics format Modified the parseStats method to accept a version parameter, handling changes in Podman 5.x's network statistics data structure. When the version is 5.x, network traffic data is retrieved from the RxBytes/TxBytes fields of the Network interface. * fix(container): Fixed Podman version detection logic to correctly retrieve network statistics Addressed Podman version number parsing issues and improved version comparison logic to support all 4.x and below versions as well as 5.x and above versions * fix(container): Resolved display formatting issues for network and disk I/O statistics Handled default values when NetIO and BlockIO are null, and reformatted display strings to distinguish upstream/downstream traffic and read/write operations. * fix: Why did I mess up the tag order?
This commit is contained in:
@@ -20,7 +20,7 @@ sealed class ContainerPs {
|
||||
|
||||
factory ContainerPs.fromRaw(String s, ContainerType typ) => typ.ps(s);
|
||||
|
||||
void parseStats(String s);
|
||||
void parseStats(String s, [String? version]);
|
||||
}
|
||||
|
||||
final class PodmanPs implements ContainerPs {
|
||||
@@ -55,7 +55,7 @@ final class PodmanPs implements ContainerPs {
|
||||
ContainerStatus get status => ContainerStatus.fromPodmanExited(exited);
|
||||
|
||||
@override
|
||||
void parseStats(String s) {
|
||||
void parseStats(String s, [String? version]) {
|
||||
final stats = json.decode(s);
|
||||
final cpuD = (stats['CPU'] as double? ?? 0).toStringAsFixed(1);
|
||||
final cpuAvgD = (stats['AvgCPU'] as double? ?? 0).toStringAsFixed(1);
|
||||
@@ -63,12 +63,32 @@ final class PodmanPs implements ContainerPs {
|
||||
final memLimit = (stats['MemLimit'] as int? ?? 0).bytes2Str;
|
||||
final memUsage = (stats['MemUsage'] as int? ?? 0).bytes2Str;
|
||||
mem = '$memUsage / $memLimit';
|
||||
final netIn = (stats['NetInput'] as int? ?? 0).bytes2Str;
|
||||
final netOut = (stats['NetOutput'] as int? ?? 0).bytes2Str;
|
||||
net = '↓ $netIn / ↑ $netOut';
|
||||
|
||||
int netIn = 0;
|
||||
int netOut = 0;
|
||||
final majorVersion = version?.split('.').firstOrNull;
|
||||
final majorVersionNum = majorVersion != null ? int.tryParse(majorVersion) : null;
|
||||
|
||||
// Podman 4.x and earlier use top-level NetInput/NetOutput fields.
|
||||
// Podman 5.x changed network backend (Netavark) and uses nested
|
||||
// Network.{iface}.RxBytes/TxBytes structure instead.
|
||||
if (majorVersionNum == null || majorVersionNum <= 4) {
|
||||
netIn = stats['NetInput'] as int? ?? 0;
|
||||
netOut = stats['NetOutput'] as int? ?? 0;
|
||||
} else if (majorVersionNum >= 5) {
|
||||
final network = stats['Network'] as Map<String, dynamic>?;
|
||||
if (network != null) {
|
||||
for (final interface in network.values) {
|
||||
netIn += interface['RxBytes'] as int? ?? 0;
|
||||
netOut += interface['TxBytes'] as int? ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
net = '↓ ${netIn.bytes2Str} / ↑ ${netOut.bytes2Str}';
|
||||
|
||||
final diskIn = (stats['BlockInput'] as int? ?? 0).bytes2Str;
|
||||
final diskOut = (stats['BlockOutput'] as int? ?? 0).bytes2Str;
|
||||
disk = '${l10n.read} $diskOut / ${l10n.write} $diskIn';
|
||||
disk = '${l10n.read} $diskIn / ${l10n.write} $diskOut';
|
||||
}
|
||||
|
||||
factory PodmanPs.fromRawJson(String str) => PodmanPs.fromJson(json.decode(str));
|
||||
@@ -125,12 +145,18 @@ final class DockerPs implements ContainerPs {
|
||||
ContainerStatus get status => ContainerStatus.fromDockerState(state);
|
||||
|
||||
@override
|
||||
void parseStats(String s) {
|
||||
void parseStats(String s, [String? version]) {
|
||||
final stats = json.decode(s);
|
||||
cpu = stats['CPUPerc'];
|
||||
mem = stats['MemUsage'];
|
||||
net = stats['NetIO'];
|
||||
disk = stats['BlockIO'];
|
||||
|
||||
final netIO = stats['NetIO'] as String? ?? '0B / 0B';
|
||||
final netParts = netIO.split(' / ');
|
||||
net = '↓ ${netParts.firstOrNull ?? '0B'} / ↑ ${netParts.length > 1 ? netParts[1] : '0B'}';
|
||||
|
||||
final blockIO = stats['BlockIO'] as String? ?? '0B / 0B';
|
||||
final blockParts = blockIO.split(' / ');
|
||||
disk = '${l10n.read} ${blockParts.firstOrNull ?? '0B'} / ${l10n.write} ${blockParts.length > 1 ? blockParts[1] : '0B'}';
|
||||
}
|
||||
|
||||
/// CONTAINER ID NAMES IMAGE STATUS
|
||||
|
||||
@@ -186,7 +186,7 @@ class ContainerNotifier extends _$ContainerNotifier {
|
||||
(element) => element.contains(id.substring(0, 5)),
|
||||
);
|
||||
if (statsLine == null) continue;
|
||||
item.parseStats(statsLine);
|
||||
item.parseStats(statsLine, state.version);
|
||||
}
|
||||
} catch (e, trace) {
|
||||
state = state.copyWith(
|
||||
|
||||
Reference in New Issue
Block a user