|
| 1 | +# This file defines the interfaces that snappi tests accept external metrics. |
| 2 | + |
| 3 | +# Metrics data are organized into the hierarchies below |
| 4 | +# ResourceMetrics |
| 5 | +# ├── ResourceID |
| 6 | +# └── ScopeMetrics |
| 7 | +# ├── ScopeID |
| 8 | +# └── Metric |
| 9 | +# ├── Name |
| 10 | +# ├── Description |
| 11 | +# ├── Unit |
| 12 | +# ├── metadata |
| 13 | +# └── data |
| 14 | +# └── Gauge |
| 15 | +# |
| 16 | +# A ResourceMetrics has its ID and a list of ScopeMetrics objects. |
| 17 | +# A ScopeMetrics has its ID and a list of Metric objects. |
| 18 | +# A Metric has several attributes and data. So far we only have Gauge type data. |
| 19 | +# A Gauge has a list of NumberDataPoint objects. |
| 20 | +# A NumberDataPoint has its label, value, flags and the timestamp at which the data was collected. |
| 21 | +# +---------------------+ |
| 22 | +# | DataPoint 1 | |
| 23 | +# | +---------+ +-----+ | |
| 24 | +# +-----+ | |timestamp| |label| | |
| 25 | +# | 1 |-->| +---------+ +-----+ | |
| 26 | +# +-----+ | | |
| 27 | +# | . | | +-----+ +-----+ | |
| 28 | +# | . | | |value| |flags| | |
| 29 | +# | . | | +-----+ +-----+ | |
| 30 | +# | . | +---------------------+ |
| 31 | +# | . | . |
| 32 | +# | . | . |
| 33 | +# | . | . |
| 34 | +# | . | +---------------------+ |
| 35 | +# | . | | DataPoint M | |
| 36 | +# +-----+ | +---------+ +-----+ | |
| 37 | +# | M |-->| |timestamp| |label| | |
| 38 | +# +-----+ | +---------+ +-----+ | |
| 39 | +# | | |
| 40 | +# | +-----+ +-----+ | |
| 41 | +# | |value| |flags| | |
| 42 | +# | +-----+ +-----+ | |
| 43 | +# +---------------------+ |
| 44 | + |
| 45 | +from typing import List, Dict, Union |
| 46 | + |
| 47 | +class NumberDataPoint: |
| 48 | + def __init__(self, time_unix_nano: int, label: List[Dict[str, str]], value: Union[int, float], flags: int = None): |
| 49 | + self.time_unix_nano = time_unix_nano # UNIX Epoch time in nanoseconds |
| 50 | + self.label = label # The key of key-value pairs in dictionaries |
| 51 | + self.value = value # Metric value (can be double or integer) |
| 52 | + self.flags = flags # Optional flags |
| 53 | + |
| 54 | + def __repr__(self): |
| 55 | + return (f"NumberDataPoint(label={self.label}, " |
| 56 | + f"time_unix_nano={self.time_unix_nano}, value={self.value}, flags={self.flags})") |
| 57 | + |
| 58 | + |
| 59 | +class Gauge: |
| 60 | + def __init__(self): |
| 61 | + self.data_points = [] # List of NumberDataPoint objects |
| 62 | + |
| 63 | + def add_data_point(self, data_point): |
| 64 | + self.data_points.append(data_point) |
| 65 | + |
| 66 | + def __repr__(self): |
| 67 | + return f"Gauge(data_points={self.data_points})" |
| 68 | + |
| 69 | + |
| 70 | +class Metric: |
| 71 | + def __init__(self, name, description, unit, data_points, metadata=None): |
| 72 | + self.name = name # Metric name |
| 73 | + self.description = description # Metric description |
| 74 | + self.unit = unit # Metric unit (e.g., seconds, bytes) |
| 75 | + self.data = data # Can be Gauge only |
| 76 | + self.metadata = metadata or {} # Default to an empty dictionary if None |
| 77 | + |
| 78 | + def __repr__(self): |
| 79 | + return (f"Metric(name={self.name}, description={self.description}, " |
| 80 | + f"unit={self.unit}, data={self.data})") |
| 81 | + |
| 82 | + |
| 83 | +# a ScopeMetrics object's ID is device_id |
| 84 | +class ScopeMetrics: |
| 85 | + def __init__(self, device_id): |
| 86 | + self.device_id = device_id |
| 87 | + self.metrics = [] |
| 88 | + |
| 89 | + def add_metric(self, metric): |
| 90 | + self.metrics.append(metric) |
| 91 | + |
| 92 | + def __repr__(self): |
| 93 | + return f"ScopeMetrics(scope={self.scope}, metrics={self.metrics})" |
| 94 | + |
| 95 | + |
| 96 | +# a ResourceMetrics object's ID is test_run_id |
| 97 | +class ResourceMetrics: |
| 98 | + def __init__(self, test_run_id, os_version): |
| 99 | + self.test_run_id = test_run_id |
| 100 | + self.os_version = os_version |
| 101 | + self.scope_metrics = [] |
| 102 | + |
| 103 | + def add_scope_metrics(self, scope_metric): |
| 104 | + self.scope_metrics.append(scope_metric) |
| 105 | + |
| 106 | + def __repr__(self): |
| 107 | + return f"ResourceMetrics(resource={self.resource}, scope_metrics={self.scope_metrics})" |
| 108 | + |
| 109 | + |
0 commit comments