[v2] doc: add more detail to telemetry guides
Checks
Commit Message
This patch adds examples to the Telemetry HowTo guide, to demonstrate
commands that use parameters. The programmer's guide is also modified to
include details on writing a callback function for a new command.
Signed-off-by: Ciara Power <ciara.power@intel.com>
---
v2:
- Replaced examples of using commands in the programmer's guide with
a link to the HowTo guide.
- Added an example showing the use of a single string value.
- Replaced inline functions with a synthetic example function below
the list of parameters.
---
doc/guides/howto/telemetry.rst | 46 ++++++-
doc/guides/prog_guide/telemetry_lib.rst | 172 ++++++++++++++++++++----
2 files changed, 187 insertions(+), 31 deletions(-)
Comments
On Tue, Jul 21, 2020 at 05:09:24PM +0100, Ciara Power wrote:
> This patch adds examples to the Telemetry HowTo guide, to demonstrate
> commands that use parameters. The programmer's guide is also modified to
> include details on writing a callback function for a new command.
>
> Signed-off-by: Ciara Power <ciara.power@intel.com>
>
> ---
> v2:
> - Replaced examples of using commands in the programmer's guide with
> a link to the HowTo guide.
> - Added an example showing the use of a single string value.
> - Replaced inline functions with a synthetic example function below
> the list of parameters.
> ---
> doc/guides/howto/telemetry.rst | 46 ++++++-
> doc/guides/prog_guide/telemetry_lib.rst | 172 ++++++++++++++++++++----
> 2 files changed, 187 insertions(+), 31 deletions(-)
>
Missed threading patch with v1, but content looks fine to me.
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
21/07/2020 18:09, Ciara Power:
> --- a/doc/guides/howto/telemetry.rst
> +++ b/doc/guides/howto/telemetry.rst
> @@ -1,6 +1,7 @@
> .. SPDX-License-Identifier: BSD-3-Clause
> Copyright(c) 2020 Intel Corporation.
>
> +.. _telemetry:
We don't need such anchor.
The beginning of a page can be linked via :doc: syntax.
Note: I would support a patch removing all such existing anchors
at beginning of files.
[...]
> + * List all commands.
> +
> + .. code-block:: console
I think you can achieve the same result as code-block
with adding double colons (::) at the end of the previous line:
* List all commands::
[...]
> --- a/doc/guides/prog_guide/telemetry_lib.rst
> +++ b/doc/guides/prog_guide/telemetry_lib.rst
> +The parameters for a callback function are:
> +
> +* **cmd**
> +
> + This is the command requested by the client, e.g. "/ethdev/list".
> + For most callbacks this may be unused, however it will allow for handling
> + multiple commands in one callback function. This can be seen in the example
> + callback below.
> +
> +* **params**
> +
> + This will contain any parameters required for the command. For example
> + when calling "/ethdev/link_status,0", the port ID will be passed to the
> + callback function in params. This can be seen in the example callback below.
> +
> +* **d**
> +
> + The rte_tel_data pointer will be used by the callback function to format the
> + requested data to be returned to Telemetry. The data APIs provided will
> + enable adding to the struct, examples of this are shown later in this
> + document.
It looks like a doxygen-level comment.
Why not linking doxygen from here and focus on example in this guide?
Note that we can also link example code from doxygen.
> +
> +**Example Callback**
> +
> +This callback is an example of handling multiple commands in one callback,
> +and also shows the use of params which holds a port ID. The params input needs
> +to be validated and converted to the required integer type for port ID. The cmd
> +parameter is then used in a comparison to decide which command was requested,
> +which will decide what port information should fill the rte_tel_data structure.
> +
> +.. code-block:: c
> +
> + int
> + handle_cmd_request(const char *cmd, const char *params,
> + struct rte_tel_data *d)
> + {
> + int port_id, used = 0;
> +
> + if (params == NULL || strlen(params) == 0 || !isdigit(*params))
> + return -1;
> +
> + port_id = atoi(params);
> + if (!rte_eth_dev_is_valid_port(port_id))
> + return -1;
> +
> + if (strcmp(cmd, "/cmd_1") == 0)
> + /* Build up port data requested for command 1 */
> + else
> + /* Build up port data requested for command 2 */
> +
> + return used;
> + }
> +
> +
> +Formatting Data
> +~~~~~~~~~~~~~~~
> +
> +The callback function provided by the library must format its telemetry
> +information in the required data format. The Telemetry library provides a data
> +utilities API to build up the data structure with the required information.
> +The telemetry library is then responsible for formatting the data structure
> +into a JSON response before sending to the client.
> +
> +* **Array Data**
It looks like a sub-title.
Please prefer sub-titles because they appear in the menu
and can be referenced with a direct HTML link.
[...]
> + .. code-block:: c
> +
> + rte_tel_data_start_dict(d);
> + rte_tel_data_add_dict_string(d, "version", rte_version());
> + rte_tel_data_add_dict_int(d, "pid", getpid());
> + rte_tel_data_add_dict_int(d, "max_output_len", MAX_OUTPUT_LEN);
> +
> + The resulting response to the client shows the key/value data provided above
> + by the handler function in telemetry, placed in a JSON reply by telemetry:
> +
> + .. code-block:: console
> +
> + {"/info": {"version": "DPDK 20.08.0-rc0", "pid": 3838, "max_output_len": 16384}}
In general I prefer avoiding real code because it will look
out-of-date quickly.
Why not demonstrating telemetry with a cooking recipe or NASA rocket?
[...]
> +For more information on the range of data functions available in the API,
> +please refer to the docs.
"the docs"? Can we add a link?
Hi Thomas,
Thanks for the review.
I have addressed your comments in the v3 patch, with one exception mentioned below.
<snip>
>[...]
>> + * List all commands.
>> +
>> + .. code-block:: console
>
>I think you can achieve the same result as code-block with adding double
>colons (::) at the end of the previous line:
> * List all commands::
>
I have added this in the v3 for all console code-blocks.
I left the C code-blocks as they were to ensure C syntax highlighting is maintained.
<snip>
Thanks,
Ciara
@@ -1,6 +1,7 @@
.. SPDX-License-Identifier: BSD-3-Clause
Copyright(c) 2020 Intel Corporation.
+.. _telemetry:
DPDK Telemetry User Guide
=========================
@@ -69,12 +70,43 @@ and query information using the telemetry client python script.
-->
#. The user can now input commands to send across the socket, and receive the
- response.
+ response. Some available commands are shown below.
- .. code-block:: console
+ * List all commands.
+
+ .. code-block:: console
+
+ --> /
+ {"/": ["/", "/eal/app_params", "/eal/params", "/ethdev/list",
+ "/ethdev/link_status", "/ethdev/xstats", "/help", "/info"]}
+
+ * Get the list of ethdev ports.
+
+ .. code-block:: console
+
+ --> /ethdev/list
+ {"/ethdev/list": [0, 1]}
+
+ .. Note::
+
+ For commands that expect a parameter, use "," to separate the command
+ and parameter. See examples below.
+
+ * Get extended statistics for an ethdev port.
+
+ .. code-block:: console
+
+ --> /ethdev/xstats,0
+ {"/ethdev/xstats": {"rx_good_packets": 0, "tx_good_packets": 0,
+ "rx_good_bytes": 0, "tx_good_bytes": 0, "rx_missed_errors": 0,
+ ...
+ "tx_priority7_xon_to_xoff_packets": 0}}
+
+ * Get the help text for a command. This will indicate what parameters are
+ required. Pass the command as a parameter.
+
+ .. code-block:: console
- --> /
- {"/": ["/", "/eal/app_params", "/eal/params", "/ethdev/list",
- "/ethdev/link_status", "/ethdev/xstats", "/help", "/info"]}
- --> /ethdev/list
- {"/ethdev/list": [0, 1]}
+ --> /help,/ethdev/xstats
+ {"/help": {"/ethdev/xstats": "Returns the extended stats for a port.
+ Parameters: int port_id"}}
@@ -16,6 +16,150 @@ function that will format the library specific stats into the correct data
format, when requested.
+Creating Callback Functions
+---------------------------
+
+
+Function Type
+~~~~~~~~~~~~~
+
+When creating a callback function in a library/app, it must be of the following type:
+
+.. code-block:: c
+
+ typedef int (*telemetry_cb)(const char *cmd, const char *params,
+ struct rte_tel_data *info);
+
+For example, the callback for "/ethdev/list" is:
+
+.. code-block:: c
+
+ static int
+ handle_port_list(const char *cmd __rte_unused, const char *params __rte_unused,
+ struct rte_tel_data *d)
+
+The parameters for a callback function are:
+
+* **cmd**
+
+ This is the command requested by the client, e.g. "/ethdev/list".
+ For most callbacks this may be unused, however it will allow for handling
+ multiple commands in one callback function. This can be seen in the example
+ callback below.
+
+* **params**
+
+ This will contain any parameters required for the command. For example
+ when calling "/ethdev/link_status,0", the port ID will be passed to the
+ callback function in params. This can be seen in the example callback below.
+
+* **d**
+
+ The rte_tel_data pointer will be used by the callback function to format the
+ requested data to be returned to Telemetry. The data APIs provided will
+ enable adding to the struct, examples of this are shown later in this
+ document.
+
+**Example Callback**
+
+This callback is an example of handling multiple commands in one callback,
+and also shows the use of params which holds a port ID. The params input needs
+to be validated and converted to the required integer type for port ID. The cmd
+parameter is then used in a comparison to decide which command was requested,
+which will decide what port information should fill the rte_tel_data structure.
+
+.. code-block:: c
+
+ int
+ handle_cmd_request(const char *cmd, const char *params,
+ struct rte_tel_data *d)
+ {
+ int port_id, used = 0;
+
+ if (params == NULL || strlen(params) == 0 || !isdigit(*params))
+ return -1;
+
+ port_id = atoi(params);
+ if (!rte_eth_dev_is_valid_port(port_id))
+ return -1;
+
+ if (strcmp(cmd, "/cmd_1") == 0)
+ /* Build up port data requested for command 1 */
+ else
+ /* Build up port data requested for command 2 */
+
+ return used;
+ }
+
+
+Formatting Data
+~~~~~~~~~~~~~~~
+
+The callback function provided by the library must format its telemetry
+information in the required data format. The Telemetry library provides a data
+utilities API to build up the data structure with the required information.
+The telemetry library is then responsible for formatting the data structure
+into a JSON response before sending to the client.
+
+* **Array Data**
+
+ Some data will need to be formatted in a list structure. For example, the
+ ethdev library provides a list of available ethdev ports in a formatted data
+ response, constructed using the following functions to build up the list:
+
+ .. code-block:: c
+
+ rte_tel_data_start_array(d, RTE_TEL_INT_VAL);
+ RTE_ETH_FOREACH_DEV(port_id)
+ rte_tel_data_add_array_int(d, port_id);
+
+ The resulting response to the client shows the port list data provided above
+ by the handler function in ethdev, placed in a JSON reply by telemetry:
+
+ .. code-block:: console
+
+ {"/ethdev/list": [0, 1]}
+
+* **Dictionary Data**
+
+ For data that needs to be structured in a dictionary with key/value pairs,
+ the data utilities API can also be used. For example, telemetry provides an
+ info command that has multiple key/value pairs, constructed in the callback
+ function shown below:
+
+ .. code-block:: c
+
+ rte_tel_data_start_dict(d);
+ rte_tel_data_add_dict_string(d, "version", rte_version());
+ rte_tel_data_add_dict_int(d, "pid", getpid());
+ rte_tel_data_add_dict_int(d, "max_output_len", MAX_OUTPUT_LEN);
+
+ The resulting response to the client shows the key/value data provided above
+ by the handler function in telemetry, placed in a JSON reply by telemetry:
+
+ .. code-block:: console
+
+ {"/info": {"version": "DPDK 20.08.0-rc0", "pid": 3838, "max_output_len": 16384}}
+
+* **String Data**
+
+ Telemetry also supports single string data. The data utilities API can again
+ be used for this, see the example below.
+
+ .. code-block:: c
+
+ rte_tel_data_string(d, "This is an example string");
+
+ Giving the following response to the client:
+
+ .. code-block:: console
+
+ {"/string_example": "This is an example string"}
+
+For more information on the range of data functions available in the API,
+please refer to the docs.
+
+
Registering Commands
--------------------
@@ -35,28 +179,8 @@ command. An example showing ethdev commands being registered is shown below:
"Returns the link status for a port. Parameters: int port_id");
-Formatting JSON response
-------------------------
-
-The callback function provided by the library must format its telemetry
-information in the required data format. The Telemetry library provides a data
-utilities API to build up the response. For example, the ethdev library provides a
-list of available ethdev ports in a formatted data response, constructed using the
-following functions to build up the list:
+Using Commands
+--------------
-.. code-block:: c
-
- rte_tel_data_start_array(d, RTE_TEL_INT_VAL);
- RTE_ETH_FOREACH_DEV(port_id)
- rte_tel_data_add_array_int(d, port_id);
-
-The data structure is then formatted into a JSON response before sending.
-The resulting response shows the port list data provided above by the handler
-function in ethdev, placed in a JSON reply by telemetry:
-
-.. code-block:: console
-
- {"/ethdev/list": [0, 1]}
-
-For more information on the range of data functions available in the API,
-please refer to the docs.
+To use commands, with a DPDK app running (e.g. testpmd), use the
+dpdk-telemetry.py script. For details on its use, see the :ref:`telemetry`.