Skip to content

Commit 9b74c32

Browse files
authored
Merge pull request #562 from p12tic/journald-labels
logging: Add container labels to log entries on journald
2 parents de270e6 + f37e9e7 commit 9b74c32

File tree

4 files changed

+75
-5
lines changed

4 files changed

+75
-5
lines changed

docs/conmon.8.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ Maximum size of the log file (in bytes).
6969
**--log-tag**
7070
Additional tag to use for logging.
7171

72+
**--log-label**
73+
Additional label to use for logging. The accepted format is LABEL=VALUE. Can be specified multiple times.
74+
Note that LABEL must contain only uppercase letters, numbers and underscore character.
75+
7276
**-n**, **--name**
7377
Container name.
7478

src/cli.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ int opt_exit_delay = 0;
4949
gboolean opt_replace_listen_pid = FALSE;
5050
char *opt_log_level = NULL;
5151
char *opt_log_tag = NULL;
52+
gchar **opt_log_labels = NULL;
5253
gboolean opt_sync = FALSE;
5354
gboolean opt_no_sync_log = FALSE;
5455
char *opt_sdnotify_socket = NULL;
@@ -78,6 +79,8 @@ GOptionEntry opt_entries[] = {
7879
{"log-size-max", 0, 0, G_OPTION_ARG_INT64, &opt_log_size_max, "Maximum size of log file", NULL},
7980
{"log-global-size-max", 0, 0, G_OPTION_ARG_INT64, &opt_log_global_size_max, "Maximum size of all log files", NULL},
8081
{"log-tag", 0, 0, G_OPTION_ARG_STRING, &opt_log_tag, "Additional tag to use for logging", NULL},
82+
{"log-label", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_log_labels,
83+
"Additional label to include in logs. Can be specified multiple times", NULL},
8184
{"name", 'n', 0, G_OPTION_ARG_STRING, &opt_name, "Container name", NULL},
8285
{"no-new-keyring", 0, 0, G_OPTION_ARG_NONE, &opt_no_new_keyring, "Do not create a new session keyring for the container", NULL},
8386
{"no-pivot", 0, 0, G_OPTION_ARG_NONE, &opt_no_pivot, "Do not use pivot_root", NULL},
@@ -194,5 +197,5 @@ void process_cli()
194197
if (opt_container_pid_file == NULL)
195198
opt_container_pid_file = g_strdup_printf("%s/pidfile-%s", cwd, opt_cid);
196199

197-
configure_log_drivers(opt_log_path, opt_log_size_max, opt_log_global_size_max, opt_cid, opt_name, opt_log_tag);
200+
configure_log_drivers(opt_log_path, opt_log_size_max, opt_log_global_size_max, opt_cid, opt_name, opt_log_tag, opt_log_labels);
198201
}

src/ctr_logging.c

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "ctr_logging.h"
33
#include "cli.h"
44
#include "config.h"
5+
#include <ctype.h>
56
#include <string.h>
67
#include <sys/stat.h>
78

@@ -70,6 +71,7 @@ static char *container_id_full = NULL;
7071
static char *container_id = NULL;
7172
static char *container_name = NULL;
7273
static char *container_tag = NULL;
74+
static gchar **container_labels = NULL;
7375
static size_t container_tag_len;
7476
static char *syslog_identifier = NULL;
7577
static size_t syslog_identifier_len;
@@ -96,13 +98,43 @@ gboolean logging_is_passthrough(void)
9698
return use_logging_passthrough;
9799
}
98100

101+
static int count_chars_in_string(const char *str, char ch)
102+
{
103+
int count = 0;
104+
105+
while (str) {
106+
str = strchr(str, ch);
107+
if (str == NULL)
108+
break;
109+
count++;
110+
str++;
111+
}
112+
113+
return count;
114+
}
115+
116+
static int is_valid_label_name(const char *str)
117+
{
118+
while (*str) {
119+
if (*str == '=') {
120+
return 1;
121+
}
122+
if (!isupper(*str) && !isdigit(*str) && *str != '_') {
123+
return 0;
124+
}
125+
str++;
126+
}
127+
return 1;
128+
}
129+
99130
/*
100131
* configures container log specific information, such as the drivers the user
101132
* called with and the max log size for log file types. For the log file types
102133
* (currently just k8s log file), it will also open the log_fd for that specific
103134
* log file.
104135
*/
105-
void configure_log_drivers(gchar **log_drivers, int64_t log_size_max_, int64_t log_global_size_max_, char *cuuid_, char *name_, char *tag)
136+
void configure_log_drivers(gchar **log_drivers, int64_t log_size_max_, int64_t log_global_size_max_, char *cuuid_, char *name_, char *tag,
137+
gchar **log_labels)
106138
{
107139
log_size_max = log_size_max_;
108140
log_global_size_max = log_global_size_max_;
@@ -126,8 +158,14 @@ void configure_log_drivers(gchar **log_drivers, int64_t log_size_max_, int64_t l
126158
}
127159
k8s_total_bytes_written = k8s_bytes_written;
128160

129-
if (!use_journald_logging && tag)
130-
nexit("k8s-file doesn't support --log-tag");
161+
if (!use_journald_logging) {
162+
if (!tag) {
163+
nexit("k8s-file doesn't support --log-tag");
164+
}
165+
if (!log_labels) {
166+
nexit("k8s-file doesn't support --log-label");
167+
}
168+
}
131169
}
132170

133171
if (use_journald_logging) {
@@ -169,6 +207,24 @@ void configure_log_drivers(gchar **log_drivers, int64_t log_size_max_, int64_t l
169207
syslog_identifier = g_strdup_printf("SYSLOG_IDENTIFIER=%s", tag);
170208
syslog_identifier_len = strlen(syslog_identifier);
171209
}
210+
if (log_labels) {
211+
container_labels = log_labels;
212+
213+
/* Ensure that valid LABEL=VALUE pairs have been passed */
214+
for (char **ptr = log_labels; *ptr; ptr++) {
215+
if (**ptr == '=') {
216+
nexitf("Container labels must be in format LABEL=VALUE (no LABEL present in '%s')", *ptr);
217+
}
218+
if (count_chars_in_string(*ptr, '=') != 1) {
219+
nexitf("Container labels must be in format LABEL=VALUE (none or more than one '=' present in '%s')",
220+
*ptr);
221+
}
222+
if (!is_valid_label_name(*ptr)) {
223+
nexitf("Container label names must contain only uppercase letters, numbers and underscore (in '%s')",
224+
*ptr);
225+
}
226+
}
227+
}
172228
}
173229
}
174230

@@ -325,6 +381,12 @@ static int write_journald(int pipe, char *buf, ssize_t buflen)
325381
/* per docker journald logging format, CONTAINER_PARTIAL_MESSAGE is set to true if it's partial, but otherwise not set. */
326382
if (partial && writev_buffer_append_segment_no_flush(&bufv, "CONTAINER_PARTIAL_MESSAGE=true", PARTIAL_MESSAGE_EQ_LEN) < 0)
327383
return -1;
384+
if (container_labels) {
385+
for (gchar **label = container_labels; *label; ++label) {
386+
if (writev_buffer_append_segment_no_flush(&bufv, *label, strlen(*label)) < 0)
387+
return -1;
388+
}
389+
}
328390

329391
int err = sd_journal_sendv(bufv.iov, bufv.iovcnt);
330392
if (err < 0) {

src/ctr_logging.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77

88
void reopen_log_files(void);
99
bool write_to_logs(stdpipe_t pipe, char *buf, ssize_t num_read);
10-
void configure_log_drivers(gchar **log_drivers, int64_t log_size_max_, int64_t log_global_size_max_, char *cuuid_, char *name_, char *tag);
10+
void configure_log_drivers(gchar **log_drivers, int64_t log_size_max_, int64_t log_global_size_max_, char *cuuid_, char *name_, char *tag,
11+
gchar **labels);
1112
void sync_logs(void);
1213
gboolean logging_is_passthrough(void);
1314
void close_logging_fds(void);

0 commit comments

Comments
 (0)