This is useful when logging to file on a cluster.
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
include/qb/qblog.h | 1 +
lib/log.c | 22 +++-------
lib/log_format.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++-----
lib/log_int.h | 2 +
tests/check_log.c | 16 ++++++++
5 files changed, 121 insertions(+), 26 deletions(-)
diff --git a/include/qb/qblog.h b/include/qb/qblog.h
index 3d7bf82..caa93a7 100644
--- a/include/qb/qblog.h
+++ b/include/qb/qblog.h
@@ -503,6 +503,7 @@ void qb_log_tags_stringify_fn_set(qb_log_tags_stringify_fn fn);
* %g TAGS
* %N name (passed into qb_log_init)
* %P PID
+ * %H hostname
*
* any number between % and character specify field length to pad or chop
*/
diff --git a/lib/log.c b/lib/log.c
index 0785b21..4bcd3f5 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -968,24 +968,16 @@ qb_log_ctl(int32_t t, enum qb_log_conf c, int32_t arg)
void
qb_log_format_set(int32_t t, const char *format)
{
- char* ptr = NULL;
- size_t len = 0;
-
- if (format) {
- ptr = strstr(format, "%N");
- len = strlen(format);
- }
+ char modified_format[256];
free(conf[t].format);
- if (ptr) {
- len += strlen(conf[t].name);
- conf[t].format = calloc(len + 1, sizeof(char));
- strncpy(conf[t].format, format, ptr - format);
- (void)strlcat(conf[t].format, conf[t].name, len);
- ptr += 2;
- (void)strlcat(conf[t].format, ptr, len);
+ if (format) {
+ printf("B %s\n", format);
+ qb_log_target_format_static(t, format, modified_format);
+ printf("A %s\n", modified_format);
+ conf[t].format = strdup(modified_format);
} else {
- conf[t].format = strdup(format ? format : "[%p] %b");
+ conf[t].format = strdup("[%p] %b");
}
assert(conf[t].format != NULL);
}
diff --git a/lib/log_format.c b/lib/log_format.c
index 70eaedb..6071a30 100644
--- a/lib/log_format.c
+++ b/lib/log_format.c
@@ -147,6 +147,96 @@ _strcpy_cutoff(char *dest, const char *src, size_t cutoff, int
ralign,
}
/*
+ * This function will do static formatting (for things that don't
+ * change on each log message).
+ *
+ * %P PID
+ * %N name passed into qb_log_init
+ * %H hostname
+ *
+ * any number between % and character specify field length to pad or chop
+ */
+void
+qb_log_target_format_static(int32_t target, const char * format,
+ char *output_buffer)
+{
+ char tmp_buf[255];
+ unsigned int format_buffer_idx = 0;
+ unsigned int output_buffer_idx = 0;
+ size_t cutoff;
+ uint32_t len;
+ int ralign;
+ int c;
+ struct qb_log_target *t = qb_log_target_get(target);
+
+ if (format == NULL) {
+ return;
+ }
+
+ while ((c = format[format_buffer_idx])) {
+ cutoff = 0;
+ ralign = 0;
+ if (c != '%') {
+ output_buffer[output_buffer_idx++] = c;
+ format_buffer_idx++;
+ } else {
+ const char *p;
+ unsigned int percent_buffer_idx = format_buffer_idx;
+
+ format_buffer_idx += 1;
+ if (format[format_buffer_idx] == '-') {
+ ralign = 1;
+ format_buffer_idx += 1;
+ }
+
+ if (isdigit(format[format_buffer_idx])) {
+ cutoff = atoi(&format[format_buffer_idx]);
+ }
+ while (isdigit(format[format_buffer_idx])) {
+ format_buffer_idx += 1;
+ }
+
+ switch (format[format_buffer_idx]) {
+ case 'P':
+ snprintf(tmp_buf, 30, "%d", getpid());
+ p = tmp_buf;
+ break;
+
+ case 'N':
+ p = t->name;
+ break;
+
+ case 'H':
+ if (gethostname(tmp_buf, 255) == 0) {
+ tmp_buf[254] = '\0';
+ } else {
+ (void)strlcpy(tmp_buf, "localhost", 255);
+ }
+ p = tmp_buf;
+ break;
+
+ default:
+ p = &format[percent_buffer_idx];
+ cutoff = (format_buffer_idx - percent_buffer_idx + 1);
+ ralign = 0;
+ break;
+ }
+ len = _strcpy_cutoff(output_buffer + output_buffer_idx,
+ p, cutoff, ralign,
+ (QB_LOG_MAX_LEN -
+ output_buffer_idx));
+ output_buffer_idx += len;
+ format_buffer_idx += 1;
+ }
+ if (output_buffer_idx >= QB_LOG_MAX_LEN - 1) {
+ break;
+ }
+ }
+
+ output_buffer[output_buffer_idx] = '\0';
+}
+
+/*
* %n FUNCTION NAME
* %f FILENAME
* %l FILELINE
@@ -163,9 +253,8 @@ qb_log_target_format(int32_t target,
time_t current_time,
const char *formatted_message, char *output_buffer)
{
- char char_time[128];
+ char tmp_buf[128];
struct tm tm_res;
- char line_no[30];
unsigned int format_buffer_idx = 0;
unsigned int output_buffer_idx = 0;
size_t cutoff;
@@ -227,18 +316,18 @@ qb_log_target_format(int32_t target,
break;
case 'l':
- snprintf(line_no, 30, "%d", cs->lineno);
- p = line_no;
+ snprintf(tmp_buf, 30, "%d", cs->lineno);
+ p = tmp_buf;
break;
case 't':
(void)localtime_r(¤t_time, &tm_res);
- snprintf(char_time, TIME_STRING_SIZE,
+ snprintf(tmp_buf, TIME_STRING_SIZE,
"%s %02d %02d:%02d:%02d",
log_month_name[tm_res.tm_mon],
tm_res.tm_mday, tm_res.tm_hour,
tm_res.tm_min, tm_res.tm_sec);
- p = char_time;
+ p = tmp_buf;
break;
case 'b':
@@ -253,11 +342,6 @@ qb_log_target_format(int32_t target,
}
break;
- case 'P':
- snprintf(line_no, 30, "%d", getpid());
- p = line_no;
- break;
-
default:
p = "";
break;
diff --git a/lib/log_int.h b/lib/log_int.h
index a1755a9..88f4b0c 100644
--- a/lib/log_int.h
+++ b/lib/log_int.h
@@ -96,5 +96,7 @@ struct qb_log_callsite *qb_log_dcs_get(int32_t *newly_created,
size_t qb_vsprintf_serialize(char *serialize, const char *fmt, va_list ap);
size_t qb_vsnprintf_deserialize(char *string, size_t str_len, const char *buf);
+void qb_log_target_format_static(int32_t target, const char * format, char
*output_buffer);
+
#endif /* _QB_LOG_INT_H_ */
diff --git a/tests/check_log.c b/tests/check_log.c
index 318de9a..4b06e67 100644
--- a/tests/check_log.c
+++ b/tests/check_log.c
@@ -363,6 +363,8 @@ static const char *_test_tags_stringify(uint32_t tags)
START_TEST(test_log_format)
{
int32_t t;
+ char cmp_str[256];
+ char host_str[256];
qb_log_init("test", LOG_USER, LOG_DEBUG);
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
@@ -406,6 +408,20 @@ START_TEST(test_log_format)
qb_log_format_set(t, "%-15f %b");
qb_log(LOG_WARNING, "Andrew");
ck_assert_str_eq(test_buf, " check_log.c Andrew");
+
+ qb_log_tags_stringify_fn_set(NULL);
+
+ gethostname(host_str, 256);
+
+ qb_log_format_set(t, "%P %H %N %b");
+ qb_log(LOG_INFO, "Angus");
+ snprintf(cmp_str, 256, "%d %s test Angus", getpid(), host_str);
+ ck_assert_str_eq(test_buf, cmp_str);
+
+ qb_log_format_set(t, "%3N %H %P %b");
+ qb_log(LOG_INFO, "Angus");
+ snprintf(cmp_str, 256, "tes %s %d Angus", host_str, getpid());
+ ck_assert_str_eq(test_buf, cmp_str);
}
END_TEST
--
1.7.7.6