stats_monitor.py 3.71 KB
Newer Older
1 2 3 4
"""
To create graphs and pickle from runtime statistics in L1,MAC,RRC,PDCP files
"""

5 6 7 8 9 10
import subprocess
import time
import shlex
import re
import sys
import pickle
11
import matplotlib.pyplot as plt
12
import numpy as np
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
import yaml


class StatMonitor():
    def __init__(self,cfg_file):
        with open(cfg_file,'r') as file:
            self.d = yaml.load(file)
        for node in self.d:
            for metric in self.d[node]:
                self.d[node][metric]=[]


    def process_gnb (self,node_type,output):
        for line in output:
            tmp=line.decode("utf-8")
            result=re.match(r'^.*\bdlsch_rounds\b ([0-9]+)\/([0-9]+).*\bdlsch_errors\b ([0-9]+)',tmp)
            if result is not None:
                self.d[node_type]['dlsch_err'].append(int(result.group(3)))
                percentage=float(result.group(2))/float(result.group(1))
                self.d[node_type]['dlsch_err_perc_round_1'].append(percentage)
            result=re.match(r'^.*\bulsch_rounds\b ([0-9]+)\/([0-9]+).*\bulsch_errors\b ([0-9]+)',tmp)
            if result is not None:
                self.d[node_type]['ulsch_err'].append(int(result.group(3)))
                percentage=float(result.group(2))/float(result.group(1))
                self.d[node_type]['ulsch_err_perc_round_1'].append(percentage)


    def process_enb (self,node_type,output):
        for line in output:
            tmp=line.decode("utf-8")
            result=re.match(r'^.*\bPHR\b ([0-9]+).+\bbler\b ([0-9]+\.[0-9]+).+\bmcsoff\b ([0-9]+).+\bmcs\b ([0-9]+)',tmp)
            if result is not None:
                self.d[node_type]['PHR'].append(int(result.group(1)))
                self.d[node_type]['bler'].append(float(result.group(2)))
                self.d[node_type]['mcsoff'].append(int(result.group(3)))
                self.d[node_type]['mcs'].append(int(result.group(4)))


    def collect(self,node_type):
        if node_type=='enb':
            cmd='cat L1_stats.log MAC_stats.log PDCP_stats.log RRC_stats.log'
        else: #'gnb'
            cmd='cat nrL1_stats.log nrMAC_stats.log nrPDCP_stats.log nrRRC_stats.log'
        process=subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
        output = process.stdout.readlines()
        if node_type=='enb':
            self.process_enb(node_type,output)
        else: #'gnb'
            self.process_gnb(node_type,output)


    def graph(self,node_type):
        col = 1
        figure, axis = plt.subplots(len(self.d[node_type]), col ,figsize=(10, 10))
        i=0
        for metric in self.d[node_type]:
            major_ticks = np.arange(0, len(self.d[node_type][metric])+1, 1)
            axis[i].set_xticks(major_ticks)
            axis[i].set_xticklabels([])
            axis[i].plot(self.d[node_type][metric],marker='o')
            axis[i].set_xlabel('time')
            axis[i].set_ylabel(metric)
            axis[i].set_title(metric)
            i+=1

        plt.tight_layout()
        # Combine all the operations and display
        plt.savefig(node_type+'_stats_monitor.png')
        plt.show()
82 83


84
if __name__ == "__main__":
85

86 87 88
    cfg_filename = sys.argv[1] #yaml file as metrics config
    node = sys.argv[2]#enb or gnb
    mon=StatMonitor(cfg_filename)
89

90 91 92
    #collecting stats when modem process is stopped
    CMD='ps aux | grep mode | grep -v grep'
    process=subprocess.Popen(CMD, shell=True, stdout=subprocess.PIPE)
93 94
    output = process.stdout.readlines()
    while len(output)!=0 :
95 96
        mon.collect(node)
        process=subprocess.Popen(CMD, shell=True, stdout=subprocess.PIPE)
97 98
        output = process.stdout.readlines()
        time.sleep(1)
99 100 101 102
    print('Process stopped')
    with open(node+'_stats_monitor.pickle', 'wb') as handle:
        pickle.dump(mon.d, handle, protocol=pickle.HIGHEST_PROTOCOL)
    mon.graph(node)