diff --git a/clmctest/monitoring/LineProtocolGenerator.py b/clmctest/monitoring/LineProtocolGenerator.py index 50700fe704728aeda869db4277b1151ba600967a..1ffeeebcb01242cad5017837b81592c9d1f80b4d 100644 --- a/clmctest/monitoring/LineProtocolGenerator.py +++ b/clmctest/monitoring/LineProtocolGenerator.py @@ -89,15 +89,14 @@ def generate_endpoint_config(time, cpu, mem, storage, current_state, current_sta validate = lambda key: kwargs.get(key) if key in kwargs else 0.0 # generate and validate the state values - fields = {"cpus": cpu, "memory": mem, "storage": storage} # NOTE: Do we need these fields ? + fields = {"cpus": cpu, "memory": mem, "storage": storage, "current_state_time": current_state_time} # NOTE: Do we need the cpus, memory and storage fields ? for state in ("unplaced", "placing", "placed", "booting", "booted", "connecting", "connected"): - fields[state] = validate(state) - fields[("avg_{0}".format(state))] = validate("avg_{0}".format(state)) + fields["{0}_sum".format(state)] = validate(state) + fields[("{0}_mst".format(state))] = validate("{0}_mst".format(state)) result = [{"measurement": "endpoint_config", "tags": { - "current_state": current_state, - "current_state_time": current_state_time, + "current_state": current_state }, "fields": fields, "time": _getNSTime(time)}] diff --git a/clmctest/monitoring/StreamingSim.py b/clmctest/monitoring/StreamingSim.py index 2348eb0298d4fddc6aa96dce5ec577c12992d2a7..ba8b9dc5ae63f3a52756b6d365d74b947f357874 100644 --- a/clmctest/monitoring/StreamingSim.py +++ b/clmctest/monitoring/StreamingSim.py @@ -105,8 +105,8 @@ class Sim(object): # since the current state in the dictionary is still placing, only the current state time is incremented for i in range(9): - self._writeVMSingleState(agent_db_client, sim_time + (i * TICK_TIME), ip_endpoint, "placing") endpoint_states_config[agent]["current_state_time"] += TICK_TIME + self._writeVMSingleState(agent_db_client, sim_time + (i * TICK_TIME), ip_endpoint, "placing", endpoint_states_config[agent]["current_state_time"]) # here, the VM exits state placing, hence need to append the current state time self._changeVMState(agent_db_client, sim_time + (9*TICK_TIME), ip_endpoint, (("placing", 0.1 + endpoint_states_config[agent]["current_state_time"], 1),), 'placed', 0.9) @@ -139,8 +139,8 @@ class Sim(object): # since the current state in the dictionary is still booting, only the current state time is incremented for i in range(9): - self._writeVMSingleState(agent_db_client, sim_time + (i * TICK_TIME), ip_endpoint, "booting") endpoint_states_config[agent]["current_state_time"] += TICK_TIME + self._writeVMSingleState(agent_db_client, sim_time + (i * TICK_TIME), ip_endpoint, "booting", endpoint_states_config[agent]["current_state_time"]) # here, the VM exits state booting, hence need to append the current state time self._changeVMState(agent_db_client, sim_time + (9*TICK_TIME), ip_endpoint, (('booting', 0.4 + endpoint_states_config[agent]["current_state_time"], 1),), 'booted', 0.6) @@ -195,15 +195,16 @@ class Sim(object): agent_db_client = InfluxDBClient(host=agent_url.hostname, port=agent_url.port, database=self.influx_db_name, timeout=10) # since the current state in the dictionary is still booted, only the current state time is incremented - self._writeVMSingleState(agent_db_client, sim_time, ip_endpoint, "booted") endpoint_states_config[agent]["current_state_time"] += TICK_TIME + self._writeVMSingleState(agent_db_client, sim_time, ip_endpoint, "booted", endpoint_states_config[agent]["current_state_time"]) # here, the VM exits state booted, hence need to append the current state time - self._changeVMState(agent_db_client, sim_time + (1*TICK_TIME), ip_endpoint, (('booted', 0.5 + endpoint_states_config[agent]["current_state_time"], 1),), 'connecting', 0.5) + self._changeVMState(agent_db_client, sim_time + (1 * TICK_TIME), ip_endpoint, (('booted', 0.5 + endpoint_states_config[agent]["current_state_time"], 1),), 'connecting', 0.5) + # since VM changed its current state, readjust the config dictionary endpoint_states_config[agent]["current_state"] = "connecting" endpoint_states_config[agent]["current_state_time"] = 0.5 - sim_time += 2*TICK_TIME + sim_time += 2 * TICK_TIME # Connect endpoints # reports: 10, connecting: 9.7s, connected: 0.3s @@ -215,15 +216,38 @@ class Sim(object): # since the current state in the dictionary is still connecting, only the current state time is incremented for i in range(9): - self._writeVMSingleState(agent_db_client, sim_time + (i * TICK_TIME), ip_endpoint, "connecting") endpoint_states_config[agent]["current_state_time"] += TICK_TIME + self._writeVMSingleState(agent_db_client, sim_time + (i * TICK_TIME), ip_endpoint, "connecting", endpoint_states_config[agent]["current_state_time"]) # here, the VM exits state booted, hence need to append the current state time - self._changeVMState(agent_db_client, sim_time + (9*TICK_TIME), ip_endpoint, (('connecting', 0.7 + endpoint_states_config[agent]["current_state_time"], 1),), 'connected', 0.3) + self._changeVMState(agent_db_client, sim_time + (9 * TICK_TIME), ip_endpoint, (('connecting', 0.7 + endpoint_states_config[agent]["current_state_time"], 1),), + 'connected', 0.3) # since VM changed its current state, readjust the config dictionary endpoint_states_config[agent]["current_state"] = "connected" endpoint_states_config[agent]["current_state_time"] = 0.3 - sim_time += 10*TICK_TIME + sim_time += 10 * TICK_TIME + + # move mpegdash_service media component state from 'stopped' to 'starting' + # Total reports = 1, (0.2 seconds in 'stopped', 0.8 seconds in 'starting') + for ip_endpoint in ip_endpoints: + agent_url = urllib.parse.urlparse(ip_endpoint["agent_url"]) + influxClient = InfluxDBClient(host=agent_url.hostname, port=agent_url.port, database=self.influx_db_name, timeout=10) + self._changeMCState(influxClient, sim_time, 'mpegdash_service_config', 10, 2, 'stopped', 'starting') + + sim_time += TICK_TIME + + # move mpegdash_service media component state from 'starting' to 'running' + # Total reports = 5, (4.7 seconds in 'starting', 0.3 seconds in 'running') + for ip_endpoint in ip_endpoints: + agent_url = urllib.parse.urlparse(ip_endpoint["agent_url"]) + influxClient = InfluxDBClient(host=agent_url.hostname, port=agent_url.port, database=self.influx_db_name, timeout=10) + + for i in range(0, 4): + self._writeMCSingleState(influxClient, 'mpegdash_service_config', 'starting', sim_time + (i * TICK_TIME)) + + self._changeMCState(influxClient, sim_time + (4 * TICK_TIME), 'mpegdash_service_config', 10, 7, 'starting', 'running') + + sim_time += 5 * TICK_TIME request_arrival_rate_inc = DEFAULT_REQUEST_RATE_INC inc_period_count = 0 @@ -290,10 +314,10 @@ class Sim(object): # remove requests processed off the queue ip_endpoint['request_queue'] -= int(requests_processed) - # update endpoint state (continuously 'connected') - self._writeVMSingleState(agent_db_client, sim_time, ip_endpoint, "connected") # update current state time in the config dictionary endpoint_states_config[agent]["current_state_time"] += 1 + # update endpoint state (continuously 'connected') + self._writeVMSingleState(agent_db_client, sim_time, ip_endpoint, "connected", endpoint_states_config[agent]["current_state_time"]) # update mpegdash media component state (continuously 'running') mc_curr_states[agent]["current_state"] = 'running' @@ -356,6 +380,27 @@ class Sim(object): sim_time += TICK_TIME + # remove endpoints + # reports: 5, connected: 4.7s, unplaced: 0.3s + # addition to uncompleted states from previous report: connected += 3600s + 0.3s + for ip_endpoint in ip_endpoints: + agent = ip_endpoint["agent_url"] + agent_url = urllib.parse.urlparse(agent) + agent_db_client = InfluxDBClient(host=agent_url.hostname, port=agent_url.port, database=self.influx_db_name, timeout=10) + + # since the current state in the dictionary is still connected, only the current state time is incremented + for i in range(4): + endpoint_states_config[agent]["current_state_time"] += TICK_TIME + self._writeVMSingleState(agent_db_client, sim_time + (i * TICK_TIME), ip_endpoint, "connected", endpoint_states_config[agent]["current_state_time"]) + + # here, the VM exits state connected, hence need to append the current state time + self._changeVMState(agent_db_client, sim_time + (4 * TICK_TIME), ip_endpoint, (('connected', 0.7 + endpoint_states_config[agent]["current_state_time"], 1),), + 'unplaced', 0.3) + # since VM changed its current state, readjust the config dictionary + endpoint_states_config[agent]["current_state"] = "unplaced" + endpoint_states_config[agent]["current_state_time"] = 0.3 + sim_time += 5 * TICK_TIME + # End simulation end_time = sim_time print("Simulation Finished. Start time {0}. End time {1}. Total time {2}".format(start_time, end_time, @@ -385,18 +430,19 @@ class Sim(object): return response_delay @staticmethod - def _writeVMSingleState(agent_db_client, sim_time, ip_endpoint, state): + def _writeVMSingleState(agent_db_client, sim_time, ip_endpoint, current_state, current_state_time): """ Write a single state as a sample over TICK_TIME. :param agent_db_client: agent used to send metric data to CLMC :param sim_time: current simulation time :param ip_endpoint: dict with info for ip endpoint - :param state: state that's being reported + :param current_state: state that's being reported + :param current_state_time: the current state time """ # since no state has been finished, the generate_endpoint_config is called without any keyword arguments (field:value pairs) and only the tags for the current state are set - data = lp.generate_endpoint_config(sim_time, ip_endpoint['cpu'], ip_endpoint['mem'], ip_endpoint['storage'], state, TICK_TIME) + data = lp.generate_endpoint_config(sim_time, ip_endpoint['cpu'], ip_endpoint['mem'], ip_endpoint['storage'], current_state, current_state_time) agent_db_client.write_points(data) @staticmethod @@ -422,7 +468,7 @@ class Sim(object): state_stats = {} for state, period, count in completed_states: state_stats[state] = period - state_stats["avg_{0}".format(state)] = float(period/count) + state_stats["{0}_mst".format(state)] = float(period/count) # transition state and state period are passed to the generate report function as keyword arguments agent_db_client.write_points(lp.generate_endpoint_config(sim_time, ip_endpoint['cpu'], ip_endpoint['mem'], ip_endpoint['storage'], diff --git a/clmctest/monitoring/test_simresults.py b/clmctest/monitoring/test_simresults.py index 41120936547c830d259865231fcb5a63d1cd5227..10c8351c67f0c833f710a3f3237167a9af3d5f58 100644 --- a/clmctest/monitoring/test_simresults.py +++ b/clmctest/monitoring/test_simresults.py @@ -32,33 +32,33 @@ class TestSimulation(object): {"time": "1970-01-01T00:00:00Z", "count_RX_BYTES_PORT_M": 7200, "count_TX_BYTES_PORT_M": 7200}), ('SELECT count(*) FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE ipendpoint=\'adaptive_streaming_I1_apache1\'', - {"time": "1970-01-01T00:00:00Z", "count_unplaced": 3639, "count_avg_unplaced": 3639, "count_placing": 3639, "count_avg_placing": 3639, "count_placed": 3639, "count_avg_placed": 3639, "count_booting": 3639, "count_avg_booting": 3639, "count_booted": 3639, - "count_avg_booted": 3639, "count_connecting": 3639, "count_avg_connecting": 3639, "count_connected": 3639, "count_avg_connected": 3639, "count_cpus": 3639, "count_memory": 3639, "count_storage": 3639}), + {"time": "1970-01-01T00:00:00Z", "count_current_state_time": 3639, "count_unplaced_sum": 3639, "count_unplaced_mst": 3639, "count_placing_sum": 3639, "count_placing_mst": 3639, "count_placed_sum": 3639, "count_placed_mst": 3639, "count_booting_sum": 3639, "count_booting_mst": 3639, "count_booted_sum": 3639, + "count_booted_mst": 3639, "count_connecting_sum": 3639, "count_connecting_mst": 3639, "count_connected_sum": 3639, "count_connected_mst": 3639, "count_cpus": 3639, "count_memory": 3639, "count_storage": 3639}), ('SELECT count(*) FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE ipendpoint=\'adaptive_streaming_I1_apache2\'', - {"time": "1970-01-01T00:00:00Z", "count_unplaced": 3639, "count_avg_unplaced": 3639, "count_placing": 3639, "count_avg_placing": 3639, "count_placed": 3639, "count_avg_placed": 3639, "count_booting": 3639, "count_avg_booting": 3639, "count_booted": 3639, - "count_avg_booted": 3639, "count_connecting": 3639, "count_avg_connecting": 3639, "count_connected": 3639, "count_avg_connected": 3639, "count_cpus": 3639, "count_memory": 3639, "count_storage": 3639}), + {"time": "1970-01-01T00:00:00Z", "count_current_state_time": 3639, "count_unplaced_sum": 3639, "count_unplaced_mst": 3639, "count_placing_sum": 3639, "count_placing_mst": 3639, "count_placed_sum": 3639, "count_placed_mst": 3639, "count_booting_sum": 3639, "count_booting_mst": 3639, "count_booted_sum": 3639, + "count_booted_mst": 3639, "count_connecting_sum": 3639, "count_connecting_mst": 3639, "count_connected_sum": 3639, "count_connected_mst": 3639, "count_cpus": 3639, "count_memory": 3639, "count_storage": 3639}), ('SELECT count(*) FROM "CLMCMetrics"."autogen"."mpegdash_mc_config" WHERE ipendpoint=\'adaptive_streaming_I1_apache1\'', {"time": "1970-01-01T00:00:00Z", "count_current_state_time": 3607, "count_running_mst": 3607, "count_running_sum": 3607, "count_starting_mst": 3607, "count_starting_sum": 3607, "count_stopped_mst": 3607, "count_stopped_sum": 3607, "count_stopping_mst": 3607, "count_stopping_sum": 3607}), ('SELECT count(*) FROM "CLMCMetrics"."autogen"."mpegdash_mc_config" WHERE ipendpoint=\'adaptive_streaming_I1_apache2\'', {"time": "1970-01-01T00:00:00Z", "count_current_state_time": 3607, "count_running_mst": 3607, "count_running_sum": 3607, "count_starting_mst": 3607, "count_starting_sum": 3607, "count_stopped_mst": 3607, "count_stopped_sum": 3607, "count_stopping_mst": 3607, "count_stopping_sum": 3607}), - ('SELECT mean(avg_placing) as "avg_placing" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE avg_placing <> 0 and ipendpoint=\'adaptive_streaming_I1_apache1\'', - {"time": "1970-01-01T00:00:00Z", "avg_placing": 9.4}), - ('SELECT mean(avg_booting) as "avg_booting" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE avg_booting <> 0 and ipendpoint=\'adaptive_streaming_I1_apache1\'', - {"time": "1970-01-01T00:00:00Z", "avg_booting": 9.6}), - ('SELECT mean(avg_connecting) as "avg_connecting" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE avg_connecting <> 0 and ipendpoint=\'adaptive_streaming_I1_apache1\'', - {"time": "1970-01-01T00:00:00Z", "avg_connecting": 10.2}), - ('SELECT mean(avg_connected) as "avg_connected" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE avg_connected <> 0 and ipendpoint=\'adaptive_streaming_I1_apache1\'', - {"time": "1970-01-01T00:00:00Z", "avg_connected": 3605.0}), - ('SELECT mean(avg_placing) as "avg_placing" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE avg_placing <> 0 and ipendpoint=\'adaptive_streaming_I1_apache2\'', - {"time": "1970-01-01T00:00:00Z", "avg_placing": 9.4}), - ('SELECT mean(avg_booting) as "avg_booting" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE avg_booting <> 0 and ipendpoint=\'adaptive_streaming_I1_apache2\'', - {"time": "1970-01-01T00:00:00Z", "avg_booting": 9.6}), - ('SELECT mean(avg_connecting) as "avg_connecting" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE avg_connecting <> 0 and ipendpoint=\'adaptive_streaming_I1_apache2\'', - {"time": "1970-01-01T00:00:00Z", "avg_connecting": 10.2}), - ('SELECT mean(avg_connected) as "avg_connected" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE avg_connected <> 0 and ipendpoint=\'adaptive_streaming_I1_apache2\'', - {"time": "1970-01-01T00:00:00Z", "avg_connected": 3605.0}), + ('SELECT mean(placing_mst) as "placing_mst" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE placing_mst <> 0 and ipendpoint=\'adaptive_streaming_I1_apache1\'', + {"time": "1970-01-01T00:00:00Z", "placing_mst": 9.4}), + ('SELECT mean(booting_mst) as "booting_mst" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE booting_mst <> 0 and ipendpoint=\'adaptive_streaming_I1_apache1\'', + {"time": "1970-01-01T00:00:00Z", "booting_mst": 9.6}), + ('SELECT mean(connecting_mst) as "connecting_mst" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE connecting_mst <> 0 and ipendpoint=\'adaptive_streaming_I1_apache1\'', + {"time": "1970-01-01T00:00:00Z", "connecting_mst": 10.2}), + ('SELECT mean(connected_mst) as "connected_mst" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE connected_mst <> 0 and ipendpoint=\'adaptive_streaming_I1_apache1\'', + {"time": "1970-01-01T00:00:00Z", "connected_mst": 3605.0}), + ('SELECT mean(placing_mst) as "placing_mst" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE placing_mst <> 0 and ipendpoint=\'adaptive_streaming_I1_apache2\'', + {"time": "1970-01-01T00:00:00Z", "placing_mst": 9.4}), + ('SELECT mean(booting_mst) as "booting_mst" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE booting_mst <> 0 and ipendpoint=\'adaptive_streaming_I1_apache2\'', + {"time": "1970-01-01T00:00:00Z", "booting_mst": 9.6}), + ('SELECT mean(connecting_mst) as "connecting_mst" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE connecting_mst <> 0 and ipendpoint=\'adaptive_streaming_I1_apache2\'', + {"time": "1970-01-01T00:00:00Z", "connecting_mst": 10.2}), + ('SELECT mean(connected_mst) as "connected_mst" FROM "CLMCMetrics"."autogen"."endpoint_config" WHERE connected_mst <> 0 and ipendpoint=\'adaptive_streaming_I1_apache2\'', + {"time": "1970-01-01T00:00:00Z", "connected_mst": 3605.0}), ('SELECT mean(stopped_sum) as "stopped_sum" FROM "CLMCMetrics"."autogen"."mpegdash_mc_config" WHERE stopped_sum <> 0', {"time": "1970-01-01T00:00:00Z", "stopped_sum": 0.2}), diff --git a/docs/monitoring.md b/docs/monitoring.md index cb439bbc0bdf43bf4f1d732a754c732f47482562..e964ce0a9c7386e13653dafe0a161b6f93abd0d1 100644 --- a/docs/monitoring.md +++ b/docs/monitoring.md @@ -532,6 +532,45 @@ In the example provided above a MC moves through several states. During each sam ##### Endpoint configuration state model +An endpoint configuration state model consists of the following states: + +* unplaced +* placing [transitional] +* placed +* booting [transitional] +* booted +* connecting [transitional] +* connected + +A simple example and some measurement rows for an endpoint configuration states is given in the table below. The scenario is the following: + +Each sample period is 1 second. + +First sample period reports the VM being in state __unpalced__ for 0.7s, then changing state to __placing__ for 0.3 seconds. __placing__ is not +reported since it is not a **completed state**. The mean state time value for __unplaced__ is the same as the sum value because the VM has only been once in this state. + +Then the VM is reported to be in current state __placing__ for the whole sample period (1s) for 9 consecutive times. Only the 'current_state' tag value and the 'current_state_time' +field value are filled in the measurement rows, since the VM has not exited its state, yet. + +The last sample period reports the VM exiting state __placing__, then changing state to __placed__. Hence, the __current_state__ tag is set to __placed__. +From the whole sample period (1s), the VM has been 0.9s in state 'placed'. Hence, the __current_state_time__ field is set to 0.9. For the other 0.1s of the sample period, +the VM has been reported to be in state __placing__. Since it has exited state __placing__, the total time spent in this state (9.3s + 0.1s = 9.4s) is reported. +This includes the state time from previous reports. The mean state time value for __placing__ is the same as the sum value because the VM has only been once in this state. + +| global tags | current_state (tag) | current_state_time | unplaced_sum | unplaced_mst | placing_sum | placing_mst | placed_sum | placed_mst | booting_sum | booting_mst | booted_sum | booted_mst | connecting_sum | connecting_mst | connected_sum | connected_mst | time | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| ... | placing | 0.3 | 0.7 | 0.7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | +| ... | placing | 1.3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | +| ... | placing | 2.3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | +| ... | placing | 3.3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | +| ... | placing | 4.3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | +| ... | placing | 5.3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | +| ... | placing | 6.3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | +| ... | placing | 7.3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | +| ... | placing | 8.3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | +| ... | placing | 9.3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | +| ... | placed | 0.9 | 0 | 0 | 9.4 | 9.4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | + ##### Media component configuration state model @@ -542,7 +581,7 @@ A media component configuration state model consists of the following states: * running * stopping [transitional] -An example (based the figure above) of some measurement rows for a media component configuration states is below: +An example (based on the figure above) of some measurement rows for a media component configuration states is below: | global tags | current_state (tag) | current_state_time | stopped_sum | stopped_mst | starting_sum | starting_mst | running_sum | running_mst | stopping_sum | stopping_mst | time | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |