From bcb01b37d262d8f13dfbff6019820813d821a3bd Mon Sep 17 00:00:00 2001
From: Hannes Feldt <feldt@astron.nl>
Date: Tue, 7 Nov 2023 12:54:18 +0000
Subject: [PATCH] L2SS-1554: Fix missing station state metric

---
 README.md                                     | 43 ++++++++++---------
 infra/dev/main.hcl                            |  4 +-
 infra/jobs/station/jupyter.levant.nomad       |  2 +-
 tangostationcontrol/VERSION                   |  2 +-
 .../base_device_classes/lofar_device.py       |  4 +-
 .../metrics/_decorators.py                    |  5 +++
 6 files changed, 33 insertions(+), 27 deletions(-)

diff --git a/README.md b/README.md
index 59bc8e7de..8762b1d5e 100644
--- a/README.md
+++ b/README.md
@@ -139,12 +139,13 @@ Next change the version in the following places:
 
 # Release Notes
 
+* 0.24.1 Let all devices emit basic prometheus metrics
 * 0.24.0 Allow multiple antenna fields to be used in single observation,
-         This renames the `Observation` device to `ObservationField`.
+  This renames the `Observation` device to `ObservationField`.
 * 0.23.0 Migrate execution environment to nomad
 * 0.22.0 Split `Antennafield` in `AFL` and `AFH` devices in order to separate Low-Band
-         and High-Band functionalities
-         Removed `Antenna_Type_R` attribute from antennafield devices
+  and High-Band functionalities
+  Removed `Antenna_Type_R` attribute from antennafield devices
 * 0.21.4 Replace `ACC-MIB.mib` with `SP2-MIB.mib` source file in PCON device
 * 0.21.3 Added DigitalBeam.Antenna_Usage_Mask_R to expose antennas used in beamforming
 * 0.21.2 Removed deprecated "Boot" device (use StationManager now)
@@ -155,38 +156,38 @@ Next change the version in the following places:
 * 0.20.3 Fix application of Field_Attenuation_R
 * 0.20.2 Support only one parent in hierarchies
 * 0.20.1 Create an abstract AntennaMapper class which implements behavior of both AntennaToSdpMapper
-         and AntennaToRecvMapper
+  and AntennaToRecvMapper
 * 0.20.0 Complete implementation of station-state transitions in StationManager device.
-         Unified power management under power_hardware_on/off(), dropping prepare_hardware(),
-         disable_hardware().
-         Replaced device.warm_boot() by device.boot().
+  Unified power management under power_hardware_on/off(), dropping prepare_hardware(),
+  disable_hardware().
+  Replaced device.warm_boot() by device.boot().
 * 0.19.0 Ensure requirements.txt are installed when using pip install
 * 0.18.3 Many configuration fixes in tango device configs, Fixed APS & EC device port mapping,
-         fixed variable initialization in several devices, Fixed XST device going into
-         fault state, prevent UDP packet loss and verify UDP buffer size for XSTs,
-         Fixed several tests due to use of numpy.array in properties, Implement control hierarchy,
-         Version pin PyASN, Fix code coverage for PyTango devices, Fix beam tracker not starting again
-         after being stopped.
+  fixed variable initialization in several devices, Fixed XST device going into
+  fault state, prevent UDP packet loss and verify UDP buffer size for XSTs,
+  Fixed several tests due to use of numpy.array in properties, Implement control hierarchy,
+  Version pin PyASN, Fix code coverage for PyTango devices, Fix beam tracker not starting again
+  after being stopped.
 * 0.18.2 Fix documentation links in README
 * 0.18.1 Various improvements including: better error handling for commands and
-         resolving a configuration issue related to beamlets
+  resolving a configuration issue related to beamlets
 * 0.18.0 Expose attribute related to SDP rings such as `FPGA_bf_ring_nof_transport_hops_RW_default` and
-         `FPGA_ring_use_cable_to_next_rn_RW_default`
+  `FPGA_ring_use_cable_to_next_rn_RW_default`
 * 0.17.1 Ensure OPCUA devices reconnect automatically if the connection is lost
 * 0.17.0 Add Power Hierarchy state transition
 * 0.16.2 Add Power_Parent and Parent_Children properties in LOFAR devices
 * 0.16.1 AntennaField: Do not put device in FAULT if an attribute cannot be read/written.
-         AntennaField: Avoid archiving HBA-specific attributes for LBA fields.
+  AntennaField: Avoid archiving HBA-specific attributes for LBA fields.
 * 0.16.0 Observation: Removed antenna mask from specification
-         DigitalBeam: Removed beamlet and antenna selection
+  DigitalBeam: Removed beamlet and antenna selection
 * 0.15.0 Split `recv` device into `rcu2h` and `rcu2l` and
-         split `recv-sim` translator into `rcu2h-sim` and `rcu2l-sim`
+  split `recv-sim` translator into `rcu2h-sim` and `rcu2l-sim`
 * 0.14.0 Create async device base and make tilebeam and digitalbeam async device servers,
-         allowing for cooperative multitasking and preventing issues with beamtracking.
+  allowing for cooperative multitasking and preventing issues with beamtracking.
 * 0.13.1 Upgrade PyTango to 9.4.x and ensure it is installed through requirements.txt
 * 0.13.0 Remove all `archiver-timescale`, `hdbppts-cm`, `hdbppts-es` functionalities
 * 0.12.1 Add `AbstractHierarchy` and `AbstractHierarchyDevice` classes and
-         functionality
+  functionality
 * 0.12.0 Add `Calibration_SDP_Subband_Weights_<XXX>MHz_R` attributes to implement HDF5 calibration tables
 * 0.11.2 Fix sleep duration in archiver test
 * 0.11.1 Fix event unsubscription in TemperatureManager
@@ -194,8 +195,8 @@ Next change the version in the following places:
 * 0.10.0 Add `AntennaToSdpMapper` and fpga_sdp_info_* mapped attributes in `Antennafield` device
 * 0.9.0 Statistics writer: moved the whole functionality to lofar-station-client repository
 * 0.8.0 Statistics writer: HDF5 format overhaul (removed `values`, added and moved attributes),
-        Statistics writer: Added `--field` parameter to record statistics of a specific AntennaField,
-        AntennaField: Added `RCU_DTH_on_R`, `RCU_DTH_freq_R(W)`, `RCU_band_select_R`, `RCU_attenuator_dB_R`.
+  Statistics writer: Added `--field` parameter to record statistics of a specific AntennaField,
+  AntennaField: Added `RCU_DTH_on_R`, `RCU_DTH_freq_R(W)`, `RCU_band_select_R`, `RCU_attenuator_dB_R`.
 * 0.7.2 Added `sdp.subband_frequency_R`, `antennafield.Frequency_Band_RW`, and support for spectral inversion
 * 0.7.1 Add restore backup configuration for `Configuration` device
 * 0.7.0 Raised required Python version to 3.10
diff --git a/infra/dev/main.hcl b/infra/dev/main.hcl
index 8122fe072..48a04f5e7 100644
--- a/infra/dev/main.hcl
+++ b/infra/dev/main.hcl
@@ -15,7 +15,7 @@ resource "nomad_job" "tango" {
   paths = ["./jobs/station/tango.nomad"]
 
   health_check {
-    timeout = "300s"
+    timeout = "1000s"
     jobs    = ["tango"]
   }
 }
@@ -26,7 +26,7 @@ resource "nomad_job" "object-storage" {
   paths = ["./jobs/station/object-storage.nomad"]
 
   health_check {
-    timeout = "300s"
+    timeout = "1000s"
     jobs    = ["object-storage"]
   }
 }
diff --git a/infra/jobs/station/jupyter.levant.nomad b/infra/jobs/station/jupyter.levant.nomad
index 3475f0dbb..81f553a5d 100644
--- a/infra/jobs/station/jupyter.levant.nomad
+++ b/infra/jobs/station/jupyter.levant.nomad
@@ -50,7 +50,7 @@ job "jupyter" {
       resources {
         cpu        = 1024
         memory     = 1024
-        memory_max = 8192
+        memory_max = 20480
       }
       template {
         data = <<EOH
diff --git a/tangostationcontrol/VERSION b/tangostationcontrol/VERSION
index 2094a100c..48b91fd89 100644
--- a/tangostationcontrol/VERSION
+++ b/tangostationcontrol/VERSION
@@ -1 +1 @@
-0.24.0
+0.24.1
diff --git a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py
index cabc55e4c..08fb8c73b 100644
--- a/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py
+++ b/tangostationcontrol/tangostationcontrol/devices/base_device_classes/lofar_device.py
@@ -38,13 +38,14 @@ from tangostationcontrol.common.type_checking import sequence_not_str
 from tangostationcontrol.devices.base_device_classes.control_hierarchy import (
     ControlHierarchyDevice,
 )
-from tangostationcontrol.metrics import DeviceMetricCollector
+from tangostationcontrol.metrics import device_metrics
 
 __all__ = ["LOFARDevice"]
 
 logger = logging.getLogger()
 
 
+@device_metrics()
 class LOFARDevice(Device):
     """
 
@@ -249,7 +250,6 @@ class LOFARDevice(Device):
 
         # record when this device was started
         self.device_start_time = time.time()
-        DeviceMetricCollector.add_device(self)
 
     def _init_device(self):
         logger.debug("[LOFARDevice] init_device")
diff --git a/tangostationcontrol/tangostationcontrol/metrics/_decorators.py b/tangostationcontrol/tangostationcontrol/metrics/_decorators.py
index c2b64134f..fbcd74ce0 100644
--- a/tangostationcontrol/tangostationcontrol/metrics/_decorators.py
+++ b/tangostationcontrol/tangostationcontrol/metrics/_decorators.py
@@ -75,6 +75,9 @@ class DeviceMetricsAttribute:
     @staticmethod
     def init_device_wrapper():
         def new_init_device(instance):
+            from ._collectors import DeviceMetricCollector
+
+            DeviceMetricCollector.add_device(instance)
             metric_values = instance.get_name().split("/")
             metric_values.append(str(instance.get_device_class().get_name()))
             instance.metric_labels = metric_values
@@ -88,6 +91,8 @@ class DeviceMetricsAttribute:
                 self.ds_state.labels(*instance.metric_labels).set(new_state)
             except ValueError as e:
                 logger.warning(e)
+            except AttributeError as e:
+                logger.warning(e)
 
         return new_set_state
 
-- 
GitLab