diff --git a/.hemtt/project.toml b/.hemtt/project.toml index 1faf74b..eddf244 100644 --- a/.hemtt/project.toml +++ b/.hemtt/project.toml @@ -9,7 +9,7 @@ git_hash=6 # Default: 8 [files] include=[ - "ifxmetrics.config.json", + "ifxmetrics.config.example.json", "LICENSE", "README.md", "mod.cpp", diff --git a/README.md b/README.md index 85590b3..71e7366 100644 --- a/README.md +++ b/README.md @@ -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 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 # 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 -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 -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 @@ -144,10 +196,10 @@ Run this from the project root. docker build -t indifox926/build-a3go:linux-so -f ./build/Dockerfile.build . # 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 -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 diff --git a/addons/capture/fnc_entity_count.sqf b/addons/capture/fnc_entity_count.sqf index d1ce7fb..cfe58e4 100644 --- a/addons/capture/fnc_entity_count.sqf +++ b/addons/capture/fnc_entity_count.sqf @@ -1,5 +1,7 @@ #include "script_component.hpp" +params ["_allUserInfos", [], [[]]]; + private _hashesOut = []; private _allUnits = allUnits; @@ -10,18 +12,20 @@ private _allPlayers = call BIS_fnc_listPlayers; { private _thisSide = _x; private _thisSideStr = _thisSide call BIS_fnc_sideNameUnlocalized; + private _tags = +GVARMAIN(standardTags); + _tags pushBack ["side", _thisSideStr]; // Number of remote units _hashesOut pushBack ([ ["bucket", "server_performance"], ["measurement", "entities_remote"], - ["tags", GVARMAIN(standardTags)], + ["tags", _tags], ["fields", [ ["units_alive", { - side _x isEqualTo _thisSide && + side group _x isEqualTo _thisSide && not (local _x) } count _allUnits], ["units_dead", { - side _x isEqualTo _thisSide && + side group _x isEqualTo _thisSide && not (local _x) } count _allDeadMen], ["groups_total", { @@ -45,14 +49,14 @@ private _allPlayers = call BIS_fnc_listPlayers; _hashesOut pushBack ([ ["bucket", "server_performance"], ["measurement", "entities_local"], - ["tags", GVARMAIN(standardTags)], + ["tags", _tags], ["fields", [ ["units_alive", { - side _x isEqualTo _thisSide && + side group _x isEqualTo _thisSide && local _x } count _allUnits], ["units_dead", { - side _x isEqualTo _thisSide && + side group _x isEqualTo _thisSide && local _x } count _allDeadMen], ["groups_total", { @@ -78,13 +82,13 @@ private _allPlayers = call BIS_fnc_listPlayers; _hashesOut pushBack ([ ["bucket", "server_performance"], ["measurement", "entities_global"], - ["tags", GVARMAIN(standardTags)], + ["tags", _tags], ["fields", [ ["units_alive", { - side _x isEqualTo _thisSide + side group _x isEqualTo _thisSide } count _allUnits], ["units_dead", { - side _x isEqualTo _thisSide + side group _x isEqualTo _thisSide } count _allDeadMen], ["groups_total", { side _x isEqualTo _thisSide @@ -98,11 +102,11 @@ private _allPlayers = call BIS_fnc_listPlayers; (_x isKindOf "WeaponHolderSimulated") } count _vehicles], ["players_alive", { - side _x isEqualTo _thisSide && + side group _x isEqualTo _thisSide && alive _x } count _allPlayers], ["players_dead", { - side _x isEqualTo _thisSide && + side group _x isEqualTo _thisSide && !alive _x } count _allPlayers] ]] @@ -116,12 +120,8 @@ if (isServer) then { ["measurement", "player_count"], ["tags", GVARMAIN(standardTags)], ["fields", [ - ["players_connected", { - private _info = getUserInfo (getPlayerId _x); - if (!isNil "_info" && {count _info >= 6}) then { - _info select 7 - } else {false} - } count _allPlayers] + ["players_connected", count (_allUserInfos select {_x#7 isEqualTo false})], + ["headless_clients_connected", count (_allUserInfos select {_x#7 isEqualTo true})] ]] ]); }; diff --git a/addons/capture/fnc_player_performance.sqf b/addons/capture/fnc_player_performance.sqf index 4ac7df1..58b0a38 100644 --- a/addons/capture/fnc_player_performance.sqf +++ b/addons/capture/fnc_player_performance.sqf @@ -1,5 +1,7 @@ #include "script_component.hpp" +params ["_allUserInfos", [], [[]]]; + private _hashesOut = []; { _x params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit"]; @@ -23,6 +25,6 @@ private _hashesOut = []; ["desync", _desync] ]] ]); -} forEach (allUsers apply {getUserInfo _x}); +} forEach _allUserInfos; _hashesOut; \ No newline at end of file diff --git a/addons/main/fnc_captureLoop.sqf b/addons/main/fnc_captureLoop.sqf index 05b6ae1..927ae30 100644 --- a/addons/main/fnc_captureLoop.sqf +++ b/addons/main/fnc_captureLoop.sqf @@ -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 { GVARMAIN(extensionName) callExtension [ ":INFLUX:WRITE:", [_x] ]; - } forEach (call EFUNC(capture,entity_count)); + } forEach ([_allUserInfos] call EFUNC(capture,entity_count)); { GVARMAIN(extensionName) callExtension [ ":INFLUX:WRITE:", [_x] ]; - } forEach (call EFUNC(capture,player_performance)); + } forEach ([_allUserInfos] call EFUNC(capture,player_performance)); ["DEBUG", format[ "Processed primary data loop in %1 ms", diff --git a/extension/cmd/main.go b/extension/IFXMetrics/cmd/main.go similarity index 100% rename from extension/cmd/main.go rename to extension/IFXMetrics/cmd/main.go diff --git a/extension/go.mod b/extension/IFXMetrics/go.mod similarity index 100% rename from extension/go.mod rename to extension/IFXMetrics/go.mod diff --git a/extension/go.sum b/extension/IFXMetrics/go.sum similarity index 100% rename from extension/go.sum rename to extension/IFXMetrics/go.sum diff --git a/extension/internal/influx/influx.go b/extension/IFXMetrics/internal/influx/influx.go similarity index 100% rename from extension/internal/influx/influx.go rename to extension/IFXMetrics/internal/influx/influx.go diff --git a/extension/internal/logger/logger.go b/extension/IFXMetrics/internal/logger/logger.go similarity index 100% rename from extension/internal/logger/logger.go rename to extension/IFXMetrics/internal/logger/logger.go diff --git a/extension/internal/settings/settings.go b/extension/IFXMetrics/internal/settings/settings.go similarity index 100% rename from extension/internal/settings/settings.go rename to extension/IFXMetrics/internal/settings/settings.go