xref: /aosp_15_r20/external/autotest/utils/frozen_chromite/third_party/infra_libs/ts_mon/common/targets.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Copyright 2015 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Classes representing the monitoring interface for tasks or devices."""
6
7
8class Target(object):
9  """Abstract base class for a monitoring target.
10
11  A Target is a "thing" that should be monitored, for example, a device or a
12  process. The majority of the time, a single process will have only a single
13  Target.
14
15  Do not directly instantiate an object of this class.
16  Use the concrete child classes instead:
17  * TaskTarget to monitor a job or tasks running in (potentially) many places;
18  * DeviceTarget to monitor a host machine that may be running a task.
19  """
20
21  def __init__(self):
22    # Subclasses should list the updatable target fields here.
23    self._fields = tuple()
24
25  def populate_target_pb(self, collection_pb):
26    """Populate the 'target' into a MetricsCollection."""
27    raise NotImplementedError()
28
29  def to_dict(self):
30    """Return target field values as a dictionary."""
31    return {field: getattr(self, field) for field in self._fields}
32
33  def update(self, target_fields):
34    """Update values of some target fields given as a dict."""
35    for field, value in target_fields.items():
36      if field not in self._fields:
37        raise AttributeError('Bad target field: %s' % field)
38      # Make sure the attribute actually exists in the object.
39      getattr(self, field)
40      setattr(self, field, value)
41
42  def __eq__(self, other):
43    if type(self) != type(other):
44      return False
45
46    for field in self._fields:
47      if getattr(self, field) != getattr(other,field):
48        return False
49
50    return True
51
52  def __hash__(self):
53    return hash(tuple(sorted(self.to_dict())))
54
55class DeviceTarget(Target):
56  """Monitoring interface class for monitoring specific hosts or devices."""
57
58  def __init__(self, region, role, network, hostname):
59    """Create a Target object exporting info about a specific device.
60
61    Args:
62      region (str): physical region in which the device is located.
63      role (str): role of the device.
64      network (str): virtual network on which the device is located.
65      hostname (str): name by which the device self-identifies.
66    """
67    super(DeviceTarget, self).__init__()
68    self.region = region
69    self.role = role
70    self.network = network
71    self.hostname = hostname
72    self.realm = 'ACQ_CHROME'
73    self.alertable = True
74    self._fields = ('region', 'role', 'network', 'hostname')
75
76  def populate_target_pb(self, collection):
77    """Populate the 'network_device' target into metrics_pb2.MetricsCollection.
78
79    Args:
80      collection (metrics_pb2.MetricsCollection): the collection proto to be
81          populated.
82    """
83    collection.network_device.metro = self.region
84    collection.network_device.role = self.role
85    collection.network_device.hostgroup = self.network
86    collection.network_device.hostname = self.hostname
87    collection.network_device.realm = self.realm
88    collection.network_device.alertable = self.alertable
89
90
91class TaskTarget(Target):
92  """Monitoring interface class for monitoring active jobs or processes."""
93
94  def __init__(self, service_name, job_name, region, hostname, task_num=0):
95    """Create a Target object exporting info about a specific task.
96
97    Args:
98      service_name (str): service of which this task is a part.
99      job_name (str): specific name of this task.
100      region (str): general region in which this task is running.
101      hostname (str): specific machine on which this task is running.
102      task_num (int): replication id of this task.
103    """
104    super(TaskTarget, self).__init__()
105    self.service_name = service_name
106    self.job_name = job_name
107    self.region = region
108    self.hostname = hostname
109    self.task_num = task_num
110    self._fields = ('service_name', 'job_name', 'region',
111                    'hostname', 'task_num')
112
113  def populate_target_pb(self, collection):
114    """Populate the 'task' target into metrics_pb2.MetricsCollection.
115
116    Args:
117      collection (metrics_pb2.MetricsCollection): the collection proto to be
118          populated.
119    """
120    collection.task.service_name = self.service_name
121    collection.task.job_name = self.job_name
122    collection.task.data_center = self.region
123    collection.task.host_name = self.hostname
124    collection.task.task_num = self.task_num
125
126