diff --git a/Companion/exporter/factory_building_collector.go b/Companion/exporter/factory_building_collector.go index 6cfabba..2a0f348 100644 --- a/Companion/exporter/factory_building_collector.go +++ b/Companion/exporter/factory_building_collector.go @@ -18,6 +18,9 @@ func NewFactoryBuildingCollector(endpoint string) *FactoryBuildingCollector { metricsDropper: NewMetricsDropper( MachineItemsProducedPerMin, MachineItemsProducedEffiency, + MachineItemsConsumedPerMin, + MachineItemsConsumedEffiency, + MachineItemsConsumedMax, ), } } @@ -39,6 +42,7 @@ func (c *FactoryBuildingCollector) Collect(frmAddress string, sessionName string MachineItemsProducedPerMin.WithLabelValues( prod.Name, building.Building, + building.Recipe, strconv.FormatFloat(building.Location.X, 'f', -1, 64), strconv.FormatFloat(building.Location.Y, 'f', -1, 64), strconv.FormatFloat(building.Location.Z, 'f', -1, 64), @@ -48,6 +52,7 @@ func (c *FactoryBuildingCollector) Collect(frmAddress string, sessionName string MachineItemsProducedEffiency.WithLabelValues( prod.Name, building.Building, + building.Recipe, strconv.FormatFloat(building.Location.X, 'f', -1, 64), strconv.FormatFloat(building.Location.Y, 'f', -1, 64), strconv.FormatFloat(building.Location.Z, 'f', -1, 64), @@ -57,6 +62,7 @@ func (c *FactoryBuildingCollector) Collect(frmAddress string, sessionName string MachineItemsProducedMax.WithLabelValues( prod.Name, building.Building, + building.Recipe, strconv.FormatFloat(building.Location.X, 'f', -1, 64), strconv.FormatFloat(building.Location.Y, 'f', -1, 64), strconv.FormatFloat(building.Location.Z, 'f', -1, 64), @@ -64,6 +70,38 @@ func (c *FactoryBuildingCollector) Collect(frmAddress string, sessionName string ).Set(prod.MaxProd) } + for _, ing := range building.Ingredients { + MachineItemsConsumedPerMin.WithLabelValues( + ing.Name, + building.Building, + building.Recipe, + 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(ing.CurrentConsumed) + + MachineItemsConsumedEffiency.WithLabelValues( + ing.Name, + building.Building, + building.Recipe, + 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(ing.ConsPercent) + + MachineItemsConsumedMax.WithLabelValues( + ing.Name, + building.Building, + building.Recipe, + 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(ing.MaxConsumed) + } + for _, item := range building.InputInventory { MachineInputInventory.WithLabelValues( item.Name, diff --git a/Companion/exporter/factory_building_collector_test.go b/Companion/exporter/factory_building_collector_test.go index 41f9a39..d2092bd 100644 --- a/Companion/exporter/factory_building_collector_test.go +++ b/Companion/exporter/factory_building_collector_test.go @@ -50,6 +50,12 @@ var _ = Describe("FactoryBuildingCollector", func() { MaxConsumed: 5.0, ConsPercent: 1.0, }, + { + Name: "Second ingredient", + CurrentConsumed: 2.0, + MaxConsumed: 8.0, + ConsPercent: 0.25, + }, }, ManuSpeed: 100.0, IsConfigured: false, @@ -108,7 +114,7 @@ var _ = Describe("FactoryBuildingCollector", func() { Describe("Machine item 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.MachineItemsProducedPerMin, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName) + metric, err := getMetric(exporter.MachineItemsProducedPerMin, "Iron Ingot", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) Expect(err).ToNot(HaveOccurred()) Expect(metric).ToNot(BeNil()) }) @@ -116,7 +122,7 @@ var _ = Describe("FactoryBuildingCollector", func() { It("records the current production figure as the metric value", func() { collector.Collect(url, sessionName) - val, err := gaugeValue(exporter.MachineItemsProducedPerMin, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName) + val, err := gaugeValue(exporter.MachineItemsProducedPerMin, "Iron Ingot", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) Expect(err).ToNot(HaveOccurred()) Expect(val).To(Equal(float64(10.0))) }) @@ -125,11 +131,11 @@ var _ = Describe("FactoryBuildingCollector", func() { It("records a metric per item", func() { collector.Collect(url, sessionName) - ironIngots, err := gaugeValue(exporter.MachineItemsProducedPerMin, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName) + ironIngots, err := gaugeValue(exporter.MachineItemsProducedPerMin, "Iron Ingot", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) Expect(err).ToNot(HaveOccurred()) Expect(ironIngots).To(Equal(float64(10.0))) - ironNothing, err := gaugeValue(exporter.MachineItemsProducedPerMin, "Iron Nothing", "Smelter", "100", "200", "-300", url, sessionName) + ironNothing, err := gaugeValue(exporter.MachineItemsProducedPerMin, "Iron Nothing", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) Expect(err).ToNot(HaveOccurred()) Expect(ironNothing).To(Equal(float64(1000.0))) }) @@ -139,7 +145,7 @@ 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) + metric, err := getMetric(exporter.MachineItemsProducedMax, "Iron Ingot", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) Expect(err).ToNot(HaveOccurred()) Expect(metric).ToNot(BeNil()) }) @@ -147,7 +153,7 @@ var _ = Describe("FactoryBuildingCollector", func() { 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) + val, err := gaugeValue(exporter.MachineItemsProducedMax, "Iron Ingot", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) Expect(err).ToNot(HaveOccurred()) Expect(val).To(Equal(float64(10))) }) @@ -156,17 +162,110 @@ var _ = Describe("FactoryBuildingCollector", 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) + ironIngots, err := gaugeValue(exporter.MachineItemsProducedMax, "Iron Ingot", "Smelter", "Iron Ingot", "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) + ironNothing, err := gaugeValue(exporter.MachineItemsProducedMax, "Iron Nothing", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) Expect(err).ToNot(HaveOccurred()) Expect(ironNothing).To(Equal(float64(4000.0))) }) }) }) + Describe("Machine item consumption metrics", func() { + It("records a metric with labels for the consumed item name, machine type, recipe, and x, y, z coordinates", func() { + collector.Collect(url, sessionName) + metric, err := getMetric(exporter.MachineItemsConsumedPerMin, "Iron Ore", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) + Expect(err).ToNot(HaveOccurred()) + Expect(metric).ToNot(BeNil()) + }) + + It("records the current consumption figure as the metric value", func() { + collector.Collect(url, sessionName) + + val, err := gaugeValue(exporter.MachineItemsConsumedPerMin, "Iron Ore", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) + Expect(err).ToNot(HaveOccurred()) + Expect(val).To(Equal(float64(5.0))) + }) + + Describe("when a machine has multiple ingredients", func() { + It("records a metric per item", func() { + collector.Collect(url, sessionName) + + ironOre, err := gaugeValue(exporter.MachineItemsConsumedPerMin, "Iron Ore", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) + Expect(err).ToNot(HaveOccurred()) + Expect(ironOre).To(Equal(float64(5.0))) + + secondIngredient, err := gaugeValue(exporter.MachineItemsConsumedPerMin, "Second ingredient", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) + Expect(err).ToNot(HaveOccurred()) + Expect(secondIngredient).To(Equal(float64(2.0))) + }) + }) + }) + + Describe("Machine item max consumption metrics", func() { + It("records a metric with labels for the consumed item name, machine type, recipe, and x, y, z coordinates", func() { + collector.Collect(url, sessionName) + metric, err := getMetric(exporter.MachineItemsConsumedMax, "Iron Ore", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) + Expect(err).ToNot(HaveOccurred()) + Expect(metric).ToNot(BeNil()) + }) + + It("records the max consumption as the metric value", func() { + collector.Collect(url, sessionName) + + val, err := gaugeValue(exporter.MachineItemsConsumedMax, "Iron Ore", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) + Expect(err).ToNot(HaveOccurred()) + Expect(val).To(Equal(float64(5.0))) + }) + + Describe("when a machine has multiple ingredients", func() { + It("records a metric per item", func() { + collector.Collect(url, sessionName) + + ironOre, err := gaugeValue(exporter.MachineItemsConsumedMax, "Iron Ore", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) + Expect(err).ToNot(HaveOccurred()) + Expect(ironOre).To(Equal(float64(5.0))) + + secondIngredient, err := gaugeValue(exporter.MachineItemsConsumedMax, "Second ingredient", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) + Expect(err).ToNot(HaveOccurred()) + Expect(secondIngredient).To(Equal(float64(8.0))) + }) + }) + }) + + Describe("Machine item consumption efficiency metrics", func() { + It("records a metric with labels for the consumed item name, machine type, recipe, and x, y, z coordinates", func() { + collector.Collect(url, sessionName) + metric, err := getMetric(exporter.MachineItemsConsumedEffiency, "Iron Ore", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) + Expect(err).ToNot(HaveOccurred()) + Expect(metric).ToNot(BeNil()) + }) + + It("records the current consumption efficiency as the metric value", func() { + collector.Collect(url, sessionName) + + val, err := gaugeValue(exporter.MachineItemsConsumedEffiency, "Iron Ore", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) + Expect(err).ToNot(HaveOccurred()) + Expect(val).To(Equal(float64(1.0))) + }) + + Describe("when a machine has multiple ingredients", func() { + It("records a metric per item", func() { + collector.Collect(url, sessionName) + + ironOre, err := gaugeValue(exporter.MachineItemsConsumedEffiency, "Iron Ore", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) + Expect(err).ToNot(HaveOccurred()) + Expect(ironOre).To(Equal(float64(1.0))) + + secondIngredient, err := gaugeValue(exporter.MachineItemsConsumedEffiency, "Second ingredient", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) + Expect(err).ToNot(HaveOccurred()) + Expect(secondIngredient).To(Equal(float64(0.25))) + }) + }) + }) + 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) @@ -294,7 +393,7 @@ var _ = Describe("FactoryBuildingCollector", func() { 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) - metric, err := getMetric(exporter.MachineItemsProducedEffiency, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName) + metric, err := getMetric(exporter.MachineItemsProducedEffiency, "Iron Ingot", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) Expect(err).ToNot(HaveOccurred()) Expect(metric).ToNot(BeNil()) }) @@ -302,7 +401,7 @@ var _ = Describe("FactoryBuildingCollector", func() { It("records the current production efficiency as the metric value", func() { collector.Collect(url, sessionName) - val, err := gaugeValue(exporter.MachineItemsProducedEffiency, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName) + val, err := gaugeValue(exporter.MachineItemsProducedEffiency, "Iron Ingot", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) Expect(err).ToNot(HaveOccurred()) Expect(val).To(Equal(float64(0.5))) }) @@ -311,11 +410,11 @@ var _ = Describe("FactoryBuildingCollector", func() { It("records a metric per item", func() { collector.Collect(url, sessionName) - ironIngots, err := gaugeValue(exporter.MachineItemsProducedEffiency, "Iron Ingot", "Smelter", "100", "200", "-300", url, sessionName) + ironIngots, err := gaugeValue(exporter.MachineItemsProducedEffiency, "Iron Ingot", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) Expect(err).ToNot(HaveOccurred()) Expect(ironIngots).To(Equal(float64(0.5))) - ironNothing, err := gaugeValue(exporter.MachineItemsProducedEffiency, "Iron Nothing", "Smelter", "100", "200", "-300", url, sessionName) + ironNothing, err := gaugeValue(exporter.MachineItemsProducedEffiency, "Iron Nothing", "Smelter", "Iron Ingot", "100", "200", "-300", url, sessionName) Expect(err).ToNot(HaveOccurred()) Expect(ironNothing).To(Equal(float64(0.25))) }) diff --git a/Companion/exporter/factory_building_metrics.go b/Companion/exporter/factory_building_metrics.go index 41ac7c8..4e494bf 100644 --- a/Companion/exporter/factory_building_metrics.go +++ b/Companion/exporter/factory_building_metrics.go @@ -11,6 +11,7 @@ var ( }, []string{ "item_name", "machine_name", + "recipe", "x", "y", "z", @@ -22,6 +23,7 @@ var ( }, []string{ "item_name", "machine_name", + "recipe", "x", "y", "z", @@ -33,6 +35,43 @@ var ( }, []string{ "item_name", "machine_name", + "recipe", + "x", + "y", + "z", + }) + + MachineItemsConsumedPerMin = RegisterNewGaugeVec(prometheus.GaugeOpts{ + Name: "machine_items_consumed_per_min", + Help: "How much of an item a building is consuming", + }, []string{ + "item_name", + "machine_name", + "recipe", + "x", + "y", + "z", + }) + + MachineItemsConsumedEffiency = RegisterNewGaugeVec(prometheus.GaugeOpts{ + Name: "machine_items_consumed_pc", + Help: "The efficiency with which a building is consuming an item", + }, []string{ + "item_name", + "machine_name", + "recipe", + "x", + "y", + "z", + }) + + MachineItemsConsumedMax = RegisterNewGaugeVec(prometheus.GaugeOpts{ + Name: "machine_items_consumed_max", + Help: "The maximum of a certain item which the machine can consume", + }, []string{ + "item_name", + "machine_name", + "recipe", "x", "y", "z", diff --git a/README.md b/README.md index 61ed935..feea188 100644 --- a/README.md +++ b/README.md @@ -88,17 +88,32 @@ The [Prometheus metrics server](https://prometheus.io/) allows you to [explore t