prometheus issues label name "port" is not unique: invalid sample when scraping
example output:
tor_hs_app_write_bytes_total{onion="duwq3shurnywtxq5z76dbcy7gbqyjgel4vzauxupuc4v773tiyxif5qd",port="80",port="443"} 1000
while I am new to Prometheus, my understanding is that each sample of a metric can have at most one value per label. therefore, port="80",port="443"
is invalid. i think this makes sense in this context: either tor is able to count the bytes per port, in which case there should be two lines, one with port="80"
, and one with port="443"
, or tor can only count the bytes per service, in which case there should be one line and no port labels.
assuming the former is true, I think https://gitlab.torproject.org/tpo/core/tor/-/blob/455471835da35d8ee64e6a2c0a70acb89a003bf4/src/feature/hs/hs_metrics.c#L46-59 should look like:
if (base_metrics[i].port_as_label && service->config.ports) {
SMARTLIST_FOREACH_BEGIN(service->config.ports,
const hs_port_config_t *, p) {
metrics_store_entry_t *entry =
metrics_store_add(store, base_metrics[i].type, base_metrics[i].name,
base_metrics[i].help);
/* Add labels to the entry. */
metrics_store_entry_add_label(entry,
metrics_format_label("onion", service->onion_address));
metrics_store_entry_add_label(entry,
metrics_format_label("port", port_to_str(p->virtual_port)));
} SMARTLIST_FOREACH_END(p);
} else {
metrics_store_entry_t *entry =
metrics_store_add(store, base_metrics[i].type, base_metrics[i].name,
base_metrics[i].help);
/* Add labels to the entry. */
metrics_store_entry_add_label(entry,
metrics_format_label("onion", service->onion_address));
}
possibly with refactoring, and maybe adjustment of the condition, although I'm not sure it is allowed to have an onion service without ports? I have not submitted this as an MR because I have not tested it at all.
strangely, however, the case of multiple ports per service seems to already be handled at https://gitlab.torproject.org/tpo/core/tor/-/blob/455471835da35d8ee64e6a2c0a70acb89a003bf4/src/feature/hs/hs_metrics.c#L80-91, it is just not initialized properly. possibly this change was intended during development and not completed?