Skip to content
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

in_podman_metrics: Added image label #7295

Merged
merged 1 commit into from
May 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 52 additions & 24 deletions plugins/in_podman_metrics/podman_metrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ static int collect_container_data(struct flb_in_metrics *ctx)
char *buffer;
char name[CONTAINER_NAME_SIZE];
char id[CONTAINER_ID_SIZE];
char image_name[IMAGE_NAME_SIZE];
char metadata[CONTAINER_METADATA_SIZE];
char *metadata_token_start;
char *metadata_token_stop;
int metadata_token_size;

int array_id;
int r, i, j;
Expand Down Expand Up @@ -95,12 +100,33 @@ static int collect_container_data(struct flb_in_metrics *ctx)
strncpy(name, buffer + t[j].start, t[j].end - t[j].start);
name[t[j].end - t[j].start] = '\0';
flb_plg_trace(ctx->ins, "Found name %s", name);
add_container_to_list(ctx, id, name);
j++;
collected_containers++;
}
}
}
else if (sizeof(JSON_FIELD_METADATA)-1 == t[i].end - t[i].start &&
strncmp(buffer + t[i].start, JSON_FIELD_METADATA, t[i].end - t[i].start) == 0) {
token_len = t[i + 1].end - t[i + 1].start;
strncpy(metadata, buffer + t[i+1].start, t[i + 1].end - t[i + 1].start);
metadata[token_len] = '\0';

metadata_token_start = strstr(metadata, JSON_SUBFIELD_IMAGE_NAME);
if (metadata_token_start) {
metadata_token_stop = strstr(metadata_token_start + JSON_SUBFIELD_SIZE_IMAGE_NAME+1, "\\\"");
metadata_token_size = metadata_token_stop - metadata_token_start - JSON_SUBFIELD_SIZE_IMAGE_NAME;

strncpy(image_name, metadata_token_start+JSON_SUBFIELD_SIZE_IMAGE_NAME, metadata_token_size);
image_name[metadata_token_size] = '\0';

flb_plg_trace(ctx->ins, "Found image name %s", image_name);
add_container_to_list(ctx, id, name, image_name);
}
else {
flb_plg_warn(ctx->ins, "Image name was not found for %s", id);
add_container_to_list(ctx, id, name, "unknown");
}
collected_containers++;
}
}
}

Expand All @@ -110,11 +136,11 @@ static int collect_container_data(struct flb_in_metrics *ctx)
}

/*
* Create structure instance based on previously found id and name. Set all its values (like
* Create structure instance based on previously found id, name and image name. Set all its values (like
* memory or cpu to UINT64_MAX, in case it won't be found later. This function also adds this structure
* to internal list, so it can be found by iteration later on.
*/
static int add_container_to_list(struct flb_in_metrics *ctx, flb_sds_t id, flb_sds_t name)
static int add_container_to_list(struct flb_in_metrics *ctx, flb_sds_t id, flb_sds_t name, flb_sds_t image_name)
{
struct container *cnt;
cnt = flb_malloc(sizeof(struct container));
Expand All @@ -124,6 +150,7 @@ static int add_container_to_list(struct flb_in_metrics *ctx, flb_sds_t id, flb_s
}
cnt->id = flb_sds_create(id);
cnt->name = flb_sds_create(name);
cnt->image_name = flb_sds_create(image_name);

cnt->memory_usage = UINT64_MAX;
cnt->memory_max_usage = UINT64_MAX;
Expand Down Expand Up @@ -157,6 +184,7 @@ static int destroy_container_list(struct flb_in_metrics *ctx)

flb_sds_destroy(cnt->id);
flb_sds_destroy(cnt->name);
flb_sds_destroy(cnt->image_name);
mk_list_foreach_safe(inner_head, inner_tmp, &cnt->net_data) {
iface = mk_list_entry(inner_head, struct net_iface, _head);
flb_sds_destroy(iface->name);
Expand All @@ -179,13 +207,13 @@ static int destroy_container_list(struct flb_in_metrics *ctx)


/*
* Create counter for given metric name, using name and value as counter labels. Counters
* Create counter for given metric name, using name, image name and value as counter labels. Counters
* are created per counter name, so they are "shared" between multiple containers - counter
* name remains the same, only labels like ID are changed.
* This function creates counter only once per counter name - every next call only sets counter
* value for specific labels.
*/
static int create_counter(struct flb_in_metrics *ctx, struct cmt_counter **counter, flb_sds_t id, flb_sds_t name, flb_sds_t metric_prefix,
static int create_counter(struct flb_in_metrics *ctx, struct cmt_counter **counter, flb_sds_t id, flb_sds_t name, flb_sds_t image_name, flb_sds_t metric_prefix,
flb_sds_t *fields, flb_sds_t metric_name, flb_sds_t description, flb_sds_t interface, uint64_t value)
{
flb_sds_t *labels;
Expand All @@ -204,12 +232,12 @@ static int create_counter(struct flb_in_metrics *ctx, struct cmt_counter **count
}

if (interface == NULL) {
labels = (char *[]){id, name};
label_count = 2;
labels = (char *[]){id, name, image_name};
label_count = 3;
}
else {
labels = (char *[]){id, name, interface};
label_count = 3;
labels = (char *[]){id, name, image_name, interface};
label_count = 4;
}

/* if counter was not yet created, it means that this function is called for the first time per counter type */
Expand All @@ -229,13 +257,13 @@ static int create_counter(struct flb_in_metrics *ctx, struct cmt_counter **count
}

/*
* Create gauge for given metric name, using name and value as counter labels. Gauges
* Create gauge for given metric name, using name, image name and value as counter labels. Gauges
* are created per counter name, so they are "shared" between multiple containers - counter
* name remains the same, only labels like ID are changed.
* This function creates gauge only once per counter name - every next call only sets gauge
* value for specific labels.
*/
static int create_gauge(struct flb_in_metrics *ctx, struct cmt_gauge **gauge, flb_sds_t id, flb_sds_t name, flb_sds_t metric_prefix,
static int create_gauge(struct flb_in_metrics *ctx, struct cmt_gauge **gauge, flb_sds_t id, flb_sds_t name, flb_sds_t image_name, flb_sds_t metric_prefix,
flb_sds_t *fields, flb_sds_t metric_name, flb_sds_t description, flb_sds_t interface, uint64_t value)
{
flb_sds_t *labels;
Expand All @@ -245,8 +273,8 @@ static int create_gauge(struct flb_in_metrics *ctx, struct cmt_gauge **gauge, fl
return -1;
}

labels = (char *[]){id, name};
label_count = 2;
labels = (char *[]){id, name, image_name};
label_count = 3;

/* if gauge was not yet created, it means that this function is called for the first time per counter type */
if (*gauge == NULL) {
Expand Down Expand Up @@ -289,28 +317,28 @@ static int create_counters(struct flb_in_metrics *ctx)
mk_list_foreach_safe(head, tmp, &ctx->items)
{
cnt = mk_list_entry(head, struct container, _head);
create_counter(ctx, &ctx->c_memory_usage, cnt->id, cnt->name, COUNTER_MEMORY_PREFIX, FIELDS_METRIC, COUNTER_MEMORY_USAGE,
create_counter(ctx, &ctx->c_memory_usage, cnt->id, cnt->name, cnt->image_name, COUNTER_MEMORY_PREFIX, FIELDS_METRIC, COUNTER_MEMORY_USAGE,
DESCRIPTION_MEMORY_USAGE, NULL, cnt->memory_usage);
create_counter(ctx, &ctx->c_memory_max_usage, cnt->id, cnt->name, COUNTER_MEMORY_PREFIX, FIELDS_METRIC, COUNTER_MEMORY_MAX_USAGE,
create_counter(ctx, &ctx->c_memory_max_usage, cnt->id, cnt->name, cnt->image_name, COUNTER_MEMORY_PREFIX, FIELDS_METRIC, COUNTER_MEMORY_MAX_USAGE,
DESCRIPTION_MEMORY_MAX_USAGE, NULL, cnt->memory_max_usage);
create_counter(ctx, &ctx->c_memory_limit, cnt->id, cnt->name, COUNTER_SPEC_MEMORY_PREFIX, FIELDS_METRIC, COUNTER_MEMORY_LIMIT,
create_counter(ctx, &ctx->c_memory_limit, cnt->id, cnt->name, cnt->image_name, COUNTER_SPEC_MEMORY_PREFIX, FIELDS_METRIC, COUNTER_MEMORY_LIMIT,
DESCRIPTION_MEMORY_LIMIT, NULL, cnt->memory_limit);
create_gauge(ctx, &ctx->g_rss, cnt->id, cnt->name, COUNTER_MEMORY_PREFIX, FIELDS_METRIC, GAUGE_MEMORY_RSS,
create_gauge(ctx, &ctx->g_rss, cnt->id, cnt->name, cnt->image_name, COUNTER_MEMORY_PREFIX, FIELDS_METRIC, GAUGE_MEMORY_RSS,
DESCRIPTION_MEMORY_RSS, NULL, cnt->rss);
create_counter(ctx, &ctx->c_cpu_user, cnt->id, cnt->name, COUNTER_CPU_PREFIX, FIELDS_METRIC, COUNTER_CPU_USER,
create_counter(ctx, &ctx->c_cpu_user, cnt->id, cnt->name, cnt->image_name, COUNTER_CPU_PREFIX, FIELDS_METRIC, COUNTER_CPU_USER,
DESCRIPTION_CPU_USER, NULL, cnt->cpu_user);
create_counter(ctx, &ctx->c_cpu, cnt->id, cnt->name, COUNTER_CPU_PREFIX, FIELDS_METRIC, COUNTER_CPU,
create_counter(ctx, &ctx->c_cpu, cnt->id, cnt->name, cnt->image_name, COUNTER_CPU_PREFIX, FIELDS_METRIC, COUNTER_CPU,
DESCRIPTION_CPU, NULL, cnt->cpu);
mk_list_foreach_safe(inner_head, inner_tmp, &cnt->net_data)
{
iface = mk_list_entry(inner_head, struct net_iface, _head);
create_counter(ctx, &ctx->rx_bytes, cnt->id, cnt->name, COUNTER_NETWORK_PREFIX, FIELDS_METRIC_WITH_IFACE, COUNTER_RX_BYTES,
create_counter(ctx, &ctx->rx_bytes, cnt->id, cnt->name, cnt->image_name, COUNTER_NETWORK_PREFIX, FIELDS_METRIC_WITH_IFACE, COUNTER_RX_BYTES,
DESCRIPTION_RX_BYTES, iface->name, iface->rx_bytes);
create_counter(ctx, &ctx->rx_errors, cnt->id, cnt->name, COUNTER_NETWORK_PREFIX, FIELDS_METRIC_WITH_IFACE, COUNTER_RX_ERRORS,
create_counter(ctx, &ctx->rx_errors, cnt->id, cnt->name, cnt->image_name, COUNTER_NETWORK_PREFIX, FIELDS_METRIC_WITH_IFACE, COUNTER_RX_ERRORS,
DESCRIPTION_RX_ERRORS, iface->name, iface->rx_errors);
create_counter(ctx, &ctx->tx_bytes, cnt->id, cnt->name, COUNTER_NETWORK_PREFIX, FIELDS_METRIC_WITH_IFACE, COUNTER_TX_BYTES,
create_counter(ctx, &ctx->tx_bytes, cnt->id, cnt->name, cnt->image_name, COUNTER_NETWORK_PREFIX, FIELDS_METRIC_WITH_IFACE, COUNTER_TX_BYTES,
DESCRIPTION_TX_BYTES, iface->name, iface->tx_bytes);
create_counter(ctx, &ctx->tx_errors, cnt->id, cnt->name, COUNTER_NETWORK_PREFIX, FIELDS_METRIC_WITH_IFACE, COUNTER_TX_ERRORS,
create_counter(ctx, &ctx->tx_errors, cnt->id, cnt->name, cnt->image_name, COUNTER_NETWORK_PREFIX, FIELDS_METRIC_WITH_IFACE, COUNTER_TX_ERRORS,
DESCRIPTION_TX_ERRORS, iface->name, iface->tx_errors);
}
}
Expand Down
6 changes: 4 additions & 2 deletions plugins/in_podman_metrics/podman_metrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@
#include "podman_metrics_config.h"

static int collect_container_data(struct flb_in_metrics *ctx);
static int add_container_to_list(struct flb_in_metrics *ctx, flb_sds_t id, flb_sds_t name);
static int add_container_to_list(struct flb_in_metrics *ctx, flb_sds_t id, flb_sds_t name, flb_sds_t image_name);
static int destroy_container_list(struct flb_in_metrics *ctx);

static int create_counter(struct flb_in_metrics *ctx, struct cmt_counter **counter, flb_sds_t id, flb_sds_t name, flb_sds_t metric_prefix,
static int create_counter(struct flb_in_metrics *ctx, struct cmt_counter **counter, flb_sds_t id, flb_sds_t name, flb_sds_t image_name, flb_sds_t metric_prefix,
flb_sds_t *fieds, flb_sds_t metric_name, flb_sds_t description, flb_sds_t interface, uint64_t value);
static int create_gauge(struct flb_in_metrics *ctx, struct cmt_gauge **gauge, flb_sds_t id, flb_sds_t name, flb_sds_t image_name, flb_sds_t metric_prefix,
flb_sds_t *fields, flb_sds_t metric_name, flb_sds_t description, flb_sds_t interface, uint64_t value);
static int create_counters(struct flb_in_metrics *ctx);

static int scrape_metrics(struct flb_config *config, struct flb_in_metrics *ctx);
Expand Down
11 changes: 9 additions & 2 deletions plugins/in_podman_metrics/podman_metrics_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#define JSON_TOKENS 2048
#define CONTAINER_NAME_SIZE 50
#define CONTAINER_ID_SIZE 80
#define CONTAINER_METADATA_SIZE 512
#define IMAGE_NAME_SIZE 512
#define PID_BUFFER_SIZE 21
#define SYSFS_FILE_PATH_SIZE 512
#define PROCFS_FILE_PATH_SIZE 512
Expand All @@ -46,6 +48,10 @@

#define JSON_FIELD_NAMES "names"
#define JSON_FIELD_ID "id"
#define JSON_FIELD_METADATA "metadata"

#define JSON_SUBFIELD_IMAGE_NAME "image-name\\\":\\\""
#define JSON_SUBFIELD_SIZE_IMAGE_NAME 15

#define CGROUP_V2_PATH "cgroup.controllers"
#define CGROUP_V1 1
Expand Down Expand Up @@ -81,8 +87,8 @@
#define STAT_KEY_CPU_USER "user_usec"

/* Static lists of fields in counters or gauges */
#define FIELDS_METRIC (char*[2]){"id", "name" }
#define FIELDS_METRIC_WITH_IFACE (char*[3]){"id", "name", "interface" }
#define FIELDS_METRIC (char*[3]){"id", "name", "image" }
#define FIELDS_METRIC_WITH_IFACE (char*[4]){"id", "name", "image", "interface" }

/* Files from sysfs containing required data (cgroups v1) */
#define V1_SYSFS_FILE_MEMORY "memory.usage_in_bytes"
Expand Down Expand Up @@ -144,6 +150,7 @@ struct net_iface {
struct container {
flb_sds_t name;
flb_sds_t id;
flb_sds_t image_name;
struct mk_list _head;

uint64_t memory_usage;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo: 34275905 6362 0 0 0 0 0 0 34275905 6362 0 0 0 0 0 0
enp6s0: 9089298401 6228223 0 0 0 0 0 5669 173774157 2534993 0 0 0 0 0 0
wlp5s0: 2802033 11801 0 0 0 0 0 0 790512 6492 0 0 0 0 0 0
virbr0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 change: 1 addition & 0 deletions tests/runtime/data/podman/reversed/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"id":"8a19d6058bfbe88cd0548eba9047d94c70161f5d74b545c7504b2f27491686d9","names":["determined_mcnulty"],"image":"27941809078cc9b2802deb2b0bb6feed6c236cde01e487f200e24653533701ee","layer":"633c06ce1a553c72c4fbf12686acd5129a453f57b73385f8e7afc975fa657d86","metadata":"{\"image-id\":\"27941809078cc9b2802deb2b0bb6feed6c236cde01e487f200e24653533701ee\",\"name\":\"determined_mcnulty\",\"created-at\":1657980361,\"image-name\":\"docker.io/library/ubuntu:latest\"}","created":"2022-07-16T14:06:01.521179687Z","flags":{"MountLabel":"system_u:object_r:container_file_t:s0:c664,c969","ProcessLabel":"system_u:system_r:container_t:s0:c664,c969"}}]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
42
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
42
18 changes: 18 additions & 0 deletions tests/runtime/in_podman_metrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "flb_tests_runtime.h"

#define DPATH_PODMAN_REGULAR FLB_TESTS_DATA_PATH "/data/podman/regular"
#define DPATH_PODMAN_REVERSED FLB_TESTS_DATA_PATH "/data/podman/reversed"
#define DPATH_PODMAN_NO_CONFIG FLB_TESTS_DATA_PATH "/data/podman/no_config"
#define DPATH_PODMAN_GARBAGE_CONFIG FLB_TESTS_DATA_PATH "/data/podman/garbage_config"
#define DPATH_PODMAN_NO_SYSFS FLB_TESTS_DATA_PATH "/data/podman/no_sysfs"
Expand Down Expand Up @@ -103,6 +104,22 @@ void flb_test_ipm_regular() {
do_destroy(ctx);
}

void flb_test_ipm_reversed() {
flb_ctx_t *ctx = flb_create();
do_create(ctx,
"podman_metrics",
"path.config", DPATH_PODMAN_REVERSED "/config.json",
"scrape_on_start", "true",
"path.sysfs", DPATH_PODMAN_REVERSED,
"path.procfs", DPATH_PODMAN_REVERSED,
NULL);
TEST_CHECK(flb_start(ctx) == 0);
sleep(1);
TEST_CHECK(check_metric(ctx, "usage_bytes") == 0);
TEST_CHECK(check_metric(ctx, "receive_bytes_total") == 0);
do_destroy(ctx);
}

void flb_test_ipm_garbage_config() {
flb_ctx_t *ctx = flb_create();
do_create(ctx,
Expand Down Expand Up @@ -195,6 +212,7 @@ void flb_test_ipm_cgroupv2() {

TEST_LIST = {
{"regular", flb_test_ipm_regular},
{"reversed", flb_test_ipm_reversed},
{"no_config", flb_test_ipm_no_config},
{"garbage_config", flb_test_ipm_garbage_config},
{"no_sysfs_data", flb_test_ipm_no_sysfs},
Expand Down