From 7934e471a7ca736bcd46536952984d803b790041 Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Mon, 2 Dec 2024 20:27:59 +0000 Subject: [PATCH] Provide production statistics for all surfaces --- plugins/statistics_exporter/instance.ts | 74 +++++++++++++------ plugins/statistics_exporter/module/export.lua | 47 ++++++------ 2 files changed, 78 insertions(+), 43 deletions(-) diff --git a/plugins/statistics_exporter/instance.ts b/plugins/statistics_exporter/instance.ts index b824992d..e09e131c 100644 --- a/plugins/statistics_exporter/instance.ts +++ b/plugins/statistics_exporter/instance.ts @@ -6,14 +6,18 @@ const { Gauge } = lib; type IpcStats = { game_tick: number, player_count: number, - game_flow_statistics: { - pollution_statistics: IpcFlowType, - }, - force_flow_statistics: { - [key:string]: { - [key:string]: IpcFlowType, + surface_statistics: { + [key: string]: { + game_flow_statistics: { + pollution_statistics: IpcFlowType, + }, + force_flow_statistics: { + [key:string]: { + [key:string]: IpcFlowType, + } + }, } - }, + } } type IpcFlowType = { @@ -34,29 +38,44 @@ const instanceGameTicksTotal = new Gauge( const instanceForceFlowStatistics = new Gauge( "clusterio_statistics_exporter_instance_force_flow_statistics", "Items/fluids/enemies/buildings produced/built/killed by a force", - { labels: ["instance_id", "force", "statistic", "direction", "name"] }, + { labels: ["instance_id", "surface", "force", "statistic", "direction", "name"] }, ); const instanceGameFlowStatistics = new Gauge( "clusterio_statistics_exporter_instance_game_flow_statistics", "Pollution produced/consumed in the game", - { labels: ["instance_id", "statistic", "direction", "name"] }, + { labels: ["instance_id", "surface", "statistic", "direction", "name"] }, ); function setForceFlowStatistic( instanceId: number, + surfaceName: string, forceName: string, statisticName: string, direction: string, item: string, value: number, ) { - instanceForceFlowStatistics.labels(String(instanceId), forceName, statisticName, direction, item).set(value); + instanceForceFlowStatistics.labels( + String(instanceId), + surfaceName, + forceName, + statisticName, + direction, + item + ).set(value); // For item and fluid statistics it's useful to compare the input flow with the // output flow, to simplify the comparison ensure both directions have a value. if (["item_production_statistics", "fluid_production_statistic"].includes(statisticName)) { let reverseDirection = direction === "input" ? "output" : "input"; - instanceForceFlowStatistics.labels(String(instanceId), forceName, statisticName, reverseDirection, item); + instanceForceFlowStatistics.labels( + String(instanceId), + surfaceName, + forceName, + statisticName, + reverseDirection, + item + ).set(value); } } @@ -84,21 +103,32 @@ export class InstancePlugin extends BaseInstancePlugin { instanceGameTicksTotal.labels(String(instanceId)).set(stats.game_tick); instancePlayerCount.labels(String(instanceId)).set(stats.player_count); - for (let [forceName, flowStatistics] of Object.entries(stats.force_flow_statistics)) { - for (let [statisticName, statistic] of Object.entries(flowStatistics)) { - for (let [direction, counts] of Object.entries(statistic)) { - for (let [item, value] of Object.entries(counts)) { - setForceFlowStatistic(instanceId, forceName, statisticName, direction, item, value); + for (let [surfaceName, surfaceStats] of Object.entries(stats.surface_statistics)) { + for (let [forceName, flowStatistics] of Object.entries(surfaceStats.force_flow_statistics)) { + for (let [statisticName, statistic] of Object.entries(flowStatistics)) { + for (let [direction, counts] of Object.entries(statistic)) { + // eslint-disable-next-line max-depth + for (let [item, value] of Object.entries(counts)) { + setForceFlowStatistic( + instanceId, + surfaceName, + forceName, + statisticName, + direction, + item, + value + ); + } } } } - } - for (let [direction, counts] of Object.entries(stats.game_flow_statistics.pollution_statistics)) { - for (let [item, value] of Object.entries(counts)) { - instanceGameFlowStatistics.labels( - String(instanceId), "pollution_statistics", direction, item - ).set(value); + for (let [direction, counts] of Object.entries(surfaceStats.game_flow_statistics.pollution_statistics)) { + for (let [item, value] of Object.entries(counts)) { + instanceGameFlowStatistics.labels( + String(instanceId), surfaceName, "pollution_statistics", direction, item + ).set(value); + } } } } diff --git a/plugins/statistics_exporter/module/export.lua b/plugins/statistics_exporter/module/export.lua index 8537d0f8..f98c7f21 100644 --- a/plugins/statistics_exporter/module/export.lua +++ b/plugins/statistics_exporter/module/export.lua @@ -11,32 +11,37 @@ local statistics = { statistics_exporter = {} function statistics_exporter.export() - --- @diagnostic disable-next-line undefined-field - local pollution = v2_stats and game.get_pollution_statistics(1) or game.pollution_statistics local stats = { game_tick = game.tick, player_count = #game.connected_players, - game_flow_statistics = { - pollution_statistics = { - --- TODO support multi surface pollution statistics - input = pollution.input_counts, - output = pollution.output_counts, - }, - }, - force_flow_statistics = {} + surface_statistics = {} } - for _, force in pairs(game.forces) do - local flow_statistics = {} - for _, statName in pairs(statistics) do - local stat = v2_stats and force["get_" .. statName](1) or force[statName] - flow_statistics[statName] = { - input = stat.input_counts, - output = stat.output_counts, - } - end - stats.force_flow_statistics[force.name] = flow_statistics - end + for _, surface in pairs(game.surfaces) do + local surface_stats = { + game_flow_statistics = { + pollution_statistics = { + input = (v2_stats and game.get_pollution_statistics(surface.index) or surface.pollution_statistics).input_counts, + output = (v2_stats and game.get_pollution_statistics(surface.index) or surface.pollution_statistics).output_counts, + }, + }, + force_flow_statistics = {} + } + + for _, force in pairs(game.forces) do + local flow_statistics = {} + for _, statName in pairs(statistics) do + local stat = v2_stats and force["get_" .. statName](surface.index) or force[statName] + flow_statistics[statName] = { + input = stat.input_counts, + output = stat.output_counts, + } + end + surface_stats.force_flow_statistics[force.name] = flow_statistics + end + + stats.surface_statistics[surface.name] = surface_stats + end rcon.print(compat.table_to_json(stats)) end