Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "encoding/json"
- "flag"
- "fmt"
- "io/ioutil"
- "net/http"
- "path/filepath"
- "strconv"
- "strings"
- "time"
- "github.com/prometheus/client_golang/prometheus"
- )
- func prepareName(name string) string {
- return fmt.Sprintf("factorio_%s", name)
- }
- func main() {
- addr := flag.String("listen", ":9000", "The address to listen on for HTTP requests.")
- dir := flag.String("dir", "/script-output", "Path to Factorio \"script-output\" directory")
- flag.Parse()
- defLabels := []string{"force", "name"}
- gaugeTick := prometheus.NewGauge(prometheus.GaugeOpts{
- Name: prepareName("tick"),
- Help: "game tick",
- })
- prometheus.MustRegister(gaugeTick)
- gaugeItemProductionInput := prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Name: prepareName("item_production_input"),
- Help: "items produced",
- },
- defLabels,
- )
- prometheus.MustRegister(gaugeItemProductionInput)
- gaugeItemProductionOutput := prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Name: prepareName("item_production_output"),
- Help: "items consumed",
- },
- defLabels,
- )
- prometheus.MustRegister(gaugeItemProductionOutput)
- gaugeFluidProductionInput := prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Name: prepareName("fluid_production_input"),
- Help: "fluids produced",
- },
- defLabels,
- )
- prometheus.MustRegister(gaugeFluidProductionInput)
- gaugeFluidProductionOutput := prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Name: prepareName("fluid_production_output"),
- Help: "fluids consumed",
- },
- defLabels,
- )
- prometheus.MustRegister(gaugeFluidProductionOutput)
- gaugeKillCountInput := prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Name: prepareName("kill_count_input"),
- Help: "kills",
- },
- defLabels,
- )
- prometheus.MustRegister(gaugeKillCountInput)
- gaugeKillCountOutput := prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Name: prepareName("kill_count_output"),
- Help: "losses",
- },
- defLabels,
- )
- prometheus.MustRegister(gaugeKillCountOutput)
- gaugeEntityBuildCountInput := prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Name: prepareName("entity_build_count_input"),
- Help: "entities placed",
- },
- defLabels,
- )
- prometheus.MustRegister(gaugeEntityBuildCountInput)
- gaugeEntityBuildCountOutput := prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Name: prepareName("entity_build_count_output"),
- Help: "entities removed",
- },
- defLabels,
- )
- prometheus.MustRegister(gaugeEntityBuildCountOutput)
- gaugeItemsLaunched := prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Name: prepareName("items_launched_total"),
- Help: "items launched in rockets",
- },
- defLabels,
- )
- prometheus.MustRegister(gaugeItemsLaunched)
- gaugePollutionInput := prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Name: prepareName("pollution_input"),
- Help: "pollution produced",
- },
- []string{"name"},
- )
- prometheus.MustRegister(gaugePollutionInput)
- gaugePollutionOutput := prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Name: prepareName("pollution_output"),
- Help: "pollution consumed",
- },
- []string{"name"},
- )
- prometheus.MustRegister(gaugePollutionOutput)
- fPath := filepath.Join(*dir, "fmetrics.stat")
- go func() {
- expire := time.Duration(1 * time.Second)
- for {
- var data []byte
- data, err := ioutil.ReadFile(fPath)
- if err != nil {
- fmt.Printf("Reading error: %s\n", err)
- } else {
- parts := strings.Split(string(data), "\n")
- for _, str := range parts {
- if str != "" {
- ss := strings.Split(str, "=")
- jData := make(map[string]float64)
- switch ss[0] {
- case "tick":
- f, _ := strconv.ParseFloat(ss[1], 64)
- gaugeTick.Set(f)
- case "pollution_in":
- err := json.Unmarshal([]byte(ss[1]), &jData)
- if err == nil {
- for k, v := range jData {
- gaugePollutionInput.WithLabelValues(k).Set(v)
- }
- }
- case "pollution_out":
- err := json.Unmarshal([]byte(ss[1]), &jData)
- if err == nil {
- for k, v := range jData {
- gaugePollutionOutput.WithLabelValues(k).Set(v)
- }
- }
- default:
- err := json.Unmarshal([]byte(ss[1]), &jData)
- sn := strings.Split(ss[0], "|")
- switch sn[0] {
- case "item_in":
- if err == nil {
- for k, v := range jData {
- gaugeItemProductionInput.WithLabelValues(sn[1], k).Set(v)
- }
- }
- case "item_out":
- if err == nil {
- for k, v := range jData {
- gaugeItemProductionOutput.WithLabelValues(sn[1], k).Set(v)
- }
- }
- case "fluid_in":
- if err == nil {
- for k, v := range jData {
- gaugeFluidProductionInput.WithLabelValues(sn[1], k).Set(v)
- }
- }
- case "fluid_out":
- if err == nil {
- for k, v := range jData {
- gaugeFluidProductionOutput.WithLabelValues(sn[1], k).Set(v)
- }
- }
- case "kill_in":
- if err == nil {
- for k, v := range jData {
- gaugeKillCountInput.WithLabelValues(sn[1], k).Set(v)
- }
- }
- case "kill_out":
- if err == nil {
- for k, v := range jData {
- gaugeKillCountOutput.WithLabelValues(sn[1], k).Set(v)
- }
- }
- case "entity_in":
- if err == nil {
- for k, v := range jData {
- gaugeEntityBuildCountInput.WithLabelValues(sn[1], k).Set(v)
- }
- }
- case "entity_out":
- if err == nil {
- for k, v := range jData {
- gaugeEntityBuildCountOutput.WithLabelValues(sn[1], k).Set(v)
- }
- }
- }
- }
- }
- }
- }
- time.Sleep(expire)
- }
- }()
- http.Handle("/metrics", prometheus.Handler())
- http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte(`<html>
- <head><title>Factorio Exporter</title></head>
- <body>
- <h1>Factorio Exporter</h1>
- <p><a href="/metrics">Metrics</a></p>
- </body>
- </html>`))
- })
- http.ListenAndServe(*addr, nil)
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement