Merge branch 'develop'

This commit is contained in:
2023-10-12 16:20:15 -07:00
14 changed files with 129 additions and 28 deletions

3
.gitignore vendored
View File

@@ -8,5 +8,6 @@
ifxmetrics.config.json ifxmetrics.config.json
.hemttout .hemttout
influxdb influxdb/data
influxdb/config
releases releases

View File

@@ -9,7 +9,8 @@ git_hash=6 # Default: 8
[files] [files]
include=[ include=[
"ifxmetrics.config.json", "ifxmetrics.config.example.json",
# "ifxmetrics.config.json", # used for copying during debugging
"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,19 @@ 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}/extension/IFXMetrics:/go/work -w /go/work -e GOARCH=amd64 -e CGO_ENABLED=1 x1unix/go-mingw:1.20 go build -o ./dist/ifxmetrics_x64.dll -buildmode=c-shared -ldflags "-w -s -X main.EXTENSION_VERSION=$IFXMETRICS_BUILD_VER" ./cmd
Move-Item -Path ./extension/IFXMetrics/dist/ifxmetrics_x64.dll -Destination ./ifxmetrics_x64.dll -Force
# 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}/extension/IFXMetrics:/go/work -w /go/work -e GOARCH=386 -e CGO_ENABLED=1 x1unix/go-mingw:1.20 go build -o ./dist/ifxmetrics.dll -buildmode=c-shared -ldflags "-w -s -X main.EXTENSION_VERSION=$IFXMETRICS_BUILD_VER" ./cmd
Move-Item -Path ./extension/IFXMetrics/dist/ifxmetrics.dll -Destination ./ifxmetrics.dll -Force
# 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}/extension/IFXMetrics:/go/work -w /go/work -e GOARCH=amd64 -e CGO_ENABLED=1 x1unix/go-mingw:1.20 go build -o ./dist/ifxmetrics_x64.exe -ldflags "-w -s -X main.EXTENSION_VERSION=$IFXMETRICS_BUILD_VER" ./cmd
Move-Item -Path ./extension/IFXMetrics/dist/ifxmetrics_x64.exe -Destination ./ifxmetrics_x64.exe -Force
``` ```
### EXTENSION: COMPILING FOR LINUX ### EXTENSION: COMPILING FOR LINUX
@@ -144,10 +202,15 @@ 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}/extension/IFXMetrics:/app -e GOOS=linux -e GOARCH=amd64 -e CGO_ENABLED=1 indifox926/build-a3go:linux-so go build -o ./dist/ifxmetrics_x64.so -linkshared -ldflags "-w -s -X main.EXTENSION_VERSION=${IFXMETRICS_BUILD_VER}" ./cmd
Move-Item -Path ./extension/IFXMetrics/dist/ifxmetrics_x64.so -Destination ./ifxmetrics_x64.so -Force
# 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}/extension/IFXMetrics:/app -e GOOS=linux -e GOARCH=386 -e CGO_ENABLED=1 indifox926/build-a3go:linux-so go build -o ./dist/ifxmetrics.so -linkshared -ldflags "-w -s -X main.EXTENSION_VERSION=${IFXMETRICS_BUILD_VER}" ./cmd
Move-Item -Path ./extension/IFXMetrics/dist/ifxmetrics.so -Destination ./ifxmetrics.so -Force
``` ```
### ADDON: COMPILE USING HEMTT ### ADDON: COMPILE USING HEMTT

View File

@@ -1,5 +1,9 @@
#include "script_component.hpp" #include "script_component.hpp"
params [
["_allUserInfos", [], [[]]]
];
private _hashesOut = []; private _hashesOut = [];
private _allUnits = allUnits; private _allUnits = allUnits;
@@ -10,18 +14,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 +51,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 +84,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 +104,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 +122,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,9 @@
#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 +27,6 @@ private _hashesOut = [];
["desync", _desync] ["desync", _desync]
]] ]]
]); ]);
} forEach (allUsers apply {getUserInfo _x}); } forEach _allUserInfos;
_hashesOut; _hashesOut;

View File

@@ -5,7 +5,11 @@ class CfgPatches {
units[] = {}; units[] = {};
weapons[] = {}; weapons[] = {};
requiredVersion = 2.10; requiredVersion = 2.10;
requiredAddons[] = {}; requiredAddons[] = {
"cba_main",
"cba_xeh",
"cba_settings"
};
author[] = {"IndigoFox"}; author[] = {"IndigoFox"};
authorUrl = "https://github.com/indig0fox/IFXMetrics"; authorUrl = "https://github.com/indig0fox/IFXMetrics";
}; };

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",

View File

@@ -319,4 +319,7 @@ func main() {
// s := settings.Active.Get("cbaEventHandlers") // s := settings.Active.Get("cbaEventHandlers")
// // return the custom cba event handlers as an arma hashmap // // return the custom cba event handlers as an arma hashmap
// fmt.Println(a3interface.ToArmaHashMap(s)) // fmt.Println(a3interface.ToArmaHashMap(s))
fmt.Println("IFXMetrics extension started. Version: " + EXTENSION_VERSION)
fmt.Scanln()
} }

View File

@@ -0,0 +1,20 @@
version: '3.8'
services:
influxdb:
image: influxdb:latest
container_name: influxdb
restart: always
ports:
- 8086:8086
volumes:
- ./data:/var/lib/influxdb2
- ./config:/etc/influxdb2
environment:
- DOCKER_INFLUXDB_INIT_MODE=setup
- DOCKER_INFLUXDB_INIT_USERNAME=exampleuser
- DOCKER_INFLUXDB_INIT_PASSWORD=dfaow3ho9i7funa0w3nv
- DOCKER_INFLUXDB_INIT_ORG=ifx-metrics
- DOCKER_INFLUXDB_INIT_BUCKET=test-bucket
- DOCKER_INFLUXDB_INIT_RETENTION=1w
- DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=f0982q3ahfu8yawbo27w8fb986ba90b0wb2f