Skip to content

Commit 93736fa

Browse files
authored
Merge pull request #31 from matthiasemde/add-inventory-collectors
feat: add inventory collectors
2 parents 6623f63 + 3299fff commit 93736fa

14 files changed

+1102
-18
lines changed

Companion/exporter/exporter.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,32 @@ func NewPrometheusExporter(frmApiHosts []string) *PrometheusExporter {
4343
portalCollector := NewPortalCollector("/getPortal")
4444
hypertubeCollector := NewHypertubeCollector("/getHyperEntrance")
4545
frackingCollector := NewFrackingCollector("/getFrackingActivator")
46-
collectorRunners = append(collectorRunners, NewCollectorRunner(ctx, frmApiHost, productionCollector, powerCollector, buildingCollector, vehicleCollector, trainCollector, droneCollector, vehicleStationCollector, trainStationCollector, resourceSinkCollector, pumpCollector, extractorCollector, portalCollector, hypertubeCollector, frackingCollector))
46+
cloudInventoryCollector := NewCloudInventoryCollector("/getCloudInv")
47+
worldInventoryCollector := NewWorldInventoryCollector("/getWorldInv")
48+
storageInventoryCollector := NewStorageInventoryCollector("/getStorageInv")
49+
crateInventoryCollector := NewCrateInventoryCollector("/getCrateInv")
50+
collectorRunners = append(collectorRunners, NewCollectorRunner(
51+
ctx,
52+
frmApiHost,
53+
productionCollector,
54+
powerCollector,
55+
buildingCollector,
56+
vehicleCollector,
57+
trainCollector,
58+
droneCollector,
59+
vehicleStationCollector,
60+
trainStationCollector,
61+
resourceSinkCollector,
62+
pumpCollector,
63+
extractorCollector,
64+
portalCollector,
65+
hypertubeCollector,
66+
frackingCollector,
67+
cloudInventoryCollector,
68+
storageInventoryCollector,
69+
crateInventoryCollector,
70+
worldInventoryCollector,
71+
))
4772
}
4873

4974
return &PrometheusExporter{

Companion/exporter/factory_build_detail.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
package exporter
22

33
type BuildingDetail struct {
4-
Building string `json:"Name"`
5-
Location Location `json:"location"`
6-
Recipe string `json:"Recipe"`
7-
Production []Production `json:"production"`
8-
Ingredients []Ingredient `json:"ingredients"`
9-
ManuSpeed float64 `json:"ManuSpeed"`
10-
IsConfigured bool `json:"IsConfigured"`
11-
IsProducing bool `json:"IsProducing"`
12-
IsPaused bool `json:"IsPaused"`
13-
CircuitGroupId int `json:"CircuitGroupID"`
14-
PowerInfo PowerInfo `json:"PowerInfo"`
15-
Somersloops float64 `json:"Somersloops"`
4+
Id string `json:"ID"`
5+
Building string `json:"Name"`
6+
Location Location `json:"location"`
7+
Recipe string `json:"Recipe"`
8+
Production []Production `json:"production"`
9+
Ingredients []Ingredient `json:"ingredients"`
10+
ManuSpeed float64 `json:"ManuSpeed"`
11+
IsConfigured bool `json:"IsConfigured"`
12+
IsProducing bool `json:"IsProducing"`
13+
IsPaused bool `json:"IsPaused"`
14+
CircuitGroupId int `json:"CircuitGroupID"`
15+
PowerInfo PowerInfo `json:"PowerInfo"`
16+
Somersloops float64 `json:"Somersloops"`
17+
InputInventory []InventoryItem `json:"InputInventory"`
18+
OutputInventory []InventoryItem `json:"OutputInventory"`
1619
}
1720

1821
type Production struct {

Companion/exporter/factory_building_collector.go

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,7 @@ func (c *FactoryBuildingCollector) Collect(frmAddress string, sessionName string
3434
powerInfo := map[float64]float64{}
3535
maxPowerInfo := map[float64]float64{}
3636
for _, building := range details {
37-
c.metricsDropper.CacheFreshMetricLabel(prometheus.Labels{"url": frmAddress, "session_name": sessionName, "machine_name": building.Building,
38-
"x": strconv.FormatFloat(building.Location.X, 'f', -1, 64),
39-
"y": strconv.FormatFloat(building.Location.Y, 'f', -1, 64),
40-
"z": strconv.FormatFloat(building.Location.Z, 'f', -1, 64),
41-
})
37+
c.metricsDropper.CacheFreshMetricLabel(prometheus.Labels{"url": frmAddress, "session_name": sessionName, "id": building.Id})
4238
for _, prod := range building.Production {
4339
MachineItemsProducedPerMin.WithLabelValues(
4440
prod.Name,
@@ -57,6 +53,53 @@ func (c *FactoryBuildingCollector) Collect(frmAddress string, sessionName string
5753
strconv.FormatFloat(building.Location.Z, 'f', -1, 64),
5854
frmAddress, sessionName,
5955
).Set(prod.ProdPercent)
56+
57+
MachineItemsProducedMax.WithLabelValues(
58+
prod.Name,
59+
building.Building,
60+
strconv.FormatFloat(building.Location.X, 'f', -1, 64),
61+
strconv.FormatFloat(building.Location.Y, 'f', -1, 64),
62+
strconv.FormatFloat(building.Location.Z, 'f', -1, 64),
63+
frmAddress, sessionName,
64+
).Set(prod.MaxProd)
65+
}
66+
67+
for _, item := range building.InputInventory {
68+
MachineInputInventory.WithLabelValues(
69+
item.Name,
70+
building.Building,
71+
strconv.FormatFloat(building.Location.X, 'f', -1, 64),
72+
strconv.FormatFloat(building.Location.Y, 'f', -1, 64),
73+
strconv.FormatFloat(building.Location.Z, 'f', -1, 64),
74+
frmAddress, sessionName,
75+
).Set(float64(item.Amount))
76+
MachineInputInventoryMax.WithLabelValues(
77+
item.Name,
78+
building.Building,
79+
strconv.FormatFloat(building.Location.X, 'f', -1, 64),
80+
strconv.FormatFloat(building.Location.Y, 'f', -1, 64),
81+
strconv.FormatFloat(building.Location.Z, 'f', -1, 64),
82+
frmAddress, sessionName,
83+
).Set(float64(item.MaxAmount))
84+
}
85+
86+
for _, item := range building.OutputInventory {
87+
MachineOutputInventory.WithLabelValues(
88+
item.Name,
89+
building.Building,
90+
strconv.FormatFloat(building.Location.X, 'f', -1, 64),
91+
strconv.FormatFloat(building.Location.Y, 'f', -1, 64),
92+
strconv.FormatFloat(building.Location.Z, 'f', -1, 64),
93+
frmAddress, sessionName,
94+
).Set(float64(item.Amount))
95+
MachineOutputInventoryMax.WithLabelValues(
96+
item.Name,
97+
building.Building,
98+
strconv.FormatFloat(building.Location.X, 'f', -1, 64),
99+
strconv.FormatFloat(building.Location.Y, 'f', -1, 64),
100+
strconv.FormatFloat(building.Location.Z, 'f', -1, 64),
101+
frmAddress, sessionName,
102+
).Set(float64(item.MaxAmount))
60103
}
61104

62105
val, ok := powerInfo[building.PowerInfo.CircuitGroupId]

Companion/exporter/factory_building_collector_test.go

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,30 @@ var _ = Describe("FactoryBuildingCollector", func() {
6161
PowerConsumed: 23,
6262
MaxPowerConsumed: 4,
6363
},
64+
InputInventory: []exporter.InventoryItem{
65+
{
66+
Name: "Iron Ore",
67+
Amount: 64,
68+
MaxAmount: 100,
69+
},
70+
{
71+
Name: "Second input",
72+
Amount: 32,
73+
MaxAmount: 1000,
74+
},
75+
},
76+
OutputInventory: []exporter.InventoryItem{
77+
{
78+
Name: "Iron Ingot",
79+
Amount: 33,
80+
MaxAmount: 200,
81+
},
82+
{
83+
Name: "Second output",
84+
Amount: 44,
85+
MaxAmount: 2000,
86+
},
87+
},
6488
},
6589
})
6690
})
@@ -112,6 +136,161 @@ var _ = Describe("FactoryBuildingCollector", func() {
112136
})
113137
})
114138

139+
Describe("Machine item max production metrics", func() {
140+
It("records a metric with labels for the produced item name, machine type, and x, y, z coordinates", func() {
141+
collector.Collect(url, sessionName)
142+
metric, err := getMetric(exporter.MachineItemsProducedMax, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
143+
Expect(err).ToNot(HaveOccurred())
144+
Expect(metric).ToNot(BeNil())
145+
})
146+
147+
It("records the current max production as the metric value", func() {
148+
collector.Collect(url, sessionName)
149+
150+
val, err := gaugeValue(exporter.MachineItemsProducedMax, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
151+
Expect(err).ToNot(HaveOccurred())
152+
Expect(val).To(Equal(float64(10)))
153+
})
154+
155+
Describe("when a machine has multiple outputs", func() {
156+
It("records a metric per item", func() {
157+
collector.Collect(url, sessionName)
158+
159+
ironIngots, err := gaugeValue(exporter.MachineItemsProducedMax, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
160+
Expect(err).ToNot(HaveOccurred())
161+
Expect(ironIngots).To(Equal(float64(10.0)))
162+
163+
ironNothing, err := gaugeValue(exporter.MachineItemsProducedMax, "Iron Nothing", "Smelter", "100", "200", "-300", url, sessionName)
164+
Expect(err).ToNot(HaveOccurred())
165+
Expect(ironNothing).To(Equal(float64(4000.0)))
166+
})
167+
})
168+
})
169+
170+
Describe("Machine input inventory metrics", func() {
171+
It("records a metric with labels for the stored item name, machine type, and x, y, z coordinates", func() {
172+
collector.Collect(url, sessionName)
173+
metric, err := getMetric(exporter.MachineInputInventory, "Iron Ore", "Smelter", "100", "200", "-300", url, sessionName)
174+
Expect(err).ToNot(HaveOccurred())
175+
Expect(metric).ToNot(BeNil())
176+
})
177+
178+
It("records the current input invetory as the metric value", func() {
179+
collector.Collect(url, sessionName)
180+
181+
val, err := gaugeValue(exporter.MachineInputInventory, "Iron Ore", "Smelter", "100", "200", "-300", url, sessionName)
182+
Expect(err).ToNot(HaveOccurred())
183+
Expect(val).To(Equal(float64(64.0)))
184+
})
185+
186+
Describe("when a machine has multiple inputs", func() {
187+
It("records a metric per item", func() {
188+
collector.Collect(url, sessionName)
189+
190+
ironIngots, err := gaugeValue(exporter.MachineInputInventory, "Iron Ore", "Smelter", "100", "200", "-300", url, sessionName)
191+
Expect(err).ToNot(HaveOccurred())
192+
Expect(ironIngots).To(Equal(float64(64.0)))
193+
194+
ironNothing, err := gaugeValue(exporter.MachineInputInventory, "Second input", "Smelter", "100", "200", "-300", url, sessionName)
195+
Expect(err).ToNot(HaveOccurred())
196+
Expect(ironNothing).To(Equal(float64(32.0)))
197+
})
198+
})
199+
})
200+
201+
Describe("Machine input inventory max metrics", func() {
202+
It("records a metric with labels for the stored item name, machine type, and x, y, z coordinates", func() {
203+
collector.Collect(url, sessionName)
204+
metric, err := getMetric(exporter.MachineInputInventoryMax, "Iron Ore", "Smelter", "100", "200", "-300", url, sessionName)
205+
Expect(err).ToNot(HaveOccurred())
206+
Expect(metric).ToNot(BeNil())
207+
})
208+
209+
It("records the current input invetory max as the metric value", func() {
210+
collector.Collect(url, sessionName)
211+
212+
val, err := gaugeValue(exporter.MachineInputInventoryMax, "Iron Ore", "Smelter", "100", "200", "-300", url, sessionName)
213+
Expect(err).ToNot(HaveOccurred())
214+
Expect(val).To(Equal(float64(100.0)))
215+
})
216+
217+
Describe("when a machine has multiple inputs", func() {
218+
It("records a metric per item", func() {
219+
collector.Collect(url, sessionName)
220+
221+
ironIngots, err := gaugeValue(exporter.MachineInputInventoryMax, "Iron Ore", "Smelter", "100", "200", "-300", url, sessionName)
222+
Expect(err).ToNot(HaveOccurred())
223+
Expect(ironIngots).To(Equal(float64(100.0)))
224+
225+
ironNothing, err := gaugeValue(exporter.MachineInputInventoryMax, "Second input", "Smelter", "100", "200", "-300", url, sessionName)
226+
Expect(err).ToNot(HaveOccurred())
227+
Expect(ironNothing).To(Equal(float64(1000.0)))
228+
})
229+
})
230+
})
231+
232+
Describe("Machine input inventory metrics", func() {
233+
It("records a metric with labels for the stored item name, machine type, and x, y, z coordinates", func() {
234+
collector.Collect(url, sessionName)
235+
metric, err := getMetric(exporter.MachineInputInventory, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
236+
Expect(err).ToNot(HaveOccurred())
237+
Expect(metric).ToNot(BeNil())
238+
})
239+
240+
It("records the current output invetory as the metric value", func() {
241+
collector.Collect(url, sessionName)
242+
243+
val, err := gaugeValue(exporter.MachineOutputInventory, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
244+
Expect(err).ToNot(HaveOccurred())
245+
Expect(val).To(Equal(float64(33.0)))
246+
})
247+
248+
Describe("when a machine has multiple outputs", func() {
249+
It("records a metric per item", func() {
250+
collector.Collect(url, sessionName)
251+
252+
ironIngots, err := gaugeValue(exporter.MachineOutputInventory, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
253+
Expect(err).ToNot(HaveOccurred())
254+
Expect(ironIngots).To(Equal(float64(33.0)))
255+
256+
ironNothing, err := gaugeValue(exporter.MachineOutputInventory, "Second output", "Smelter", "100", "200", "-300", url, sessionName)
257+
Expect(err).ToNot(HaveOccurred())
258+
Expect(ironNothing).To(Equal(float64(44.0)))
259+
})
260+
})
261+
})
262+
263+
Describe("Machine output inventory max metrics", func() {
264+
It("records a metric with labels for the stored item name, machine type, and x, y, z coordinates", func() {
265+
collector.Collect(url, sessionName)
266+
metric, err := getMetric(exporter.MachineOutputInventoryMax, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
267+
Expect(err).ToNot(HaveOccurred())
268+
Expect(metric).ToNot(BeNil())
269+
})
270+
271+
It("records the current output invetory max as the metric value", func() {
272+
collector.Collect(url, sessionName)
273+
274+
val, err := gaugeValue(exporter.MachineOutputInventoryMax, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
275+
Expect(err).ToNot(HaveOccurred())
276+
Expect(val).To(Equal(float64(200.0)))
277+
})
278+
279+
Describe("when a machine has multiple outputs", func() {
280+
It("records a metric per item", func() {
281+
collector.Collect(url, sessionName)
282+
283+
ironIngots, err := gaugeValue(exporter.MachineOutputInventoryMax, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName)
284+
Expect(err).ToNot(HaveOccurred())
285+
Expect(ironIngots).To(Equal(float64(200.0)))
286+
287+
ironNothing, err := gaugeValue(exporter.MachineOutputInventoryMax, "Second output", "Smelter", "100", "200", "-300", url, sessionName)
288+
Expect(err).ToNot(HaveOccurred())
289+
Expect(ironNothing).To(Equal(float64(2000.0)))
290+
})
291+
})
292+
})
293+
115294
Describe("Machine item production efficiency metrics", func() {
116295
It("records a metric with labels for the produced item name, machine type, and x, y, z coordinates", func() {
117296
collector.Collect(url, sessionName)

Companion/exporter/factory_building_metrics.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,62 @@ var (
2626
"y",
2727
"z",
2828
})
29+
30+
MachineItemsProducedMax = RegisterNewGaugeVec(prometheus.GaugeOpts{
31+
Name: "machine_items_produced_max",
32+
Help: "The maximum of a certain item which the machine can produce",
33+
}, []string{
34+
"item_name",
35+
"machine_name",
36+
"x",
37+
"y",
38+
"z",
39+
})
40+
41+
MachineInputInventory = RegisterNewGaugeVec(prometheus.GaugeOpts{
42+
Name: "machine_input_inventory",
43+
Help: "How much of an item a building has stored in its input",
44+
}, []string{
45+
"item_name",
46+
"machine_name",
47+
"x",
48+
"y",
49+
"z",
50+
})
51+
52+
MachineInputInventoryMax = RegisterNewGaugeVec(prometheus.GaugeOpts{
53+
Name: "machine_input_inventory_max",
54+
Help: "How much of an item a building can store in its input",
55+
}, []string{
56+
"item_name",
57+
"machine_name",
58+
"x",
59+
"y",
60+
"z",
61+
})
62+
63+
MachineOutputInventory = RegisterNewGaugeVec(prometheus.GaugeOpts{
64+
Name: "machine_output_inventory",
65+
Help: "How much of an item a building has stored in its output",
66+
}, []string{
67+
"item_name",
68+
"machine_name",
69+
"x",
70+
"y",
71+
"z",
72+
})
73+
74+
MachineOutputInventoryMax = RegisterNewGaugeVec(prometheus.GaugeOpts{
75+
Name: "machine_output_inventory_max",
76+
Help: "How much of an item a building can store in its output",
77+
}, []string{
78+
"item_name",
79+
"machine_name",
80+
"x",
81+
"y",
82+
"z",
83+
})
84+
2985
FactoryPower = RegisterNewGaugeVec(prometheus.GaugeOpts{
3086
Name: "factory_power",
3187
Help: "Power draw from factory machines in MW. Does not include extractors.",

0 commit comments

Comments
 (0)