@@ -179,7 +179,7 @@ rte_telemetry_send_error_response(struct telemetry_impl *telemetry,
return -EPERM;
}
- json_buffer = json_dumps(root, JSON_INDENT(2));
+ json_buffer = json_dumps(root, 0);
json_decref(root);
ret = rte_telemetry_write_to_socket(telemetry, json_buffer);
@@ -190,6 +190,311 @@ rte_telemetry_send_error_response(struct telemetry_impl *telemetry,
return 0;
}
+static int
+rte_telemetry_get_metrics(struct telemetry_impl *telemetry, uint32_t port_id,
+ struct rte_metric_value *metrics, struct rte_metric_name *names,
+ int num_metrics)
+{
+ int ret, num_values;
+
+ if (num_metrics < 0) {
+ TELEMETRY_LOG_ERR("Error - Invalid metrics count\n");
+ goto einval_fail;
+ } else if (num_metrics == 0) {
+ TELEMETRY_LOG_ERR("No metrics to display (none have been "
+ "registered)\n");
+ goto eperm_fail;
+ }
+
+ if (metrics == NULL) {
+ TELEMETRY_LOG_ERR("Error - metrics must be initialised.\n");
+ goto einval_fail;
+ }
+
+ if (names == NULL) {
+ TELEMETRY_LOG_ERR("Error - names must be initialised.\n");
+ goto einval_fail;
+ }
+
+ ret = rte_metrics_get_names(names, num_metrics);
+ if (ret < 0 || ret > num_metrics) {
+ TELEMETRY_LOG_ERR("Error - Cannot get metrics names\n");
+ goto eperm_fail;
+ }
+
+ num_values = rte_metrics_get_values(port_id, NULL, 0);
+ ret = rte_metrics_get_values(port_id, metrics, num_values);
+ if (ret < 0 || ret > num_values) {
+ TELEMETRY_LOG_ERR("Error - Cannot get metrics values\n");
+ goto eperm_fail;
+ }
+ return 0;
+
+eperm_fail:
+ ret = rte_telemetry_send_error_response(telemetry, -EPERM);
+ if (ret < 0)
+ TELEMETRY_LOG_ERR("Error - Could not send error\n");
+ return -1;
+
+einval_fail:
+ ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+ if (ret < 0)
+ TELEMETRY_LOG_ERR("Error - Could not send error\n");
+ return -1;
+
+}
+
+static int32_t
+rte_telemetry_json_format_stat(struct telemetry_impl *telemetry, json_t *stats,
+ const char *metric_name, uint64_t metric_value)
+{
+ int ret;
+ json_t *stat = json_object();
+
+ if (!stat) {
+ TELEMETRY_LOG_ERR("Error - Could not create stat JSON "
+ "object\n");
+ goto eperm_fail;
+ }
+
+ ret = json_object_set_new(stat, "name", json_string(metric_name));
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Error - Stat Name field cannot be set\n");
+ goto eperm_fail;
+ }
+
+ ret = json_object_set_new(stat, "value", json_integer(metric_value));
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Error - Stat Value field cannot be set\n");
+ goto eperm_fail;
+ }
+
+ ret = json_array_append_new(stats, stat);
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Error - Stat cannot be added to stats json "
+ "array\n");
+ goto eperm_fail;
+ }
+ return 0;
+
+eperm_fail:
+ ret = rte_telemetry_send_error_response(telemetry, -EPERM);
+ if (ret < 0)
+ TELEMETRY_LOG_ERR("Error - Could not send error\n");
+ return -1;
+
+}
+
+static int32_t
+rte_telemetry_json_format_port(struct telemetry_impl *telemetry,
+ uint32_t port_id, json_t *ports, uint32_t *metric_ids,
+ uint32_t num_metric_ids)
+{
+ struct rte_metric_value *metrics = 0;
+ struct rte_metric_name *names = 0;
+ int num_metrics, ret;
+
+ num_metrics = rte_metrics_get_names(NULL, 0);
+ if (num_metrics < 0) {
+ TELEMETRY_LOG_ERR("Error - Cannot get metrics count\n");
+ goto einval_fail;
+ } else if (num_metrics == 0) {
+ TELEMETRY_LOG_ERR("Error - No metrics to display (none have "
+ "been registered)\n");
+ goto eperm_fail;
+ }
+
+ metrics = malloc(sizeof(struct rte_metric_value) * num_metrics);
+ names = malloc(sizeof(struct rte_metric_name) * num_metrics);
+ if (metrics == NULL || names == NULL) {
+ TELEMETRY_LOG_ERR("Error - Cannot allocate memory\n");
+ free(metrics);
+ free(names);
+ int err_ret = rte_telemetry_send_error_response(telemetry,
+ -ENOMEM);
+ if (err_ret < 0)
+ TELEMETRY_LOG_ERR("Error - Could not send error\n");
+ return -1;
+ }
+
+ ret = rte_telemetry_get_metrics(telemetry, port_id, metrics, names,
+ num_metrics);
+ if (ret < 0) {
+ free(metrics);
+ free(names);
+ TELEMETRY_LOG_ERR("Error - rte_telemetry_get_metrics failed\n");
+ return -1;
+ }
+
+ json_t *port = json_object();
+ json_t *stats = json_array();
+ if (!port || !stats) {
+ TELEMETRY_LOG_ERR("Error - Could not create port/stats JSON "
+ "objects\n");
+ goto eperm_fail;
+ }
+
+ ret = json_object_set_new(port, "port", json_integer(port_id));
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Error - Port field cannot be set\n");
+ goto eperm_fail;
+ }
+
+ uint32_t i;
+ for (i = 0; i < num_metric_ids; i++) {
+ if (metric_ids[i] >= (uint32_t)num_metrics) {
+ TELEMETRY_LOG_ERR("Error - Metric_id: %d is "
+ "not valid\n", metric_ids[i]);
+ goto einval_fail;
+ }
+
+ int metric_id = metric_ids[i];
+ int metric_index = -1;
+ int metric_name_key = -1;
+ int32_t j;
+
+ for (j = 0; j < num_metrics; j++) {
+ if (metrics[j].key == metric_id) {
+ metric_name_key = metrics[j].key;
+ metric_index = j;
+ break;
+ }
+ }
+
+ if (metric_name_key < 0 || metric_index < 0) {
+ TELEMETRY_LOG_ERR("Error - Could not get metric "
+ "name/index\n");
+ goto eperm_fail;
+ }
+
+ const char *metric_name = names[metric_name_key].name;
+ uint64_t metric_value = metrics[metric_index].value;
+ ret = rte_telemetry_json_format_stat(telemetry, stats,
+ metric_name, metric_value);
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Error - Format stat with id: %u "
+ "failed\n", metric_id);
+ free(metrics);
+ free(names);
+ return -1;
+ }
+ }
+
+ if (json_array_size(stats) == 0)
+ ret = json_object_set_new(port, "stats", json_null());
+ else
+ ret = json_object_set_new(port, "stats", stats);
+
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Error - Stats object cannot be set\n");
+ goto eperm_fail;
+ }
+
+ ret = json_array_append_new(ports, port);
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Error - Port object cannot be added to "
+ "ports array\n");
+ goto eperm_fail;
+ }
+
+ free(metrics);
+ free(names);
+ return 0;
+
+eperm_fail:
+ free(metrics);
+ free(names);
+ ret = rte_telemetry_send_error_response(telemetry, -EPERM);
+ if (ret < 0)
+ TELEMETRY_LOG_ERR("Error - Could not send error\n");
+ return -1;
+
+einval_fail:
+ free(metrics);
+ free(names);
+ ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+ if (ret < 0)
+ TELEMETRY_LOG_ERR("Error - Could not send error\n");
+ return -1;
+}
+
+static int32_t
+rte_telemetry_encode_json_format(struct telemetry_impl *telemetry,
+ uint32_t *port_ids, uint32_t num_port_ids, uint32_t *metric_ids,
+ uint32_t num_metric_ids, char **json_buffer)
+{
+ int ret;
+ json_t *root, *ports;
+
+ if (num_port_ids <= 0 || num_metric_ids <= 0) {
+ TELEMETRY_LOG_ERR("Error - Please provide port and metric ids "
+ "to query\n");
+ goto einval_fail;
+ }
+
+ ports = json_array();
+ if (!ports) {
+ TELEMETRY_LOG_ERR("Error - Could not create ports JSON "
+ "array\n");
+ goto eperm_fail;
+ }
+
+ uint32_t i;
+ for (i = 0; i < num_port_ids; i++) {
+ if (!rte_eth_dev_is_valid_port(port_ids[i])) {
+ TELEMETRY_LOG_ERR("Error - Port: %d invalid\n",
+ port_ids[i]);
+ goto einval_fail;
+ }
+ }
+
+ for (i = 0; i < num_port_ids; i++) {
+ ret = rte_telemetry_json_format_port(telemetry, port_ids[i],
+ ports, metric_ids, num_metric_ids);
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Error - format port in JSON "
+ "failed\n");
+ return -1;
+ }
+ }
+
+ root = json_object();
+ if (!root) {
+ TELEMETRY_LOG_ERR("Error - Could not create root JSON "
+ "object\n");
+ goto eperm_fail;
+ }
+
+ ret = json_object_set_new(root, "status_code",
+ json_string("Status OK: 200"));
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Error - Status code field cannot be set\n");
+ goto eperm_fail;
+ }
+
+ ret = json_object_set_new(root, "data", ports);
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Error - Data field cannot be set\n");
+ goto eperm_fail;
+ }
+
+ *json_buffer = json_dumps(root, JSON_INDENT(2));
+ json_decref(root);
+ return 0;
+
+eperm_fail:
+ ret = rte_telemetry_send_error_response(telemetry, -EPERM);
+ if (ret < 0)
+ TELEMETRY_LOG_ERR("Error - Could not send error\n");
+ return -1;
+
+einval_fail:
+ ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+ if (ret < 0)
+ TELEMETRY_LOG_ERR("Error - Could not send error\n");
+ return -1;
+}
+
int32_t
rte_telemetry_send_ports_stats_values(uint32_t *metric_ids, int num_metric_ids,
uint32_t *port_ids, int num_port_ids, struct telemetry_impl *telemetry)
@@ -235,6 +540,13 @@ rte_telemetry_send_ports_stats_values(uint32_t *metric_ids, int num_metric_ids,
}
char *json_buffer = NULL;
+ ret = rte_telemetry_encode_json_format(telemetry, port_ids,
+ num_port_ids, metric_ids, num_metric_ids, &json_buffer);
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Error - JSON encode function failed\n");
+ return -1;
+ }
+
ret = rte_telemetry_write_to_socket(telemetry, json_buffer);
if (ret < 0) {
TELEMETRY_LOG_ERR("Error - Could not write to socket\n");