Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2019
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 8.55 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "encoding/json"
  5.     "flag"
  6.     "fmt"
  7.     "io/ioutil"
  8.     "net/http"
  9.     "path/filepath"
  10.     "strconv"
  11.     "strings"
  12.     "time"
  13.  
  14.     "github.com/prometheus/client_golang/prometheus"
  15. )
  16.  
  17. func prepareName(name string) string {
  18.     return fmt.Sprintf("factorio_%s", name)
  19. }
  20.  
  21. func main() {
  22.     addr := flag.String("listen", ":9000", "The address to listen on for HTTP requests.")
  23.     dir := flag.String("dir", "/script-output", "Path to Factorio \"script-output\" directory")
  24.  
  25.     flag.Parse()
  26.  
  27.     defLabels := []string{"force", "name"}
  28.  
  29.     gaugeTick := prometheus.NewGauge(prometheus.GaugeOpts{
  30.         Name:   prepareName("tick"),
  31.         Help:   "game tick",
  32.     })
  33.     prometheus.MustRegister(gaugeTick)
  34.  
  35.     gaugeItemProductionInput := prometheus.NewGaugeVec(
  36.         prometheus.GaugeOpts{
  37.             Name:   prepareName("item_production_input"),
  38.             Help:   "items produced",
  39.         },
  40.         defLabels,
  41.     )
  42.     prometheus.MustRegister(gaugeItemProductionInput)
  43.  
  44.     gaugeItemProductionOutput := prometheus.NewGaugeVec(
  45.         prometheus.GaugeOpts{
  46.             Name:   prepareName("item_production_output"),
  47.             Help:   "items consumed",
  48.         },
  49.         defLabels,
  50.     )
  51.     prometheus.MustRegister(gaugeItemProductionOutput)
  52.  
  53.     gaugeFluidProductionInput := prometheus.NewGaugeVec(
  54.         prometheus.GaugeOpts{
  55.             Name:   prepareName("fluid_production_input"),
  56.             Help:   "fluids produced",
  57.         },
  58.         defLabels,
  59.     )
  60.     prometheus.MustRegister(gaugeFluidProductionInput)
  61.  
  62.     gaugeFluidProductionOutput := prometheus.NewGaugeVec(
  63.         prometheus.GaugeOpts{
  64.             Name:   prepareName("fluid_production_output"),
  65.             Help:   "fluids consumed",
  66.         },
  67.         defLabels,
  68.     )
  69.     prometheus.MustRegister(gaugeFluidProductionOutput)
  70.  
  71.     gaugeKillCountInput := prometheus.NewGaugeVec(
  72.         prometheus.GaugeOpts{
  73.             Name:   prepareName("kill_count_input"),
  74.             Help:   "kills",
  75.         },
  76.         defLabels,
  77.     )
  78.     prometheus.MustRegister(gaugeKillCountInput)
  79.  
  80.     gaugeKillCountOutput := prometheus.NewGaugeVec(
  81.         prometheus.GaugeOpts{
  82.             Name:   prepareName("kill_count_output"),
  83.             Help:   "losses",
  84.         },
  85.         defLabels,
  86.     )
  87.     prometheus.MustRegister(gaugeKillCountOutput)
  88.  
  89.     gaugeEntityBuildCountInput := prometheus.NewGaugeVec(
  90.         prometheus.GaugeOpts{
  91.             Name:   prepareName("entity_build_count_input"),
  92.             Help:   "entities placed",
  93.         },
  94.         defLabels,
  95.     )
  96.     prometheus.MustRegister(gaugeEntityBuildCountInput)
  97.  
  98.     gaugeEntityBuildCountOutput := prometheus.NewGaugeVec(
  99.         prometheus.GaugeOpts{
  100.             Name:   prepareName("entity_build_count_output"),
  101.             Help:   "entities removed",
  102.         },
  103.         defLabels,
  104.     )
  105.     prometheus.MustRegister(gaugeEntityBuildCountOutput)
  106.  
  107.     gaugeItemsLaunched := prometheus.NewGaugeVec(
  108.         prometheus.GaugeOpts{
  109.             Name:   prepareName("items_launched_total"),
  110.             Help:   "items launched in rockets",
  111.         },
  112.         defLabels,
  113.     )
  114.     prometheus.MustRegister(gaugeItemsLaunched)
  115.  
  116.     gaugePollutionInput := prometheus.NewGaugeVec(
  117.         prometheus.GaugeOpts{
  118.             Name:   prepareName("pollution_input"),
  119.             Help:   "pollution produced",
  120.         },
  121.         []string{"name"},
  122.     )
  123.     prometheus.MustRegister(gaugePollutionInput)
  124.  
  125.     gaugePollutionOutput := prometheus.NewGaugeVec(
  126.         prometheus.GaugeOpts{
  127.             Name:   prepareName("pollution_output"),
  128.             Help:   "pollution consumed",
  129.         },
  130.         []string{"name"},
  131.     )
  132.     prometheus.MustRegister(gaugePollutionOutput)
  133.  
  134.     fPath := filepath.Join(*dir, "fmetrics.stat")
  135.  
  136.     go func() {
  137.         expire := time.Duration(1 * time.Second)
  138.         for {
  139.             var data []byte
  140.             data, err := ioutil.ReadFile(fPath)
  141.             if err != nil {
  142.                 fmt.Printf("Reading error: %s\n", err)
  143.             } else {
  144.                 parts := strings.Split(string(data), "\n")
  145.                 for _, str := range parts {
  146.                     if str != "" {
  147.                         ss := strings.Split(str, "=")
  148.                         jData := make(map[string]float64)
  149.                         switch ss[0] {
  150.                         case "tick":
  151.                             f, _ := strconv.ParseFloat(ss[1], 64)
  152.                             gaugeTick.Set(f)
  153.                         case "pollution_in":
  154.                             err := json.Unmarshal([]byte(ss[1]), &jData)
  155.                             if err == nil {
  156.                                 for k, v := range jData {
  157.                                     gaugePollutionInput.WithLabelValues(k).Set(v)
  158.                                 }
  159.                             }
  160.                         case "pollution_out":
  161.                             err := json.Unmarshal([]byte(ss[1]), &jData)
  162.                             if err == nil {
  163.                                 for k, v := range jData {
  164.                                     gaugePollutionOutput.WithLabelValues(k).Set(v)
  165.                                 }
  166.                             }
  167.                         default:
  168.                             err := json.Unmarshal([]byte(ss[1]), &jData)
  169.                             sn := strings.Split(ss[0], "|")
  170.                             switch sn[0] {
  171.                             case "item_in":
  172.                                 if err == nil {
  173.                                     for k, v := range jData {
  174.                                         gaugeItemProductionInput.WithLabelValues(sn[1], k).Set(v)
  175.                                     }
  176.                                 }
  177.                             case "item_out":
  178.                                 if err == nil {
  179.                                     for k, v := range jData {
  180.                                         gaugeItemProductionOutput.WithLabelValues(sn[1], k).Set(v)
  181.                                     }
  182.                                 }
  183.                             case "fluid_in":
  184.                                 if err == nil {
  185.                                     for k, v := range jData {
  186.                                         gaugeFluidProductionInput.WithLabelValues(sn[1], k).Set(v)
  187.                                     }
  188.                                 }
  189.                             case "fluid_out":
  190.                                 if err == nil {
  191.                                     for k, v := range jData {
  192.                                         gaugeFluidProductionOutput.WithLabelValues(sn[1], k).Set(v)
  193.                                     }
  194.                                 }
  195.                             case "kill_in":
  196.                                 if err == nil {
  197.                                     for k, v := range jData {
  198.                                         gaugeKillCountInput.WithLabelValues(sn[1], k).Set(v)
  199.                                     }
  200.                                 }
  201.                             case "kill_out":
  202.                                 if err == nil {
  203.                                     for k, v := range jData {
  204.                                         gaugeKillCountOutput.WithLabelValues(sn[1], k).Set(v)
  205.                                     }
  206.                                 }
  207.                             case "entity_in":
  208.                                 if err == nil {
  209.                                     for k, v := range jData {
  210.                                         gaugeEntityBuildCountInput.WithLabelValues(sn[1], k).Set(v)
  211.                                     }
  212.                                 }
  213.                             case "entity_out":
  214.                                 if err == nil {
  215.                                     for k, v := range jData {
  216.                                         gaugeEntityBuildCountOutput.WithLabelValues(sn[1], k).Set(v)
  217.                                     }
  218.                                 }
  219.                             }
  220.                         }
  221.                     }
  222.                 }
  223.             }
  224.             time.Sleep(expire)
  225.         }
  226.     }()
  227.     http.Handle("/metrics", prometheus.Handler())
  228.     http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  229.         w.Write([]byte(`<html>
  230.             <head><title>Factorio Exporter</title></head>
  231.             <body>
  232.             <h1>Factorio Exporter</h1>
  233.             <p><a href="/metrics">Metrics</a></p>
  234.             </body>
  235.             </html>`))
  236.     })
  237.     http.ListenAndServe(*addr, nil)
  238. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement