Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion Companion/exporter/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,32 @@ func NewPrometheusExporter(frmApiHosts []string) *PrometheusExporter {
portalCollector := NewPortalCollector("/getPortal")
hypertubeCollector := NewHypertubeCollector("/getHyperEntrance")
frackingCollector := NewFrackingCollector("/getFrackingActivator")
collectorRunners = append(collectorRunners, NewCollectorRunner(ctx, frmApiHost, productionCollector, powerCollector, buildingCollector, vehicleCollector, trainCollector, droneCollector, vehicleStationCollector, trainStationCollector, resourceSinkCollector, pumpCollector, extractorCollector, portalCollector, hypertubeCollector, frackingCollector))
cloudInventoryCollector := NewCloudInventoryCollector("/getCloudInv")
worldInventoryCollector := NewWorldInventoryCollector("/getWorldInv")
storageInventoryCollector := NewStorageInventoryCollector("/getStorageInv")
crateInventoryCollector := NewCrateInventoryCollector("/getCrateInv")
collectorRunners = append(collectorRunners, NewCollectorRunner(
ctx,
frmApiHost,
productionCollector,
powerCollector,
buildingCollector,
vehicleCollector,
trainCollector,
droneCollector,
vehicleStationCollector,
trainStationCollector,
resourceSinkCollector,
pumpCollector,
extractorCollector,
portalCollector,
hypertubeCollector,
frackingCollector,
cloudInventoryCollector,
storageInventoryCollector,
crateInventoryCollector,
worldInventoryCollector,
))
}

return &PrometheusExporter{
Expand Down
27 changes: 15 additions & 12 deletions Companion/exporter/factory_build_detail.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
package exporter

type BuildingDetail struct {
Building string `json:"Name"`
Location Location `json:"location"`
Recipe string `json:"Recipe"`
Production []Production `json:"production"`
Ingredients []Ingredient `json:"ingredients"`
ManuSpeed float64 `json:"ManuSpeed"`
IsConfigured bool `json:"IsConfigured"`
IsProducing bool `json:"IsProducing"`
IsPaused bool `json:"IsPaused"`
CircuitGroupId int `json:"CircuitGroupID"`
PowerInfo PowerInfo `json:"PowerInfo"`
Somersloops float64 `json:"Somersloops"`
Id string `json:"ID"`
Building string `json:"Name"`
Location Location `json:"location"`
Recipe string `json:"Recipe"`
Production []Production `json:"production"`
Ingredients []Ingredient `json:"ingredients"`
ManuSpeed float64 `json:"ManuSpeed"`
IsConfigured bool `json:"IsConfigured"`
IsProducing bool `json:"IsProducing"`
IsPaused bool `json:"IsPaused"`
CircuitGroupId int `json:"CircuitGroupID"`
PowerInfo PowerInfo `json:"PowerInfo"`
Somersloops float64 `json:"Somersloops"`
InputInventory []InventoryItem `json:"InputInventory"`
OutputInventory []InventoryItem `json:"OutputInventory"`
}

type Production struct {
Expand Down
53 changes: 48 additions & 5 deletions Companion/exporter/factory_building_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,7 @@ func (c *FactoryBuildingCollector) Collect(frmAddress string, sessionName string
powerInfo := map[float64]float64{}
maxPowerInfo := map[float64]float64{}
for _, building := range details {
c.metricsDropper.CacheFreshMetricLabel(prometheus.Labels{"url": frmAddress, "session_name": sessionName, "machine_name": building.Building,
"x": strconv.FormatFloat(building.Location.X, 'f', -1, 64),
"y": strconv.FormatFloat(building.Location.Y, 'f', -1, 64),
"z": strconv.FormatFloat(building.Location.Z, 'f', -1, 64),
})
c.metricsDropper.CacheFreshMetricLabel(prometheus.Labels{"url": frmAddress, "session_name": sessionName, "id": building.Id})
for _, prod := range building.Production {
MachineItemsProducedPerMin.WithLabelValues(
prod.Name,
Expand All @@ -57,6 +53,53 @@ func (c *FactoryBuildingCollector) Collect(frmAddress string, sessionName string
strconv.FormatFloat(building.Location.Z, 'f', -1, 64),
frmAddress, sessionName,
).Set(prod.ProdPercent)

MachineItemsProducedMax.WithLabelValues(
prod.Name,
building.Building,
strconv.FormatFloat(building.Location.X, 'f', -1, 64),
strconv.FormatFloat(building.Location.Y, 'f', -1, 64),
strconv.FormatFloat(building.Location.Z, 'f', -1, 64),
frmAddress, sessionName,
).Set(prod.MaxProd)
}

for _, item := range building.InputInventory {
MachineInputInventory.WithLabelValues(
item.Name,
building.Building,
strconv.FormatFloat(building.Location.X, 'f', -1, 64),
strconv.FormatFloat(building.Location.Y, 'f', -1, 64),
strconv.FormatFloat(building.Location.Z, 'f', -1, 64),
frmAddress, sessionName,
).Set(float64(item.Amount))
MachineInputInventoryMax.WithLabelValues(
item.Name,
building.Building,
strconv.FormatFloat(building.Location.X, 'f', -1, 64),
strconv.FormatFloat(building.Location.Y, 'f', -1, 64),
strconv.FormatFloat(building.Location.Z, 'f', -1, 64),
frmAddress, sessionName,
).Set(float64(item.MaxAmount))
}

for _, item := range building.OutputInventory {
MachineOutputInventory.WithLabelValues(
item.Name,
building.Building,
strconv.FormatFloat(building.Location.X, 'f', -1, 64),
strconv.FormatFloat(building.Location.Y, 'f', -1, 64),
strconv.FormatFloat(building.Location.Z, 'f', -1, 64),
frmAddress, sessionName,
).Set(float64(item.Amount))
MachineOutputInventoryMax.WithLabelValues(
item.Name,
building.Building,
strconv.FormatFloat(building.Location.X, 'f', -1, 64),
strconv.FormatFloat(building.Location.Y, 'f', -1, 64),
strconv.FormatFloat(building.Location.Z, 'f', -1, 64),
frmAddress, sessionName,
).Set(float64(item.MaxAmount))
}

val, ok := powerInfo[building.PowerInfo.CircuitGroupId]
Expand Down
179 changes: 179 additions & 0 deletions Companion/exporter/factory_building_collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,30 @@ var _ = Describe("FactoryBuildingCollector", func() {
PowerConsumed: 23,
MaxPowerConsumed: 4,
},
InputInventory: []exporter.InventoryItem{
{
Name: "Iron Ore",
Amount: 64,
MaxAmount: 100,
},
{
Name: "Second input",
Amount: 32,
MaxAmount: 1000,
},
},
OutputInventory: []exporter.InventoryItem{
{
Name: "Iron Ingot",
Amount: 33,
MaxAmount: 200,
},
{
Name: "Second output",
Amount: 44,
MaxAmount: 2000,
},
},
},
})
})
Expand Down Expand Up @@ -112,6 +136,161 @@ var _ = Describe("FactoryBuildingCollector", func() {
})
})

Describe("Machine item max production metrics", func() {
It("records a metric with labels for the produced item name, machine type, and x, y, z coordinates", func() {
collector.Collect(url, sessionName)
metric, err := getMetric(exporter.MachineItemsProducedMax, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(metric).ToNot(BeNil())
})

It("records the current max production as the metric value", func() {
collector.Collect(url, sessionName)

val, err := gaugeValue(exporter.MachineItemsProducedMax, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(val).To(Equal(float64(10)))
})

Describe("when a machine has multiple outputs", func() {
It("records a metric per item", func() {
collector.Collect(url, sessionName)

ironIngots, err := gaugeValue(exporter.MachineItemsProducedMax, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(ironIngots).To(Equal(float64(10.0)))

ironNothing, err := gaugeValue(exporter.MachineItemsProducedMax, "Iron Nothing", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(ironNothing).To(Equal(float64(4000.0)))
})
})
})

Describe("Machine input inventory metrics", func() {
It("records a metric with labels for the stored item name, machine type, and x, y, z coordinates", func() {
collector.Collect(url, sessionName)
metric, err := getMetric(exporter.MachineInputInventory, "Iron Ore", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(metric).ToNot(BeNil())
})

It("records the current input invetory as the metric value", func() {
collector.Collect(url, sessionName)

val, err := gaugeValue(exporter.MachineInputInventory, "Iron Ore", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(val).To(Equal(float64(64.0)))
})

Describe("when a machine has multiple inputs", func() {
It("records a metric per item", func() {
collector.Collect(url, sessionName)

ironIngots, err := gaugeValue(exporter.MachineInputInventory, "Iron Ore", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(ironIngots).To(Equal(float64(64.0)))

ironNothing, err := gaugeValue(exporter.MachineInputInventory, "Second input", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(ironNothing).To(Equal(float64(32.0)))
})
})
})

Describe("Machine input inventory max metrics", func() {
It("records a metric with labels for the stored item name, machine type, and x, y, z coordinates", func() {
collector.Collect(url, sessionName)
metric, err := getMetric(exporter.MachineInputInventoryMax, "Iron Ore", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(metric).ToNot(BeNil())
})

It("records the current input invetory max as the metric value", func() {
collector.Collect(url, sessionName)

val, err := gaugeValue(exporter.MachineInputInventoryMax, "Iron Ore", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(val).To(Equal(float64(100.0)))
})

Describe("when a machine has multiple inputs", func() {
It("records a metric per item", func() {
collector.Collect(url, sessionName)

ironIngots, err := gaugeValue(exporter.MachineInputInventoryMax, "Iron Ore", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(ironIngots).To(Equal(float64(100.0)))

ironNothing, err := gaugeValue(exporter.MachineInputInventoryMax, "Second input", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(ironNothing).To(Equal(float64(1000.0)))
})
})
})

Describe("Machine input inventory metrics", func() {
It("records a metric with labels for the stored item name, machine type, and x, y, z coordinates", func() {
collector.Collect(url, sessionName)
metric, err := getMetric(exporter.MachineInputInventory, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(metric).ToNot(BeNil())
})

It("records the current output invetory as the metric value", func() {
collector.Collect(url, sessionName)

val, err := gaugeValue(exporter.MachineOutputInventory, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(val).To(Equal(float64(33.0)))
})

Describe("when a machine has multiple outputs", func() {
It("records a metric per item", func() {
collector.Collect(url, sessionName)

ironIngots, err := gaugeValue(exporter.MachineOutputInventory, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(ironIngots).To(Equal(float64(33.0)))

ironNothing, err := gaugeValue(exporter.MachineOutputInventory, "Second output", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(ironNothing).To(Equal(float64(44.0)))
})
})
})

Describe("Machine output inventory max metrics", func() {
It("records a metric with labels for the stored item name, machine type, and x, y, z coordinates", func() {
collector.Collect(url, sessionName)
metric, err := getMetric(exporter.MachineOutputInventoryMax, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(metric).ToNot(BeNil())
})

It("records the current output invetory max as the metric value", func() {
collector.Collect(url, sessionName)

val, err := gaugeValue(exporter.MachineOutputInventoryMax, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(val).To(Equal(float64(200.0)))
})

Describe("when a machine has multiple outputs", func() {
It("records a metric per item", func() {
collector.Collect(url, sessionName)

ironIngots, err := gaugeValue(exporter.MachineOutputInventoryMax, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(ironIngots).To(Equal(float64(200.0)))

ironNothing, err := gaugeValue(exporter.MachineOutputInventoryMax, "Second output", "Smelter", "100", "200", "-300", url, sessionName)
Expect(err).ToNot(HaveOccurred())
Expect(ironNothing).To(Equal(float64(2000.0)))
})
})
})

Describe("Machine item production efficiency metrics", func() {
It("records a metric with labels for the produced item name, machine type, and x, y, z coordinates", func() {
collector.Collect(url, sessionName)
Expand Down
56 changes: 56 additions & 0 deletions Companion/exporter/factory_building_metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,62 @@ var (
"y",
"z",
})

MachineItemsProducedMax = RegisterNewGaugeVec(prometheus.GaugeOpts{
Name: "machine_items_produced_max",
Help: "The maximum of a certain item which the machine can produce",
}, []string{
"item_name",
"machine_name",
"x",
"y",
"z",
})

MachineInputInventory = RegisterNewGaugeVec(prometheus.GaugeOpts{
Name: "machine_input_inventory",
Help: "How much of an item a building has stored in its input",
}, []string{
"item_name",
"machine_name",
"x",
"y",
"z",
})

MachineInputInventoryMax = RegisterNewGaugeVec(prometheus.GaugeOpts{
Name: "machine_input_inventory_max",
Help: "How much of an item a building can store in its input",
}, []string{
"item_name",
"machine_name",
"x",
"y",
"z",
})

MachineOutputInventory = RegisterNewGaugeVec(prometheus.GaugeOpts{
Name: "machine_output_inventory",
Help: "How much of an item a building has stored in its output",
}, []string{
"item_name",
"machine_name",
"x",
"y",
"z",
})

MachineOutputInventoryMax = RegisterNewGaugeVec(prometheus.GaugeOpts{
Name: "machine_output_inventory_max",
Help: "How much of an item a building can store in its output",
}, []string{
"item_name",
"machine_name",
"x",
"y",
"z",
})

FactoryPower = RegisterNewGaugeVec(prometheus.GaugeOpts{
Name: "factory_power",
Help: "Power draw from factory machines in MW. Does not include extractors.",
Expand Down
Loading
Loading