NetUsage: finish module

This commit is contained in:
李通洲
2023-09-26 22:34:37 +08:00
parent 917b049030
commit b29b78b321
12 changed files with 145 additions and 23 deletions
+31
View File
@@ -558,6 +558,7 @@
"media",
"memory",
"monitor",
"netusage",
"opencl",
"opengl",
"os",
@@ -1019,6 +1020,36 @@
},
"additionalProperties": false
},
{
"title": "Network throughput (usage)",
"properties": {
"type": {
"const": "netusage"
},
"namePrefix": {
"title": "Show IPs with given name prefix only",
"type": "string"
},
"defaultRouteOnly": {
"title": "Show ips that are used for default routing only",
"type": "boolean",
"default": false
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
},
"additionalProperties": false
},
{
"title": "OpenGL",
"properties": {
+1 -1
View File
@@ -61,7 +61,7 @@ void ffPrepareCommandOption(FFdata* data)
ffPrepareCPUUsage();
if(ffStrbufContainIgnCaseS(&data->structure, FF_NETUSAGE_MODULE_NAME))
ffPrepareNetUsage();
ffPrepareNetUsage(&instance.config.netUsage);
if(instance.config.multithreading)
{
+8
View File
@@ -112,6 +112,14 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module)
ffPrepareCPUUsage();
break;
}
case 'n': case 'N': {
if (ffStrEqualsIgnCase(type, FF_NETUSAGE_MODULE_NAME))
{
if (module) ffParseNetUsageJsonObject(&cfg->netUsage, module);
ffPrepareNetUsage(&cfg->netUsage);
}
break;
}
case 'p': case 'P': {
if (ffStrEqualsIgnCase(type, FF_PUBLICIP_MODULE_NAME))
{
+9 -7
View File
@@ -2,31 +2,33 @@
#include "common/time.h"
const char* ffNetUsageGetIoCounters(FFlist* result);
const char* ffNetUsageGetIoCounters(FFlist* result, FFNetUsageOptions* options);
static FFlist ioCounters1;
static uint64_t time1;
void ffPrepareNetUsage(void)
void ffPrepareNetUsage(FFNetUsageOptions* options)
{
ffListInit(&ioCounters1, sizeof(FFNetUsageIoCounters));
ffNetUsageGetIoCounters(&ioCounters1);
ffNetUsageGetIoCounters(&ioCounters1, options);
time1 = ffTimeGetNow();
}
const char* ffDetectNetUsage(FFlist* result)
const char* ffDetectNetUsage(FFlist* result, FFNetUsageOptions* options)
{
const char* error = NULL;
if (time1 == 0)
{
ffListInit(&ioCounters1, sizeof(FFNetUsageIoCounters));
error = ffNetUsageGetIoCounters(&ioCounters1);
error = ffNetUsageGetIoCounters(&ioCounters1, options);
if (error)
return error;
time1 = ffTimeGetNow();
ffTimeSleep(1000);
}
if (ioCounters1.length == 0)
return "No network interfaces found";
uint64_t time2 = ffTimeGetNow();
while (time2 - time1 < 1000)
{
@@ -34,7 +36,7 @@ const char* ffDetectNetUsage(FFlist* result)
time2 = ffTimeGetNow();
}
error = ffNetUsageGetIoCounters(result);
error = ffNetUsageGetIoCounters(result, options);
if (error)
return error;
+2 -1
View File
@@ -3,6 +3,7 @@
typedef struct FFNetUsageIoCounters
{
FFstrbuf name;
bool defaultRoute;
uint64_t txBytes;
uint64_t rxBytes;
uint64_t txPackets;
@@ -13,4 +14,4 @@ typedef struct FFNetUsageIoCounters
uint64_t txDrops;
} FFNetUsageIoCounters;
const char* ffDetectNetUsage(FFlist* result);
const char* ffDetectNetUsage(FFlist* result, FFNetUsageOptions* options);
+16 -4
View File
@@ -1,6 +1,7 @@
#include "netusage.h"
#include "common/io/io.h"
#include "common/netif/netif.h"
#include "util/mallocHelper.h"
#include <net/if.h>
@@ -10,7 +11,7 @@
#include <sys/sysctl.h>
#include <sys/socket.h>
const char* ffNetUsageGetIoCounters(FFlist* result)
const char* ffNetUsageGetIoCounters(FFlist* result, FFNetUsageOptions* options)
{
size_t bufSize = 0;
if (sysctl((int[]) { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0 }, 6, NULL, &bufSize, 0, 0) < 0)
@@ -20,6 +21,8 @@ const char* ffNetUsageGetIoCounters(FFlist* result)
if (sysctl((int[]) { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0 }, 6, buf, &bufSize, 0, 0) < 0)
return "sysctl({ CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0 }, 6, buf, &bufSize, 0, 0) failed";
const char* defaultRouteIface = ffNetifGetDefaultRoute();
for (struct if_msghdr2* ifm = buf;
ifm < (struct if_msghdr2*) ((uint8_t*) buf + bufSize);
ifm = (struct if_msghdr2*) ((uint8_t*) ifm + ifm->ifm_msglen))
@@ -29,9 +32,19 @@ const char* ffNetUsageGetIoCounters(FFlist* result)
struct sockaddr_dl* sdl = (struct sockaddr_dl*) (ifm + 1);
assert(sdl->sdl_family == AF_LINK);
if (sdl->sdl_type != IFT_ETHER && !(ifm->ifm_flags & IFF_LOOPBACK)) continue;
FFNetUsageIoCounters* counters = (FFNetUsageIoCounters*) ffListAdd(result);
sdl->sdl_data[sdl->sdl_nlen] = 0;
bool isDefaultRoute = ffStrEquals(sdl->sdl_data, defaultRouteIface);
if(options->defaultRouteOnly && !isDefaultRoute)
continue;
if (options->namePrefix.length && strncmp(sdl->sdl_data, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
FFNetUsageIoCounters* counters = (FFNetUsageIoCounters*) ffListAdd(result);
*counters = (FFNetUsageIoCounters) {
.name = ffStrbufCreateNS(sdl->sdl_nlen, sdl->sdl_data),
.txBytes = ifm->ifm_data.ifi_obytes,
.rxBytes = ifm->ifm_data.ifi_ibytes,
.txPackets = ifm->ifm_data.ifi_opackets,
@@ -40,9 +53,8 @@ const char* ffNetUsageGetIoCounters(FFlist* result)
.rxErrors = ifm->ifm_data.ifi_ierrors,
.txDrops = 0, // unsupported
.rxDrops = ifm->ifm_data.ifi_iqdrops,
.defaultRoute = isDefaultRoute,
};
ffStrbufInitNS(&counters->name, sdl->sdl_nlen, sdl->sdl_data);
}
return NULL;
+14 -2
View File
@@ -1,10 +1,12 @@
#include "netusage.h"
#include "common/io/io.h"
#include "common/netif/netif.h"
#include "util/stringUtils.h"
#include <net/if.h>
const char* ffNetUsageGetIoCounters(FFlist* result)
const char* ffNetUsageGetIoCounters(FFlist* result, FFNetUsageOptions* options)
{
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/net");
if (!dirp) return "opendir(\"/sys/class/net\") == NULL";
@@ -12,20 +14,30 @@ const char* ffNetUsageGetIoCounters(FFlist* result)
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateA(64);
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
const char* defaultRouteIface = ffNetifGetDefaultRoute();
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(entry->d_name[0] == '.')
continue;
bool isDefaultRoute = ffStrEquals(entry->d_name, defaultRouteIface);
if(options->defaultRouteOnly && !isDefaultRoute)
continue;
if (options->namePrefix.length && strncmp(entry->d_name, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
ffStrbufSetF(&path, "/sys/class/net/%s/operstate", entry->d_name);
if(!ffReadFileBuffer(path.chars, &buffer) || !ffStrbufEqualS(&buffer, "up"))
continue;
FFNetUsageIoCounters* counters = (FFNetUsageIoCounters*) ffListAdd(result);
ffStrbufInitS(&counters->name, entry->d_name);
counters->defaultRoute = isDefaultRoute;
ffStrbufSetF(&path, "/sys/class/net/%s/statistics/");
ffStrbufSetF(&path, "/sys/class/net/%s/statistics/", entry->d_name);
uint32_t statLen = path.length;
ffStrbufAppendS(&path, "rx_bytes");
+15 -3
View File
@@ -1,13 +1,13 @@
#include "netusage.h"
#include "common/io/io.h"
#include "common/netif/netif.h"
#include "util/mallocHelper.h"
#include "util/windows/unicode.h"
#include <ws2tcpip.h>
#include <iphlpapi.h>
const char* ffNetUsageGetIoCounters(FFlist* result)
const char* ffNetUsageGetIoCounters(FFlist* result, FFNetUsageOptions* options)
{
IP_ADAPTER_ADDRESSES* FF_AUTO_FREE adapter_addresses = NULL;
@@ -37,14 +37,26 @@ const char* ffNetUsageGetIoCounters(FFlist* result)
return "GetAdaptersAddresses() failed";
}
uint32_t defaultRouteIfIndex = ffNetifGetDefaultRoute();
// Iterate through all of the adapters
for (IP_ADAPTER_ADDRESSES* adapter = adapter_addresses; adapter; adapter = adapter->Next)
{
bool isDefaultRoute = adapter->IfIndex == defaultRouteIfIndex;
if (options->defaultRouteOnly && !isDefaultRoute)
continue;
char name[128];
WideCharToMultiByte(CP_UTF8, 0, adapter->FriendlyName, -1, name, sizeof(name), NULL, NULL);
if (options->namePrefix.length && strncmp(name, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
MIB_IF_ROW2 ifRow = { .InterfaceIndex = adapter->IfIndex };
if (GetIfEntry2(&ifRow) == NO_ERROR)
{
FFNetUsageIoCounters* counters = (FFNetUsageIoCounters*) ffListAdd(result);
*counters = (FFNetUsageIoCounters) {
.name = ffStrbufCreateS(name),
.txBytes = ifRow.OutOctets,
.rxBytes = ifRow.InOctets,
.txPackets = (ifRow.OutUcastPkts + ifRow.OutNUcastPkts),
@@ -53,8 +65,8 @@ const char* ffNetUsageGetIoCounters(FFlist* result)
.txErrors = ifRow.OutErrors,
.rxDrops = ifRow.InDiscards,
.txDrops = ifRow.OutDiscards,
.defaultRoute = isDefaultRoute,
};
ffStrbufSetWS(&counters->name, adapter->FriendlyName);
}
}
+44 -3
View File
@@ -35,7 +35,7 @@ static void formatKey(const FFNetUsageOptions* options, FFNetUsageIoCounters* in
void ffPrintNetUsage(FFNetUsageOptions* options)
{
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFNetUsageIoCounters));
const char* error = ffDetectNetUsage(&result);
const char* error = ffDetectNetUsage(&result, options);
if(error)
{
@@ -63,6 +63,8 @@ void ffPrintNetUsage(FFNetUsageOptions* options)
ffStrbufAppendS(&buffer, "/s (in) - ");
ffParseSize(inf->txBytes, &buffer);
ffStrbufAppendS(&buffer, "/s (out)");
if (!options->defaultRouteOnly && inf->defaultRoute)
ffStrbufAppendS(&buffer, " *");
ffStrbufPutTo(&buffer, stdout);
}
else
@@ -82,16 +84,25 @@ void ffPrintNetUsage(FFNetUsageOptions* options)
{FF_FORMAT_ARG_TYPE_UINT64, &inf->txErrors},
{FF_FORMAT_ARG_TYPE_UINT64, &inf->rxDrops},
{FF_FORMAT_ARG_TYPE_UINT64, &inf->txDrops},
{FF_FORMAT_ARG_TYPE_BOOL, &inf->defaultRoute},
});
}
++index;
}
FF_LIST_FOR_EACH(FFNetUsageIoCounters, inf, result)
{
ffStrbufDestroy(&inf->name);
}
}
void ffInitNetUsageOptions(FFNetUsageOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_NETUSAGE_MODULE_NAME, ffParseNetUsageCommandOptions, ffParseNetUsageJsonObject, ffPrintNetUsage, ffGenerateNetUsageJson);
ffOptionInitModuleArg(&options->moduleArgs);
ffStrbufInit(&options->namePrefix);
options->defaultRouteOnly = false;
}
bool ffParseNetUsageCommandOptions(FFNetUsageOptions* options, const char* key, const char* value)
@@ -101,12 +112,25 @@ bool ffParseNetUsageCommandOptions(FFNetUsageOptions* options, const char* key,
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
if (ffStrEqualsIgnCase(subKey, "name-prefix"))
{
ffOptionParseString(key, value, &options->namePrefix);
return true;
}
if (ffStrEqualsIgnCase(subKey, "default-route-only"))
{
options->defaultRouteOnly = ffOptionParseBoolean(value);
return true;
}
return false;
}
void ffDestroyNetUsageOptions(FFNetUsageOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
ffStrbufDestroy(&options->namePrefix);
}
void ffParseNetUsageJsonObject(FFNetUsageOptions* options, yyjson_val* module)
@@ -122,14 +146,26 @@ void ffParseNetUsageJsonObject(FFNetUsageOptions* options, yyjson_val* module)
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
if (ffStrEqualsIgnCase(key, "namePrefix"))
{
ffStrbufSetS(&options->namePrefix, yyjson_get_str(val));
continue;
}
if (ffStrEqualsIgnCase(key, "defaultRouteOnly"))
{
options->defaultRouteOnly = yyjson_get_bool(val);
continue;
}
ffPrintError(FF_NETUSAGE_MODULE_NAME, 0, &options->moduleArgs, "Unknown JSON key %s", key);
}
}
void ffGenerateNetUsageJson(FF_MAYBE_UNUSED FFNetUsageOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
void ffGenerateNetUsageJson(FFNetUsageOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFNetUsageIoCounters));
const char* error = ffDetectNetUsage(&result);
const char* error = ffDetectNetUsage(&result, options);
if(error)
{
@@ -150,6 +186,11 @@ void ffGenerateNetUsageJson(FF_MAYBE_UNUSED FFNetUsageOptions* options, yyjson_m
yyjson_mut_obj_add_uint(doc, obj, "txErrors", counter->txErrors);
yyjson_mut_obj_add_uint(doc, obj, "rxDrops", counter->rxDrops);
yyjson_mut_obj_add_uint(doc, obj, "txDrops", counter->txDrops);
yyjson_mut_obj_add_bool(doc, obj, "defaultRoute", counter->defaultRoute);
}
FF_LIST_FOR_EACH(FFNetUsageIoCounters, inf, result)
{
ffStrbufDestroy(&inf->name);
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
#define FF_NETUSAGE_MODULE_NAME "NetUsage"
void ffPrepareNetUsage();
void ffPrepareNetUsage(FFNetUsageOptions* options);
void ffPrintNetUsage(FFNetUsageOptions* options);
void ffInitNetUsageOptions(FFNetUsageOptions* options);
+3
View File
@@ -8,4 +8,7 @@ typedef struct FFNetUsageOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
FFstrbuf namePrefix;
bool defaultRouteOnly;
} FFNetUsageOptions;
+1 -1
View File
@@ -50,7 +50,7 @@ void ffStrbufPrependNS(FFstrbuf* strbuf, uint32_t length, const char* value);
void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value);
void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value);
void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...);
FF_C_PRINTF(2, 3) void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...);
void ffStrbufTrimLeft(FFstrbuf* strbuf, char c);
void ffStrbufTrimRight(FFstrbuf* strbuf, char c);