From: Bruce Richardson <bruce.richard...@intel.com> The functions added in this patch will make it easier for applications to build up correct JSON responses to telemetry requests.
Signed-off-by: Bruce Richardson <bruce.richard...@intel.com> --- lib/librte_telemetry/Makefile | 1 + lib/librte_telemetry/meson.build | 2 +- lib/librte_telemetry/rte_telemetry.h | 1 + lib/librte_telemetry/rte_telemetry_json.h | 206 ++++++++++++++++++++++ 4 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 lib/librte_telemetry/rte_telemetry_json.h diff --git a/lib/librte_telemetry/Makefile b/lib/librte_telemetry/Makefile index 270e1aac54..dbf16f4bec 100644 --- a/lib/librte_telemetry/Makefile +++ b/lib/librte_telemetry/Makefile @@ -27,5 +27,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) += telemetry.c # export include files SYMLINK-$(CONFIG_RTE_LIBRTE_TELEMETRY)-include := rte_telemetry.h +SYMLINK-$(CONFIG_RTE_LIBRTE_TELEMETRY)-include += rte_telemetry_json.h include $(RTE_SDK)/mk/rte.lib.mk diff --git a/lib/librte_telemetry/meson.build b/lib/librte_telemetry/meson.build index 0cdae414a4..c8e2fdd0b2 100644 --- a/lib/librte_telemetry/meson.build +++ b/lib/librte_telemetry/meson.build @@ -5,7 +5,7 @@ includes = [global_inc] sources = files('rte_telemetry.c', 'rte_telemetry_parser.c', 'rte_telemetry_parser_test.c', 'telemetry.c') -headers = files('rte_telemetry.h', 'rte_telemetry_internal.h', 'rte_telemetry_parser.h') +headers = files('rte_telemetry.h', 'rte_telemetry_internal.h', 'rte_telemetry_parser.h', 'rte_telemetry_json.h') includes += include_directories('../librte_metrics') jansson = dependency('jansson', required: false) diff --git a/lib/librte_telemetry/rte_telemetry.h b/lib/librte_telemetry/rte_telemetry.h index 27067b1250..dc63b54423 100644 --- a/lib/librte_telemetry/rte_telemetry.h +++ b/lib/librte_telemetry/rte_telemetry.h @@ -4,6 +4,7 @@ #include <stdint.h> #include <rte_compat.h> +#include <rte_telemetry_json.h> #ifndef _RTE_TELEMETRY_H_ #define _RTE_TELEMETRY_H_ diff --git a/lib/librte_telemetry/rte_telemetry_json.h b/lib/librte_telemetry/rte_telemetry_json.h new file mode 100644 index 0000000000..bb926b918b --- /dev/null +++ b/lib/librte_telemetry/rte_telemetry_json.h @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 Intel Corporation + */ + +#ifndef _RTE_TELEMETRY_JSON_H_ +#define _RTE_TELEMETRY_JSON_H_ + +#include <inttypes.h> +#include <stdarg.h> +#include <stdio.h> +#include <rte_common.h> + +/** + * @warning + * @b EXPERIMENTAL: all functions in this file may change without prior notice + * + * @file + * RTE Telemetry Utility Functions for Creating JSON Responses + * + * This file contains small inline functions to make it easier for applications + * to build up valid JSON responses to telemetry requests. + * + ***/ + +/** + * @internal + * + * Copies a value into a buffer if the buffer has enough available space. + * Nothing written to buffer if an overflow ocurs. + * This function is not for use for values larger than 1k. + * + * @param buf + * Buffer for data to be appended to. + * @param len + * Length of buffer. + * @param format + * Format string. + * @param ... + * Optional arguments that may be required by the format string. + * + * @return + * Number of characters added to buffer + */ +__rte_format_printf(3, 4) +static inline int +__json_snprintf(char *buf, const int len, const char *format, ...) +{ + char tmp[1024]; + va_list ap; + int ret; + + va_start(ap, format); + ret = vsnprintf(tmp, sizeof(tmp), format, ap); + va_end(ap); + if (ret > 0 && ret < (int)sizeof(tmp) && ret < len) { + strcpy(buf, tmp); + return ret; + } + return 0; /* nothing written or modified */ +} + +/** + * Copies an empty array into the provided buffer. + * + * @param buf + * Buffer to hold the empty array. + * @param len + * Length of buffer. + * @param used + * The number of used characters in the buffer. + * + * @return + * Total number of characters in buffer. + */ +static inline int +rte_tel_json_empty_array(char *buf, const int len, const int used) +{ + return used + __json_snprintf(buf + used, len - used, "[]"); +} + +/** + * Copies an empty object into the provided buffer. + * + * @param buf + * Buffer to hold the empty object. + * @param len + * Length of buffer. + * @param used + * The number of used characters in the buffer. + * + * @return + * Total number of characters in buffer + */ +static inline int +rte_tel_json_empty_obj(char *buf, const int len, const int used) +{ + return used + __json_snprintf(buf + used, len - used, "{}"); +} + +/** + * Copies a string into the provided buffer, in JSON format. + * + * @param buf + * Buffer to copy string into. + * @param len + * Length of buffer. + * @param used + * The number of used characters in the buffer. + * @param str + * String value to copy into buffer. + * + * @return + * Total number of characters in buffer + */ +static inline int +rte_tel_json_str(char *buf, const int len, const int used, const char *str) +{ + return used + __json_snprintf(buf + used, len - used, "\"%s\"", str); +} + +/** + * Appends a string into the JSON array in the provided buffer. + * + * @param buf + * Buffer to append array string to. + * @param len + * Length of buffer. + * @param used + * The number of used characters in the buffer. + * @param str + * String value to append to buffer. + * + * @return + * Total number of characters in buffer + */ +static inline int +rte_tel_json_add_array_string(char *buf, const int len, const int used, + const char *str) +{ + int ret, end = used - 1; /* strip off final delimiter */ + if (used <= 2) /* assume empty, since minimum is '[]' */ + return __json_snprintf(buf, len, "[\"%s\"]", str); + + ret = __json_snprintf(buf + end, len - end, ",\"%s\"]", str); + return ret == 0 ? used : end + ret; +} + +/** + * Appends an integer into the JSON array in the provided buffer. + * + * @param buf + * Buffer to append array integer to. + * @param len + * Length of buffer. + * @param used + * The number of used characters in the buffer. + * @param val + * Integer value to append to buffer. + * + * @return + * Total number of characters in buffer + */ +static inline int +rte_tel_json_add_array_int(char *buf, const int len, const int used, int val) +{ + int ret, end = used - 1; /* strip off final delimiter */ + if (used <= 2) /* assume empty, since minimum is '[]' */ + return __json_snprintf(buf, len, "[%d]", val); + + ret = __json_snprintf(buf + end, len - end, ",%d]", val); + return ret == 0 ? used : end + ret; +} + +/** + * Add a new element with uint64_t value to the JSON object stored in the + * provided buffer. + * + * @param buf + * Buffer to append object element to. + * @param len + * Length of buffer. + * @param used + * The number of used characters in the buffer. + * @param name + * String for object element key. + * @param val + * Uint64_t for object element value. + * + * @return + * Total number of characters in buffer + */ +static inline int +rte_tel_json_add_obj_u64(char *buf, const int len, const int used, + const char *name, uint64_t val) +{ + int ret, end = used - 1; + if (used <= 2) /* assume empty, since minimum is '{}' */ + return __json_snprintf(buf, len, "{\"%s\":%"PRIu64"}", name, + val); + + ret = __json_snprintf(buf + end, len - end, ",\"%s\":%"PRIu64"}", + name, val); + return ret == 0 ? used : end + ret; +} + +#endif /*_RTE_TELEMETRY_JSON_H_*/ -- 2.17.1