-
Notifications
You must be signed in to change notification settings - Fork 26
Openmetric stats improvements #617
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
07abbee
d27c0e7
74cdf4c
a52f1c7
53372c5
04a531a
31346bc
467c644
a8ba60d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| #include "module.h" | ||
|
|
||
| #include <gr_infra.h> | ||
| #include <gr_net_types.h> | ||
| #include <gr_string.h> | ||
|
|
||
| static struct gr_iface *iface_to_api(const struct iface *priv) { | ||
|
|
@@ -235,17 +236,22 @@ METRIC_COUNTER( | |
| ); | ||
| METRIC_COUNTER(m_cp_tx_bytes, "iface_cp_tx_bytes", "Number of bytes transmitted by control plane."); | ||
|
|
||
| METRIC_GAUGE(m_speed_bps, "iface_speed_bps", "Interface speed in bits per second."); | ||
|
|
||
| static void iface_metrics_collect(struct metrics_writer *w) { | ||
| struct iface *iface = NULL; | ||
| struct metrics_ctx ctx; | ||
| char vrf[16]; | ||
|
|
||
| while ((iface = iface_next(GR_IFACE_TYPE_UNDEF, iface)) != NULL) { | ||
| const struct iface_type *type = iface_type_get(iface->type); | ||
| char id_str[8]; | ||
|
|
||
| snprintf(id_str, sizeof(id_str), "%u", iface->id); | ||
| metrics_ctx_init( | ||
| &ctx, | ||
| w, | ||
| "id", | ||
| id_str, | ||
| "name", | ||
| iface->name, | ||
| "type", | ||
|
|
@@ -258,15 +264,25 @@ static void iface_metrics_collect(struct metrics_writer *w) { | |
| ); | ||
|
|
||
| if (iface->mode == GR_IFACE_MODE_VRF) { | ||
| snprintf(vrf, sizeof(vrf), "%u", iface->vrf_id); | ||
| metrics_labels_add(&ctx, "vrf", vrf, NULL); | ||
| const struct iface *vrf_iface = iface_from_id(iface->vrf_id); | ||
| metrics_labels_add( | ||
| &ctx, "vrf", vrf_iface ? vrf_iface->name : "[deleted]", NULL | ||
| ); | ||
| } else { | ||
| const struct iface *domain = iface_from_id(iface->domain_id); | ||
| metrics_labels_add( | ||
| &ctx, "domain", domain ? domain->name : "[deleted]", NULL | ||
| ); | ||
| } | ||
|
|
||
| // Attach the MAC as a label so the address is reported on | ||
| // every per-iface metric without requiring a separate API call. | ||
| struct rte_ether_addr mac_addr = {0}; | ||
| char mac_str[18] = "00:00:00:00:00:00"; | ||
| if (iface_get_eth_addr(iface, &mac_addr) == 0) | ||
| snprintf(mac_str, sizeof(mac_str), ETH_F, &mac_addr); | ||
| metrics_labels_add(&ctx, "mac", mac_str, NULL); | ||
|
|
||
| metric_emit(&ctx, &m_up, !!(iface->flags & GR_IFACE_F_UP)); | ||
| metric_emit(&ctx, &m_running, !!(iface->state & GR_IFACE_S_RUNNING)); | ||
| metric_emit(&ctx, &m_mtu, iface->mtu); | ||
|
|
@@ -297,6 +313,10 @@ static void iface_metrics_collect(struct metrics_writer *w) { | |
| metric_emit(&ctx, &m_cp_tx_packets, cp_tx_pkts); | ||
| metric_emit(&ctx, &m_cp_tx_bytes, cp_tx_bytes); | ||
|
|
||
| // gr_iface.speed is in Megabit/sec; convert to bit/sec for | ||
| // the metric. 0 means unknown / link down. | ||
| metric_emit(&ctx, &m_speed_bps, (uint64_t)iface->speed * 1000000ULL); | ||
|
Comment on lines
+317
to
+318
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be checked, but I think "unknown" is UINT32_MAX. |
||
|
|
||
| // Dispatch to type-specific collector | ||
| if (type->metrics_collect != NULL) | ||
| type->metrics_collect(&ctx, iface); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -746,7 +746,44 @@ METRIC_GAUGE(m_txqs, "iface_port_txqs", "Number of TX queues."); | |
| METRIC_GAUGE(m_rxq_size, "iface_port_rxq_size", "Number of descriptors in RX queues."); | ||
| METRIC_GAUGE(m_txq_size, "iface_port_txq_size", "Number of descriptors in TX queues."); | ||
| METRIC_COUNTER(m_rx_missed, "iface_port_rx_missed", "Number of packets dropped by HW."); | ||
| METRIC_COUNTER(m_rx_errors, "iface_port_rx_errors", "Number of RX packets with errors."); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps also add |
||
| METRIC_COUNTER(m_tx_errors, "iface_port_tx_errors", "Number of TX failures."); | ||
| METRIC_COUNTER(m_port_rx_bytes, "iface_port_rx_bytes", "Number of bytes received by HW."); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is already covered by the generic software interface stats. |
||
| METRIC_COUNTER(m_port_tx_bytes, "iface_port_tx_bytes", "Number of bytes transmitted by HW."); | ||
| METRIC_COUNTER( | ||
| m_port_xstat, | ||
| "iface_port_xstat", | ||
| "Raw PMD extended statistic. The xstat label carries the driver-native counter name." | ||
| ); | ||
|
|
||
| static void port_xstats_emit(struct metrics_ctx *ctx, uint16_t port_id) { | ||
| int n = rte_eth_xstats_get_names(port_id, NULL, 0); | ||
| if (n <= 0) | ||
| return; | ||
|
|
||
| struct rte_eth_xstat_name *names = calloc(n, sizeof(*names)); | ||
| struct rte_eth_xstat *values = calloc(n, sizeof(*values)); | ||
| if (names == NULL || values == NULL) | ||
| goto out; | ||
|
|
||
| if (rte_eth_xstats_get_names(port_id, names, n) != n) | ||
| goto out; | ||
| if (rte_eth_xstats_get(port_id, values, n) != n) | ||
| goto out; | ||
|
|
||
| // Save the base label set; rewind it between iterations so each emit | ||
| // replaces (not appends) the xstat label. | ||
| size_t base_len = ctx->labels_len; | ||
| for (int i = 0; i < n; i++) { | ||
| ctx->labels_len = base_len; | ||
| metrics_labels_add(ctx, "xstat", names[i].name, NULL); | ||
| metric_emit(ctx, &m_port_xstat, values[i].value); | ||
| } | ||
| ctx->labels_len = base_len; | ||
| out: | ||
| free(names); | ||
| free(values); | ||
| } | ||
|
|
||
| static void port_metrics_collect(struct metrics_ctx *ctx, const struct iface *iface) { | ||
| const struct iface_info_port *port = iface_info_port(iface); | ||
|
|
@@ -765,8 +802,13 @@ static void port_metrics_collect(struct metrics_ctx *ctx, const struct iface *if | |
|
|
||
| if (rte_eth_stats_get(port->port_id, &stats) == 0) { | ||
| metric_emit(ctx, &m_rx_missed, stats.imissed); | ||
| metric_emit(ctx, &m_rx_errors, stats.ierrors); | ||
| metric_emit(ctx, &m_tx_errors, stats.oerrors); | ||
| metric_emit(ctx, &m_port_rx_bytes, stats.ibytes); | ||
| metric_emit(ctx, &m_port_tx_bytes, stats.obytes); | ||
| } | ||
|
|
||
| port_xstats_emit(ctx, port->port_id); | ||
| } | ||
|
|
||
| static struct event *link_event; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| #include "event.h" | ||
| #include "iface.h" | ||
| #include "log.h" | ||
| #include "metrics.h" | ||
| #include "module.h" | ||
| #include "rcu.h" | ||
| #include "vlan.h" | ||
|
|
@@ -228,6 +229,13 @@ static void vlan_to_api(void *info, const struct iface *iface) { | |
| *api = vlan->base; | ||
| } | ||
|
|
||
| static void vlan_metrics_collect(struct metrics_ctx *ctx, const struct iface *iface) { | ||
| const struct iface_info_vlan *vlan = iface_info_vlan(iface); | ||
| const struct iface *parent = iface_from_id(vlan->parent_id); | ||
|
|
||
| metrics_labels_add(ctx, "parent", parent ? parent->name : "[deleted]", NULL); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add a vlan-specific metric for VLAN ID. |
||
| } | ||
|
|
||
| static const struct iface_type iface_type_vlan = { | ||
| .id = GR_IFACE_TYPE_VLAN, | ||
| .pub_size = sizeof(struct gr_iface_info_vlan), | ||
|
|
@@ -242,6 +250,7 @@ static const struct iface_type iface_type_vlan = { | |
| .del_eth_addr = iface_vlan_del_eth_addr, | ||
| .set_promisc = iface_vlan_promisc_set, | ||
| .to_api = vlan_to_api, | ||
| .metrics_collect = vlan_metrics_collect, | ||
| }; | ||
|
|
||
| static void vlan_init(struct event_base *) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.