get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 21017,
    "url": "https://patches.dpdk.org/api/patches/21017/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1488385639-31471-1-git-send-email-romanx.korynkevych@intel.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<1488385639-31471-1-git-send-email-romanx.korynkevych@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1488385639-31471-1-git-send-email-romanx.korynkevych@intel.com",
    "date": "2017-03-01T16:27:19",
    "name": "[dpdk-dev,v3] proc-info: added collectd-format and host-id options.",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "d63f0097aa99f5ba3546d485f2147e0778c7ae86",
    "submitter": {
        "id": 683,
        "url": "https://patches.dpdk.org/api/people/683/?format=api",
        "name": "Roman Korynkevych",
        "email": "romanx.korynkevych@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1488385639-31471-1-git-send-email-romanx.korynkevych@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/21017/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/21017/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id CC6272C2B;\n\tWed,  1 Mar 2017 17:28:20 +0100 (CET)",
            "from mga03.intel.com (mga03.intel.com [134.134.136.65])\n\tby dpdk.org (Postfix) with ESMTP id 48EF42BB1\n\tfor <dev@dpdk.org>; Wed,  1 Mar 2017 17:28:18 +0100 (CET)",
            "from orsmga002.jf.intel.com ([10.7.209.21])\n\tby orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t01 Mar 2017 08:28:16 -0800",
            "from silpixa00390851.ir.intel.com ([10.237.223.109])\n\tby orsmga002.jf.intel.com with ESMTP; 01 Mar 2017 08:27:15 -0800"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.35,226,1484035200\"; d=\"scan'208\";a=\"54539509\"",
        "From": "Roman Korynkevych <romanx.korynkevych@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Roman Korynkevych <romanx.korynkevych@intel.com>",
        "Date": "Wed,  1 Mar 2017 16:27:19 +0000",
        "Message-Id": "<1488385639-31471-1-git-send-email-romanx.korynkevych@intel.com>",
        "X-Mailer": "git-send-email 2.1.0",
        "In-Reply-To": "<1488204982-32291-1-git-send-email-romanx.korynkevych@intel.com>",
        "References": "<1488204982-32291-1-git-send-email-romanx.korynkevych@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v3] proc-info: added collectd-format and host-id\n\toptions.",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Extended proc-info application to send DPDK port statistics to\nSTDOUT in the format expected by collectd exec plugin. Added\nHOST ID option to identify the host DPDK process is running on\nwhen multiple instance of DPDK are running in parallel. This is\nneeded for the barometer project in OPNFV.\n\nSigned-off-by: Roman Korynkevych <romanx.korynkevych@intel.com>\n---\n app/proc_info/main.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++--\n 1 file changed, 125 insertions(+), 5 deletions(-)",
    "diff": "diff --git a/app/proc_info/main.c b/app/proc_info/main.c\nindex 2c56d10..ef2098d 100644\n--- a/app/proc_info/main.c\n+++ b/app/proc_info/main.c\n@@ -40,6 +40,7 @@\n #include <sys/queue.h>\n #include <stdlib.h>\n #include <getopt.h>\n+#include <unistd.h>\n \n #include <rte_eal.h>\n #include <rte_common.h>\n@@ -62,12 +63,20 @@\n #define MAX_LONG_OPT_SZ 64\n #define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1\n \n+#define MAX_STRING_LEN 256\n+\n /**< mask of enabled ports */\n static uint32_t enabled_port_mask;\n /**< Enable stats. */\n static uint32_t enable_stats;\n /**< Enable xstats. */\n static uint32_t enable_xstats;\n+/**< Enable collectd format*/\n+static uint32_t enable_collectd_format;\n+/**< FD to send collectd format messages to STDOUT*/\n+static int stdout_fd;\n+/**< Host id process is running on */\n+static char host_id[MAX_LONG_OPT_SZ];\n /**< Enable stats reset. */\n static uint32_t reset_stats;\n /**< Enable xstats reset. */\n@@ -86,7 +95,9 @@ proc_info_usage(const char *prgname)\n \t\t\"  --xstats: to display extended port statistics, disabled by \"\n \t\t\t\"default\\n\"\n \t\t\"  --stats-reset: to reset port statistics\\n\"\n-\t\t\"  --xstats-reset: to reset port extended statistics\\n\",\n+\t\t\"  --xstats-reset: to reset port extended statistics\\n\"\n+\t\t\"  --collectd-format: to print statistics to STDOUT in expected by collectd format\\n\"\n+\t\t\"  --host-id STRING: host id used to identify the system process is running on\\n\",\n \t\tprgname);\n }\n \n@@ -116,6 +127,39 @@ parse_portmask(const char *portmask)\n \n }\n \n+static int\n+proc_info_preparse_args(int argc, char **argv)\n+{\n+\tchar *prgname = argv[0];\n+\tint i;\n+\n+\tfor (i = 0; i < argc; i++) {\n+\t\t/* Print stats or xstats to STDOUT in collectd format */\n+\t\tif (!strncmp(argv[i], \"--collectd-format\", MAX_LONG_OPT_SZ)) {\n+\t\t\tenable_collectd_format = 1;\n+\t\t\tstdout_fd = dup(STDOUT_FILENO);\n+\t\t\tclose(STDOUT_FILENO);\n+\t\t}\n+\t\tif (!strncmp(argv[i], \"--host-id\", MAX_LONG_OPT_SZ)) {\n+\t\t\tif ((i + 1) == argc) {\n+\t\t\t\tprintf(\"Invalid host id or not specified\\n\");\n+\t\t\t\tproc_info_usage(prgname);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tstrncpy(host_id, argv[i+1], sizeof(host_id));\n+\t\t}\n+\t}\n+\n+\tif (!strlen(host_id)) {\n+\t\tint err = gethostname(host_id, MAX_LONG_OPT_SZ-1);\n+\n+\t\tif (err)\n+\t\t\tstrcpy(host_id, \"unknown\");\n+\t}\n+\n+\treturn 0;\n+}\n+\n /* Parse the argument given in the command line of the application */\n static int\n proc_info_parse_args(int argc, char **argv)\n@@ -128,6 +172,8 @@ proc_info_parse_args(int argc, char **argv)\n \t\t{\"stats-reset\", 0, NULL, 0},\n \t\t{\"xstats\", 0, NULL, 0},\n \t\t{\"xstats-reset\", 0, NULL, 0},\n+\t\t{\"collectd-format\", 0, NULL, 0},\n+\t\t{\"host-id\", 0, NULL, 0},\n \t\t{NULL, 0, 0, 0}\n \t};\n \n@@ -240,6 +286,60 @@ nic_stats_clear(uint8_t port_id)\n \tprintf(\"\\n  NIC statistics for port %d cleared\\n\", port_id);\n }\n \n+static void collectd_resolve_cnt_type(char *cnt_type, size_t cnt_type_len,\n+\t\t\t\t      const char *cnt_name) {\n+\tchar *type_end = strrchr(cnt_name, '_');\n+\n+\tif ((type_end != NULL) &&\n+\t    (strncmp(cnt_name, \"rx_\", strlen(\"rx_\")) == 0)) {\n+\t\tif (strncmp(type_end, \"_errors\", strlen(\"_errors\")) == 0)\n+\t\t\tstrncpy(cnt_type, \"if_rx_errors\", cnt_type_len);\n+\t\telse if (strncmp(type_end, \"_dropped\", strlen(\"_dropped\")) == 0)\n+\t\t\tstrncpy(cnt_type, \"if_rx_dropped\", cnt_type_len);\n+\t\telse if (strncmp(type_end, \"_bytes\", strlen(\"_bytes\")) == 0)\n+\t\t\tstrncpy(cnt_type, \"if_rx_octets\", cnt_type_len);\n+\t\telse if (strncmp(type_end, \"_packets\", strlen(\"_packets\")) == 0)\n+\t\t\tstrncpy(cnt_type, \"if_rx_packets\", cnt_type_len);\n+\t\telse if (strncmp(type_end, \"_placement\",\n+\t\t\t\t strlen(\"_placement\")) == 0)\n+\t\t\tstrncpy(cnt_type, \"if_rx_errors\", cnt_type_len);\n+\t\telse if (strncmp(type_end, \"_buff\", strlen(\"_buff\")) == 0)\n+\t\t\tstrncpy(cnt_type, \"if_rx_errors\", cnt_type_len);\n+\t\telse\n+\t\t\t/* Does not fit obvious type: use a more generic one */\n+\t\t\tstrncpy(cnt_type, \"derive\", cnt_type_len);\n+\t} else if ((type_end != NULL) &&\n+\t\t(strncmp(cnt_name, \"tx_\", strlen(\"tx_\"))) == 0) {\n+\t\tif (strncmp(type_end, \"_errors\", strlen(\"_errors\")) == 0)\n+\t\t\tstrncpy(cnt_type, \"if_tx_errors\", cnt_type_len);\n+\t\telse if (strncmp(type_end, \"_dropped\", strlen(\"_dropped\")) == 0)\n+\t\t\tstrncpy(cnt_type, \"if_tx_dropped\", cnt_type_len);\n+\t\telse if (strncmp(type_end, \"_bytes\", strlen(\"_bytes\")) == 0)\n+\t\t\tstrncpy(cnt_type, \"if_tx_octets\", cnt_type_len);\n+\t\telse if (strncmp(type_end, \"_packets\", strlen(\"_packets\")) == 0)\n+\t\t\tstrncpy(cnt_type, \"if_tx_packets\", cnt_type_len);\n+\t\telse\n+\t\t\t/* Does not fit obvious type: use a more generic one */\n+\t\t\tstrncpy(cnt_type, \"derive\", cnt_type_len);\n+\t} else if ((type_end != NULL) &&\n+\t\t   (strncmp(cnt_name, \"flow_\", strlen(\"flow_\"))) == 0) {\n+\t\tif (strncmp(type_end, \"_filters\", strlen(\"_filters\")) == 0)\n+\t\t\tstrncpy(cnt_type, \"operations\", cnt_type_len);\n+\t\telse if (strncmp(type_end, \"_errors\", strlen(\"_errors\")) == 0)\n+\t\t\tstrncpy(cnt_type, \"errors\", cnt_type_len);\n+\t\telse if (strncmp(type_end, \"_filters\", strlen(\"_filters\")) == 0)\n+\t\t\tstrncpy(cnt_type, \"filter_result\", cnt_type_len);\n+\t} else if ((type_end != NULL) &&\n+\t\t   (strncmp(cnt_name, \"mac_\", strlen(\"mac_\"))) == 0) {\n+\t\tif (strncmp(type_end, \"_errors\", strlen(\"_errors\")) == 0)\n+\t\t\tstrncpy(cnt_type, \"errors\", cnt_type_len);\n+\t} else {\n+\t\t/* Does not fit obvious type, or strrchr error: */\n+\t\t/* use a more generic type */\n+\t\tstrncpy(cnt_type, \"derive\", cnt_type_len);\n+\t}\n+}\n+\n static void\n nic_xstats_display(uint8_t port_id)\n {\n@@ -281,10 +381,23 @@ nic_xstats_display(uint8_t port_id)\n \t\tgoto err;\n \t}\n \n-\tfor (i = 0; i < len; i++)\n-\t\tprintf(\"%s: %\"PRIu64\"\\n\",\n-\t\t\txstats_names[i].name,\n-\t\t\txstats[i].value);\n+\tfor (i = 0; i < len; i++) {\n+\t\tif (enable_collectd_format) {\n+\t\t\tchar counter_type[MAX_STRING_LEN];\n+\t\t\tchar buf[MAX_STRING_LEN];\n+\n+\t\t\tcollectd_resolve_cnt_type(counter_type,\n+\t\t\t\t\t\t  sizeof(counter_type),\n+\t\t\t\t\t\t  xstats_names[i].name);\n+\t\t\tsprintf(buf, \"PUTVAL %s/dpdkstat-port.%u/%s-%s N:%\"\n+\t\t\t\tPRIu64\"\\n\", host_id, port_id, counter_type,\n+\t\t\t\txstats_names[i].name, xstats[i].value);\n+\t\t\twrite(stdout_fd, buf, strlen(buf));\n+\t\t} else {\n+\t\t\tprintf(\"%s: %\"PRIu64\"\\n\", xstats_names[i].name,\n+\t\t\t       xstats[i].value);\n+\t\t}\n+\t}\n \n \tprintf(\"%s############################\\n\",\n \t\t\t   nic_stats_border);\n@@ -312,6 +425,13 @@ main(int argc, char **argv)\n \tchar *argp[argc + 3];\n \tuint8_t nb_ports;\n \n+\t/* preparse app arguments */\n+\tret = proc_info_preparse_args(argc, argv);\n+\tif (ret < 0) {\n+\t\tprintf(\"Failed to parse arguments\\n\");\n+\t\treturn -1;\n+\t}\n+\n \targp[0] = argv[0];\n \targp[1] = c_flag;\n \targp[2] = n_flag;\n",
    "prefixes": [
        "dpdk-dev",
        "v3"
    ]
}