feat(prometheus-exporter): add metrics-pole for power metrics
This commit is contained in:
@@ -1,83 +1,55 @@
|
||||
-- Config
|
||||
local steps_per_tick = 1 -- process 1 surface×force per tick
|
||||
local flush_interval_ticks = 60 * 15 -- flush every n ticks
|
||||
local metrics = require("utils.metrics")
|
||||
|
||||
-- State
|
||||
-- config
|
||||
local flush_interval_ticks = 60 -- flush every n ticks
|
||||
|
||||
-- state
|
||||
--- @type table<number, fun()>
|
||||
local queue = {}
|
||||
local buffer = {}
|
||||
local last_flush_tick = 0
|
||||
|
||||
-- Initialize queue with all surface×force pairs
|
||||
--- @type table<number, string>
|
||||
local buffer = {}
|
||||
local last_reset = 0
|
||||
|
||||
-- queue operations to perform for each round of metric processing
|
||||
-- that way, avoid doing too much work in a single game tick and causing UPS inconsistencies
|
||||
local function prepare_queue()
|
||||
queue = {}
|
||||
for surface_name, _ in pairs(game.surfaces) do
|
||||
for force_name, _ in pairs(game.forces) do
|
||||
table.insert(queue, {surface_name = surface_name, force_name = force_name})
|
||||
for _, surface in pairs(game.surfaces) do
|
||||
for _, force in pairs(game.forces) do
|
||||
table.insert(queue, metrics.calc_item_production_statistics(buffer, surface, force))
|
||||
table.insert(queue, metrics.calc_fluid_production_statistics(buffer, surface, force))
|
||||
end
|
||||
table.insert(queue, metrics.calc_power_statistics(buffer, surface))
|
||||
end
|
||||
end
|
||||
|
||||
-- Process a few items from the queue each tick
|
||||
local function process_queue()
|
||||
for i = 1, steps_per_tick do
|
||||
local entry = table.remove(queue, 1)
|
||||
if not entry then break end
|
||||
|
||||
local surface_name, force_name = entry.surface_name, entry.force_name
|
||||
local force = game.forces[force_name]
|
||||
|
||||
-- Items
|
||||
local item_stats = force.get_item_production_statistics(surface_name)
|
||||
for item, count in pairs(item_stats.input_counts) do
|
||||
table.insert(buffer, string.format(
|
||||
"factorio_production_total{type=\"item\",surface=\"%s\",force=\"%s\",name=\"%s\"} %d",
|
||||
surface_name, force_name, item, count
|
||||
))
|
||||
end
|
||||
for item, count in pairs(item_stats.output_counts) do
|
||||
table.insert(buffer, string.format(
|
||||
"factorio_consumption_total{type=\"item\",surface=\"%s\",force=\"%s\",name=\"%s\"} %d",
|
||||
surface_name, force_name, item, count
|
||||
))
|
||||
end
|
||||
|
||||
-- Fluids
|
||||
local fluid_stats = force.get_fluid_production_statistics(surface_name)
|
||||
for fluid, count in pairs(fluid_stats.input_counts) do
|
||||
table.insert(buffer, string.format(
|
||||
"factorio_production_total{type=\"fluid\",surface=\"%s\",force=\"%s\",name=\"%s\"} %d",
|
||||
surface_name, force_name, fluid, count
|
||||
))
|
||||
end
|
||||
for fluid, count in pairs(fluid_stats.output_counts) do
|
||||
table.insert(buffer, string.format(
|
||||
"factorio_consumption_total{type=\"fluid\",surface=\"%s\",force=\"%s\",name=\"%s\"} %d",
|
||||
surface_name, force_name, fluid, count
|
||||
))
|
||||
end
|
||||
local entry = table.remove(queue, 1)
|
||||
if entry then
|
||||
entry()
|
||||
end
|
||||
end
|
||||
|
||||
-- Flush buffer to file periodically
|
||||
local function maybe_flush()
|
||||
if #queue == 0 and game.tick - last_flush_tick >= flush_interval_ticks then
|
||||
if #buffer > 0 then
|
||||
helpers.write_file("metrics.prom", table.concat(buffer, "\n"), false)
|
||||
buffer = {}
|
||||
end
|
||||
last_flush_tick = game.tick
|
||||
prepare_queue()
|
||||
end
|
||||
end
|
||||
|
||||
-- Main tick handler
|
||||
script.on_event(defines.events.on_tick, function()
|
||||
local function tick()
|
||||
process_queue()
|
||||
maybe_flush()
|
||||
end)
|
||||
|
||||
-- Bootstrap
|
||||
if #queue == 0 and #buffer > 0 then
|
||||
helpers.write_file("metrics.prom", table.concat(buffer, "\n"), false)
|
||||
buffer = {}
|
||||
end
|
||||
|
||||
if #queue == 0 and game.tick - last_reset >= flush_interval_ticks then
|
||||
prepare_queue()
|
||||
last_reset = game.tick
|
||||
end
|
||||
end
|
||||
|
||||
-- main tick handler
|
||||
script.on_event(defines.events.on_tick, tick)
|
||||
|
||||
-- startup
|
||||
script.on_init(function()
|
||||
last_flush_tick = game.tick
|
||||
last_reset = game.tick
|
||||
prepare_queue()
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user