get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/69013/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 69013,
    "url": "http://patches.dpdk.org/api/patches/69013/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200421123949.38270-3-ciara.power@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20200421123949.38270-3-ciara.power@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200421123949.38270-3-ciara.power@intel.com",
    "date": "2020-04-21T12:39:34",
    "name": "[v3,02/17] telemetry: move code to metrics for later reuse",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "5a83e00743e3dcf34cf3db2aefc6d6cb4834e694",
    "submitter": {
        "id": 978,
        "url": "http://patches.dpdk.org/api/people/978/?format=api",
        "name": "Power, Ciara",
        "email": "ciara.power@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20200421123949.38270-3-ciara.power@intel.com/mbox/",
    "series": [
        {
            "id": 9543,
            "url": "http://patches.dpdk.org/api/series/9543/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=9543",
            "date": "2020-04-21T12:39:32",
            "name": "update and simplify telemetry library.",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/9543/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/69013/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/69013/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 5FF4CA0597;\n\tTue, 21 Apr 2020 14:59:46 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id AD4091D50A;\n\tTue, 21 Apr 2020 14:59:31 +0200 (CEST)",
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n by dpdk.org (Postfix) with ESMTP id 245291D508\n for <dev@dpdk.org>; Tue, 21 Apr 2020 14:59:28 +0200 (CEST)",
            "from fmsmga004.fm.intel.com ([10.253.24.48])\n by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 21 Apr 2020 05:59:28 -0700",
            "from silpixa00399953.ir.intel.com (HELO\n silpixa00399953.ger.corp.intel.com) ([10.237.222.53])\n by fmsmga004.fm.intel.com with ESMTP; 21 Apr 2020 05:59:26 -0700"
        ],
        "IronPort-SDR": [
            "\n SJOHGaCs0+qrAFTCCa402aPtBgU3sAMQjs7o6qr8j+GrqC9Dgt7yH8jwDhSeBw7N1Kbd6y6YB0\n fG8V3DO5Er0w==",
            "\n /0Mgx/l8zbgRWazQyCUoJq3MhPTG9nUAtGvaG3VhT4WciRmBYZdSzgCaabVZ3Mzpbalw39IsqS\n VAssd4uz0kSQ=="
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.72,410,1580803200\"; d=\"scan'208\";a=\"279629056\"",
        "From": "Ciara Power <ciara.power@intel.com>",
        "To": "dev@dpdk.org,\n\tkevin.laatz@intel.com",
        "Cc": "reshma.pattan@intel.com, jerinjacobk@gmail.com, david.marchand@redhat.com,\n keith.wiles@intel.com, mb@smartsharesystems.com, thomas@monjalon.net,\n Ciara Power <ciara.power@intel.com>",
        "Date": "Tue, 21 Apr 2020 13:39:34 +0100",
        "Message-Id": "<20200421123949.38270-3-ciara.power@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20200421123949.38270-1-ciara.power@intel.com>",
        "References": "<20200319171907.60891-1-ciara.power@intel.com>\n <20200421123949.38270-1-ciara.power@intel.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v3 02/17] telemetry: move code to metrics for\n\tlater reuse",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This commit moves some of the telemetry library code to a new file in\nthe metrics library. No modifications are made to the moved code,\nexcept what is needed to allow it to compile and run. The additional\ncode in metrics is built only when the Jansson library is  present.\nTelemetry functions as normal, using the functions from the\nmetrics_telemetry file. This move will enable code be reused by the new\nversion of telemetry in a later commit, to support backward\ncompatibility with the existing telemetry usage.\n\nSigned-off-by: Ciara Power <ciara.power@intel.com>\n---\n lib/Makefile                                  |   2 +-\n lib/librte_metrics/Makefile                   |   9 +\n lib/librte_metrics/meson.build                |   8 +\n lib/librte_metrics/rte_metrics.c              |   1 -\n lib/librte_metrics/rte_metrics.h              |   3 +-\n lib/librte_metrics/rte_metrics_telemetry.c    | 719 ++++++++++++++++++\n lib/librte_metrics/rte_metrics_telemetry.h    |  71 ++\n lib/librte_metrics/rte_metrics_version.map    |   7 +\n lib/librte_telemetry/rte_telemetry.c          | 550 +-------------\n lib/librte_telemetry/rte_telemetry_internal.h |  32 +-\n lib/librte_telemetry/rte_telemetry_parser.c   | 270 +------\n mk/rte.app.mk                                 |   2 +\n 12 files changed, 857 insertions(+), 817 deletions(-)\n create mode 100644 lib/librte_metrics/rte_metrics_telemetry.c\n create mode 100644 lib/librte_metrics/rte_metrics_telemetry.h",
    "diff": "diff --git a/lib/Makefile b/lib/Makefile\nindex 2cbb096f12..345ad39655 100644\n--- a/lib/Makefile\n+++ b/lib/Makefile\n@@ -71,7 +71,7 @@ DEPDIRS-librte_gro := librte_eal librte_mbuf librte_ethdev librte_net\n DIRS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += librte_jobstats\n DEPDIRS-librte_jobstats := librte_eal\n DIRS-$(CONFIG_RTE_LIBRTE_METRICS) += librte_metrics\n-DEPDIRS-librte_metrics := librte_eal\n+DEPDIRS-librte_metrics := librte_eal librte_ethdev\n DIRS-$(CONFIG_RTE_LIBRTE_BITRATE) += librte_bitratestats\n DEPDIRS-librte_bitratestats := librte_eal librte_metrics librte_ethdev\n DIRS-$(CONFIG_RTE_LIBRTE_LATENCY_STATS) += librte_latencystats\ndiff --git a/lib/librte_metrics/Makefile b/lib/librte_metrics/Makefile\nindex 6b385f5cf1..aa4d8546f3 100644\n--- a/lib/librte_metrics/Makefile\n+++ b/lib/librte_metrics/Makefile\n@@ -14,6 +14,15 @@ EXPORT_MAP := rte_metrics_version.map\n # all source are stored in SRCS-y\n SRCS-$(CONFIG_RTE_LIBRTE_METRICS) := rte_metrics.c\n \n+ifeq ($(CONFIG_RTE_LIBRTE_TELEMETRY),y)\n+SRCS-y += rte_metrics_telemetry.c\n+SYMLINK-$(CONFIG_RTE_LIBRTE_METRICS)-include += rte_metrics_telemetry.h\n+\n+LDLIBS += -lrte_ethdev\n+LDLIBS += -ljansson\n+\n+endif\n+\n # Install header file\n SYMLINK-$(CONFIG_RTE_LIBRTE_METRICS)-include += rte_metrics.h\n \ndiff --git a/lib/librte_metrics/meson.build b/lib/librte_metrics/meson.build\nindex e26d1f46c1..a39bc7a2a6 100644\n--- a/lib/librte_metrics/meson.build\n+++ b/lib/librte_metrics/meson.build\n@@ -3,3 +3,11 @@\n \n sources = files('rte_metrics.c')\n headers = files('rte_metrics.h')\n+\n+jansson = dependency('jansson', required: false)\n+if jansson.found()\n+\text_deps += jansson\n+\tsources += files('rte_metrics_telemetry.c')\n+\theaders = files('rte_metrics_telemetry.h')\n+\tdeps += ['ethdev']\n+endif\ndiff --git a/lib/librte_metrics/rte_metrics.c b/lib/librte_metrics/rte_metrics.c\nindex df5e32c59f..9b38d7787c 100644\n--- a/lib/librte_metrics/rte_metrics.c\n+++ b/lib/librte_metrics/rte_metrics.c\n@@ -13,7 +13,6 @@\n #include <rte_memzone.h>\n #include <rte_spinlock.h>\n \n-#define RTE_METRICS_MAX_METRICS 256\n #define RTE_METRICS_MEMZONE_NAME \"RTE_METRICS\"\n \n /**\ndiff --git a/lib/librte_metrics/rte_metrics.h b/lib/librte_metrics/rte_metrics.h\nindex 77bffe08e4..466ca98c31 100644\n--- a/lib/librte_metrics/rte_metrics.h\n+++ b/lib/librte_metrics/rte_metrics.h\n@@ -32,6 +32,7 @@ extern \"C\" {\n \n /** Maximum length of metric name (including null-terminator) */\n #define RTE_METRICS_MAX_NAME_LEN 64\n+#define RTE_METRICS_MAX_METRICS 256\n \n /**\n  * Global metric special id.\n@@ -43,7 +44,6 @@ extern \"C\" {\n  */\n #define RTE_METRICS_GLOBAL -1\n \n-\n /**\n  * A name-key lookup for metrics.\n  *\n@@ -71,7 +71,6 @@ struct rte_metric_value {\n \tuint64_t value;\n };\n \n-\n /**\n  * Initializes metric module. This function must be called from\n  * a primary process before metrics are used.\ndiff --git a/lib/librte_metrics/rte_metrics_telemetry.c b/lib/librte_metrics/rte_metrics_telemetry.c\nnew file mode 100644\nindex 0000000000..a6b2616714\n--- /dev/null\n+++ b/lib/librte_metrics/rte_metrics_telemetry.c\n@@ -0,0 +1,719 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+\n+#include <jansson.h>\n+\n+#include <rte_ethdev.h>\n+#include <rte_string_fns.h>\n+\n+#include \"rte_metrics.h\"\n+#include \"rte_metrics_telemetry.h\"\n+\n+int metrics_log_level;\n+\n+/* Logging Macros */\n+#define METRICS_LOG(level, fmt, args...) \\\n+\trte_log(RTE_LOG_ ##level, metrics_log_level, \"%s(): \"fmt \"\\n\", \\\n+\t\t__func__, ##args)\n+\n+#define METRICS_LOG_ERR(fmt, args...) \\\n+\tMETRICS_LOG(ERR, fmt, ## args)\n+\n+#define METRICS_LOG_WARN(fmt, args...) \\\n+\tMETRICS_LOG(WARNING, fmt, ## args)\n+\n+static int32_t\n+rte_metrics_tel_is_port_active(int port_id)\n+{\n+\tint ret;\n+\n+\tret = rte_eth_find_next(port_id);\n+\tif (ret == port_id)\n+\t\treturn 1;\n+\n+\tMETRICS_LOG_ERR(\"port_id: %d is invalid, not active\",\n+\t\tport_id);\n+\n+\treturn 0;\n+}\n+\n+static int32_t\n+rte_metrics_tel_reg_port_ethdev_to_metrics(uint16_t port_id)\n+{\n+\tint ret, num_xstats, ret_val, i;\n+\tstruct rte_eth_xstat *eth_xstats = NULL;\n+\tstruct rte_eth_xstat_name *eth_xstats_names = NULL;\n+\n+\tif (!rte_eth_dev_is_valid_port(port_id)) {\n+\t\tMETRICS_LOG_ERR(\"port_id: %d is invalid\", port_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tnum_xstats = rte_eth_xstats_get(port_id, NULL, 0);\n+\tif (num_xstats < 0) {\n+\t\tMETRICS_LOG_ERR(\"rte_eth_xstats_get(%u) failed: %d\",\n+\t\t\t\tport_id, num_xstats);\n+\t\treturn -EPERM;\n+\t}\n+\n+\teth_xstats = malloc(sizeof(struct rte_eth_xstat) * num_xstats);\n+\tif (eth_xstats == NULL) {\n+\t\tMETRICS_LOG_ERR(\"Failed to malloc memory for xstats\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tret = rte_eth_xstats_get(port_id, eth_xstats, num_xstats);\n+\tconst char *xstats_names[num_xstats];\n+\teth_xstats_names = malloc(sizeof(struct rte_eth_xstat_name)\n+\t\t\t* num_xstats);\n+\tif (ret < 0 || ret > num_xstats) {\n+\t\tMETRICS_LOG_ERR(\"rte_eth_xstats_get(%u) len%i failed: %d\",\n+\t\t\t\tport_id, num_xstats, ret);\n+\t\tret_val = -EPERM;\n+\t\tgoto free_xstats;\n+\t}\n+\n+\tif (eth_xstats_names == NULL) {\n+\t\tMETRICS_LOG_ERR(\"Failed to malloc memory for xstats_names\");\n+\t\tret_val = -ENOMEM;\n+\t\tgoto free_xstats;\n+\t}\n+\n+\tret = rte_eth_xstats_get_names(port_id, eth_xstats_names, num_xstats);\n+\tif (ret < 0 || ret > num_xstats) {\n+\t\tMETRICS_LOG_ERR(\"rte_eth_xstats_get_names(%u) len%i failed: %d\",\n+\t\t\t\tport_id, num_xstats, ret);\n+\t\tret_val = -EPERM;\n+\t\tgoto free_xstats;\n+\t}\n+\n+\tfor (i = 0; i < num_xstats; i++)\n+\t\txstats_names[i] = eth_xstats_names[eth_xstats[i].id].name;\n+\n+\tret_val = rte_metrics_reg_names(xstats_names, num_xstats);\n+\tif (ret_val < 0) {\n+\t\tMETRICS_LOG_ERR(\"rte_metrics_reg_names failed - metrics may already be registered\");\n+\t\tret_val = -1;\n+\t\tgoto free_xstats;\n+\t}\n+\n+\tgoto free_xstats;\n+\n+free_xstats:\n+\tfree(eth_xstats);\n+\tfree(eth_xstats_names);\n+\treturn ret_val;\n+}\n+\n+int32_t\n+rte_metrics_tel_reg_all_ethdev(int *metrics_register_done, int *reg_index_list)\n+{\n+\tstruct driver_index {\n+\t\tconst void *dev_ops;\n+\t\tint reg_index;\n+\t} drv_idx[RTE_MAX_ETHPORTS] = { {0} };\n+\tint nb_drv_idx = 0;\n+\tuint16_t pid;\n+\tint ret;\n+\n+\tRTE_ETH_FOREACH_DEV(pid) {\n+\t\tint i;\n+\t\t/* Different device types have different numbers of stats, so\n+\t\t * first check if the stats for this type of device have\n+\t\t * already been registered\n+\t\t */\n+\t\tfor (i = 0; i < nb_drv_idx; i++) {\n+\t\t\tif (rte_eth_devices[pid].dev_ops ==\n+\t\t\t\t\tdrv_idx[i].dev_ops) {\n+\t\t\t\treg_index_list[pid] = drv_idx[i].reg_index;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\tif (i < nb_drv_idx)\n+\t\t\tcontinue; /* we found a match, go to next port */\n+\n+\t\t/* No match, register a new set of xstats for this port */\n+\t\tret = rte_metrics_tel_reg_port_ethdev_to_metrics(pid);\n+\t\tif (ret < 0) {\n+\t\t\tMETRICS_LOG_ERR(\"Failed to register ethdev metrics\");\n+\t\t\treturn -1;\n+\t\t}\n+\t\treg_index_list[pid] = ret;\n+\t\tdrv_idx[nb_drv_idx].dev_ops = rte_eth_devices[pid].dev_ops;\n+\t\tdrv_idx[nb_drv_idx].reg_index = ret;\n+\t\tnb_drv_idx++;\n+\t}\n+\n+\t*metrics_register_done = 1;\n+\treturn 0;\n+}\n+\n+static int32_t\n+rte_metrics_tel_update_metrics_ethdev(uint16_t port_id, int reg_start_index)\n+{\n+\tint ret, num_xstats, i;\n+\tstruct rte_eth_xstat *eth_xstats;\n+\n+\tif (!rte_eth_dev_is_valid_port(port_id)) {\n+\t\tMETRICS_LOG_ERR(\"port_id: %d is invalid\", port_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tret = rte_metrics_tel_is_port_active(port_id);\n+\tif (ret < 1)\n+\t\treturn -EINVAL;\n+\n+\tnum_xstats = rte_eth_xstats_get(port_id, NULL, 0);\n+\tif (num_xstats < 0) {\n+\t\tMETRICS_LOG_ERR(\"rte_eth_xstats_get(%u) failed: %d\", port_id,\n+\t\t\t\tnum_xstats);\n+\t\treturn -EPERM;\n+\t}\n+\n+\teth_xstats = malloc(sizeof(struct rte_eth_xstat) * num_xstats);\n+\tif (eth_xstats == NULL) {\n+\t\tMETRICS_LOG_ERR(\"Failed to malloc memory for xstats\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tret = rte_eth_xstats_get(port_id, eth_xstats, num_xstats);\n+\tif (ret < 0 || ret > num_xstats) {\n+\t\tfree(eth_xstats);\n+\t\tMETRICS_LOG_ERR(\"rte_eth_xstats_get(%u) len%i failed: %d\",\n+\t\t\t\tport_id, num_xstats, ret);\n+\t\treturn -EPERM;\n+\t}\n+\n+\tuint64_t xstats_values[num_xstats];\n+\tfor (i = 0; i < num_xstats; i++)\n+\t\txstats_values[i] = eth_xstats[i].value;\n+\n+\tret = rte_metrics_update_values(port_id, reg_start_index, xstats_values,\n+\t\t\tnum_xstats);\n+\tif (ret < 0) {\n+\t\tMETRICS_LOG_ERR(\"Could not update metrics values\");\n+\t\tfree(eth_xstats);\n+\t\treturn -EPERM;\n+\t}\n+\n+\tfree(eth_xstats);\n+\treturn 0;\n+}\n+\n+static int\n+rte_metrics_tel_get_metrics(uint32_t port_id, struct rte_metric_value\n+\t*metrics, struct rte_metric_name *names, int num_metrics)\n+{\n+\tint ret, num_values;\n+\n+\tif (num_metrics < 0) {\n+\t\tMETRICS_LOG_ERR(\"Invalid metrics count\");\n+\t\treturn -EINVAL;\n+\t} else if (num_metrics == 0) {\n+\t\tMETRICS_LOG_ERR(\"No metrics to display (none have been registered)\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\tif (metrics == NULL) {\n+\t\tMETRICS_LOG_ERR(\"Metrics must be initialised.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (names == NULL) {\n+\t\tMETRICS_LOG_ERR(\"Names must be initialised.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tret = rte_metrics_get_names(names, num_metrics);\n+\tif (ret < 0 || ret > num_metrics) {\n+\t\tMETRICS_LOG_ERR(\"Cannot get metrics names\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\tnum_values = rte_metrics_get_values(port_id, NULL, 0);\n+\tret = rte_metrics_get_values(port_id, metrics, num_values);\n+\tif (ret < 0 || ret > num_values) {\n+\t\tMETRICS_LOG_ERR(\"Cannot get metrics values\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int32_t\n+rte_metrics_tel_json_format_stat(json_t *stats, const char *metric_name,\n+\tuint64_t metric_value)\n+{\n+\tint ret;\n+\tjson_t *stat = json_object();\n+\n+\tif (stat == NULL) {\n+\t\tMETRICS_LOG_ERR(\"Could not create stat JSON object\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\tret = json_object_set_new(stat, \"name\", json_string(metric_name));\n+\tif (ret < 0) {\n+\t\tMETRICS_LOG_ERR(\"Stat Name field cannot be set\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\tret = json_object_set_new(stat, \"value\", json_integer(metric_value));\n+\tif (ret < 0) {\n+\t\tMETRICS_LOG_ERR(\"Stat Value field cannot be set\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\tret = json_array_append_new(stats, stat);\n+\tif (ret < 0) {\n+\t\tMETRICS_LOG_ERR(\"Stat cannot be added to stats json array\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int32_t\n+rte_metrics_tel_json_format_port(uint32_t port_id, json_t *ports,\n+\tuint32_t *metric_ids, int num_metric_ids)\n+{\n+\tstruct rte_metric_value *metrics = 0;\n+\tstruct rte_metric_name *names = 0;\n+\tint num_metrics, ret;\n+\tjson_t *port, *stats;\n+\tint i;\n+\n+\tnum_metrics = rte_metrics_get_names(NULL, 0);\n+\tif (num_metrics < 0) {\n+\t\tMETRICS_LOG_ERR(\"Cannot get metrics count\");\n+\t\tgoto einval_fail;\n+\t} else if (num_metrics == 0) {\n+\t\tMETRICS_LOG_ERR(\"No metrics to display (none have been registered)\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tmetrics = malloc(sizeof(struct rte_metric_value) * num_metrics);\n+\tnames = malloc(sizeof(struct rte_metric_name) * num_metrics);\n+\tif (metrics == NULL || names == NULL) {\n+\t\tMETRICS_LOG_ERR(\"Cannot allocate memory\");\n+\t\tfree(metrics);\n+\t\tfree(names);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tret  = rte_metrics_tel_get_metrics(port_id, metrics, names,\n+\t\t\tnum_metrics);\n+\tif (ret < 0) {\n+\t\tfree(metrics);\n+\t\tfree(names);\n+\t\tMETRICS_LOG_ERR(\"rte_metrics_tel_get_metrics failed\");\n+\t\treturn ret;\n+\t}\n+\n+\tport = json_object();\n+\tstats = json_array();\n+\tif (port == NULL || stats == NULL) {\n+\t\tMETRICS_LOG_ERR(\"Could not create port/stats JSON objects\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tret = json_object_set_new(port, \"port\", json_integer(port_id));\n+\tif (ret < 0) {\n+\t\tMETRICS_LOG_ERR(\"Port field cannot be set\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tfor (i = 0; i < num_metric_ids; i++) {\n+\t\tint metric_id = metric_ids[i];\n+\t\tint metric_index = -1;\n+\t\tint metric_name_key = -1;\n+\t\tint32_t j;\n+\t\tuint64_t metric_value;\n+\n+\t\tif (metric_id >= num_metrics) {\n+\t\t\tMETRICS_LOG_ERR(\"Metric_id: %d is not valid\",\n+\t\t\t\t\tmetric_id);\n+\t\t\tgoto einval_fail;\n+\t\t}\n+\n+\t\tfor (j = 0; j < num_metrics; j++) {\n+\t\t\tif (metrics[j].key == metric_id) {\n+\t\t\t\tmetric_name_key = metrics[j].key;\n+\t\t\t\tmetric_index = j;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\tconst char *metric_name = names[metric_name_key].name;\n+\t\tmetric_value = metrics[metric_index].value;\n+\n+\t\tif (metric_name_key < 0 || metric_index < 0) {\n+\t\t\tMETRICS_LOG_ERR(\"Could not get metric name/index\");\n+\t\t\tgoto eperm_fail;\n+\t\t}\n+\n+\t\tret = rte_metrics_tel_json_format_stat(stats, metric_name,\n+\t\t\t\tmetric_value);\n+\t\tif (ret < 0) {\n+\t\t\tMETRICS_LOG_ERR(\"Format stat with id: %u failed\",\n+\t\t\t\t\tmetric_id);\n+\t\t\tfree(metrics);\n+\t\t\tfree(names);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\tif (json_array_size(stats) == 0)\n+\t\tret = json_object_set_new(port, \"stats\", json_null());\n+\telse\n+\t\tret = json_object_set_new(port, \"stats\", stats);\n+\n+\tif (ret < 0) {\n+\t\tMETRICS_LOG_ERR(\"Stats object cannot be set\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tret = json_array_append_new(ports, port);\n+\tif (ret < 0) {\n+\t\tMETRICS_LOG_ERR(\"Port object cannot be added to ports array\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tfree(metrics);\n+\tfree(names);\n+\treturn 0;\n+\n+eperm_fail:\n+\tfree(metrics);\n+\tfree(names);\n+\treturn -EPERM;\n+\n+einval_fail:\n+\tfree(metrics);\n+\tfree(names);\n+\treturn -EINVAL;\n+}\n+\n+int32_t\n+rte_metrics_tel_encode_json_format(struct telemetry_encode_param *ep,\n+\t\tchar **json_buffer)\n+{\n+\tint ret;\n+\tjson_t *root, *ports;\n+\tint i;\n+\tuint32_t port_id;\n+\tint num_port_ids;\n+\tint num_metric_ids;\n+\n+\tports = json_array();\n+\tif (ports == NULL) {\n+\t\tMETRICS_LOG_ERR(\"Could not create ports JSON array\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\tif (ep->type == PORT_STATS) {\n+\t\tnum_port_ids = ep->pp.num_port_ids;\n+\t\tnum_metric_ids = ep->pp.num_metric_ids;\n+\n+\t\tif (num_port_ids <= 0 || num_metric_ids <= 0) {\n+\t\t\tMETRICS_LOG_ERR(\"Please provide port and metric ids to query\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tfor (i = 0; i < num_port_ids; i++) {\n+\t\t\tport_id = ep->pp.port_ids[i];\n+\t\t\tif (!rte_eth_dev_is_valid_port(port_id)) {\n+\t\t\t\tMETRICS_LOG_ERR(\"Port: %d invalid\",\n+\t\t\t\t\t\tport_id);\n+\t\t\t\treturn -EINVAL;\n+\t\t\t}\n+\t\t}\n+\n+\t\tfor (i = 0; i < num_port_ids; i++) {\n+\t\t\tport_id = ep->pp.port_ids[i];\n+\t\t\tret = rte_metrics_tel_json_format_port(port_id,\n+\t\t\t\t\tports, &ep->pp.metric_ids[0],\n+\t\t\t\t\tnum_metric_ids);\n+\t\t\tif (ret < 0) {\n+\t\t\t\tMETRICS_LOG_ERR(\"Format port in JSON failed\");\n+\t\t\t\treturn ret;\n+\t\t\t}\n+\t\t}\n+\t} else if (ep->type == GLOBAL_STATS) {\n+\t\t/* Request Global Metrics */\n+\t\tret = rte_metrics_tel_json_format_port(RTE_METRICS_GLOBAL,\n+\t\t\t\tports, &ep->gp.metric_ids[0],\n+\t\t\t\tep->gp.num_metric_ids);\n+\t\tif (ret < 0) {\n+\t\t\tMETRICS_LOG_ERR(\" Request Global Metrics Failed\");\n+\t\t\treturn ret;\n+\t\t}\n+\t} else {\n+\t\tMETRICS_LOG_ERR(\" Invalid metrics type in encode params\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\troot = json_object();\n+\tif (root == NULL) {\n+\t\tMETRICS_LOG_ERR(\"Could not create root JSON object\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\tret = json_object_set_new(root, \"status_code\",\n+\t\tjson_string(\"Status OK: 200\"));\n+\tif (ret < 0) {\n+\t\tMETRICS_LOG_ERR(\"Status code field cannot be set\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\tret = json_object_set_new(root, \"data\", ports);\n+\tif (ret < 0) {\n+\t\tMETRICS_LOG_ERR(\"Data field cannot be set\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\t*json_buffer = json_dumps(root, JSON_INDENT(2));\n+\tjson_decref(root);\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_metrics_tel_get_global_stats(struct telemetry_encode_param *ep)\n+{\n+\tint num_metrics, ret, i;\n+\tstruct rte_metric_value *values;\n+\n+\tnum_metrics = rte_metrics_get_values(RTE_METRICS_GLOBAL, NULL, 0);\n+\tif (num_metrics < 0) {\n+\t\tMETRICS_LOG_ERR(\"Cannot get metrics count\");\n+\t\treturn -EINVAL;\n+\t} else if (num_metrics == 0) {\n+\t\tMETRICS_LOG_ERR(\"No metrics to display (none have been registered)\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\tvalues = malloc(sizeof(struct rte_metric_value) * num_metrics);\n+\tif (values == NULL) {\n+\t\tMETRICS_LOG_ERR(\"Cannot allocate memory\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tret = rte_metrics_get_values(RTE_METRICS_GLOBAL, values, num_metrics);\n+\tif (ret < 0) {\n+\t\tMETRICS_LOG_ERR(\"Could not get stat values\");\n+\t\tfree(values);\n+\t\treturn -EINVAL;\n+\t}\n+\tfor (i = 0; i < num_metrics; i++)\n+\t\tep->gp.metric_ids[i] = values[i].key;\n+\n+\tep->gp.num_metric_ids = num_metrics;\n+\tep->type = GLOBAL_STATS;\n+\tfree(values);\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_metrics_tel_get_ports_stats_json(struct telemetry_encode_param *ep,\n+\t\tint *reg_index, char **json_buffer)\n+{\n+\tint ret, i;\n+\tuint32_t port_id;\n+\n+\tfor (i = 0; i < ep->pp.num_port_ids; i++) {\n+\t\tport_id = ep->pp.port_ids[i];\n+\t\tif (!rte_eth_dev_is_valid_port(port_id)) {\n+\t\t\tMETRICS_LOG_ERR(\"Port: %d invalid\", port_id);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tret = rte_metrics_tel_update_metrics_ethdev(port_id,\n+\t\t\t\treg_index[i]);\n+\t\tif (ret < 0) {\n+\t\t\tMETRICS_LOG_ERR(\"Failed to update ethdev metrics\");\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\tret = rte_metrics_tel_encode_json_format(ep, json_buffer);\n+\tif (ret < 0) {\n+\t\tMETRICS_LOG_ERR(\"JSON encode function failed\");\n+\t\treturn ret;\n+\t}\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_metrics_tel_get_port_stats_ids(struct telemetry_encode_param *ep)\n+{\n+\tint ret, num_metrics, i, p;\n+\tstruct rte_metric_value *values;\n+\tuint64_t num_port_ids = 0;\n+\n+\tnum_metrics = rte_metrics_get_values(0, NULL, 0);\n+\tif (num_metrics < 0) {\n+\t\tMETRICS_LOG_ERR(\"Cannot get metrics count\");\n+\t\treturn -EINVAL;\n+\t} else if (num_metrics == 0) {\n+\t\tMETRICS_LOG_ERR(\"No metrics to display (none have been registered)\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\tvalues = malloc(sizeof(struct rte_metric_value) * num_metrics);\n+\tif (values == NULL) {\n+\t\tMETRICS_LOG_ERR(\"Cannot allocate memory\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tRTE_ETH_FOREACH_DEV(p) {\n+\t\tep->pp.port_ids[num_port_ids] = p;\n+\t\tnum_port_ids++;\n+\t}\n+\n+\tif (!num_port_ids) {\n+\t\tMETRICS_LOG_ERR(\"No active ports\");\n+\t\tgoto fail;\n+\t}\n+\n+\tret = rte_metrics_get_values(ep->pp.port_ids[0], values, num_metrics);\n+\tif (ret < 0) {\n+\t\tMETRICS_LOG_ERR(\"Could not get stat values\");\n+\t\tgoto fail;\n+\t}\n+\tfor (i = 0; i < num_metrics; i++)\n+\t\tep->pp.metric_ids[i] = values[i].key;\n+\n+\tep->pp.num_port_ids = num_port_ids;\n+\tep->pp.num_metric_ids = num_metrics;\n+\tep->type = PORT_STATS;\n+\treturn 0;\n+\n+fail:\n+\tfree(values);\n+\treturn -EINVAL;\n+}\n+\n+static int32_t\n+rte_metrics_tel_stat_names_to_ids(const char * const *stat_names,\n+\tuint32_t *stat_ids, uint64_t num_stat_names)\n+{\n+\tstruct rte_metric_name *names;\n+\tint ret, num_metrics;\n+\tuint32_t i, k;\n+\n+\tif (stat_names == NULL) {\n+\t\tMETRICS_LOG_WARN(\"Invalid stat_names argument\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (num_stat_names <= 0) {\n+\t\tMETRICS_LOG_WARN(\"Invalid num_stat_names argument\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tnum_metrics = rte_metrics_get_names(NULL, 0);\n+\tif (num_metrics < 0) {\n+\t\tMETRICS_LOG_ERR(\"Cannot get metrics count\");\n+\t\treturn -EPERM;\n+\t} else if (num_metrics == 0) {\n+\t\tMETRICS_LOG_WARN(\"No metrics have been registered\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\tnames = malloc(sizeof(struct rte_metric_name) * num_metrics);\n+\tif (names == NULL) {\n+\t\tMETRICS_LOG_ERR(\"Cannot allocate memory for names\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tret = rte_metrics_get_names(names, num_metrics);\n+\tif (ret < 0 || ret > num_metrics) {\n+\t\tMETRICS_LOG_ERR(\"Cannot get metrics names\");\n+\t\tfree(names);\n+\t\treturn -EPERM;\n+\t}\n+\n+\tk = 0;\n+\tfor (i = 0; i < (uint32_t)num_stat_names; i++) {\n+\t\tuint32_t j;\n+\t\tfor (j = 0; j < (uint32_t)num_metrics; j++) {\n+\t\t\tif (strcmp(stat_names[i], names[j].name) == 0) {\n+\t\t\t\tstat_ids[k] = j;\n+\t\t\t\tk++;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tif (k != num_stat_names) {\n+\t\tMETRICS_LOG_WARN(\"Invalid stat names provided\");\n+\t\tfree(names);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfree(names);\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_metrics_tel_extract_data(struct telemetry_encode_param *ep, json_t *data)\n+{\n+\tint ret;\n+\tjson_t *port_ids_json = json_object_get(data, \"ports\");\n+\tjson_t *stat_names_json = json_object_get(data, \"stats\");\n+\tuint64_t num_stat_names = json_array_size(stat_names_json);\n+\tconst char *stat_names[num_stat_names];\n+\tsize_t index;\n+\tjson_t *value;\n+\n+\tmemset(ep, 0, sizeof(*ep));\n+\tep->pp.num_port_ids = json_array_size(port_ids_json);\n+\tep->pp.num_metric_ids = num_stat_names;\n+\tif (!json_is_object(data)) {\n+\t\tMETRICS_LOG_WARN(\"Invalid data provided for this command\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!json_is_array(port_ids_json) ||\n+\t\t !json_is_array(stat_names_json)) {\n+\t\tMETRICS_LOG_WARN(\"Invalid input data array(s)\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tjson_array_foreach(port_ids_json, index, value) {\n+\t\tif (!json_is_integer(value)) {\n+\t\t\tMETRICS_LOG_WARN(\"Port ID given is not valid\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tep->pp.port_ids[index] = json_integer_value(value);\n+\t\tret = rte_metrics_tel_is_port_active(ep->pp.port_ids[index]);\n+\t\tif (ret < 1)\n+\t\t\treturn -EINVAL;\n+\t}\n+\n+\tjson_array_foreach(stat_names_json, index, value) {\n+\t\tif (!json_is_string(value)) {\n+\t\t\tMETRICS_LOG_WARN(\"Stat Name given is not a string\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tstat_names[index] = json_string_value(value);\n+\t}\n+\n+\tret = rte_metrics_tel_stat_names_to_ids(stat_names, ep->pp.metric_ids,\n+\t\t\tnum_stat_names);\n+\tif (ret < 0) {\n+\t\tMETRICS_LOG_ERR(\"Could not convert stat names to IDs\");\n+\t\treturn ret;\n+\t}\n+\n+\tep->type = PORT_STATS;\n+\treturn 0;\n+}\n+\n+RTE_INIT(metrics_ctor)\n+{\n+\tmetrics_log_level = rte_log_register(\"lib.metrics\");\n+\tif (metrics_log_level >= 0)\n+\t\trte_log_set_level(metrics_log_level, RTE_LOG_ERR);\n+}\ndiff --git a/lib/librte_metrics/rte_metrics_telemetry.h b/lib/librte_metrics/rte_metrics_telemetry.h\nnew file mode 100644\nindex 0000000000..4104f15681\n--- /dev/null\n+++ b/lib/librte_metrics/rte_metrics_telemetry.h\n@@ -0,0 +1,71 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+\n+#ifdef RTE_LIBRTE_TELEMETRY\n+#include <jansson.h>\n+#else\n+#define json_t void *\n+#endif\n+\n+#include \"rte_metrics.h\"\n+\n+#ifndef _RTE_METRICS_TELEMETRY_H_\n+#define _RTE_METRICS_TELEMETRY_H_\n+\n+\n+enum rte_telemetry_stats_type {\n+\tPORT_STATS = 0,\n+\tGLOBAL_STATS = 1\n+};\n+\n+struct telemetry_encode_param {\n+\tenum rte_telemetry_stats_type type;\n+\tunion {\n+\t\tstruct port_param {\n+\t\t\tint num_metric_ids;\n+\t\t\tuint32_t metric_ids[RTE_METRICS_MAX_METRICS];\n+\t\t\tint num_port_ids;\n+\t\t\tuint32_t port_ids[RTE_MAX_ETHPORTS];\n+\t\t} pp;\n+\t\tstruct global_param {\n+\t\t\tint num_metric_ids;\n+\t\t\tuint32_t metric_ids[RTE_METRICS_MAX_METRICS];\n+\t\t} gp;\n+\t};\n+};\n+\n+struct telemetry_metrics_data {\n+\tint reg_index[RTE_MAX_ETHPORTS];\n+\tint metrics_register_done;\n+};\n+\n+struct telemetry_metrics_data tel_met_data;\n+\n+__rte_experimental\n+int32_t rte_metrics_tel_reg_all_ethdev(int *metrics_register_done,\n+\t\tint *reg_index_list);\n+\n+__rte_experimental\n+int32_t\n+rte_metrics_tel_encode_json_format(struct telemetry_encode_param *ep,\n+\t\tchar **json_buffer);\n+\n+__rte_experimental\n+int32_t\n+rte_metrics_tel_get_global_stats(struct telemetry_encode_param *ep);\n+\n+__rte_experimental\n+int32_t\n+rte_metrics_tel_get_port_stats_ids(struct telemetry_encode_param *ep);\n+\n+__rte_experimental\n+int32_t\n+rte_metrics_tel_get_ports_stats_json(struct telemetry_encode_param *ep,\n+\t\tint *reg_index, char **json_buffer);\n+\n+__rte_experimental\n+int32_t\n+rte_metrics_tel_extract_data(struct telemetry_encode_param *ep, json_t *data);\n+\n+#endif\ndiff --git a/lib/librte_metrics/rte_metrics_version.map b/lib/librte_metrics/rte_metrics_version.map\nindex 85663f356e..c88939b117 100644\n--- a/lib/librte_metrics/rte_metrics_version.map\n+++ b/lib/librte_metrics/rte_metrics_version.map\n@@ -16,4 +16,11 @@ EXPERIMENTAL {\n \tglobal:\n \n \trte_metrics_deinit;\n+\trte_metrics_tel_encode_json_format;\n+\trte_metrics_tel_reg_all_ethdev;\n+\trte_metrics_tel_get_global_stats;\n+\trte_metrics_tel_get_port_stats_ids;\n+\trte_metrics_tel_get_ports_stats_json;\n+\trte_metrics_tel_extract_data;\n+\n };\ndiff --git a/lib/librte_telemetry/rte_telemetry.c b/lib/librte_telemetry/rte_telemetry.c\nindex eb20cc6515..1867b61f6f 100644\n--- a/lib/librte_telemetry/rte_telemetry.c\n+++ b/lib/librte_telemetry/rte_telemetry.c\n@@ -49,93 +49,6 @@ rte_telemetry_get_runtime_dir(char *socket_path, size_t size)\n \tsnprintf(socket_path, size, \"%s/telemetry\", rte_eal_get_runtime_dir());\n }\n \n-int32_t\n-rte_telemetry_is_port_active(int port_id)\n-{\n-\tint ret;\n-\n-\tret = rte_eth_find_next(port_id);\n-\tif (ret == port_id)\n-\t\treturn 1;\n-\n-\tTELEMETRY_LOG_ERR(\"port_id: %d is invalid, not active\",\n-\t\tport_id);\n-\n-\treturn 0;\n-}\n-\n-static int32_t\n-rte_telemetry_update_metrics_ethdev(struct telemetry_impl *telemetry,\n-\tuint16_t port_id, int reg_start_index)\n-{\n-\tint ret, num_xstats, i;\n-\tstruct rte_eth_xstat *eth_xstats;\n-\n-\tif (!rte_eth_dev_is_valid_port(port_id)) {\n-\t\tTELEMETRY_LOG_ERR(\"port_id: %d is invalid\", port_id);\n-\t\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\t\treturn -1;\n-\t}\n-\n-\tret = rte_telemetry_is_port_active(port_id);\n-\tif (ret < 1) {\n-\t\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\t\treturn -1;\n-\t}\n-\n-\tnum_xstats = rte_eth_xstats_get(port_id, NULL, 0);\n-\tif (num_xstats < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"rte_eth_xstats_get(%u) failed: %d\", port_id,\n-\t\t\t\tnum_xstats);\n-\t\tret = rte_telemetry_send_error_response(telemetry, -EPERM);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\t\treturn -1;\n-\t}\n-\n-\teth_xstats = malloc(sizeof(struct rte_eth_xstat) * num_xstats);\n-\tif (eth_xstats == NULL) {\n-\t\tTELEMETRY_LOG_ERR(\"Failed to malloc memory for xstats\");\n-\t\tret = rte_telemetry_send_error_response(telemetry, -ENOMEM);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\t\treturn -1;\n-\t}\n-\n-\tret = rte_eth_xstats_get(port_id, eth_xstats, num_xstats);\n-\tif (ret < 0 || ret > num_xstats) {\n-\t\tfree(eth_xstats);\n-\t\tTELEMETRY_LOG_ERR(\"rte_eth_xstats_get(%u) len%i failed: %d\",\n-\t\t\t\tport_id, num_xstats, ret);\n-\t\tret = rte_telemetry_send_error_response(telemetry, -EPERM);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\t\treturn -1;\n-\t}\n-\n-\tuint64_t xstats_values[num_xstats];\n-\tfor (i = 0; i < num_xstats; i++)\n-\t\txstats_values[i] = eth_xstats[i].value;\n-\n-\tret = rte_metrics_update_values(port_id, reg_start_index, xstats_values,\n-\t\t\tnum_xstats);\n-\tif (ret < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Could not update metrics values\");\n-\t\tret = rte_telemetry_send_error_response(telemetry, -EPERM);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\t\tfree(eth_xstats);\n-\t\treturn -1;\n-\t}\n-\n-\tfree(eth_xstats);\n-\treturn 0;\n-}\n-\n static int32_t\n rte_telemetry_write_to_socket(struct telemetry_impl *telemetry,\n \tconst char *json_string)\n@@ -220,328 +133,6 @@ rte_telemetry_send_error_response(struct telemetry_impl *telemetry,\n \treturn 0;\n }\n \n-static int\n-rte_telemetry_get_metrics(struct telemetry_impl *telemetry, uint32_t port_id,\n-\tstruct rte_metric_value *metrics, struct rte_metric_name *names,\n-\tint num_metrics)\n-{\n-\tint ret, num_values;\n-\n-\tif (num_metrics < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Invalid metrics count\");\n-\t\tgoto einval_fail;\n-\t} else if (num_metrics == 0) {\n-\t\tTELEMETRY_LOG_ERR(\"No metrics to display (none have been registered)\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tif (metrics == NULL) {\n-\t\tTELEMETRY_LOG_ERR(\"Metrics must be initialised.\");\n-\t\tgoto einval_fail;\n-\t}\n-\n-\tif (names == NULL) {\n-\t\tTELEMETRY_LOG_ERR(\"Names must be initialised.\");\n-\t\tgoto einval_fail;\n-\t}\n-\n-\tret = rte_metrics_get_names(names, num_metrics);\n-\tif (ret < 0 || ret > num_metrics) {\n-\t\tTELEMETRY_LOG_ERR(\"Cannot get metrics names\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tnum_values = rte_metrics_get_values(port_id, NULL, 0);\n-\tret = rte_metrics_get_values(port_id, metrics, num_values);\n-\tif (ret < 0 || ret > num_values) {\n-\t\tTELEMETRY_LOG_ERR(\"Cannot get metrics values\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\treturn 0;\n-\n-eperm_fail:\n-\tret = rte_telemetry_send_error_response(telemetry, -EPERM);\n-\tif (ret < 0)\n-\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\treturn -1;\n-\n-einval_fail:\n-\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n-\tif (ret < 0)\n-\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\treturn -1;\n-\n-}\n-\n-static int32_t\n-rte_telemetry_json_format_stat(struct telemetry_impl *telemetry, json_t *stats,\n-\tconst char *metric_name, uint64_t metric_value)\n-{\n-\tint ret;\n-\tjson_t *stat = json_object();\n-\n-\tif (stat == NULL) {\n-\t\tTELEMETRY_LOG_ERR(\"Could not create stat JSON object\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tret = json_object_set_new(stat, \"name\", json_string(metric_name));\n-\tif (ret < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Stat Name field cannot be set\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tret = json_object_set_new(stat, \"value\", json_integer(metric_value));\n-\tif (ret < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Stat Value field cannot be set\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tret = json_array_append_new(stats, stat);\n-\tif (ret < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Stat cannot be added to stats json array\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\treturn 0;\n-\n-eperm_fail:\n-\tret = rte_telemetry_send_error_response(telemetry, -EPERM);\n-\tif (ret < 0)\n-\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\treturn -1;\n-\n-}\n-\n-static int32_t\n-rte_telemetry_json_format_port(struct telemetry_impl *telemetry,\n-\tuint32_t port_id, json_t *ports, uint32_t *metric_ids,\n-\tint num_metric_ids)\n-{\n-\tstruct rte_metric_value *metrics = 0;\n-\tstruct rte_metric_name *names = 0;\n-\tint num_metrics, ret, err_ret;\n-\tjson_t *port, *stats;\n-\tint i;\n-\n-\tnum_metrics = rte_metrics_get_names(NULL, 0);\n-\tif (num_metrics < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Cannot get metrics count\");\n-\t\tgoto einval_fail;\n-\t} else if (num_metrics == 0) {\n-\t\tTELEMETRY_LOG_ERR(\"No metrics to display (none have been registered)\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tmetrics = malloc(sizeof(struct rte_metric_value) * num_metrics);\n-\tnames = malloc(sizeof(struct rte_metric_name) * num_metrics);\n-\tif (metrics == NULL || names == NULL) {\n-\t\tTELEMETRY_LOG_ERR(\"Cannot allocate memory\");\n-\t\tfree(metrics);\n-\t\tfree(names);\n-\n-\t\terr_ret = rte_telemetry_send_error_response(telemetry, -ENOMEM);\n-\t\tif (err_ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\t\treturn -1;\n-\t}\n-\n-\tret  = rte_telemetry_get_metrics(telemetry, port_id, metrics, names,\n-\t\tnum_metrics);\n-\tif (ret < 0) {\n-\t\tfree(metrics);\n-\t\tfree(names);\n-\t\tTELEMETRY_LOG_ERR(\"rte_telemetry_get_metrics failed\");\n-\t\treturn -1;\n-\t}\n-\n-\tport = json_object();\n-\tstats = json_array();\n-\tif (port == NULL || stats == NULL) {\n-\t\tTELEMETRY_LOG_ERR(\"Could not create port/stats JSON objects\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tret = json_object_set_new(port, \"port\", json_integer(port_id));\n-\tif (ret < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Port field cannot be set\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tfor (i = 0; i < num_metric_ids; i++) {\n-\t\tint metric_id = metric_ids[i];\n-\t\tint metric_index = -1;\n-\t\tint metric_name_key = -1;\n-\t\tint32_t j;\n-\t\tuint64_t metric_value;\n-\n-\t\tif (metric_id >= num_metrics) {\n-\t\t\tTELEMETRY_LOG_ERR(\"Metric_id: %d is not valid\",\n-\t\t\t\t\tmetric_id);\n-\t\t\tgoto einval_fail;\n-\t\t}\n-\n-\t\tfor (j = 0; j < num_metrics; j++) {\n-\t\t\tif (metrics[j].key == metric_id) {\n-\t\t\t\tmetric_name_key = metrics[j].key;\n-\t\t\t\tmetric_index = j;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t}\n-\n-\t\tconst char *metric_name = names[metric_name_key].name;\n-\t\tmetric_value = metrics[metric_index].value;\n-\n-\t\tif (metric_name_key < 0 || metric_index < 0) {\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not get metric name/index\");\n-\t\t\tgoto eperm_fail;\n-\t\t}\n-\n-\t\tret = rte_telemetry_json_format_stat(telemetry, stats,\n-\t\t\tmetric_name, metric_value);\n-\t\tif (ret < 0) {\n-\t\t\tTELEMETRY_LOG_ERR(\"Format stat with id: %u failed\",\n-\t\t\t\t\tmetric_id);\n-\t\t\tfree(metrics);\n-\t\t\tfree(names);\n-\t\t\treturn -1;\n-\t\t}\n-\t}\n-\n-\tif (json_array_size(stats) == 0)\n-\t\tret = json_object_set_new(port, \"stats\", json_null());\n-\telse\n-\t\tret = json_object_set_new(port, \"stats\", stats);\n-\n-\tif (ret < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Stats object cannot be set\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tret = json_array_append_new(ports, port);\n-\tif (ret < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Port object cannot be added to ports array\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tfree(metrics);\n-\tfree(names);\n-\treturn 0;\n-\n-eperm_fail:\n-\tfree(metrics);\n-\tfree(names);\n-\tret = rte_telemetry_send_error_response(telemetry, -EPERM);\n-\tif (ret < 0)\n-\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\treturn -1;\n-\n-einval_fail:\n-\tfree(metrics);\n-\tfree(names);\n-\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n-\tif (ret < 0)\n-\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\treturn -1;\n-}\n-\n-static int32_t\n-rte_telemetry_encode_json_format(struct telemetry_impl *telemetry,\n-\tstruct telemetry_encode_param *ep, char **json_buffer)\n-{\n-\tint ret;\n-\tjson_t *root, *ports;\n-\tint i;\n-\tuint32_t port_id;\n-\tint num_port_ids;\n-\tint num_metric_ids;\n-\n-\tports = json_array();\n-\tif (ports == NULL) {\n-\t\tTELEMETRY_LOG_ERR(\"Could not create ports JSON array\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tif (ep->type == PORT_STATS) {\n-\t\tnum_port_ids = ep->pp.num_port_ids;\n-\t\tnum_metric_ids = ep->pp.num_metric_ids;\n-\n-\t\tif (num_port_ids <= 0 || num_metric_ids <= 0) {\n-\t\t\tTELEMETRY_LOG_ERR(\"Please provide port and metric ids to query\");\n-\t\t\tgoto einval_fail;\n-\t\t}\n-\n-\t\tfor (i = 0; i < num_port_ids; i++) {\n-\t\t\tport_id = ep->pp.port_ids[i];\n-\t\t\tif (!rte_eth_dev_is_valid_port(port_id)) {\n-\t\t\t\tTELEMETRY_LOG_ERR(\"Port: %d invalid\",\n-\t\t\t\t\t\t\tport_id);\n-\t\t\t\tgoto einval_fail;\n-\t\t\t}\n-\t\t}\n-\n-\t\tfor (i = 0; i < num_port_ids; i++) {\n-\t\t\tport_id = ep->pp.port_ids[i];\n-\t\t\tret = rte_telemetry_json_format_port(telemetry,\n-\t\t\t\t\tport_id, ports, &ep->pp.metric_ids[0],\n-\t\t\t\t\tnum_metric_ids);\n-\t\t\tif (ret < 0) {\n-\t\t\t\tTELEMETRY_LOG_ERR(\"Format port in JSON failed\");\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t}\n-\t} else if (ep->type == GLOBAL_STATS) {\n-\t\t/* Request Global Metrics */\n-\t\tret = rte_telemetry_json_format_port(telemetry,\n-\t\t\t\tRTE_METRICS_GLOBAL,\n-\t\t\t\tports, &ep->gp.metric_ids[0],\n-\t\t\t\tep->gp.num_metric_ids);\n-\t\tif (ret < 0) {\n-\t\t\tTELEMETRY_LOG_ERR(\" Request Global Metrics Failed\");\n-\t\t\treturn -1;\n-\t\t}\n-\t} else {\n-\t\tTELEMETRY_LOG_ERR(\" Invalid metrics type in encode params\");\n-\t\tgoto einval_fail;\n-\t}\n-\n-\troot = json_object();\n-\tif (root == NULL) {\n-\t\tTELEMETRY_LOG_ERR(\"Could not create root JSON object\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tret = json_object_set_new(root, \"status_code\",\n-\t\tjson_string(\"Status OK: 200\"));\n-\tif (ret < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Status code field cannot be set\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tret = json_object_set_new(root, \"data\", ports);\n-\tif (ret < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Data field cannot be set\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\t*json_buffer = json_dumps(root, JSON_INDENT(2));\n-\tjson_decref(root);\n-\treturn 0;\n-\n-eperm_fail:\n-\tret = rte_telemetry_send_error_response(telemetry, -EPERM);\n-\tif (ret < 0)\n-\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\treturn -1;\n-\n-einval_fail:\n-\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n-\tif (ret < 0)\n-\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\treturn -1;\n-}\n-\n int32_t\n rte_telemetry_send_global_stats_values(struct telemetry_encode_param *ep,\n \tstruct telemetry_impl *telemetry)\n@@ -559,10 +150,12 @@ rte_telemetry_send_global_stats_values(struct telemetry_encode_param *ep,\n \t\tgoto einval_fail;\n \t}\n \n-\tret = rte_telemetry_encode_json_format(telemetry, ep,\n-\t\t&json_buffer);\n+\tret = rte_metrics_tel_encode_json_format(ep, &json_buffer);\n \tif (ret < 0) {\n \t\tTELEMETRY_LOG_ERR(\"JSON encode function failed\");\n+\t\tret = rte_telemetry_send_error_response(telemetry, ret);\n+\t\tif (ret < 0)\n+\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n \t\treturn -1;\n \t}\n \n@@ -587,8 +180,6 @@ rte_telemetry_send_ports_stats_values(struct telemetry_encode_param *ep,\n {\n \tint ret;\n \tchar *json_buffer = NULL;\n-\tuint32_t port_id;\n-\tint i;\n \n \tif (telemetry == NULL) {\n \t\tTELEMETRY_LOG_ERR(\"Invalid telemetry argument\");\n@@ -610,24 +201,14 @@ rte_telemetry_send_ports_stats_values(struct telemetry_encode_param *ep,\n \t\tgoto einval_fail;\n \t}\n \n-\tfor (i = 0; i < ep->pp.num_port_ids; i++) {\n-\t\tport_id = ep->pp.port_ids[i];\n-\t\tif (!rte_eth_dev_is_valid_port(port_id)) {\n-\t\t\tTELEMETRY_LOG_ERR(\"Port: %d invalid\", port_id);\n-\t\t\tgoto einval_fail;\n-\t\t}\n-\n-\t\tret = rte_telemetry_update_metrics_ethdev(telemetry,\n-\t\t\t\tport_id, telemetry->reg_index[i]);\n-\t\tif (ret < 0) {\n-\t\t\tTELEMETRY_LOG_ERR(\"Failed to update ethdev metrics\");\n-\t\t\treturn -1;\n-\t\t}\n-\t}\n-\n-\tret = rte_telemetry_encode_json_format(telemetry, ep, &json_buffer);\n+\tret = rte_metrics_tel_get_ports_stats_json(ep, telemetry->reg_index,\n+\t\t\t&json_buffer);\n \tif (ret < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"JSON encode function failed\");\n+\t\tTELEMETRY_LOG_ERR(\"Function for get_ports_stats_json\"\n+\t\t\t\t\" failed\");\n+\t\tret = rte_telemetry_send_error_response(telemetry, ret);\n+\t\tif (ret < 0)\n+\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n \t\treturn -1;\n \t}\n \n@@ -646,114 +227,23 @@ rte_telemetry_send_ports_stats_values(struct telemetry_encode_param *ep,\n \treturn -1;\n }\n \n-\n-static int32_t\n-rte_telemetry_reg_ethdev_to_metrics(uint16_t port_id)\n-{\n-\tint ret, num_xstats, ret_val, i;\n-\tstruct rte_eth_xstat *eth_xstats = NULL;\n-\tstruct rte_eth_xstat_name *eth_xstats_names = NULL;\n-\n-\tif (!rte_eth_dev_is_valid_port(port_id)) {\n-\t\tTELEMETRY_LOG_ERR(\"port_id: %d is invalid\", port_id);\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tnum_xstats = rte_eth_xstats_get(port_id, NULL, 0);\n-\tif (num_xstats < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"rte_eth_xstats_get(%u) failed: %d\",\n-\t\t\t\tport_id, num_xstats);\n-\t\treturn -EPERM;\n-\t}\n-\n-\teth_xstats = malloc(sizeof(struct rte_eth_xstat) * num_xstats);\n-\tif (eth_xstats == NULL) {\n-\t\tTELEMETRY_LOG_ERR(\"Failed to malloc memory for xstats\");\n-\t\treturn -ENOMEM;\n-\t}\n-\n-\tret = rte_eth_xstats_get(port_id, eth_xstats, num_xstats);\n-\tconst char *xstats_names[num_xstats];\n-\teth_xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * num_xstats);\n-\tif (ret < 0 || ret > num_xstats) {\n-\t\tTELEMETRY_LOG_ERR(\"rte_eth_xstats_get(%u) len%i failed: %d\",\n-\t\t\t\tport_id, num_xstats, ret);\n-\t\tret_val = -EPERM;\n-\t\tgoto free_xstats;\n-\t}\n-\n-\tif (eth_xstats_names == NULL) {\n-\t\tTELEMETRY_LOG_ERR(\"Failed to malloc memory for xstats_names\");\n-\t\tret_val = -ENOMEM;\n-\t\tgoto free_xstats;\n-\t}\n-\n-\tret = rte_eth_xstats_get_names(port_id, eth_xstats_names, num_xstats);\n-\tif (ret < 0 || ret > num_xstats) {\n-\t\tTELEMETRY_LOG_ERR(\"rte_eth_xstats_get_names(%u) len%i failed: %d\",\n-\t\t\t\tport_id, num_xstats, ret);\n-\t\tret_val = -EPERM;\n-\t\tgoto free_xstats;\n-\t}\n-\n-\tfor (i = 0; i < num_xstats; i++)\n-\t\txstats_names[i] = eth_xstats_names[eth_xstats[i].id].name;\n-\n-\tret_val = rte_metrics_reg_names(xstats_names, num_xstats);\n-\tif (ret_val < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"rte_metrics_reg_names failed - metrics may already be registered\");\n-\t\tret_val = -1;\n-\t\tgoto free_xstats;\n-\t}\n-\n-\tgoto free_xstats;\n-\n-free_xstats:\n-\tfree(eth_xstats);\n-\tfree(eth_xstats_names);\n-\treturn ret_val;\n-}\n-\n static int32_t\n rte_telemetry_initial_accept(struct telemetry_impl *telemetry)\n {\n-\tstruct driver_index {\n-\t\tconst void *dev_ops;\n-\t\tint reg_index;\n-\t} drv_idx[RTE_MAX_ETHPORTS] = { {0} };\n-\tint nb_drv_idx = 0;\n-\tuint16_t pid;\n \tint ret;\n \tint selftest = 0;\n \n-\tRTE_ETH_FOREACH_DEV(pid) {\n-\t\tint i;\n-\t\t/* Different device types have different numbers of stats, so\n-\t\t * first check if the stats for this type of device have\n-\t\t * already been registered\n-\t\t */\n-\t\tfor (i = 0; i < nb_drv_idx; i++) {\n-\t\t\tif (rte_eth_devices[pid].dev_ops == drv_idx[i].dev_ops) {\n-\t\t\t\ttelemetry->reg_index[pid] = drv_idx[i].reg_index;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t}\n-\t\tif (i < nb_drv_idx)\n-\t\t\tcontinue; /* we found a match, go to next port */\n-\n-\t\t/* No match, register a new set of xstats for this port */\n-\t\tret = rte_telemetry_reg_ethdev_to_metrics(pid);\n-\t\tif (ret < 0) {\n-\t\t\tTELEMETRY_LOG_ERR(\"Failed to register ethdev metrics\");\n-\t\t\treturn -1;\n-\t\t}\n-\t\ttelemetry->reg_index[pid] = ret;\n-\t\tdrv_idx[nb_drv_idx].dev_ops = rte_eth_devices[pid].dev_ops;\n-\t\tdrv_idx[nb_drv_idx].reg_index = ret;\n-\t\tnb_drv_idx++;\n+\tret = rte_metrics_tel_reg_all_ethdev(\n+\t\t\t&telemetry->metrics_register_done,\n+\t\t\ttelemetry->reg_index);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Failed to register ethdev metrics\");\n+\t\tret = rte_telemetry_send_error_response(telemetry, ret);\n+\t\tif (ret < 0)\n+\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n+\t\treturn -1;\n \t}\n \n-\ttelemetry->metrics_register_done = 1;\n \tif (selftest) {\n \t\tret = rte_telemetry_socket_messaging_testing(telemetry->reg_index[0],\n \t\t\t\ttelemetry->server_fd);\ndiff --git a/lib/librte_telemetry/rte_telemetry_internal.h b/lib/librte_telemetry/rte_telemetry_internal.h\nindex 3f8dbc2db5..ca70e2ed77 100644\n--- a/lib/librte_telemetry/rte_telemetry_internal.h\n+++ b/lib/librte_telemetry/rte_telemetry_internal.h\n@@ -4,6 +4,8 @@\n \n #include <rte_log.h>\n #include <rte_tailq.h>\n+#include <rte_metrics.h>\n+#include <rte_metrics_telemetry.h>\n \n #ifndef _RTE_TELEMETRY_INTERNAL_H_\n #define _RTE_TELEMETRY_INTERNAL_H_\n@@ -50,28 +52,6 @@ enum rte_telemetry_parser_actions {\n \tACTION_DELETE = 2\n };\n \n-enum rte_telemetry_stats_type {\n-\tPORT_STATS = 0,\n-\tGLOBAL_STATS = 1\n-};\n-\n-/* @internal */\n-struct telemetry_encode_param {\n-\tenum rte_telemetry_stats_type type;\n-\tunion {\n-\t\tstruct port_param {\n-\t\t\tint num_metric_ids;\n-\t\t\tuint32_t metric_ids[MAX_METRICS];\n-\t\t\tint num_port_ids;\n-\t\t\tuint32_t port_ids[RTE_MAX_ETHPORTS];\n-\t\t} pp;\n-\t\tstruct global_param {\n-\t\t\tint num_metric_ids;\n-\t\t\tuint32_t metric_ids[MAX_METRICS];\n-\t\t} gp;\n-\t};\n-};\n-\n int32_t\n rte_telemetry_parse_client_message(struct telemetry_impl *telemetry, char *buf);\n \n@@ -87,14 +67,6 @@ int32_t\n rte_telemetry_unregister_client(struct telemetry_impl *telemetry,\n \tconst char *client_path);\n \n-/**\n- * This is a wrapper for the ethdev api rte_eth_find_next().\n- * If rte_eth_find_next() returns the same port id that we passed it,\n- * then we know that that port is active.\n- */\n-int32_t\n-rte_telemetry_is_port_active(int port_id);\n-\n int32_t\n rte_telemetry_send_ports_stats_values(struct telemetry_encode_param *ep,\n \tstruct telemetry_impl *telemetry);\ndiff --git a/lib/librte_telemetry/rte_telemetry_parser.c b/lib/librte_telemetry/rte_telemetry_parser.c\nindex e8c269e85e..11edf79e81 100644\n--- a/lib/librte_telemetry/rte_telemetry_parser.c\n+++ b/lib/librte_telemetry/rte_telemetry_parser.c\n@@ -11,6 +11,7 @@\n #include <rte_metrics.h>\n #include <rte_common.h>\n #include <rte_ethdev.h>\n+#include <rte_metrics_telemetry.h>\n \n #include \"rte_telemetry_internal.h\"\n #include \"rte_telemetry_parser.h\"\n@@ -172,93 +173,11 @@ rte_telemetry_command_port_stats(struct telemetry_impl *telemetry, int action,\n \treturn -1;\n }\n \n-static int32_t\n-rte_telemetry_stat_names_to_ids(struct telemetry_impl *telemetry,\n-\tconst char * const *stat_names, uint32_t *stat_ids,\n-\tuint64_t num_stat_names)\n-{\n-\tstruct rte_metric_name *names;\n-\tint ret, num_metrics;\n-\tuint32_t i, k;\n-\n-\tif (stat_names == NULL) {\n-\t\tTELEMETRY_LOG_WARN(\"Invalid stat_names argument\");\n-\t\tgoto einval_fail;\n-\t}\n-\n-\tif (num_stat_names <= 0) {\n-\t\tTELEMETRY_LOG_WARN(\"Invalid num_stat_names argument\");\n-\t\tgoto einval_fail;\n-\t}\n-\n-\tnum_metrics = rte_metrics_get_names(NULL, 0);\n-\tif (num_metrics < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Cannot get metrics count\");\n-\t\tgoto eperm_fail;\n-\t} else if (num_metrics == 0) {\n-\t\tTELEMETRY_LOG_WARN(\"No metrics have been registered\");\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tnames = malloc(sizeof(struct rte_metric_name) * num_metrics);\n-\tif (names == NULL) {\n-\t\tTELEMETRY_LOG_ERR(\"Cannot allocate memory for names\");\n-\n-\t\tret = rte_telemetry_send_error_response(telemetry, -ENOMEM);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\n-\t\treturn -1;\n-\t}\n-\n-\tret = rte_metrics_get_names(names, num_metrics);\n-\tif (ret < 0 || ret > num_metrics) {\n-\t\tTELEMETRY_LOG_ERR(\"Cannot get metrics names\");\n-\t\tfree(names);\n-\t\tgoto eperm_fail;\n-\t}\n-\n-\tk = 0;\n-\tfor (i = 0; i < (uint32_t)num_stat_names; i++) {\n-\t\tuint32_t j;\n-\t\tfor (j = 0; j < (uint32_t)num_metrics; j++) {\n-\t\t\tif (strcmp(stat_names[i], names[j].name) == 0) {\n-\t\t\t\tstat_ids[k] = j;\n-\t\t\t\tk++;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t}\n-\t}\n-\n-\tif (k != num_stat_names) {\n-\t\tTELEMETRY_LOG_WARN(\"Invalid stat names provided\");\n-\t\tfree(names);\n-\t\tgoto einval_fail;\n-\t}\n-\n-\tfree(names);\n-\treturn 0;\n-\n-einval_fail:\n-\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n-\tif (ret < 0)\n-\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\treturn -1;\n-\n-eperm_fail:\n-\tret = rte_telemetry_send_error_response(telemetry, -EPERM);\n-\tif (ret < 0)\n-\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\treturn -1;\n-}\n-\n static int32_t\n rte_telemetry_command_ports_all_stat_values(struct telemetry_impl *telemetry,\n \t int action, json_t *data)\n {\n-\tint ret, num_metrics, i, p;\n-\tstruct rte_metric_value *values;\n-\tuint64_t num_port_ids = 0;\n+\tint ret;\n \tstruct telemetry_encode_param ep;\n \n \tmemset(&ep, 0, sizeof(ep));\n@@ -283,85 +202,29 @@ rte_telemetry_command_ports_all_stat_values(struct telemetry_impl *telemetry,\n \t\treturn -1;\n \t}\n \n-\tnum_metrics = rte_metrics_get_values(0, NULL, 0);\n-\tif (num_metrics < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Cannot get metrics count\");\n-\n-\t\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\n-\t\treturn -1;\n-\t} else if (num_metrics == 0) {\n-\t\tTELEMETRY_LOG_ERR(\"No metrics to display (none have been registered)\");\n-\n-\t\tret = rte_telemetry_send_error_response(telemetry, -EPERM);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\n-\t\treturn -1;\n-\t}\n-\n-\tvalues = malloc(sizeof(struct rte_metric_value) * num_metrics);\n-\tif (values == NULL) {\n-\t\tTELEMETRY_LOG_ERR(\"Cannot allocate memory\");\n-\t\tret = rte_telemetry_send_error_response(telemetry,\n-\t\t\t -ENOMEM);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\t\treturn -1;\n-\t}\n-\n-\tRTE_ETH_FOREACH_DEV(p) {\n-\t\tep.pp.port_ids[num_port_ids] = p;\n-\t\tnum_port_ids++;\n-\t}\n-\n-\tif (!num_port_ids) {\n-\t\tTELEMETRY_LOG_WARN(\"No active ports\");\n-\n-\t\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\n-\t\tgoto fail;\n-\t}\n-\n-\tret = rte_metrics_get_values(ep.pp.port_ids[0], values, num_metrics);\n+\tret = rte_metrics_tel_get_port_stats_ids(&ep);\n \tif (ret < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Could not get stat values\");\n-\t\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n+\t\tTELEMETRY_LOG_ERR(\"Could not get ports stat values\");\n+\t\tret = rte_telemetry_send_error_response(telemetry, ret);\n \t\tif (ret < 0)\n \t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\t\tgoto fail;\n+\t\treturn -1;\n \t}\n-\tfor (i = 0; i < num_metrics; i++)\n-\t\tep.pp.metric_ids[i] = values[i].key;\n-\n-\tep.pp.num_port_ids = num_port_ids;\n-\tep.pp.num_metric_ids = num_metrics;\n-\tep.type = PORT_STATS;\n \n \tret = rte_telemetry_send_ports_stats_values(&ep, telemetry);\n \tif (ret < 0) {\n \t\tTELEMETRY_LOG_ERR(\"Sending ports stats values failed\");\n-\t\tgoto fail;\n+\t\treturn -1;\n \t}\n \n-\tfree(values);\n \treturn 0;\n-\n-fail:\n-\tfree(values);\n-\treturn -1;\n }\n \n static int32_t\n rte_telemetry_command_global_stat_values(struct telemetry_impl *telemetry,\n \t int action, json_t *data)\n {\n-\tint ret, num_metrics, i;\n-\tstruct rte_metric_value *values;\n+\tint ret;\n \tstruct telemetry_encode_param ep;\n \n \tmemset(&ep, 0, sizeof(ep));\n@@ -386,61 +249,22 @@ rte_telemetry_command_global_stat_values(struct telemetry_impl *telemetry,\n \t\treturn -1;\n \t}\n \n-\tnum_metrics = rte_metrics_get_values(RTE_METRICS_GLOBAL, NULL, 0);\n-\tif (num_metrics < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Cannot get metrics count\");\n-\n-\t\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\n-\t\treturn -1;\n-\t} else if (num_metrics == 0) {\n-\t\tTELEMETRY_LOG_ERR(\"No metrics to display (none have been registered)\");\n-\n-\t\tret = rte_telemetry_send_error_response(telemetry, -EPERM);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\n-\t\treturn -1;\n-\t}\n-\n-\tvalues = malloc(sizeof(struct rte_metric_value) * num_metrics);\n-\tif (values == NULL) {\n-\t\tTELEMETRY_LOG_ERR(\"Cannot allocate memory\");\n-\t\tret = rte_telemetry_send_error_response(telemetry,\n-\t\t\t -ENOMEM);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\t\treturn -1;\n-\t}\n-\n-\tret = rte_metrics_get_values(RTE_METRICS_GLOBAL, values, num_metrics);\n+\tret = rte_metrics_tel_get_global_stats(&ep);\n \tif (ret < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Could not get stat values\");\n-\t\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n+\t\tTELEMETRY_LOG_ERR(\"Could not get global stat values\");\n+\t\tret = rte_telemetry_send_error_response(telemetry, ret);\n \t\tif (ret < 0)\n \t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\t\tgoto fail;\n+\t\treturn -1;\n \t}\n-\tfor (i = 0; i < num_metrics; i++)\n-\t\tep.gp.metric_ids[i] = values[i].key;\n-\n-\tep.gp.num_metric_ids = num_metrics;\n-\tep.type = GLOBAL_STATS;\n \n \tret = rte_telemetry_send_global_stats_values(&ep, telemetry);\n \tif (ret < 0) {\n \t\tTELEMETRY_LOG_ERR(\"Sending global stats values failed\");\n-\t\tgoto fail;\n+\t\treturn -1;\n \t}\n \n-\tfree(values);\n \treturn 0;\n-\n-fail:\n-\tfree(values);\n-\treturn -1;\n }\n \n static int32_t\n@@ -448,17 +272,7 @@ rte_telemetry_command_ports_stats_values_by_name(struct telemetry_impl\n \t*telemetry, int action, json_t *data)\n {\n \tint ret;\n-\tjson_t *port_ids_json = json_object_get(data, \"ports\");\n-\tjson_t *stat_names_json = json_object_get(data, \"stats\");\n-\tuint64_t num_stat_names = json_array_size(stat_names_json);\n-\tconst char *stat_names[num_stat_names];\n \tstruct telemetry_encode_param ep;\n-\tsize_t index;\n-\tjson_t *value;\n-\n-\tmemset(&ep, 0, sizeof(ep));\n-\tep.pp.num_port_ids = json_array_size(port_ids_json);\n-\tep.pp.num_metric_ids = num_stat_names;\n \tif (telemetry == NULL) {\n \t\tTELEMETRY_LOG_ERR(\"Invalid telemetry argument\");\n \t\treturn -1;\n@@ -472,65 +286,15 @@ rte_telemetry_command_ports_stats_values_by_name(struct telemetry_impl\n \t\treturn -1;\n \t}\n \n-\tif (!json_is_object(data)) {\n-\t\tTELEMETRY_LOG_WARN(\"Invalid data provided for this command\");\n-\t\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n-\t\tif (ret < 0)\n-\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\t\treturn -1;\n-\t}\n-\n-\tif (!json_is_array(port_ids_json) ||\n-\t\t !json_is_array(stat_names_json)) {\n-\t\tTELEMETRY_LOG_WARN(\"Invalid input data array(s)\");\n-\t\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n+\tret = rte_metrics_tel_extract_data(&ep, data);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Extracting JSON data failed\");\n+\t\tret = rte_telemetry_send_error_response(telemetry, ret);\n \t\tif (ret < 0)\n \t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n \t\treturn -1;\n \t}\n \n-\tjson_array_foreach(port_ids_json, index, value) {\n-\t\tif (!json_is_integer(value)) {\n-\t\t\tTELEMETRY_LOG_WARN(\"Port ID given is not valid\");\n-\t\t\tret = rte_telemetry_send_error_response(telemetry,\n-\t\t\t\t-EINVAL);\n-\t\t\tif (ret < 0)\n-\t\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\t\t\treturn -1;\n-\t\t}\n-\t\tep.pp.port_ids[index] = json_integer_value(value);\n-\t\tret = rte_telemetry_is_port_active(ep.pp.port_ids[index]);\n-\t\tif (ret < 1) {\n-\t\t\tret = rte_telemetry_send_error_response(telemetry,\n-\t\t\t\t-EINVAL);\n-\t\t\tif (ret < 0)\n-\t\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\t\t\treturn -1;\n-\t\t}\n-\t}\n-\n-\tjson_array_foreach(stat_names_json, index, value) {\n-\t\tif (!json_is_string(value)) {\n-\t\t\tTELEMETRY_LOG_WARN(\"Stat Name given is not a string\");\n-\n-\t\t\tret = rte_telemetry_send_error_response(telemetry,\n-\t\t\t\t\t-EINVAL);\n-\t\t\tif (ret < 0)\n-\t\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n-\n-\t\t\treturn -1;\n-\t\t}\n-\t\tstat_names[index] = json_string_value(value);\n-\t}\n-\n-\tret = rte_telemetry_stat_names_to_ids(telemetry, stat_names,\n-\t\tep.pp.metric_ids, num_stat_names);\n-\tif (ret < 0) {\n-\t\tTELEMETRY_LOG_ERR(\"Could not convert stat names to IDs\");\n-\t\treturn -1;\n-\t}\n-\n-\tep.type = PORT_STATS;\n \tret = rte_telemetry_send_ports_stats_values(&ep, telemetry);\n \tif (ret < 0) {\n \t\tTELEMETRY_LOG_ERR(\"Sending ports stats values failed\");\ndiff --git a/mk/rte.app.mk b/mk/rte.app.mk\nindex d295ca0a52..e683686147 100644\n--- a/mk/rte.app.mk\n+++ b/mk/rte.app.mk\n@@ -55,7 +55,9 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_TELEMETRY)      += -lrte_telemetry -ljansson\n _LDLIBS-$(CONFIG_RTE_LIBRTE_TELEMETRY)      += --no-whole-archive\n _LDLIBS-$(CONFIG_RTE_LIBRTE_TELEMETRY)      += --as-needed\n _LDLIBS-$(CONFIG_RTE_LIBRTE_JOBSTATS)       += -lrte_jobstats\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS)        += --whole-archive\n _LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS)        += -lrte_metrics\n+_LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS)        += --no-whole-archive\n _LDLIBS-$(CONFIG_RTE_LIBRTE_BITRATE)        += -lrte_bitratestats\n _LDLIBS-$(CONFIG_RTE_LIBRTE_LATENCY_STATS)  += -lrte_latencystats\n _LDLIBS-$(CONFIG_RTE_LIBRTE_POWER)          += -lrte_power\n",
    "prefixes": [
        "v3",
        "02/17"
    ]
}