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 | 205 ++++++++++++++++++++++ 4 files changed, 208 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 74a6e2d2f7..9012156c1b 100644 --- a/lib/librte_telemetry/Makefile +++ b/lib/librte_telemetry/Makefile @@ -29,5 +29,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 710c119b7a..cc0cdeb5f6 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') cflags += '-DALLOW_EXPERIMENTAL_API' includes += include_directories('../librte_metrics') diff --git a/lib/librte_telemetry/rte_telemetry.h b/lib/librte_telemetry/rte_telemetry.h index d0230d4544..8b3df04292 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..02fcafc73a --- /dev/null +++ b/lib/librte_telemetry/rte_telemetry_json.h @@ -0,0 +1,205 @@ +/* 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> + +/** + * @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 + */ +__attribute__((__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