FactorioSharp.Instrumentation 0.3.6

dotnet add package FactorioSharp.Instrumentation --version 0.3.6                
NuGet\Install-Package FactorioSharp.Instrumentation -Version 0.3.6                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FactorioSharp.Instrumentation" Version="0.3.6" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add FactorioSharp.Instrumentation --version 0.3.6                
#r "nuget: FactorioSharp.Instrumentation, 0.3.6"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install FactorioSharp.Instrumentation as a Cake Addin
#addin nuget:?package=FactorioSharp.Instrumentation&version=0.3.6

// Install FactorioSharp.Instrumentation as a Cake Tool
#tool nuget:?package=FactorioSharp.Instrumentation&version=0.3.6                

FactorioSharp.Instrumentation

Collect data from a Factorio server through an RCON connection and define emit them as metrics.

In order to keep the number of requests per second manageable, the collection of data from the server is rate-limited: in addition to specifying refresh rates on the different quantities that are measured, there is a master rate-limit that restricts the number of requests per second performed on the server.
The orchestration is performed by a background service that must be added to the host application.

Note: Emitting traces for the commands that are executed on the RCON is a WIP.

Getting started

The RCON interface must be enabled when running factorio. It must also be secured using a password. Add the following parameters to the factorio launch command: --rcon-port 27015 --rcon-password factory

For example

bin\x64\factorio.exe --start-server saves/save.zip --rcon-port 27015 --rcon-password password

You should see a log message in the factorio console that looks like:

Info RemoteCommandProcessor.cpp:133: Starting RCON interface at IP ADDR:({0.0.0.0:27015})

The instrumentation can then be configured using the provided extension methods

Using the console exporter

The program above should write all the metrics to the console. There are way too many metrics for it to be readable, but making this work ensures that the connection between factorio and the application works as expected.

using FactorioSharp.Instrumentation.Meters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;

const string serviceName = "Factorio";
const string serviceVersion = "1.1.104";

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Services.AddOpenTelemetry()
    .WithMetrics(
        metrics => metrics.ConfigureResource(resource => resource.AddService(serviceName, serviceVersion))
            .AddFactorioInstrumentation(
                options =>
                {
                    options.Server.Uri = new Uri("http://localhost:27015");
                    options.Server.RconPassword = "password";
                }
            )
            .AddConsoleExporter()
    );

IHost app = builder.Build();

app.Run();

Using the Prometheus listener

This library uses the standard System.Diagnostics tools to expose the collected data and it registers them with the OpenTelemetry SDK. It can be used with any OpenTelemetry exporter including the Prometheus one.

See also this documentation from Microsoft about metrics collection using Prometheus and Grafana.

Expose the metrics using the Prometheus HTTP listener

Install the OpenTelemetry.Exporter.Prometheus.HttpListener nuget which provides the AddPrometheusHttpListener extension method, then use it to expose the collected metrics on http://localhost:9184.

using FactorioSharp.Instrumentation.Meters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;

const string serviceName = "Factorio";
const string serviceVersion = "1.1.104";

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Services.AddOpenTelemetry()
    .WithMetrics(
        metrics => metrics.ConfigureResource(resource => resource.AddService(serviceName, serviceVersion))
            .AddFactorioInstrumentation(
                options =>
                {
                    options.Server.Uri = new Uri("http://localhost:27015");
                    options.Server.RconPassword = "password";
                }
            )
            .AddPrometheusHttpListener(options => options.UriPrefixes = ["http://localhost:9184/"])
    );

IHost app = builder.Build();

app.Run();
Prometheus
  • Install prometheus.
  • Setup the collector to read from the endpoint at localhost:9184. See below for a minimal config.yml.
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'factorio-otlp'
    scrape_interval: 1s
    static_configs:
      - targets: ['localhost:9184']

Prometheus targets showing the connection to http://localhost:9185

Display the factorio_server_status signal to make sure that it works as expected

Prometheus graph showing the factorio_server_status signal

The timeseries exposed by prometheus can then be used to build dashboards.

Example of Grafana dashboard in an early game:

Grafana dashboard displaying the amount of iron (ore and plate) and copper (ore and plate) that the player has available

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.3.6 117 4/14/2024
0.3.5 105 4/7/2024
0.3.4 105 4/7/2024
0.3.3 120 4/7/2024
0.3.2 123 4/7/2024
0.3.1 111 4/7/2024
0.3.0 115 4/7/2024
0.2.14 136 4/6/2024
0.2.13 120 4/6/2024
0.2.12 138 4/6/2024
0.2.11 114 4/6/2024
0.2.10 124 4/3/2024
0.2.9 123 4/2/2024
0.2.8 110 4/1/2024
0.2.6 109 4/1/2024
0.2.5 107 4/1/2024
0.2.4 124 4/1/2024
0.2.3 115 4/1/2024
0.2.2 108 3/31/2024
0.2.1 118 3/30/2024
0.2.0 105 3/30/2024
0.1.0 112 3/30/2024