-- Config local steps_per_tick = 1 -- process 1 surfaceƗforce per tick local flush_interval_ticks = 60 * 15 -- flush every n ticks -- State local queue = {} local buffer = {} local last_flush_tick = 0 -- Initialize queue with all surfaceƗforce pairs 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}) end 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( "production{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( "consumption{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( "production{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( "consumption{type=\"fluid\",surface=\"%s\",force=\"%s\",name=\"%s\"} %d", surface_name, force_name, fluid, count )) end 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() process_queue() maybe_flush() end) -- Bootstrap script.on_init(function() last_flush_tick = game.tick prepare_queue() end)