Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
from types import NoneType
import numpy as np
import random
import logging
import queue
import time
LOGGER = logging.getLogger(__name__)
class SyntheticMetricsGenerator():
"""
This collector class generates synthetic network metrics based on the current network state.
The metrics include packet_in, packet_out, bytes_in, bytes_out, packet_loss (percentage), packet_drop_count, byte_drop_count, and latency.
The network state can be 'good', 'moderate', or 'poor', and it affects the generated metrics accordingly.
"""
def __init__(self, metric_queue=None, network_state="good"):
LOGGER.info("Initiaitng Emulator")
super().__init__()
self.metric_queue = metric_queue if metric_queue is not None else queue.Queue()
self.network_state = network_state
self.running = True
self.set_initial_parameter_values() # update this method to set the initial values for the parameters
def set_initial_parameter_values(self):
self.bytes_per_pkt = random.uniform(65, 150)
self.states = ["good", "moderate", "poor"]
self.state_probabilities = {
"good" : [0.9, 0.1, 0.0],
"moderate": [0.2, 0.7, 0.1],
"poor" : [0.0, 0.3, 0.7]
}
if self.network_state == "good":
self.packet_in = random.uniform(700, 900)
elif self.network_state == "moderate":
self.packet_in = random.uniform(300, 700)
else:
self.packet_in = random.uniform(100, 300)
def generate_synthetic_data_point(self, resource_key, sample_type_ids):
"""
Generates a synthetic data point based on the current network state.
Parameters:
resource_key (str): The key associated with the resource for which the data point is generated.
Returns:
tuple: A tuple containing the timestamp, resource key, and a dictionary of generated metrics.
"""
if self.network_state == "good":
packet_loss = random.uniform(0.01, 0.1)
random_noise = random.uniform(1,10)
latency = random.uniform(5, 25)
elif self.network_state == "moderate":
packet_loss = random.uniform(0.1, 1)
random_noise = random.uniform(10, 40)
latency = random.uniform(25, 100)
elif self.network_state == "poor":
packet_loss = random.uniform(1, 3)
random_noise = random.uniform(40, 100)
latency = random.uniform(100, 300)
else:
raise ValueError("Invalid network state. Must be 'good', 'moderate', or 'poor'.")
period = 60 * 60 * random.uniform(10, 100)
amplitude = random.uniform(50, 100)
sin_wave = amplitude * np.sin(2 * np.pi * 100 / period) + self.packet_in
packet_in = sin_wave + ((sin_wave/100) * random_noise)
packet_out = packet_in - ((packet_in / 100) * packet_loss)
bytes_in = packet_in * self.bytes_per_pkt
bytes_out = packet_out * self.bytes_per_pkt
packet_drop_count = packet_in * (packet_loss / 100)
byte_drop_count = packet_drop_count * self.bytes_per_pkt
state_prob = self.state_probabilities[self.network_state]
self.network_state = random.choices(self.states, state_prob)[0]
print (self.network_state)
generated_samples = {
"packet_in" : int(packet_in), "packet_out" : int(packet_out), "bytes_in" : float(bytes_in),
"bytes_out" : float(bytes_out), "packet_loss": float(packet_loss), "packet_drop_count" : int(packet_drop_count),
"latency" : float(latency), "byte_drop_count": float(byte_drop_count)
}
requested_metrics = self.metric_id_mapper(sample_type_ids)
generated_samples = {metric: generated_samples[metric] for metric in requested_metrics}
return (time.time(), resource_key, generated_samples)
def metric_id_mapper(self, sample_type_ids):
"""
Maps the sample type IDs to the corresponding metric names.
Parameters:
sample_type_ids (list): A list of sample type IDs.
Returns:
list: A list of metric names.
"""
metric_names = []
for sample_type_id in sample_type_ids:
if sample_type_id == 102:
metric_names.append("packet_in")
elif sample_type_id == 101:
metric_names.append("packet_out")
elif sample_type_id == 103:
metric_names.append("packet_drop_count")
elif sample_type_id == 202:
metric_names.append("bytes_in")
elif sample_type_id == 201:
metric_names.append("bytes_out")
elif sample_type_id == 203:
metric_names.append("byte_drop_count")
elif sample_type_id == 701:
metric_names.append("latency")
else:
raise ValueError(f"Invalid sample type ID: {sample_type_id}")
return metric_names