Skip to content
Open
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
30 changes: 22 additions & 8 deletions plugins/in_podman_metrics/podman_metrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,15 @@ static int collect_container_data(struct flb_in_metrics *ctx)
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';
if (metadata_token_stop) {
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';
}
else {
strncpy(image_name, "unknown", IMAGE_NAME_SIZE - 1);
image_name[sizeof("unknown") - 1] = '\0';
}

flb_plg_trace(ctx->ins, "Found image name %s", image_name);
add_container_to_list(ctx, id, name, image_name);
Expand Down Expand Up @@ -229,10 +234,19 @@ static int create_counter(struct flb_in_metrics *ctx, struct cmt_counter **count
return -1;
}

if (strcmp(metric_name, COUNTER_CPU) == 0 || strcmp(metric_name, COUNTER_CPU_USER) == 0) {
fvalue = fvalue / 1000000000;
flb_plg_trace(ctx->ins, "Converting %s from nanoseconds to seconds (%lu -> %lu)", metric_name, value, fvalue);

if (strcmp(metric_name, COUNTER_CPU) == 0 ||
strcmp(metric_name, COUNTER_CPU_USER) == 0) {
if (ctx->cgroup_version == CGROUP_V2) {
/* cgroup v2 cpu.stat reports in microseconds */
fvalue = fvalue / 1000000;
}
else {
/* cgroup v1 cpuacct reports in nanoseconds */
fvalue = fvalue / 1000000000;
}
flb_plg_trace(ctx->ins,
"Converting %s to seconds (%lu -> %lu)",
metric_name, value, fvalue);
}

labels = (char *[]){id, name, image_name, interface};
Expand Down
4 changes: 3 additions & 1 deletion plugins/in_podman_metrics/podman_metrics_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@

/* Key names in .stat files */
#define STAT_KEY_RSS "rss"
#define V2_STAT_KEY_RSS "anon"
#define STAT_KEY_CPU "usage_usec"
#define STAT_KEY_CPU_USER "user_usec"

Expand Down Expand Up @@ -112,7 +113,8 @@
#define V2_SYSFS_FILE_MEMORY_LIMIT "memory.max"
#define V2_SYSFS_FILE_CPU_STAT "cpu.stat"
#define V2_SYSFS_FILE_PIDS "cgroup.procs"
#define V2_SYSFS_FILE_PIDS_ALT "containers/cgroup.procs"
#define V2_SYSFS_FILE_PIDS_ALT "container/cgroup.procs"
#define V2_SYSFS_FILE_PIDS_ALT_LEGACY "containers/cgroup.procs"
#define V2_SYSFS_FILE_IO_STAT "io.stat"

/* Values used to construct counters/gauges names and descriptions */
Expand Down
64 changes: 62 additions & 2 deletions plugins/in_podman_metrics/podman_metrics_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,59 @@ int fill_counters_with_sysfs_data_v1(struct flb_in_metrics *ctx)
return 0;
}

/*
* Read uint64_t value from sysfs file, with special handling for the "max"
* keyword used by cgroup v2 to indicate an unlimited resource.
* Returns 0 when file contains "max".
*/
static uint64_t read_from_sysfs_or_max(struct flb_in_metrics *ctx,
flb_sds_t dir,
flb_sds_t name)
{
char path[SYSFS_FILE_PATH_SIZE];
char buf[32];
uint64_t value = UINT64_MAX;
FILE *fp;
int c;

if (dir == NULL) {
return value;
}

snprintf(path, sizeof(path), "%s/%s", dir, name);

fp = fopen(path, "r");
if (!fp) {
flb_plg_warn(ctx->ins, "Failed to read %s", path);
return value;
}

if (fgets(buf, sizeof(buf), fp) == NULL) {
flb_plg_warn(ctx->ins, "Failed to read a value from %s", path);
fclose(fp);
return UINT64_MAX;
}

/* cgroup v2 uses "max" to indicate unlimited */
if (strncmp(buf, "max", 3) == 0) {
flb_plg_debug(ctx->ins, "%s: max (unlimited)", path);
fclose(fp);
return 0;
}

c = sscanf(buf, "%lu", &value);
if (c != 1) {
flb_plg_warn(ctx->ins,
"Failed to read a number from %s", path);
fclose(fp);
return UINT64_MAX;
}

fclose(fp);
flb_plg_debug(ctx->ins, "%s: %lu", path, value);
return value;
}

/*
* Iterate over previously created container list. For each entry, generate its
* path in sysfs system directory. From this path, grab data about container metrics
Expand All @@ -430,15 +483,22 @@ int fill_counters_with_sysfs_data_v2(struct flb_in_metrics *ctx)

cnt->memory_usage = get_data_from_sysfs(ctx, path, V2_SYSFS_FILE_MEMORY, NULL);
cnt->memory_max_usage = get_data_from_sysfs(ctx, path, V2_SYSFS_FILE_MAX_MEMORY, NULL);
cnt->rss = get_data_from_sysfs(ctx, path, V2_SYSFS_FILE_MEMORY_STAT, STAT_KEY_RSS);
cnt->memory_limit = get_data_from_sysfs(ctx, path, V2_SYSFS_FILE_MEMORY_LIMIT, NULL);
cnt->rss = get_data_from_sysfs(ctx, path,
V2_SYSFS_FILE_MEMORY_STAT,
V2_STAT_KEY_RSS);
cnt->memory_limit = read_from_sysfs_or_max(ctx, path,
V2_SYSFS_FILE_MEMORY_LIMIT);
cnt->cpu_user = get_data_from_sysfs(ctx, path, V2_SYSFS_FILE_CPU_STAT, STAT_KEY_CPU_USER);
cnt->cpu = get_data_from_sysfs(ctx, path, V2_SYSFS_FILE_CPU_STAT, STAT_KEY_CPU);
read_io_stat(ctx, path, V2_SYSFS_FILE_IO_STAT, cnt);
pid = get_data_from_sysfs(ctx, path, V2_SYSFS_FILE_PIDS, NULL);
if (!pid || pid == UINT64_MAX) {
pid = get_data_from_sysfs(ctx, path, V2_SYSFS_FILE_PIDS_ALT, NULL);
}
if (!pid || pid == UINT64_MAX) {
pid = get_data_from_sysfs(ctx, path,
V2_SYSFS_FILE_PIDS_ALT_LEGACY, NULL);
}
if (pid && pid != UINT64_MAX) {
get_net_data_from_proc(ctx, cnt, pid);
}
Expand Down
Loading