Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:Update
collectd.23723
dpdk_telemetry-plugin-add-plugin-for-DPDK-metri...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File dpdk_telemetry-plugin-add-plugin-for-DPDK-metrics-via-DPDK-Telemetry-library.patch of Package collectd.23723
From: Reshma Pattan <reshma.pattan@intel.com> Subject: dpdk_telemetry plugin: add plugin for DPDK metrics via DPDK Telemetry library References: jsc#SLE-23472 Patch-Mainline: collectd-5.11.0 Git-commit: 00cbd4d2c016a676db476ae66bbc58d6bf11a6a0 Git-repo: git://github.com/collectd/collectd.git.git This patch introduces a new plugin for collectd, which consumes DPDK metrics via the dpdk_telemetry library. The collectd plugin here provides an easy way to use the DPDK telemetry API to query ethernet device metrics. The collectd plugin retrieves metrics from a DPDK packet forwarding application by sending a JSON formatted message via a UNIX domain socket. The DPDK telemetry component will respond with a JSON formatted reply, delivering the requested metrics. The dpdk_telemetry collectd plugin parses the JSON data, and publishes the metric values to collectd for further use. This plugin has a dependency on the DPDK Telemetry library, as it must be "in sync" with the DPDK Telemetry implementation. Change-Id: If3343aae4c5473f0574465fab0395b7672fa2488 Signed-off-by: Emma Kenny <emma.kenny@intel.com> Signed-off-by: Brian Archbold <brian.archbold@intel.com> Signed-off-by: Reshma Pattan <reshma.pattan@intel.com> Signed-off-by: <trenn@suse.com> Index: collectd-5.10.0/Makefile.am =================================================================== --- collectd-5.10.0.orig/Makefile.am +++ collectd-5.10.0/Makefile.am @@ -963,6 +963,13 @@ dpdkstat_la_CFLAGS = $(AM_CFLAGS) $(LIBD dpdkstat_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBDPDK_LDFLAGS) dpdkstat_la_LIBADD = $(LIBDPDK_LIBS) endif +if BUILD_PLUGIN_DPDK_TELEMETRY +pkglib_LTLIBRARIES += dpdk_telemetry.la +dpdk_telemetry_la_SOURCES = src/dpdk_telemetry.c +dpdk_telemetry_la_CFLAGS = $(AM_CFLAGS) +dpdk_telemetry_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBJANSSON_LDFLAGS) +dpdk_telemetry_la_LIBADD = $(BUILD_WITH_LIBJANSSON_LIBS) +endif if BUILD_PLUGIN_DRBD pkglib_LTLIBRARIES += drbd.la Index: collectd-5.10.0/README =================================================================== --- collectd-5.10.0.orig/README +++ collectd-5.10.0/README @@ -106,6 +106,15 @@ Features This plugin should be compiled with compiler defenses enabled, for example -fstack-protector. + - dpdk_telemetry + Collect DPDK interface, application and global statistics. + This plugin can be used as substitute to dpdkstat plugin. + + This plugin is dependent on DPDK 19.08 release and must be used + along with the DPDK application. + + Also, this plugin has dependency on Jansson library. + - drbd Collect individual drbd resource statistics. @@ -824,6 +833,9 @@ Prerequisites For querying iptables counters. <http://netfilter.org/> + * libjansson (optional) + Used by the `dpdk_telemetry` plugin. + * libjevents (optional) The jevents library is used by the `intel_pmu' plugin to access the Linux kernel perf interface. Index: collectd-5.10.0/configure.ac =================================================================== --- collectd-5.10.0.orig/configure.ac +++ collectd-5.10.0/configure.ac @@ -4520,6 +4520,51 @@ AC_SUBST([BUILD_WITH_LIBPQOS_LDFLAGS]) AC_SUBST([BUILD_WITH_LIBPQOS_LIBS]) # }}} +# --with-libjansson {{{ +AC_ARG_WITH([libjansson], +[AS_HELP_STRING([--with-libjansson@<:@=PREFIX@:>@], [Path to libjansson.])], +[ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + with_libjansson_cppflags="-I$withval/include" + with_libjansson_ldflags="-L$withval/lib" + with_libjansson="yes" + else + with_libjansson="$withval" + fi +], + [with_libjansson="yes"] +) + +if test "x$with_libjansson" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libjansson_cppflags" + + AC_CHECK_HEADERS([jansson.h], + [with_libjansson="yes"], + [with_libjansson="no (jansson.h not found)"] + ) + CPPFLAGS="$SAVE_CPPFLAGS" +fi +if test "x$with_libjansson" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_jansson_ldflags" + + AC_CHECK_LIB([jansson], [json_is_object], + [with_jansson="yes"], + [with_jansson="no (Symbol 'json_is_object' not found)"] + ) + + LDFLAGS="$SAVE_LDFLAGS" +fi + +BUILD_WITH_LIBJANSSON_CPPFLAGS="$with_libjansson_cppflags" +BUILD_WITH_LIBJANSSON_LDFLAGS="$with_libjansson_ldflags" +BUILD_WITH_LIBJANSSON_LIBS="-ljansson" +AC_SUBST(BUILD_WITH_LIBJANSSON_CPPFLAGS) +AC_SUBST(BUILD_WITH_LIBJANSSON_LDFLAGS) +AC_SUBST(BUILD_WITH_LIBJANSSON_LIBS) +# }}} + # --with-libjevents {{{ with_libjevents_cppflags="" with_libjevents_ldflags="" @@ -6354,6 +6399,7 @@ plugin_disk="no" plugin_drbd="no" plugin_dpdkevents="no" plugin_dpdkstat="no" +plugin_dpdk_telemetry="no" plugin_entropy="no" plugin_ethstat="no" plugin_fhcount="no" @@ -6741,6 +6787,10 @@ if test "x$with_libdpdk" = "xyes"; then plugin_dpdkstat="yes" fi +if test "x$with_libjansson" = "xyes"; then + plugin_dpdk_telemetry="yes" +fi + m4_divert_once([HELP_ENABLE], [ collectd plugins:]) @@ -6792,6 +6842,7 @@ AC_PLUGIN([dns], [$with_ AC_PLUGIN([dpdkevents], [$plugin_dpdkevents], [Events from DPDK]) AC_PLUGIN([dpdkstat], [$plugin_dpdkstat], [Stats from DPDK]) AC_PLUGIN([drbd], [$plugin_drbd], [DRBD statistics]) +AC_PLUGIN([dpdk_telemetry], [$plugin_dpdk_telemetry], [Metrics from DPDK Telemetry]) AC_PLUGIN([email], [yes], [EMail statistics]) AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics]) AC_PLUGIN([ethstat], [$plugin_ethstat], [Stats from NIC driver]) @@ -7132,6 +7183,7 @@ AC_MSG_RESULT([ libhiredis . . . . . AC_MSG_RESULT([ libi2c-dev . . . . . $with_libi2c]) AC_MSG_RESULT([ libiokit . . . . . . $with_libiokit]) AC_MSG_RESULT([ libiptc . . . . . . . $with_libiptc]) +AC_MSG_RESULT([ libjansson . . . . . $with_libjansson]) AC_MSG_RESULT([ libjevents . . . . . $with_libjevents]) AC_MSG_RESULT([ libjvm . . . . . . . $with_java]) AC_MSG_RESULT([ libkstat . . . . . . $with_kstat]) @@ -7225,6 +7277,7 @@ AC_MSG_RESULT([ dns . . . . . . . . . AC_MSG_RESULT([ dpdkevents. . . . . . $enable_dpdkevents]) AC_MSG_RESULT([ dpdkstat . . . . . . $enable_dpdkstat]) AC_MSG_RESULT([ drbd . . . . . . . . $enable_drbd]) +AC_MSG_RESULT([ dpdk_telemetry. . . . $enable_dpdk_telemetry]) AC_MSG_RESULT([ email . . . . . . . . $enable_email]) AC_MSG_RESULT([ entropy . . . . . . . $enable_entropy]) AC_MSG_RESULT([ ethstat . . . . . . . $enable_ethstat]) Index: collectd-5.10.0/src/collectd.conf.in =================================================================== --- collectd-5.10.0.orig/src/collectd.conf.in +++ collectd-5.10.0/src/collectd.conf.in @@ -119,6 +119,7 @@ #@BUILD_PLUGIN_DNS_TRUE@LoadPlugin dns #@BUILD_PLUGIN_DPDKEVENTS_TRUE@LoadPlugin dpdkevents #@BUILD_PLUGIN_DPDKSTAT_TRUE@LoadPlugin dpdkstat +#@BUILD_PLUGIN_DPDK_TELEMETRY_TRUE@LoadPlugin dpdk_telemetry #@BUILD_PLUGIN_DRBD_TRUE@LoadPlugin drbd #@BUILD_PLUGIN_EMAIL_TRUE@LoadPlugin email #@BUILD_PLUGIN_ENTROPY_TRUE@LoadPlugin entropy @@ -610,6 +611,11 @@ # PortName "interface2" #</Plugin> +#<Plugin dpdk_telemetry> +# ClientSocketPath "/var/run/.client" +# DpdkSocketPath "/var/run/dpdk/rte/telemetry" +#</Plugin> + #<Plugin email> # SocketFile "@localstatedir@/run/@PACKAGE_NAME@-email" # SocketGroup "collectd" Index: collectd-5.10.0/src/collectd.conf.pod =================================================================== --- collectd-5.10.0.orig/src/collectd.conf.pod +++ collectd-5.10.0/src/collectd.conf.pod @@ -2944,6 +2944,41 @@ convention will be used for the addition =back +=head2 Plugin C<dpdk_telemetry> + + +The I< dpdk_telemetry > plugin collects DPDK ethernet device metrics via +dpdk_telemetry library. + +The plugin retrieves metrics from a DPDK packet forwarding application +by sending the JSON formatted message via a UNIX domain socket. +The DPDK telemetry component will respond with a JSON formatted reply, +delivering the requested metrics. The plugin parses the JSON data, +and publishes the metric values to collectd for further use. + +B<Synopsis:> + + <Plugin dpdk_telemetry> + ClientSocketPath "/var/run/.client" + DpdkSocketPath "/var/run/dpdk/rte/telemetry" + </Plugin> + +B<Options:> + +=over 2 + +=item B<ClientSocketPath> I<Client_Path> + +The UNIX domain client socket at I<Client_Path> to receive messages from DPDK +telemetry library. Defaults to B<"/var/run/.client">. + +=item B<DpdkSocketPath> I<Dpdk_Path> + +The UNIX domain DPDK telemetry socket to be connected at I<Dpdk_Path> to send +messages. Defaults to B<"/var/run/dpdk/rte/telemetry">. + +=back + =head2 Plugin C<email> =over 4 Index: collectd-5.10.0/src/dpdk_telemetry.c =================================================================== --- /dev/null +++ collectd-5.10.0/src/dpdk_telemetry.c @@ -0,0 +1,434 @@ +/*- + * collectd - src/dpdk_telemetry.c + * MIT License + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to + * do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#include "collectd.h" +#include "plugin.h" +#include "utils/common/common.h" +#include "utils_time.h" + +#include <errno.h> +#include <jansson.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/queue.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <sys/unistd.h> + +#define BUF_SIZE 100000 +#define PLUGIN_NAME "dpdk_telemetry" +#define DEFAULT_DPDK_PATH "/var/run/dpdk/rte/telemetry" +#define DEFAULT_CLIENT_PATH "/var/run/.client" +#define MAX_COMMANDS 2 + +struct client_info { + int s_send; + int s_recv; + int fd; + const char *dpdk_path; + const char *client_path; + struct sockaddr_un addr; + struct sockaddr_un addrs; +}; + +typedef struct client_info client_info_t; + +static client_info_t client; +static char g_client_path[BUF_SIZE]; +static char g_dpdk_path[BUF_SIZE]; +cdtime_t dpdk_tel_interval = 0; + +static int dpdk_telemetry_config(oconfig_item_t *ci) { + int ret, i; + + INFO(PLUGIN_NAME ": %s:%d", __FUNCTION__, __LINE__); + + for (i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("ClientSocketPath", child->key) == 0) { + ret = cf_util_get_string_buffer(child, g_client_path, + sizeof(g_client_path)); + } else if (strcasecmp("DpdkSocketPath", child->key) == 0) { + ret = cf_util_get_string_buffer(child, g_dpdk_path, sizeof(g_dpdk_path)); + } else { + ERROR(PLUGIN_NAME ": Unknown configuration parameter" + "\"%s\"", + child->key); + ret = -1; + } + + if (ret < 0) { + INFO(PLUGIN_NAME ": %s:%d ret =%d", __FUNCTION__, __LINE__, ret); + return ret; + } + } + + dpdk_tel_interval = plugin_get_interval(); + return 0; +} + +static int dpdk_telemetry_parse(json_t *stats, json_t *port) { + json_t *statsArrayObj; + int portid; + + if (!stats) { + ERROR(PLUGIN_NAME ": Stats pointer is invalid"); + return -1; + } + + if (!port) { + ERROR(PLUGIN_NAME ": Port pointer is invalid"); + return -1; + } + portid = json_integer_value(port); + + if (portid < -1) { + ERROR(PLUGIN_NAME ": portid is invalid"); + return -1; + } + + json_t *name, *value; + const char *name_string; + int statslen, i; + uint64_t value_int; + statslen = json_array_size(stats); + for (i = 0; i < statslen; i++) { + statsArrayObj = json_array_get(stats, i); + name = json_object_get(statsArrayObj, "name"); + value = json_object_get(statsArrayObj, "value"); + if (!name) { + ERROR(PLUGIN_NAME ": Request does not have name field"); + return -1; + } + if (!json_is_string(name)) { + ERROR(PLUGIN_NAME ": Metric name is not a string"); + return -1; + } + name_string = json_string_value(name); + if (!value) { + ERROR(PLUGIN_NAME ": Request does not have value name"); + return -1; + } + if (!json_is_integer(value)) { + ERROR(PLUGIN_NAME ": Metric value is not an integer"); + return -1; + } + + char dev_name[DATA_MAX_NAME_LEN]; + if (portid == -1) + snprintf(dev_name, sizeof(dev_name), "%s", name_string); + else + snprintf(dev_name, sizeof(dev_name), "%s.%d", name_string, portid); + value_int = json_integer_value(value); + value_t dpdk_telemetry_values[1]; + value_list_t dpdk_telemetry_vl = VALUE_LIST_INIT; + dpdk_telemetry_values[0].counter = value_int; + dpdk_telemetry_vl.values = dpdk_telemetry_values; + dpdk_telemetry_vl.values_len = 1; + dpdk_telemetry_vl.time = cdtime(); + snprintf(dpdk_telemetry_vl.host, sizeof(dpdk_telemetry_vl.host), "%s", + hostname_g); + snprintf(dpdk_telemetry_vl.plugin, sizeof(dpdk_telemetry_vl.plugin), + "dpdk_telemetry"); + sstrncpy(dpdk_telemetry_vl.plugin_instance, dev_name, + sizeof(dpdk_telemetry_vl.plugin_instance)); + snprintf(dpdk_telemetry_vl.type, sizeof(dpdk_telemetry_vl.type), + "dpdk_telemetry"); + snprintf(dpdk_telemetry_vl.type_instance, + sizeof(dpdk_telemetry_vl.type_instance), "%s", name_string); + + int ret = plugin_dispatch_values(&dpdk_telemetry_vl); + if (ret < 0) { + ERROR(PLUGIN_NAME ": Failed to dispatch values"); + return -1; + } + } + return 0; +} + +static int parse_json(char *buf) { + + if (!buf) { + ERROR(PLUGIN_NAME ": buf pointer is invalid"); + return -1; + } + json_error_t error; + json_t *root = json_loads(buf, 0, &error); + int arraylen, i; + json_t *status, *dataArray, *stats, *dataArrayObj; + stats = NULL; + + if (!root) { + ERROR(PLUGIN_NAME ": Could not load JSON object from data passed in" + " : %s", + error.text); + return -1; + } else if (!json_is_object(root)) { + ERROR(PLUGIN_NAME ": JSON Request is not a JSON object"); + json_decref(root); + return -1; + } + + status = json_object_get(root, "status_code"); + if (!status) { + ERROR(PLUGIN_NAME ": Request does not have status field"); + return -1; + } else if (!json_is_string(status)) { + ERROR(PLUGIN_NAME ": Status value is not a string"); + return -1; + } + dataArray = json_object_get(root, "data"); + if (!dataArray) { + ERROR(PLUGIN_NAME ": Request does not have data field"); + return -1; + } + arraylen = json_array_size(dataArray); + if (!arraylen) { + ERROR(PLUGIN_NAME ": No data to get"); + return -1; + } + + for (i = 0; i < arraylen; i++) { + json_t *port; + dataArrayObj = json_array_get(dataArray, i); + port = json_object_get(dataArrayObj, "port"); + stats = json_object_get(dataArrayObj, "stats"); + if (!port) { + ERROR(PLUGIN_NAME ": Request does not have port field"); + return -1; + } + if (!json_is_integer(port)) { + ERROR(PLUGIN_NAME ": Port value is not an integer"); + return -1; + } + + if (!stats) { + ERROR(PLUGIN_NAME ": Request does not have stats field"); + return -1; + } + dpdk_telemetry_parse(stats, port); + } + return 0; +} + +static int dpdk_telemetry_cleanup(void) { + close(client.s_send); + close(client.s_recv); + close(client.fd); + return 0; +} + +static int dpdk_telemetry_socket_init(void) { + INFO(PLUGIN_NAME ": %s:%d", __FUNCTION__, __LINE__); + char message[BUF_SIZE]; + + /* Here we look up the length of the g_dpdk_path string + * If it has a length we use it, otherwise we fall back to default + * See dpdk_telemetry_config() for details + */ + client.dpdk_path = (strlen(g_dpdk_path)) ? g_dpdk_path : DEFAULT_DPDK_PATH; + client.client_path = + (strlen(g_client_path)) ? g_client_path : DEFAULT_CLIENT_PATH; + client.s_send = socket(AF_UNIX, SOCK_SEQPACKET, 0); + if (client.s_send < 0) { + ERROR(PLUGIN_NAME ": Failed to open socket errno(%d), error(%s)", errno, + strerror(errno)); + dpdk_telemetry_cleanup(); + return -1; + } + client.s_recv = socket(AF_UNIX, SOCK_SEQPACKET, 0); + if (client.s_recv < 0) { + ERROR(PLUGIN_NAME ": Failed to open message socket errno(%d), error(%s)", + errno, strerror(errno)); + dpdk_telemetry_cleanup(); + return -1; + } + client.addr.sun_family = AF_UNIX; + snprintf(client.addr.sun_path, sizeof(client.addr.sun_path), "%s", + client.dpdk_path); + if (connect(client.s_send, (struct sockaddr *)&client.addr, + sizeof(client.addr)) < 0) { + ERROR(PLUGIN_NAME ": Failed to connect errno(%d), error(%s)", errno, + strerror(errno)); + dpdk_telemetry_cleanup(); + return -1; + } + client.addrs.sun_family = AF_UNIX; + snprintf(client.addrs.sun_path, sizeof(client.addrs.sun_path), "%s", + client.client_path); + unlink(client.client_path); + if (bind(client.s_recv, (struct sockaddr *)&client.addrs, + sizeof(client.addrs)) < 0) { + ERROR(PLUGIN_NAME ": Failed to bind errno(%d), error(%s)", errno, + strerror(errno)); + dpdk_telemetry_cleanup(); + return -1; + } + if (listen(client.s_recv, 1) < 0) { + ERROR(PLUGIN_NAME ": Listen failed errno(%d), error(%s)", errno, + strerror(errno)); + dpdk_telemetry_cleanup(); + return -1; + } + snprintf(message, sizeof(message), + "{\"action\":1,\"command\":\"clients\"" + ",\"data\":{\"client_path\":\"%s\"}}", + client.client_path); + if (send(client.s_send, message, strlen(message), 0) < 0) { + ERROR(PLUGIN_NAME ": Could not send register message errno(%d), error(%s)", + errno, strerror(errno)); + dpdk_telemetry_cleanup(); + return -1; + } + client.fd = accept(client.s_recv, NULL, NULL); + if (client.fd < 0) { + ERROR(PLUGIN_NAME ": Failed to accept errno(%d), error(%s)", errno, + strerror(errno)); + dpdk_telemetry_cleanup(); + return -1; + } + return 0; +} + +static int dpdk_telemetry_shutdown(void) { + INFO(PLUGIN_NAME ": %s:%d", __FUNCTION__, __LINE__); + char msg[BUF_SIZE]; + int ret; + + snprintf(msg, sizeof(msg), + "{\"action\":2,\"command\":\"clients\"" + ",\"data\":{\"client_path\":\"%s\"}}", + client.client_path); + ret = send(client.fd, msg, strlen(msg), 0); + if (ret < 0) { + ERROR(PLUGIN_NAME ": Could not send unregister message"); + dpdk_telemetry_cleanup(); + return -1; + } + dpdk_telemetry_cleanup(); + return 0; +} + +static int dpdk_telemetry_read(user_data_t *ud) { + INFO(PLUGIN_NAME ": %s:%d", __FUNCTION__, __LINE__); + char buffer[BUF_SIZE]; + int bytes = 0, ret; + cdtime_t prev = 0; + char *json_string[MAX_COMMANDS] = {"{\"action\":0,\"command\":" + "\"ports_all_stat_values\",\"data\":null}", + "{\"action\":0,\"command\":" + "\"global_stat_values\",\"data\":null}"}; + size_t size = sizeof(json_string) / sizeof(json_string[0]); + + prev = cdtime(); + for (int i = 0; i < size; i++) { + /* Exit the read function after passing the half of the + * plugin interval to avoid blocking of other collectd plugins. + */ + if ((cdtime() - prev) > (dpdk_tel_interval / 2)) { + ERROR(PLUGIN_NAME ":Cannot read after the interval %d", __LINE__); + return -1; + } + while (1) { + /* Exit the read function after passing the half of the plugin + * interval in order to avoid blocking of other collectd + * plugins. + * + * For send() and parse_json() failures, try reconnecting + * to the socket, as we don't know what exactly happened on + * server side. + */ + if ((cdtime() - prev) > (dpdk_tel_interval / 2)) { + ERROR(PLUGIN_NAME ":Cannot read after interval %d", __LINE__); + return -1; + } + if (send(client.fd, json_string[i], strlen(json_string[i]), 0) < 0) { + ERROR(PLUGIN_NAME ": Could not send stats errno(%d), error(%s)", errno, + strerror(errno)); + if (errno == EBADF || errno == ECONNRESET || errno == ENOTCONN || + errno == EPIPE) { + dpdk_telemetry_cleanup(); + if (dpdk_telemetry_socket_init() < 0) + continue; + } + } else { + bytes = recv(client.fd, buffer, sizeof(buffer) - 1, 0); + if (bytes < 0) { + ERROR(PLUGIN_NAME ": Could not receive stats errno(%d), error(%s)", + errno, strerror(errno)); + continue; + } else { + buffer[bytes] = '\0'; + ret = parse_json(buffer); + if (ret < 0) { + ERROR(PLUGIN_NAME ": Parsing failed"); + dpdk_telemetry_cleanup(); + dpdk_telemetry_socket_init(); + continue; + } + break; + } + } + } + } + return 0; +} + +static int dpdk_telemetry_init(void) { + cdtime_t prev = 0; + + prev = cdtime(); + while (1) { + /* If server socket is already not running, try connecting + * for period of 6 seconds to provide resiliency. + * If server doesn't shows up even after 6seconds, mark the + * initialization as failure. + */ + if ((cdtime() - prev) > dpdk_tel_interval) { + ERROR(PLUGIN_NAME ":Cannot retry initialization after the interval"); + return -1; + } + if (dpdk_telemetry_socket_init() < 0) { + ERROR(PLUGIN_NAME ": Socket initialization failed"); + continue; + } + break; + } + plugin_register_complex_read(NULL, PLUGIN_NAME, dpdk_telemetry_read, + dpdk_tel_interval, NULL); + return 0; +} + +void module_register(void) { + plugin_register_init(PLUGIN_NAME, dpdk_telemetry_init); + plugin_register_complex_config(PLUGIN_NAME, dpdk_telemetry_config); + plugin_register_shutdown(PLUGIN_NAME, dpdk_telemetry_shutdown); +} Index: collectd-5.10.0/src/types.db =================================================================== --- collectd-5.10.0.orig/src/types.db +++ collectd-5.10.0/src/types.db @@ -79,6 +79,7 @@ dns_transfer value:DERIVE:0:U dns_update value:DERIVE:0:U dns_zops value:DERIVE:0:U domain_state state:GAUGE:0:U, reason:GAUGE:0:U +dpdk_telemetry value:COUNTER:0:U drbd_resource value:DERIVE:0:U duration seconds:GAUGE:0:U email_check value:GAUGE:0:U
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor