small reorg, some improvements, readme updates

- fix hemtt config to copy example
- add measurements table in Readme
- ENTITY COUNTS
  - re add side tags
  - use `side group _x` for units and players
  - fix players_connected and add headless_clients
- get `_allUserInfos = allUsers apply {getUserInfo _x} select {count _x > 0};` from main loop and use in entity counts and player performance
This commit is contained in:
2023-10-10 18:07:25 -07:00
parent 9ccb6fd3cd
commit 40b5a3d26f
11 changed files with 83 additions and 26 deletions

View File

@@ -9,7 +9,7 @@ git_hash=6 # Default: 8
[files] [files]
include=[ include=[
"ifxmetrics.config.json", "ifxmetrics.config.example.json",
"LICENSE", "LICENSE",
"README.md", "README.md",
"mod.cpp", "mod.cpp",

View File

@@ -105,6 +105,58 @@ Grafana is a dashboarding tool. It is used to display the data from InfluxDB. A
--- ---
## CORE METRICS
These metrics will be gathered by default every `refreshRateMs` milliseconds.
| Bucket | Measurement | Tags | Field |
| --- | --- | --- | --- |
| server_performance | fps | profile=`profileName` world=`worldName` server=`serverName` | fps_avg=`diag_fps` |
| server_performance | fps | ... | fps_min=`diag_fpsMin` |
| server_performance | running_scripts | ... | spawn=`diag_activeScripts#0` |
| server_performance | running_scripts | ... | execVM=`diag_activeScripts#1` |
| server_performance | running_scripts | ... | exec=`diag_activeScripts#2` |
| server_performance | running_scripts | ... | execFSM=`diag_activeScripts#3` |
| server_performance | running_scripts | ... | pfh=`count CBA_common_perFrameHandlerArray \|\| 0` |
| server_performance | entities_remote | ... + side=`WEST`,`EAST`, etc | units_alive=`{side group _x isEqualTo _thisSide && not (local _x)} count _allUnits` |
| server_performance | entities_remote | ... + side=`WEST`,`EAST`, etc | units_dead=`{side group _x isEqualTo _thisSide && not (local _x)} count _allDeadMen` |
| server_performance | entities_remote | ... + side=`WEST`,`EAST`, etc | groups_total=`{side _x isEqualTo _thisSide && not (local _x)} count _allGroups` |
| server_performance | entities_remote | ... + side=`WEST`,`EAST`, etc | vehicles_total=`{side _x isEqualTo _thisSide && not (local _x) && !(_x isKindOf "WeaponHolderSimulated")} count _vehicles` |
| server_performance | entities_remote | ... + side=`WEST`,`EAST`, etc | vehicles_weaponholder=`{side _x isEqualTo _thisSide && not (local _x) && (_x isKindOf "WeaponHolderSimulated")} count _vehicles` |
| server_performance | entities_local | ... + side=`WEST`,`EAST`, etc | units_alive=`{side group _x isEqualTo _thisSide && (local _x)} count _allUnits` |
| server_performance | entities_local | ... + side=`WEST`,`EAST`, etc | units_dead=`{side group _x isEqualTo _thisSide && (local _x)} count _allDeadMen` |
| server_performance | entities_local | ... + side=`WEST`,`EAST`, etc | groups_total=`{side _x isEqualTo _thisSide && (local _x)} count _allGroups` |
| server_performance | entities_local | ... + side=`WEST`,`EAST`, etc | vehicles_total=`{side _x isEqualTo _thisSide && (local _x) && !(_x isKindOf "WeaponHolderSimulated")} count _vehicles` |
| server_performance | entities_local | ... + side=`WEST`,`EAST`, etc | vehicles_weaponholder=`{side _x isEqualTo _thisSide && (local _x) && (_x isKindOf "WeaponHolderSimulated")} count _vehicles` |
| server_performance | entities_global | ... + side=`WEST`,`EAST`, etc | units_alive=`{side group _x isEqualTo _thisSide} count _allUnits` |
| server_performance | entities_global | ... + side=`WEST`,`EAST`, etc | units_dead=`{side group _x isEqualTo _thisSide} count _allDeadMen` |
| server_performance | entities_global | ... + side=`WEST`,`EAST`, etc | groups_total=`{side _x isEqualTo _thisSide} count _allGroups` |
| server_performance | entities_global | ... + side=`WEST`,`EAST`, etc | vehicles_total=`{side _x isEqualTo _thisSide && !(_x isKindOf "WeaponHolderSimulated")} count _vehicles` |
| server_performance | entities_global | ... + side=`WEST`,`EAST`, etc | vehicles_weaponholder=`{side _x isEqualTo _thisSide && (_x isKindOf "WeaponHolderSimulated")} count _vehicles` |
| server_performance | entities_global | ... + side=`WEST`,`EAST`, etc | players_alive=`{side group _x isEqualTo _thisSide && alive _x} count (call BIS_fnc_listPlayers)` |
| server_performance | entities_global | ... + side=`WEST`,`EAST`, etc | players_dead=`{side group _x isEqualTo _thisSide && !alive _x} count (call BIS_fnc_listPlayers)` |
| server_performance | player_count | ... | players_connected=`count (_allUserInfos select {_x#7 isEqualTo false})` |
| server_performance | player_count | ... | headless_clients_connected=`count (_allUserInfos select {_x#7 isEqualTo true})` |
| player_performance | network | ... + playerUID=`getUserInfo#2`, playerName=`getUserInfo#3` | avgPing=`getUserInfo#9#0` |
| player_performance | network | ... + playerUID=`getUserInfo#2`, playerName=`getUserInfo#3` | avgBandwidth=`getUserInfo#9#1` |
| player_performance | network | ... + playerUID=`getUserInfo#2`, playerName=`getUserInfo#3` | desync=`getUserInfo#9#2` |
| mission_data | server_time | ... | diag_tickTime=`diag_tickTime` |
| mission_data | server_time | ... | serverTime=`time` |
| mission_data | server_time | ... | timeMultiplier=`timeMultiplier` |
| mission_data | server_time | ... | accTime=`accTime` |
| mission_data | weather | ... | fog=`fog` |
| mission_data | weather | ... | overcast=`overcast` |
| mission_data | weather | ... | rain=`rain` |
| mission_data | weather | ... | humidity=`humidity` |
| mission_data | weather | ... | waves=`waves` |
| mission_data | weather | ... | windDir=`windDir` |
| mission_data | weather | ... | windStr=`windStr` |
| mission_data | weather | ... | gusts=`gusts` |
| mission_data | weather | ... | lightnings=`lightnings` |
| mission_data | weather | ... | moonIntensity=`moonIntensity` |
| mission_data | weather | ... | moonPhase=`moonPhase` |
| mission_data | weather | ... | sunOrMoon=`sunOrMoon` |
## BUILDING ## BUILDING
Set an environment variable in your terminal with the desired extension build version. It defaults to "DEVELOPMENT". Set an environment variable in your terminal with the desired extension build version. It defaults to "DEVELOPMENT".
@@ -127,13 +179,13 @@ Run this from the project root.
docker pull x1unix/go-mingw:1.20 docker pull x1unix/go-mingw:1.20
# Compile x64 Windows DLL # Compile x64 Windows DLL
docker run --rm -it -v ${PWD}:/go/work -w /go/work -e GOARCH=amd64 -e CGO_ENABLED=1 x1unix/go-mingw:1.20 go build -o ./ifxmetrics_x64.dll -buildmode=c-shared -ldflags "-w -s -X main.EXTENSION_VERSION=`"$IFXMETRICS_BUILD_VER`"" ./extension/cmd docker run --rm -it -v ${PWD}:/go/work -w /go/work -e GOARCH=amd64 -e CGO_ENABLED=1 x1unix/go-mingw:1.20 go build -o ./ifxmetrics_x64.dll -buildmode=c-shared -ldflags "-w -s -X main.EXTENSION_VERSION=`"$IFXMETRICS_BUILD_VER`"" ./extension/IFXMetrics/cmd
# Compile x86 Windows DLL # Compile x86 Windows DLL
docker run --rm -it -v ${PWD}:/go/work -w /go/work -e GOARCH=386 -e CGO_ENABLED=1 x1unix/go-mingw:1.20 go build -o ./ifxmetrics.dll -buildmode=c-shared -ldflags "-w -s -X main.EXTENSION_VERSION=`"$IFXMETRICS_BUILD_VER`"" ./extension/cmd docker run --rm -it -v ${PWD}:/go/work -w /go/work -e GOARCH=386 -e CGO_ENABLED=1 x1unix/go-mingw:1.20 go build -o ./ifxmetrics.dll -buildmode=c-shared -ldflags "-w -s -X main.EXTENSION_VERSION=`"$IFXMETRICS_BUILD_VER`"" ./extension/IFXMetrics/cmd
# Compile x64 Windows EXE # Compile x64 Windows EXE
docker run --rm -it -v ${PWD}:/go/work -w /go/work -e GOARCH=amd64 -e CGO_ENABLED=1 x1unix/go-mingw:1.20 go build -o ./ifxmetrics_x64.exe -ldflags "-w -s -X main.EXTENSION_VERSION=`"$IFXMETRICS_BUILD_VER`"" ./extension/cmd docker run --rm -it -v ${PWD}:/go/work -w /go/work -e GOARCH=amd64 -e CGO_ENABLED=1 x1unix/go-mingw:1.20 go build -o ./ifxmetrics_x64.exe -ldflags "-w -s -X main.EXTENSION_VERSION=`"$IFXMETRICS_BUILD_VER`"" ./extension/IFXMetrics/cmd
``` ```
### EXTENSION: COMPILING FOR LINUX ### EXTENSION: COMPILING FOR LINUX
@@ -144,10 +196,10 @@ Run this from the project root.
docker build -t indifox926/build-a3go:linux-so -f ./build/Dockerfile.build . docker build -t indifox926/build-a3go:linux-so -f ./build/Dockerfile.build .
# Compile x64 Linux .so # Compile x64 Linux .so
docker run --rm -it -v ${PWD}:/app -e GOOS=linux -e GOARCH=amd64 -e CGO_ENABLED=1 indifox926/build-a3go:linux-so go build -o ./ifxmetrics_x64.so -linkshared -ldflags "-w -s -X main.EXTENSION_VERSION=${IFXMETRICS_BUILD_VER}" ./extension/cmd docker run --rm -it -v ${PWD}:/app -e GOOS=linux -e GOARCH=amd64 -e CGO_ENABLED=1 indifox926/build-a3go:linux-so go build -o ./ifxmetrics_x64.so -linkshared -ldflags "-w -s -X main.EXTENSION_VERSION=${IFXMETRICS_BUILD_VER}" ./extension/IFXMetrics/cmd
# Compile x86 Linux .so # Compile x86 Linux .so
docker run --rm -it -v ${PWD}:/app -e GOOS=linux -e GOARCH=386 -e CGO_ENABLED=1 indifox926/build-a3go:linux-so go build -o ./ifxmetrics.so -linkshared -ldflags "-w -s -X main.EXTENSION_VERSION=${IFXMETRICS_BUILD_VER}" ./extension/cmd docker run --rm -it -v ${PWD}:/app -e GOOS=linux -e GOARCH=386 -e CGO_ENABLED=1 indifox926/build-a3go:linux-so go build -o ./ifxmetrics.so -linkshared -ldflags "-w -s -X main.EXTENSION_VERSION=${IFXMETRICS_BUILD_VER}" ./extension/IFXMetrics/cmd
``` ```
### ADDON: COMPILE USING HEMTT ### ADDON: COMPILE USING HEMTT

View File

@@ -1,5 +1,7 @@
#include "script_component.hpp" #include "script_component.hpp"
params ["_allUserInfos", [], [[]]];
private _hashesOut = []; private _hashesOut = [];
private _allUnits = allUnits; private _allUnits = allUnits;
@@ -10,18 +12,20 @@ private _allPlayers = call BIS_fnc_listPlayers;
{ {
private _thisSide = _x; private _thisSide = _x;
private _thisSideStr = _thisSide call BIS_fnc_sideNameUnlocalized; private _thisSideStr = _thisSide call BIS_fnc_sideNameUnlocalized;
private _tags = +GVARMAIN(standardTags);
_tags pushBack ["side", _thisSideStr];
// Number of remote units // Number of remote units
_hashesOut pushBack ([ _hashesOut pushBack ([
["bucket", "server_performance"], ["bucket", "server_performance"],
["measurement", "entities_remote"], ["measurement", "entities_remote"],
["tags", GVARMAIN(standardTags)], ["tags", _tags],
["fields", [ ["fields", [
["units_alive", { ["units_alive", {
side _x isEqualTo _thisSide && side group _x isEqualTo _thisSide &&
not (local _x) not (local _x)
} count _allUnits], } count _allUnits],
["units_dead", { ["units_dead", {
side _x isEqualTo _thisSide && side group _x isEqualTo _thisSide &&
not (local _x) not (local _x)
} count _allDeadMen], } count _allDeadMen],
["groups_total", { ["groups_total", {
@@ -45,14 +49,14 @@ private _allPlayers = call BIS_fnc_listPlayers;
_hashesOut pushBack ([ _hashesOut pushBack ([
["bucket", "server_performance"], ["bucket", "server_performance"],
["measurement", "entities_local"], ["measurement", "entities_local"],
["tags", GVARMAIN(standardTags)], ["tags", _tags],
["fields", [ ["fields", [
["units_alive", { ["units_alive", {
side _x isEqualTo _thisSide && side group _x isEqualTo _thisSide &&
local _x local _x
} count _allUnits], } count _allUnits],
["units_dead", { ["units_dead", {
side _x isEqualTo _thisSide && side group _x isEqualTo _thisSide &&
local _x local _x
} count _allDeadMen], } count _allDeadMen],
["groups_total", { ["groups_total", {
@@ -78,13 +82,13 @@ private _allPlayers = call BIS_fnc_listPlayers;
_hashesOut pushBack ([ _hashesOut pushBack ([
["bucket", "server_performance"], ["bucket", "server_performance"],
["measurement", "entities_global"], ["measurement", "entities_global"],
["tags", GVARMAIN(standardTags)], ["tags", _tags],
["fields", [ ["fields", [
["units_alive", { ["units_alive", {
side _x isEqualTo _thisSide side group _x isEqualTo _thisSide
} count _allUnits], } count _allUnits],
["units_dead", { ["units_dead", {
side _x isEqualTo _thisSide side group _x isEqualTo _thisSide
} count _allDeadMen], } count _allDeadMen],
["groups_total", { ["groups_total", {
side _x isEqualTo _thisSide side _x isEqualTo _thisSide
@@ -98,11 +102,11 @@ private _allPlayers = call BIS_fnc_listPlayers;
(_x isKindOf "WeaponHolderSimulated") (_x isKindOf "WeaponHolderSimulated")
} count _vehicles], } count _vehicles],
["players_alive", { ["players_alive", {
side _x isEqualTo _thisSide && side group _x isEqualTo _thisSide &&
alive _x alive _x
} count _allPlayers], } count _allPlayers],
["players_dead", { ["players_dead", {
side _x isEqualTo _thisSide && side group _x isEqualTo _thisSide &&
!alive _x !alive _x
} count _allPlayers] } count _allPlayers]
]] ]]
@@ -116,12 +120,8 @@ if (isServer) then {
["measurement", "player_count"], ["measurement", "player_count"],
["tags", GVARMAIN(standardTags)], ["tags", GVARMAIN(standardTags)],
["fields", [ ["fields", [
["players_connected", { ["players_connected", count (_allUserInfos select {_x#7 isEqualTo false})],
private _info = getUserInfo (getPlayerId _x); ["headless_clients_connected", count (_allUserInfos select {_x#7 isEqualTo true})]
if (!isNil "_info" && {count _info >= 6}) then {
_info select 7
} else {false}
} count _allPlayers]
]] ]]
]); ]);
}; };

View File

@@ -1,5 +1,7 @@
#include "script_component.hpp" #include "script_component.hpp"
params ["_allUserInfos", [], [[]]];
private _hashesOut = []; private _hashesOut = [];
{ {
_x params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit"]; _x params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit"];
@@ -23,6 +25,6 @@ private _hashesOut = [];
["desync", _desync] ["desync", _desync]
]] ]]
]); ]);
} forEach (allUsers apply {getUserInfo _x}); } forEach _allUserInfos;
_hashesOut; _hashesOut;

View File

@@ -24,19 +24,22 @@ GVARMAIN(captureLoop) = [
] ]
]; ];
// getUserInfo for all users
private _allUserInfos = allUsers apply {getUserInfo _x} select {count _x > 0};
// entity_count returns an array of hashMap // entity_count returns an array of hashMap
{ {
GVARMAIN(extensionName) callExtension [ GVARMAIN(extensionName) callExtension [
":INFLUX:WRITE:", ":INFLUX:WRITE:",
[_x] [_x]
]; ];
} forEach (call EFUNC(capture,entity_count)); } forEach ([_allUserInfos] call EFUNC(capture,entity_count));
{ {
GVARMAIN(extensionName) callExtension [ GVARMAIN(extensionName) callExtension [
":INFLUX:WRITE:", ":INFLUX:WRITE:",
[_x] [_x]
]; ];
} forEach (call EFUNC(capture,player_performance)); } forEach ([_allUserInfos] call EFUNC(capture,player_performance));
["DEBUG", format[ ["DEBUG", format[
"Processed primary data loop in %1 ms", "Processed primary data loop in %1 ms",