3 from __future__ import print_function
8 typedef uint64_t counter_t;
15 STAT_DIR_TYPE_ILLEGAL = 0,
16 STAT_DIR_TYPE_SCALAR_POINTER,
17 STAT_DIR_TYPE_VECTOR_POINTER,
18 STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE,
19 STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED,
20 STAT_DIR_TYPE_ERROR_INDEX,
21 STAT_DIR_TYPE_SERIALIZED_NODES,
22 } stat_directory_type_t;
25 stat_directory_type_t type;
27 } stat_segment_directory_entry_t;
31 stat_directory_type_t type;
35 uint64_t *vector_pointer;
36 counter_t **simple_counter_vec;
37 vlib_counter_t **combined_counter_vec;
39 } stat_segment_data_t;
43 stat_segment_directory_entry_t *ep;
44 } stat_segment_cached_pointer_t;
46 int stat_segment_connect (char *socket_name);
47 void stat_segment_disconnect (void);
49 uint8_t **stat_segment_ls (uint8_t **pattern);
50 stat_segment_data_t *stat_segment_dump (uint8_t ** counter_vec);
51 /* Collects registered counters */
52 stat_segment_cached_pointer_t *stat_segment_register (uint8_t ** counter_vec);
53 stat_segment_data_t *stat_segment_collect (stat_segment_cached_pointer_t *);
54 void stat_segment_data_free (stat_segment_data_t * res);
55 double stat_segment_heartbeat (void);
56 int stat_segment_vec_len(void *vec);
57 uint8_t **stat_segment_string_vector(uint8_t **string_vector, char *string);
62 def make_string_vector(api, strings):
64 if type(strings) is not list:
67 vec = api.stat_segment_string_vector(vec, ffi.new("char []", s))
71 def make_string_list(api, vec):
72 vec_len = api.stat_segment_vec_len(vec)
73 return [ffi.string(vec[i]) for i in range(vec_len)]
76 # 2-dimensonal array of thread, index
77 def simple_counter_vec_list(api, e):
79 for thread in range(api.stat_segment_vec_len(e)):
80 len_interfaces = api.stat_segment_vec_len(e[thread])
81 if_per_thread = [e[thread][interfaces]
82 for interfaces in range(len_interfaces)]
83 vec.append(if_per_thread)
87 def vlib_counter_dict(c):
88 return {'packets': c.packets,
92 def combined_counter_vec_list(api, e):
94 for thread in range(api.stat_segment_vec_len(e)):
95 len_interfaces = api.stat_segment_vec_len(e[thread])
96 if_per_thread = [vlib_counter_dict(e[thread][interfaces])
97 for interfaces in range(len_interfaces)]
98 vec.append(if_per_thread)
102 def stat_entry_to_python(api, e):
104 return simple_counter_vec_list(e.simple_counter_vec)
106 return combined_counter_vec_list(api, e.combined_counter_vec)
113 def __init__(self, socketname='/var/run/stats.sock'):
114 self.api = ffi.dlopen('libvppapiclient.so')
115 rv = self.api.stat_segment_connect(socketname)
120 return self.api.stat_segment_heartbeat()
122 def ls(self, patterns):
123 return self.api.stat_segment_ls(make_string_vector(self.api, patterns))
125 def dump(self, counters):
127 rv = self.api.stat_segment_dump(counters)
128 rv_len = self.api.stat_segment_vec_len(rv)
129 for i in range(rv_len):
130 n = ffi.string(rv[i].name)
131 e = stat_entry_to_python(self.api, rv[i])
136 def dump_str(self, counters_str):
137 return self.dump(make_string_vector(self.api, counters_str))
139 def disconnect(self):
140 self.api.stat_segment_disconnect()
142 def set_errors(self):
143 '''Return all errors counters > 0'''
144 error_names = self.ls(['/err/'])
145 error_counters = self.dump(error_names)
146 return {k: error_counters[k]
147 for k in error_counters.keys() if error_counters[k]}
149 def set_errors_str(self):
150 '''Return all errors counters > 0 pretty printed'''
152 error_counters = self.set_errors()
153 for k in sorted(error_counters):
154 s += '{:<60}{:>10}\n'.format(k, error_counters[k])