MAJOR rework
- improves a lot on the Go side including better config and logging libraries (including log rotation), better internal package distribution, and new a3go functionality to make data transfer more performant - SQF side preprocessing of capture data is now minimal - arrays in hashmap format are sent directly to the extension and parsed there to minimize game impact - CBA custom events are implemented in a better fashion - README update - license change - with performance improvements, the deep customization of integrated metric gathering is removed in return to a single refreshRateMs, defining the interval at which core metrics are captured - peeled back the list of core metrics to the core information used in troubleshooting and benchmarking
This commit is contained in:
1
addons/capture/$PBOPREFIX$
Normal file
1
addons/capture/$PBOPREFIX$
Normal file
@@ -0,0 +1 @@
|
||||
x\ifxmetrics\addons\capture
|
||||
26
addons/capture/config.cpp
Normal file
26
addons/capture/config.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
units[] = {};
|
||||
weapons[] = {};
|
||||
requiredVersion = 2.10;
|
||||
requiredAddons[] = {"cba_main"};
|
||||
author[] = {"IndigoFox"};
|
||||
authorUrl = "https://github.com/indig0fox/IFXMetrics";
|
||||
};
|
||||
};
|
||||
|
||||
class CfgFunctions {
|
||||
class ADDON {
|
||||
class functions {
|
||||
PATHTO_FNC(entity_count);
|
||||
PATHTO_FNC(player_performance);
|
||||
PATHTO_FNC(running_mission);
|
||||
PATHTO_FNC(running_scripts);
|
||||
PATHTO_FNC(server_performance);
|
||||
PATHTO_FNC(server_time);
|
||||
PATHTO_FNC(weather);
|
||||
};
|
||||
};
|
||||
};
|
||||
129
addons/capture/fnc_entity_count.sqf
Normal file
129
addons/capture/fnc_entity_count.sqf
Normal file
@@ -0,0 +1,129 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
private _hashesOut = [];
|
||||
|
||||
private _allUnits = allUnits;
|
||||
private _allDeadMen = allDeadMen;
|
||||
private _allGroups = allGroups;
|
||||
private _vehicles = vehicles;
|
||||
private _allPlayers = call BIS_fnc_listPlayers;
|
||||
{
|
||||
private _thisSide = _x;
|
||||
private _thisSideStr = _thisSide call BIS_fnc_sideNameUnlocalized;
|
||||
// Number of remote units
|
||||
_hashesOut pushBack ([
|
||||
["bucket", "server_performance"],
|
||||
["measurement", "entities_remote"],
|
||||
["tags", GVARMAIN(standardTags)],
|
||||
["fields", [
|
||||
["units_alive", {
|
||||
side _x isEqualTo _thisSide &&
|
||||
not (local _x)
|
||||
} count _allUnits],
|
||||
["units_dead", {
|
||||
side _x isEqualTo _thisSide &&
|
||||
not (local _x)
|
||||
} count _allDeadMen],
|
||||
["groups_total", {
|
||||
side _x isEqualTo _thisSide &&
|
||||
not (local _x)
|
||||
} count _allGroups],
|
||||
["vehicles_total", {
|
||||
side _x isEqualTo _thisSide &&
|
||||
not (local _x) &&
|
||||
!(_x isKindOf "WeaponHolderSimulated")
|
||||
} count _vehicles],
|
||||
["vehicles_weaponholder", {
|
||||
side _x isEqualTo _thisSide &&
|
||||
not (local _x) &&
|
||||
(_x isKindOf "WeaponHolderSimulated")
|
||||
} count _vehicles]
|
||||
]]
|
||||
]);
|
||||
|
||||
// Number of local units
|
||||
_hashesOut pushBack ([
|
||||
["bucket", "server_performance"],
|
||||
["measurement", "entities_local"],
|
||||
["tags", GVARMAIN(standardTags)],
|
||||
["fields", [
|
||||
["units_alive", {
|
||||
side _x isEqualTo _thisSide &&
|
||||
local _x
|
||||
} count _allUnits],
|
||||
["units_dead", {
|
||||
side _x isEqualTo _thisSide &&
|
||||
local _x
|
||||
} count _allDeadMen],
|
||||
["groups_total", {
|
||||
side _x isEqualTo _thisSide &&
|
||||
local _x
|
||||
} count _allGroups],
|
||||
["vehicles_total", {
|
||||
side _x isEqualTo _thisSide &&
|
||||
local _x &&
|
||||
!(_x isKindOf "WeaponHolderSimulated")
|
||||
} count _vehicles],
|
||||
["vehicles_weaponholder", {
|
||||
side _x isEqualTo _thisSide &&
|
||||
local _x &&
|
||||
(_x isKindOf "WeaponHolderSimulated")
|
||||
} count _vehicles]
|
||||
]]
|
||||
]);
|
||||
|
||||
|
||||
// Number of global units - only track on server
|
||||
if (isServer) then {
|
||||
_hashesOut pushBack ([
|
||||
["bucket", "server_performance"],
|
||||
["measurement", "entities_global"],
|
||||
["tags", GVARMAIN(standardTags)],
|
||||
["fields", [
|
||||
["units_alive", {
|
||||
side _x isEqualTo _thisSide
|
||||
} count _allUnits],
|
||||
["units_dead", {
|
||||
side _x isEqualTo _thisSide
|
||||
} count _allDeadMen],
|
||||
["groups_total", {
|
||||
side _x isEqualTo _thisSide
|
||||
} count _allGroups],
|
||||
["vehicles_total", {
|
||||
side _x isEqualTo _thisSide &&
|
||||
!(_x isKindOf "WeaponHolderSimulated")
|
||||
} count _vehicles],
|
||||
["vehicles_weaponholder", {
|
||||
side _x isEqualTo _thisSide &&
|
||||
(_x isKindOf "WeaponHolderSimulated")
|
||||
} count _vehicles],
|
||||
["players_alive", {
|
||||
side _x isEqualTo _thisSide &&
|
||||
alive _x
|
||||
} count _allPlayers],
|
||||
["players_dead", {
|
||||
side _x isEqualTo _thisSide &&
|
||||
!alive _x
|
||||
} count _allPlayers]
|
||||
]]
|
||||
]);
|
||||
};
|
||||
} forEach [east, west, independent, civilian];
|
||||
|
||||
if (isServer) then {
|
||||
_hashesOut pushBack ([
|
||||
["bucket", "server_performance"],
|
||||
["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]
|
||||
]]
|
||||
]);
|
||||
};
|
||||
|
||||
_hashesOut;
|
||||
28
addons/capture/fnc_player_performance.sqf
Normal file
28
addons/capture/fnc_player_performance.sqf
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
private _hashesOut = [];
|
||||
{
|
||||
_x params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit"];
|
||||
_networkInfo params ["_avgPing", "_avgBandwidth", "_desync"];
|
||||
|
||||
if (_unit == objNull || _isHC) then {
|
||||
continue;
|
||||
};
|
||||
|
||||
_tags = +GVARMAIN(standardTags);
|
||||
_tags pushBack ["playerUID", _playerUID];
|
||||
_tags pushBack ["playerName", _profileName];
|
||||
|
||||
_hashesOut pushBack ([
|
||||
["bucket", "player_performance"],
|
||||
["measurement", "network"],
|
||||
["tags", _tags],
|
||||
["fields", [
|
||||
["avgPing", _avgPing],
|
||||
["avgBandwidth", _avgBandwidth],
|
||||
["desync", _desync]
|
||||
]]
|
||||
]);
|
||||
} forEach (allUsers apply {getUserInfo _x});
|
||||
|
||||
_hashesOut;
|
||||
23
addons/capture/fnc_running_mission.sqf
Normal file
23
addons/capture/fnc_running_mission.sqf
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
[
|
||||
["bucket", "mission_data"],
|
||||
["measurement", "loaded_info"],
|
||||
["tags", GVARMAIN(standardTags)],
|
||||
["fields", [
|
||||
["briefing_name", briefingName],
|
||||
["mission_name", missionName],
|
||||
["mission_name_source", missionNameSource],
|
||||
[
|
||||
"on_load_name",
|
||||
getMissionConfigValue ["onLoadName", "Unknown"]
|
||||
],
|
||||
["author", getMissionConfigValue ["author", "Unknown"]],
|
||||
["server_name", serverName],
|
||||
["playable_slots_west", playableSlotsNumber west],
|
||||
["playable_slots_east", playableSlotsNumber east],
|
||||
["playable_slots_guer", playableSlotsNumber independent],
|
||||
["playable_slots_civ", playableSlotsNumber civilian],
|
||||
["playable_slots_logic", playableSlotsNumber sideLogic]
|
||||
]]
|
||||
];
|
||||
18
addons/capture/fnc_running_scripts.sqf
Normal file
18
addons/capture/fnc_running_scripts.sqf
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
[
|
||||
["bucket", "server_performance"],
|
||||
["measurement", "running_scripts"],
|
||||
["tags", GVARMAIN(standardTags)],
|
||||
["fields", [
|
||||
["spawn", diag_activeScripts select 0],
|
||||
["execVM", diag_activeScripts select 1],
|
||||
["exec", diag_activeScripts select 2],
|
||||
["execFSM", diag_activeScripts select 3],
|
||||
["pfh",
|
||||
if (GVARMAIN(cbaLoaded)) then {
|
||||
count CBA_common_perFrameHandlerArray
|
||||
} else {0}
|
||||
]
|
||||
]]
|
||||
];
|
||||
11
addons/capture/fnc_server_performance.sqf
Normal file
11
addons/capture/fnc_server_performance.sqf
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
[
|
||||
["bucket", "server_performance"],
|
||||
["measurement", "fps"],
|
||||
["tags", GVARMAIN(standardTags)],
|
||||
["fields", [
|
||||
["fps_avg", diag_fps],
|
||||
["fps_min", diag_fpsMin]
|
||||
]]
|
||||
];
|
||||
13
addons/capture/fnc_server_time.sqf
Normal file
13
addons/capture/fnc_server_time.sqf
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
[
|
||||
["bucket", "mission_data"],
|
||||
["measurement", "server_time"],
|
||||
["tags", GVARMAIN(standardTags)],
|
||||
["fields", [
|
||||
["diag_tickTime", diag_tickTime],
|
||||
["serverTime", time],
|
||||
["timeMultiplier", timeMultiplier],
|
||||
["accTime", accTime]
|
||||
]]
|
||||
];
|
||||
21
addons/capture/fnc_weather.sqf
Normal file
21
addons/capture/fnc_weather.sqf
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
[
|
||||
["bucket", "mission_data"],
|
||||
["measurement", "weather"],
|
||||
["tags", GVARMAIN(standardTags)],
|
||||
["fields", [
|
||||
["fog", fog],
|
||||
["overcast", overcast],
|
||||
["rain", rain],
|
||||
["humidity", humidity],
|
||||
["waves", waves],
|
||||
["windDir", windDir],
|
||||
["windStr", windStr],
|
||||
["gusts", gusts],
|
||||
["lightnings", lightnings],
|
||||
["moonIntensity", moonIntensity],
|
||||
["moonPhase", moonPhase date],
|
||||
["sunOrMoon", sunOrMoon]
|
||||
]]
|
||||
];
|
||||
4
addons/capture/script_component.hpp
Normal file
4
addons/capture/script_component.hpp
Normal file
@@ -0,0 +1,4 @@
|
||||
#define COMPONENT capture
|
||||
#define COMPONENT_BEAUTIFIED Capture
|
||||
|
||||
#include "\x\ifxmetrics\addons\main\script_mod.hpp"
|
||||
1
addons/main/$PBOPREFIX$
Normal file
1
addons/main/$PBOPREFIX$
Normal file
@@ -0,0 +1 @@
|
||||
x\ifxmetrics\addons\main
|
||||
27
addons/main/config.cpp
Normal file
27
addons/main/config.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
units[] = {};
|
||||
weapons[] = {};
|
||||
requiredVersion = 2.10;
|
||||
requiredAddons[] = {};
|
||||
author[] = {"IndigoFox"};
|
||||
authorUrl = "https://github.com/indig0fox/IFXMetrics";
|
||||
};
|
||||
};
|
||||
|
||||
class CfgFunctions {
|
||||
class ADDON {
|
||||
class functions {
|
||||
class postInit {
|
||||
file = QPATHTOF(DOUBLES(fnc,postInit).sqf);
|
||||
postInit = 1;
|
||||
};
|
||||
PATHTO_FNC(callbackHandler);
|
||||
PATHTO_FNC(captureLoop);
|
||||
PATHTO_FNC(log);
|
||||
PATHTO_FNC(onExtLoad);
|
||||
};
|
||||
};
|
||||
};
|
||||
37
addons/main/fnc_callbackHandler.sqf
Normal file
37
addons/main/fnc_callbackHandler.sqf
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_name", "_function", "_data"];
|
||||
if !(_name == GVARMAIN(extensionName)) exitWith {};
|
||||
|
||||
// Validate data param
|
||||
if (isNil "_data") then {_data = ""};
|
||||
|
||||
if (_data isEqualTo "") exitWith {
|
||||
[
|
||||
"WARN",
|
||||
format ["Callback empty data: %1", _function]
|
||||
] call FUNC(log);
|
||||
false;
|
||||
};
|
||||
|
||||
private _dataArr = parseSimpleArray _data;
|
||||
if (
|
||||
(count _dataArr isEqualTo 0) &&
|
||||
(_function isNotEqualTo ":LOG:")
|
||||
) exitWith {
|
||||
[
|
||||
"WARN",
|
||||
format ["Callback invalid data for function %1: %2", _function, _data]
|
||||
] call FUNC(log);
|
||||
false;
|
||||
};
|
||||
|
||||
|
||||
switch (_function) do {
|
||||
case ":LOG:": {
|
||||
diag_log formatText ["[%1] %2", GVARMAIN(logPrefix), _dataArr#0];
|
||||
};
|
||||
default {
|
||||
["INFO", _data] call FUNC(log);
|
||||
};
|
||||
};
|
||||
65
addons/main/fnc_captureLoop.sqf
Normal file
65
addons/main/fnc_captureLoop.sqf
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
Parameters
|
||||
_function The function you wish to execute. <CODE>
|
||||
_delay The amount of time in seconds between executions, 0 for every frame. (optional, default: 0) <NUMBER>
|
||||
_args Parameters passed to the function executing. (optional) <ANY>
|
||||
_start Function that is executed when the PFH is added. (optional) <CODE>
|
||||
_end Function that is executed when the PFH is removed. (optional) <CODE>
|
||||
_runCondition Condition that has to return true for the PFH to be executed. (optional, default {true}) <CODE>
|
||||
_exitCondition Condition that has to return true to delete the PFH object. (optional, default {false}) <CODE>
|
||||
_private List of local variables that are serialized between executions. (optional) <CODE>
|
||||
*/
|
||||
GVARMAIN(captureLoop) = [
|
||||
{
|
||||
private _startTime = diag_tickTime;
|
||||
|
||||
GVARMAIN(extensionName) callExtension [
|
||||
":INFLUX:WRITE:",
|
||||
[
|
||||
call EFUNC(capture,server_performance),
|
||||
call EFUNC(capture,running_scripts),
|
||||
call EFUNC(capture,server_time),
|
||||
call EFUNC(capture,weather)
|
||||
]
|
||||
];
|
||||
|
||||
// entity_count returns an array of hashMap
|
||||
{
|
||||
GVARMAIN(extensionName) callExtension [
|
||||
":INFLUX:WRITE:",
|
||||
[_x]
|
||||
];
|
||||
} forEach (call EFUNC(capture,entity_count));
|
||||
{
|
||||
GVARMAIN(extensionName) callExtension [
|
||||
":INFLUX:WRITE:",
|
||||
[_x]
|
||||
];
|
||||
} forEach (call EFUNC(capture,player_performance));
|
||||
|
||||
["DEBUG", format[
|
||||
"Processed primary data loop in %1 ms",
|
||||
(diag_tickTime - _startTime) * 1000
|
||||
]] call FUNC(log);
|
||||
},
|
||||
(GVARMAIN(refreshRateMs) / 1000), // delay in seconds,
|
||||
[], // args
|
||||
{
|
||||
// start
|
||||
["DEBUG", "Starting server performance capture"] call FUNC(log);
|
||||
},
|
||||
{
|
||||
// end
|
||||
["DEBUG", "Stopping server performance capture"] call FUNC(log);
|
||||
},
|
||||
{
|
||||
// runCondition
|
||||
true
|
||||
},
|
||||
{
|
||||
// exitCondition
|
||||
false
|
||||
},
|
||||
[] // private
|
||||
] call CBA_fnc_createPerFrameHandlerObject;
|
||||
27
addons/main/fnc_log.sqf
Normal file
27
addons/main/fnc_log.sqf
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
if (!isServer) exitWith {};
|
||||
|
||||
if (typeName _this != "ARRAY") exitWith {
|
||||
diag_log format ["[%1]: Invalid log params: %2", GVARMAIN(logPrefix), _this];
|
||||
};
|
||||
|
||||
params [
|
||||
["_level", "INFO", [""]],
|
||||
["_text", "", [""]]
|
||||
];
|
||||
|
||||
if (
|
||||
_level == "DEBUG" &&
|
||||
!GVARMAIN(debug)
|
||||
) exitWith {};
|
||||
|
||||
if (_text isEqualTo "") exitWith {};
|
||||
|
||||
diag_log formatText [
|
||||
"[%1] %2: %3",
|
||||
GVARMAIN(logPrefix),
|
||||
_level,
|
||||
_text
|
||||
];
|
||||
|
||||
121
addons/main/fnc_onExtLoad.sqf
Normal file
121
addons/main/fnc_onExtLoad.sqf
Normal file
@@ -0,0 +1,121 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
// wait until READY
|
||||
waitUntil {
|
||||
sleep 2;
|
||||
(GVARMAIN(extensionName) callExtension ":READY:") isEqualTo "true";
|
||||
};
|
||||
|
||||
// load settings from extension
|
||||
private _settings = GVARMAIN(extensionName) callExtension ":SETTINGS:";
|
||||
if (isNil "_settings") exitWith {
|
||||
diag_log formatText[
|
||||
"[%1] (ERROR): IFXMetrics extension settings not loaded. IFXMetrics will not be available.",
|
||||
GVARMAIN(logPrefix)
|
||||
];
|
||||
};
|
||||
|
||||
_settingsArr = parseSimpleArray _settings;
|
||||
GVARMAIN(enabled) = _settingsArr select 0;
|
||||
GVARMAIN(debug) = _settingsArr select 1;
|
||||
GVARMAIN(refreshRateMs) = _settingsArr select 2;
|
||||
|
||||
if (!GVARMAIN(enabled)) exitWith {
|
||||
diag_log formatText[
|
||||
"[%1] (WARN): IFXMetrics config entry influxdb.enabled is false. IFXMetrics will not be available.",
|
||||
GVARMAIN(logPrefix)
|
||||
];
|
||||
};
|
||||
|
||||
// get custom CBA handlers
|
||||
private _handlersFromExtension = GVARMAIN(extensionName) callExtension ":CUSTOM:CBA:EVENTS:";
|
||||
|
||||
_handlersFromExtension = parseSimpleArray _handlersFromExtension;
|
||||
if (count _handlersFromExtension isEqualTo 0) then {
|
||||
diag_log formatText[
|
||||
"[%1] (WARN): IFXMetrics custom CBA handlers failed to parse. Custom events will not be logged.",
|
||||
GVARMAIN(logPrefix)
|
||||
];
|
||||
} else {
|
||||
diag_log formatText[
|
||||
"[%1] (INFO): IFXMetrics custom CBA handlers loaded: %2",
|
||||
GVARMAIN(logPrefix),
|
||||
_handlersFromExtension
|
||||
];
|
||||
|
||||
// data is a keyed HashMap
|
||||
GVARMAIN(cbaHandlers) = createHashMapFromArray _handlersFromExtension;
|
||||
};
|
||||
|
||||
|
||||
GVARMAIN(standardTags) = [
|
||||
["profile", profileName],
|
||||
["world", worldName],
|
||||
["server", serverName]
|
||||
];
|
||||
|
||||
|
||||
|
||||
// Connect to InfluxDB
|
||||
GVARMAIN(extensionName) callExtension ":INFLUX:CONNECT:";
|
||||
waitUntil {
|
||||
sleep 2;
|
||||
(GVARMAIN(extensionName) callExtension ":INFLUX:CONNECTED:") isEqualTo "true";
|
||||
};
|
||||
|
||||
|
||||
// Send initial mission info
|
||||
GVARMAIN(extensionName) callExtension [
|
||||
":INFLUX:WRITE:",
|
||||
[(call EFUNC(capture,running_mission))]
|
||||
];
|
||||
|
||||
|
||||
// Set up CBA event listeners
|
||||
/* example usage:
|
||||
["milsimServerEfficiency", [
|
||||
["tags", [ // tags must be string values!
|
||||
["missionPhase", "init"]
|
||||
]],
|
||||
["fields", [ // fields can be any type
|
||||
["value", 0.5]
|
||||
["numberOfShinyObjects", 3]
|
||||
]]
|
||||
]] call CBA_fnc_serverEvent;
|
||||
*/
|
||||
{
|
||||
_key = _x;
|
||||
_hash = _y;
|
||||
[
|
||||
_hash get "eventName", // event name
|
||||
{ // function
|
||||
_thisArgs params [
|
||||
"_enabled",
|
||||
"_bucket",
|
||||
"_measurement",
|
||||
"_description"
|
||||
];
|
||||
private _data = [
|
||||
["bucket", _bucket],
|
||||
["measurement", _measurement],
|
||||
["tags", GVARMAIN(standardTags)],
|
||||
["fields", _this]
|
||||
];
|
||||
|
||||
GVARMAIN(extensionName) callExtension [
|
||||
":INFLUX:WRITE:",
|
||||
[_data]
|
||||
];
|
||||
},
|
||||
[ // args
|
||||
_hash get "enabled",
|
||||
_hash get "bucket",
|
||||
_hash get "measurement",
|
||||
_hash get "description"
|
||||
]
|
||||
] call CBA_fnc_addEventHandlerArgs;
|
||||
} forEach GVARMAIN(cbaHandlers);
|
||||
|
||||
|
||||
// wait five seconds, then start the loop
|
||||
[{call FUNC(captureLoop);}, 5] call CBA_fnc_waitAndExecute;
|
||||
159
addons/main/fnc_postInit.sqf
Normal file
159
addons/main/fnc_postInit.sqf
Normal file
@@ -0,0 +1,159 @@
|
||||
#include "script_component.hpp"
|
||||
// if (!isServer) exitWith {};
|
||||
|
||||
if (is3DEN || !isMultiplayer) exitWith {};
|
||||
if (!isServer && hasInterface) exitWith {};
|
||||
|
||||
|
||||
GVARMAIN(cbaLoaded) = isClass(configFile >> "CfgPatches" >> "cba_main");
|
||||
GVARMAIN(logPrefix) = QUOTE(PREFIX_BEAUTIFIED);
|
||||
GVARMAIN(extensionName) = QUOTE(PREFIX);
|
||||
|
||||
|
||||
// Create listener for async callbacks
|
||||
addMissionEventHandler [
|
||||
"ExtensionCallback",
|
||||
FUNC(callbackHandler)
|
||||
];
|
||||
|
||||
// start loading the extension
|
||||
[(parseSimpleArray (GVARMAIN(extensionName) callExtension ":START:")) select 0] remoteExec ["systemChat", 0];
|
||||
|
||||
// load settings from extension
|
||||
private _settings = GVARMAIN(extensionName) callExtension ":SETTINGS:";
|
||||
if (isNil "_settings") exitWith {
|
||||
diag_log formatText[
|
||||
"[%1] (ERROR): IFXMetrics extension settings not loaded. IFXMetrics will not be available.",
|
||||
GVARMAIN(logPrefix)
|
||||
];
|
||||
};
|
||||
|
||||
_settingsArr = parseSimpleArray _settings;
|
||||
GVARMAIN(enabled) = _settingsArr select 0;
|
||||
GVARMAIN(debug) = _settingsArr select 1;
|
||||
GVARMAIN(refreshRateMs) = _settingsArr select 2;
|
||||
|
||||
if (!GVARMAIN(enabled)) exitWith {
|
||||
diag_log formatText[
|
||||
"[%1] (WARN): IFXMetrics config entry influxdb.enabled is false. IFXMetrics will not be available.",
|
||||
GVARMAIN(logPrefix)
|
||||
];
|
||||
};
|
||||
|
||||
// get custom CBA handlers
|
||||
private _handlersFromExtension = GVARMAIN(extensionName) callExtension ":CUSTOM:CBA:EVENTS:";
|
||||
|
||||
_handlersFromExtension = parseSimpleArray _handlersFromExtension;
|
||||
if (count _handlersFromExtension isEqualTo 0) then {
|
||||
diag_log formatText[
|
||||
"[%1] (WARN): IFXMetrics custom CBA handlers failed to parse. Custom events will not be logged.",
|
||||
GVARMAIN(logPrefix)
|
||||
];
|
||||
} else {
|
||||
diag_log formatText[
|
||||
"[%1] (INFO): IFXMetrics custom CBA handlers loaded: %2",
|
||||
GVARMAIN(logPrefix),
|
||||
_handlersFromExtension
|
||||
];
|
||||
|
||||
// data is a keyed HashMap
|
||||
GVARMAIN(cbaHandlers) = createHashMapFromArray _handlersFromExtension;
|
||||
};
|
||||
|
||||
|
||||
GVARMAIN(standardTags) = [
|
||||
["profile", profileName],
|
||||
["world", worldName],
|
||||
["server", serverName]
|
||||
];
|
||||
|
||||
|
||||
|
||||
// Connect to InfluxDB
|
||||
private _connectResult = parseSimpleArray (GVARMAIN(extensionName) callExtension ":INFLUX:CONNECT:");
|
||||
if (count _connectResult isEqualTo 0) exitWith {
|
||||
diag_log formatText[
|
||||
"[%1] (ERROR): IFXMetrics failed to connect to InfluxDB. IFXMetrics will not be available.",
|
||||
GVARMAIN(logPrefix)
|
||||
];
|
||||
};
|
||||
if (_connectResult select 0 isNotEqualTo "OK") exitWith {
|
||||
diag_log formatText[
|
||||
"[%1] (ERROR): IFXMetrics failed to connect to InfluxDB. IFXMetrics will not be available.",
|
||||
GVARMAIN(logPrefix)
|
||||
];
|
||||
};
|
||||
[format ["%1", (_connectResult select 1)]] remoteExec ["systemChat", 0];
|
||||
|
||||
|
||||
// Send initial mission info
|
||||
[
|
||||
"DEBUG",
|
||||
str (call EFUNC(capture,running_mission))
|
||||
] call FUNC(log);
|
||||
|
||||
GVARMAIN(extensionName) callExtension [
|
||||
":INFLUX:WRITE:",
|
||||
[(call EFUNC(capture,running_mission))]
|
||||
];
|
||||
|
||||
|
||||
// Set up CBA event listeners
|
||||
/* example usage:
|
||||
["milsimServerEfficiency", [
|
||||
[ // tags in hash format. must be string values!
|
||||
["missionPhase", "init"]
|
||||
],
|
||||
[ // fields in hash format. can be any type
|
||||
["value", 0.5]
|
||||
["numberOfShinyObjects", 3]
|
||||
]
|
||||
]] call CBA_fnc_serverEvent;
|
||||
*/
|
||||
{
|
||||
_key = _x;
|
||||
_hash = createHashMapFromArray _y;
|
||||
[
|
||||
_hash get "eventName", // event name
|
||||
{ // function
|
||||
|
||||
if (count _this isNotEqualTo 2) exitWith {
|
||||
diag_log formatText[
|
||||
"[%1] (ERROR): IFXMetrics CBA handler %2 received invalid number of arguments. Expected 2, got %3.",
|
||||
GVARMAIN(logPrefix),
|
||||
_thisType,
|
||||
count _this
|
||||
];
|
||||
};
|
||||
|
||||
_thisArgs params [
|
||||
"_enabled",
|
||||
"_bucket",
|
||||
"_measurement",
|
||||
"_description"
|
||||
];
|
||||
private _data = [
|
||||
["bucket", _bucket],
|
||||
["measurement", _measurement],
|
||||
["tags", _this#0],
|
||||
["fields", _this#1]
|
||||
];
|
||||
|
||||
GVARMAIN(extensionName) callExtension [
|
||||
":INFLUX:WRITE:",
|
||||
[_data]
|
||||
];
|
||||
},
|
||||
[ // args
|
||||
_key,
|
||||
_hash get "enabled",
|
||||
_hash get "bucket",
|
||||
_hash get "measurement",
|
||||
_hash get "description"
|
||||
]
|
||||
] call CBA_fnc_addEventHandlerArgs;
|
||||
} forEach GVARMAIN(cbaHandlers);
|
||||
|
||||
|
||||
// wait five seconds, then start the loop
|
||||
call FUNC(captureLoop);
|
||||
4
addons/main/script_component.hpp
Normal file
4
addons/main/script_component.hpp
Normal file
@@ -0,0 +1,4 @@
|
||||
#define COMPONENT main
|
||||
#define COMPONENT_BEAUTIFIED Main
|
||||
|
||||
#include "\x\ifxmetrics\addons\main\script_mod.hpp"
|
||||
8
addons/main/script_mod.hpp
Normal file
8
addons/main/script_mod.hpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "script_version.hpp"
|
||||
|
||||
#define MAINPREFIX x
|
||||
#define PREFIX ifxmetrics
|
||||
#define PREFIX_BEAUTIFIED IFXMetrics
|
||||
#define SUBPREFIX addons
|
||||
|
||||
#include "\x\cba\addons\main\script_macros_common.hpp"
|
||||
8
addons/main/script_version.hpp
Normal file
8
addons/main/script_version.hpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#define MAJOR 2
|
||||
#define MINOR 0
|
||||
#define PATCH 0
|
||||
#define BUILD 20231009
|
||||
|
||||
#define VERSION 2.0
|
||||
#define VERSION_STR MAJOR##.##MINOR##.##PATCH##.##BUILD
|
||||
#define VERSION_AR MAJOR,MINOR,PATCH,BUILD
|
||||
Reference in New Issue
Block a user