xref: /dpdk/doc/guides/prog_guide/metrics_lib.rst (revision 349950ddb9c5700dc4921ee758fb55265f0e7f16)
1*349950ddSRemy Horton..  BSD LICENSE
2*349950ddSRemy Horton    Copyright(c) 2017 Intel Corporation. All rights reserved.
3*349950ddSRemy Horton    All rights reserved.
4*349950ddSRemy Horton
5*349950ddSRemy Horton    Redistribution and use in source and binary forms, with or without
6*349950ddSRemy Horton    modification, are permitted provided that the following conditions
7*349950ddSRemy Horton    are met:
8*349950ddSRemy Horton
9*349950ddSRemy Horton    * Redistributions of source code must retain the above copyright
10*349950ddSRemy Horton    notice, this list of conditions and the following disclaimer.
11*349950ddSRemy Horton    * Redistributions in binary form must reproduce the above copyright
12*349950ddSRemy Horton    notice, this list of conditions and the following disclaimer in
13*349950ddSRemy Horton    the documentation and/or other materials provided with the
14*349950ddSRemy Horton    distribution.
15*349950ddSRemy Horton    * Neither the name of Intel Corporation nor the names of its
16*349950ddSRemy Horton    contributors may be used to endorse or promote products derived
17*349950ddSRemy Horton    from this software without specific prior written permission.
18*349950ddSRemy Horton
19*349950ddSRemy Horton    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20*349950ddSRemy Horton    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21*349950ddSRemy Horton    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22*349950ddSRemy Horton    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23*349950ddSRemy Horton    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24*349950ddSRemy Horton    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25*349950ddSRemy Horton    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26*349950ddSRemy Horton    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27*349950ddSRemy Horton    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28*349950ddSRemy Horton    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29*349950ddSRemy Horton    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*349950ddSRemy Horton
31*349950ddSRemy Horton.. _Metrics_Library:
32*349950ddSRemy Horton
33*349950ddSRemy HortonMetrics Library
34*349950ddSRemy Horton===============
35*349950ddSRemy Horton
36*349950ddSRemy HortonThe Metrics library implements a mechanism by which *producers* can
37*349950ddSRemy Hortonpublish numeric information for later querying by *consumers*. In
38*349950ddSRemy Hortonpractice producers will typically be other libraries or primary
39*349950ddSRemy Hortonprocesses, whereas consumers will typically be applications.
40*349950ddSRemy Horton
41*349950ddSRemy HortonMetrics themselves are statistics that are not generated by PMDs. Metric
42*349950ddSRemy Hortoninformation is populated using a push model, where producers update the
43*349950ddSRemy Hortonvalues contained within the metric library by calling an update function
44*349950ddSRemy Hortonon the relevant metrics. Consumers receive metric information by querying
45*349950ddSRemy Hortonthe central metric data, which is held in shared memory.
46*349950ddSRemy Horton
47*349950ddSRemy HortonFor each metric, a separate value is maintained for each port id, and
48*349950ddSRemy Hortonwhen publishing metric values the producers need to specify which port is
49*349950ddSRemy Hortonbeing updated. In addition there is a special id ``RTE_METRICS_GLOBAL``
50*349950ddSRemy Hortonthat is intended for global statistics that are not associated with any
51*349950ddSRemy Hortonindividual device. Since the metrics library is self-contained, the only
52*349950ddSRemy Hortonrestriction on port numbers is that they are less than ``RTE_MAX_ETHPORTS``
53*349950ddSRemy Horton- there is no requirement for the ports to actually exist.
54*349950ddSRemy Horton
55*349950ddSRemy HortonInitialising the library
56*349950ddSRemy Horton------------------------
57*349950ddSRemy Horton
58*349950ddSRemy HortonBefore the library can be used, it has to be initialized by calling
59*349950ddSRemy Horton``rte_metrics_init()`` which sets up the metric store in shared memory.
60*349950ddSRemy HortonThis is where producers will publish metric information to, and where
61*349950ddSRemy Hortonconsumers will query it from.
62*349950ddSRemy Horton
63*349950ddSRemy Horton.. code-block:: c
64*349950ddSRemy Horton
65*349950ddSRemy Horton    rte_metrics_init(rte_socket_id());
66*349950ddSRemy Horton
67*349950ddSRemy HortonThis function **must** be called from a primary process, but otherwise
68*349950ddSRemy Hortonproducers and consumers can be in either primary or secondary processes.
69*349950ddSRemy Horton
70*349950ddSRemy HortonRegistering metrics
71*349950ddSRemy Horton-------------------
72*349950ddSRemy Horton
73*349950ddSRemy HortonMetrics must first be *registered*, which is the way producers declare
74*349950ddSRemy Hortonthe names of the metrics they will be publishing. Registration can either
75*349950ddSRemy Hortonbe done individually, or a set of metrics can be registered as a group.
76*349950ddSRemy HortonIndividual registration is done using ``rte_metrics_reg_name()``:
77*349950ddSRemy Horton
78*349950ddSRemy Horton.. code-block:: c
79*349950ddSRemy Horton
80*349950ddSRemy Horton    id_1 = rte_metrics_reg_name("mean_bits_in");
81*349950ddSRemy Horton    id_2 = rte_metrics_reg_name("mean_bits_out");
82*349950ddSRemy Horton    id_3 = rte_metrics_reg_name("peak_bits_in");
83*349950ddSRemy Horton    id_4 = rte_metrics_reg_name("peak_bits_out");
84*349950ddSRemy Horton
85*349950ddSRemy Hortonor alternatively, a set of metrics can be registered together using
86*349950ddSRemy Horton``rte_metrics_reg_names()``:
87*349950ddSRemy Horton
88*349950ddSRemy Horton.. code-block:: c
89*349950ddSRemy Horton
90*349950ddSRemy Horton    const char * const names[] = {
91*349950ddSRemy Horton        "mean_bits_in", "mean_bits_out",
92*349950ddSRemy Horton        "peak_bits_in", "peak_bits_out",
93*349950ddSRemy Horton    };
94*349950ddSRemy Horton    id_set = rte_metrics_reg_names(&names[0], 4);
95*349950ddSRemy Horton
96*349950ddSRemy HortonIf the return value is negative, it means registration failed. Otherwise
97*349950ddSRemy Hortonthe return value is the *key* for the metric, which is used when updating
98*349950ddSRemy Hortonvalues. A table mapping together these key values and the metrics' names
99*349950ddSRemy Hortoncan be obtained using ``rte_metrics_get_names()``.
100*349950ddSRemy Horton
101*349950ddSRemy HortonUpdating metric values
102*349950ddSRemy Horton----------------------
103*349950ddSRemy Horton
104*349950ddSRemy HortonOnce registered, producers can update the metric for a given port using
105*349950ddSRemy Hortonthe ``rte_metrics_update_value()`` function. This uses the metric key
106*349950ddSRemy Hortonthat is returned when registering the metric, and can also be looked up
107*349950ddSRemy Hortonusing ``rte_metrics_get_names()``.
108*349950ddSRemy Horton
109*349950ddSRemy Horton.. code-block:: c
110*349950ddSRemy Horton
111*349950ddSRemy Horton    rte_metrics_update_value(port_id, id_1, values[0]);
112*349950ddSRemy Horton    rte_metrics_update_value(port_id, id_2, values[1]);
113*349950ddSRemy Horton    rte_metrics_update_value(port_id, id_3, values[2]);
114*349950ddSRemy Horton    rte_metrics_update_value(port_id, id_4, values[3]);
115*349950ddSRemy Horton
116*349950ddSRemy Hortonif metrics were registered as a single set, they can either be updated
117*349950ddSRemy Hortonindividually using ``rte_metrics_update_value()``, or updated together
118*349950ddSRemy Hortonusing the ``rte_metrics_update_values()`` function:
119*349950ddSRemy Horton
120*349950ddSRemy Horton.. code-block:: c
121*349950ddSRemy Horton
122*349950ddSRemy Horton    rte_metrics_update_value(port_id, id_set, values[0]);
123*349950ddSRemy Horton    rte_metrics_update_value(port_id, id_set + 1, values[1]);
124*349950ddSRemy Horton    rte_metrics_update_value(port_id, id_set + 2, values[2]);
125*349950ddSRemy Horton    rte_metrics_update_value(port_id, id_set + 3, values[3]);
126*349950ddSRemy Horton
127*349950ddSRemy Horton    rte_metrics_update_values(port_id, id_set, values, 4);
128*349950ddSRemy Horton
129*349950ddSRemy HortonNote that ``rte_metrics_update_values()`` cannot be used to update
130*349950ddSRemy Hortonmetric values from *multiple* *sets*, as there is no guarantee two
131*349950ddSRemy Hortonsets registered one after the other have contiguous id values.
132*349950ddSRemy Horton
133*349950ddSRemy HortonQuerying metrics
134*349950ddSRemy Horton----------------
135*349950ddSRemy Horton
136*349950ddSRemy HortonConsumers can obtain metric values by querying the metrics library using
137*349950ddSRemy Hortonthe ``rte_metrics_get_values()`` function that return an array of
138*349950ddSRemy Horton``struct rte_metric_value``. Each entry within this array contains a metric
139*349950ddSRemy Hortonvalue and its associated key. A key-name mapping can be obtained using the
140*349950ddSRemy Horton``rte_metrics_get_names()`` function that returns an array of
141*349950ddSRemy Horton``struct rte_metric_name`` that is indexed by the key. The following will
142*349950ddSRemy Hortonprint out all metrics for a given port:
143*349950ddSRemy Horton
144*349950ddSRemy Horton.. code-block:: c
145*349950ddSRemy Horton
146*349950ddSRemy Horton    void print_metrics() {
147*349950ddSRemy Horton        struct rte_metric_name *names;
148*349950ddSRemy Horton        int len;
149*349950ddSRemy Horton
150*349950ddSRemy Horton        len = rte_metrics_get_names(NULL, 0);
151*349950ddSRemy Horton        if (len < 0) {
152*349950ddSRemy Horton            printf("Cannot get metrics count\n");
153*349950ddSRemy Horton            return;
154*349950ddSRemy Horton        }
155*349950ddSRemy Horton        if (len == 0) {
156*349950ddSRemy Horton            printf("No metrics to display (none have been registered)\n");
157*349950ddSRemy Horton            return;
158*349950ddSRemy Horton        }
159*349950ddSRemy Horton        metrics = malloc(sizeof(struct rte_metric_value) * len);
160*349950ddSRemy Horton        names =  malloc(sizeof(struct rte_metric_name) * len);
161*349950ddSRemy Horton        if (metrics == NULL || names == NULL) {
162*349950ddSRemy Horton            printf("Cannot allocate memory\n");
163*349950ddSRemy Horton            free(metrics);
164*349950ddSRemy Horton            free(names);
165*349950ddSRemy Horton            return;
166*349950ddSRemy Horton        }
167*349950ddSRemy Horton        ret = rte_metrics_get_values(port_id, metrics, len);
168*349950ddSRemy Horton        if (ret < 0 || ret > len) {
169*349950ddSRemy Horton            printf("Cannot get metrics values\n");
170*349950ddSRemy Horton            free(metrics);
171*349950ddSRemy Horton            free(names);
172*349950ddSRemy Horton            return;
173*349950ddSRemy Horton        }
174*349950ddSRemy Horton        printf("Metrics for port %i:\n", port_id);
175*349950ddSRemy Horton        for (i = 0; i < len; i++)
176*349950ddSRemy Horton            printf("  %s: %"PRIu64"\n",
177*349950ddSRemy Horton                names[metrics[i].key].name, metrics[i].value);
178*349950ddSRemy Horton        free(metrics);
179*349950ddSRemy Horton        free(names);
180*349950ddSRemy Horton    }
181