[v2] doc: add more detail to telemetry guides

Message ID 20200721160924.62082-1-ciara.power@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series [v2] doc: add more detail to telemetry guides |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/travis-robot success Travis build: passed
ci/Intel-compilation success Compilation OK

Commit Message

Power, Ciara July 21, 2020, 4:09 p.m. UTC
  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

Bruce Richardson July 21, 2020, 5:38 p.m. UTC | #1
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>
  
Thomas Monjalon July 22, 2020, 5:27 p.m. UTC | #2
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?
  
Power, Ciara July 24, 2020, 11:32 a.m. UTC | #3
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
  

Patch

diff --git a/doc/guides/howto/telemetry.rst b/doc/guides/howto/telemetry.rst
index b4a34ed67..7e8a5d6f3 100644
--- 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:
 
 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"}}
diff --git a/doc/guides/prog_guide/telemetry_lib.rst b/doc/guides/prog_guide/telemetry_lib.rst
index 8563a7200..694cef26b 100644
--- a/doc/guides/prog_guide/telemetry_lib.rst
+++ b/doc/guides/prog_guide/telemetry_lib.rst
@@ -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`.