X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=adapter%2Fvppapiclient%2Fstat_client.go;h=2615b6537df52ea3ed57f014b9cc9b5f401db3ae;hb=6acebecfc33da246685c1cc14b2fc8bc6be3191b;hp=5f3b932e5cf3f605e077d87765dff32945ad4422;hpb=28df7c855784e784fb0e614c1cca0e565a7ef75f;p=govpp.git diff --git a/adapter/vppapiclient/stat_client.go b/adapter/vppapiclient/stat_client.go index 5f3b932..2615b65 100644 --- a/adapter/vppapiclient/stat_client.go +++ b/adapter/vppapiclient/stat_client.go @@ -20,135 +20,12 @@ package vppapiclient #cgo CFLAGS: -DPNG_DEBUG=1 #cgo LDFLAGS: -lvppapiclient -#include -#include -#include -#include -#include -#include - -static int -govpp_stat_connect(char *socket_name) -{ - return stat_segment_connect(socket_name); -} - -static void -govpp_stat_disconnect() -{ - stat_segment_disconnect(); -} - -static uint32_t* -govpp_stat_segment_ls(uint8_t ** pattern) -{ - return stat_segment_ls(pattern); -} - -static int -govpp_stat_segment_vec_len(void *vec) -{ - return stat_segment_vec_len(vec); -} - -static void -govpp_stat_segment_vec_free(void *vec) -{ - stat_segment_vec_free(vec); -} - -static char* -govpp_stat_segment_dir_index_to_name(uint32_t *dir, uint32_t index) -{ - return stat_segment_index_to_name(dir[index]); -} - -static stat_segment_data_t* -govpp_stat_segment_dump(uint32_t *counter_vec) -{ - return stat_segment_dump(counter_vec); -} - -static stat_segment_data_t -govpp_stat_segment_dump_index(stat_segment_data_t *data, int index) -{ - return data[index]; -} - -static int -govpp_stat_segment_data_type(stat_segment_data_t *data) -{ - return data->type; -} - -static double -govpp_stat_segment_data_get_scalar_value(stat_segment_data_t *data) -{ - return data->scalar_value; -} - -static double -govpp_stat_segment_data_get_error_value(stat_segment_data_t *data) -{ - return data->error_value; -} - -static uint64_t** -govpp_stat_segment_data_get_simple_counter(stat_segment_data_t *data) -{ - return data->simple_counter_vec; -} - -static uint64_t* -govpp_stat_segment_data_get_simple_counter_index(stat_segment_data_t *data, int index) -{ - return data->simple_counter_vec[index]; -} - -static uint64_t -govpp_stat_segment_data_get_simple_counter_index_value(stat_segment_data_t *data, int index, int index2) -{ - return data->simple_counter_vec[index][index2]; -} - -static vlib_counter_t** -govpp_stat_segment_data_get_combined_counter(stat_segment_data_t *data) -{ - return data->combined_counter_vec; -} - -static vlib_counter_t* -govpp_stat_segment_data_get_combined_counter_index(stat_segment_data_t *data, int index) -{ - return data->combined_counter_vec[index]; -} - -static uint64_t -govpp_stat_segment_data_get_combined_counter_index_packets(stat_segment_data_t *data, int index, int index2) -{ - return data->combined_counter_vec[index][index2].packets; -} - -static uint64_t -govpp_stat_segment_data_get_combined_counter_index_bytes(stat_segment_data_t *data, int index, int index2) -{ - return data->combined_counter_vec[index][index2].bytes; -} - -static void -govpp_stat_segment_data_free(stat_segment_data_t *data) -{ - stat_segment_data_free(data); -} - -static uint8_t** -govpp_stat_segment_string_vector(uint8_t ** string_vector, char *string) -{ - return stat_segment_string_vector(string_vector, string); -} +#include "stat_client_wrapper.h" */ import "C" + import ( + "errors" "fmt" "os" "unsafe" @@ -156,26 +33,38 @@ import ( "git.fd.io/govpp.git/adapter" ) +var ( + ErrStatDirBusy = errors.New("stat dir busy") + ErrStatDumpBusy = errors.New("stat dump busy") +) + var ( // DefaultStatSocket is the default path for the VPP stat socket file. DefaultStatSocket = "/run/vpp/stats.sock" ) -// StatClient is the default implementation of StatsAPI. -type StatClient struct { +// global VPP stats API client, library vppapiclient only supports +// single connection at a time +var globalStatClient *statClient + +// stubStatClient is the default implementation of StatsAPI. +type statClient struct { socketName string } // NewStatClient returns new VPP stats API client. -func NewStatClient(socketName string) *StatClient { - return &StatClient{ +func NewStatClient(socketName string) adapter.StatsAPI { + return &statClient{ socketName: socketName, } } -func (c *StatClient) Connect() error { - var sockName string +func (c *statClient) Connect() error { + if globalStatClient != nil { + return fmt.Errorf("already connected to stats API, disconnect first") + } + var sockName string if c.socketName == "" { sockName = DefaultStatSocket } else { @@ -187,16 +76,22 @@ func (c *StatClient) Connect() error { return fmt.Errorf("connecting to VPP stats API failed (rc=%v)", rc) } + globalStatClient = c return nil } -func (c *StatClient) Disconnect() error { +func (c *statClient) Disconnect() error { + globalStatClient = nil + C.govpp_stat_disconnect() return nil } -func (c *StatClient) ListStats(patterns ...string) (stats []string, err error) { +func (c *statClient) ListStats(patterns ...string) (stats []string, err error) { dir := C.govpp_stat_segment_ls(convertStringSlice(patterns)) + if dir == nil { + return nil, ErrStatDirBusy + } defer C.govpp_stat_segment_vec_free(unsafe.Pointer(dir)) l := C.govpp_stat_segment_vec_len(unsafe.Pointer(dir)) @@ -209,11 +104,17 @@ func (c *StatClient) ListStats(patterns ...string) (stats []string, err error) { return stats, nil } -func (c *StatClient) DumpStats(patterns ...string) (stats []*adapter.StatEntry, err error) { +func (c *statClient) DumpStats(patterns ...string) (stats []*adapter.StatEntry, err error) { dir := C.govpp_stat_segment_ls(convertStringSlice(patterns)) + if dir == nil { + return nil, ErrStatDirBusy + } defer C.govpp_stat_segment_vec_free(unsafe.Pointer(dir)) dump := C.govpp_stat_segment_dump(dir) + if dump == nil { + return nil, ErrStatDumpBusy + } defer C.govpp_stat_segment_data_free(dump) l := C.govpp_stat_segment_vec_len(unsafe.Pointer(dump)) @@ -239,8 +140,8 @@ func (c *StatClient) DumpStats(patterns ...string) (stats []*adapter.StatEntry, length := int(C.govpp_stat_segment_vec_len(unsafe.Pointer(C.govpp_stat_segment_data_get_simple_counter(&v)))) vector := make([][]adapter.Counter, length) for k := 0; k < length; k++ { - for j := 0; j < int(C.govpp_stat_segment_vec_len(unsafe.Pointer(C.govpp_stat_segment_data_get_simple_counter_index(&v, _Ctype_int(k))))); j++ { - vector[k] = append(vector[k], adapter.Counter(C.govpp_stat_segment_data_get_simple_counter_index_value(&v, _Ctype_int(k), _Ctype_int(j)))) + for j := 0; j < int(C.govpp_stat_segment_vec_len(unsafe.Pointer(C.govpp_stat_segment_data_get_simple_counter_index(&v, C.int(k))))); j++ { + vector[k] = append(vector[k], adapter.Counter(C.govpp_stat_segment_data_get_simple_counter_index_value(&v, C.int(k), C.int(j)))) } } stat.Data = adapter.SimpleCounterStat(vector) @@ -249,17 +150,30 @@ func (c *StatClient) DumpStats(patterns ...string) (stats []*adapter.StatEntry, length := int(C.govpp_stat_segment_vec_len(unsafe.Pointer(C.govpp_stat_segment_data_get_combined_counter(&v)))) vector := make([][]adapter.CombinedCounter, length) for k := 0; k < length; k++ { - for j := 0; j < int(C.govpp_stat_segment_vec_len(unsafe.Pointer(C.govpp_stat_segment_data_get_combined_counter_index(&v, _Ctype_int(k))))); j++ { + for j := 0; j < int(C.govpp_stat_segment_vec_len(unsafe.Pointer(C.govpp_stat_segment_data_get_combined_counter_index(&v, C.int(k))))); j++ { vector[k] = append(vector[k], adapter.CombinedCounter{ - Packets: adapter.Counter(C.govpp_stat_segment_data_get_combined_counter_index_packets(&v, _Ctype_int(k), _Ctype_int(j))), - Bytes: adapter.Counter(C.govpp_stat_segment_data_get_combined_counter_index_bytes(&v, _Ctype_int(k), _Ctype_int(j))), + Packets: adapter.Counter(C.govpp_stat_segment_data_get_combined_counter_index_packets(&v, C.int(k), C.int(j))), + Bytes: adapter.Counter(C.govpp_stat_segment_data_get_combined_counter_index_bytes(&v, C.int(k), C.int(j))), }) } } stat.Data = adapter.CombinedCounterStat(vector) + case adapter.NameVector: + length := int(C.govpp_stat_segment_vec_len(unsafe.Pointer(C.govpp_stat_segment_data_get_name_vector(&v)))) + var vector []adapter.Name + for k := 0; k < length; k++ { + s := C.govpp_stat_segment_data_get_name_vector_index(&v, C.int(k)) + var name adapter.Name + if s != nil { + name = adapter.Name(C.GoString(s)) + } + vector = append(vector, name) + } + stat.Data = adapter.NameStat(vector) + default: - fmt.Fprintf(os.Stderr, "invalid stat type: %v (%d)", typ, typ) + fmt.Fprintf(os.Stderr, "invalid stat type: %v (%v)\n", typ, name) continue }