[sheepdog] [PATCH v3 3/3] let logger work on rhel5 environment
Robin Dong
robin.k.dong at gmail.com
Wed Aug 21 11:54:12 CEST 2013
From: Robin Dong <sanbai at taobao.com>
In gcc-4.1.2, it dose not support attribute like "constructor(priority)" (it only support
contstructor without 'priority'), so change log_format_register from macro to function and
call it in init_log_formatter() directly.
Signed-off-by: Robin Dong <sanbai at taobao.com>
---
lib/logger.c | 200 +++++++++++++++++++++++++++++----------------------------
1 files changed, 102 insertions(+), 98 deletions(-)
diff --git a/lib/logger.c b/lib/logger.c
index 6c2f96f..a031c77 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -95,20 +95,14 @@ struct logmsg {
char str[0];
};
+typedef int (*formatter_fn)(char *, size_t, const struct logmsg *);
+
struct log_format {
const char *name;
- int (*formatter)(char *, size_t, const struct logmsg *);
+ formatter_fn formatter;
struct list_node list;
};
-#define log_format_register(n, formatter_fn) \
- static void __attribute__((constructor(101))) \
- regist_ ## formatter_fn(void) { \
- static struct log_format f = \
- { .name = n, .formatter = formatter_fn }; \
- list_add(&f.list, &log_formats); \
-}
-
static LIST_HEAD(log_formats);
static struct log_format *format;
@@ -141,15 +135,113 @@ static const char *format_thread_name(char *str, size_t size, const char *name,
return str;
}
+static int server_log_formatter(char *buff, size_t size,
+ const struct logmsg *msg)
+{
+ char *p = buff;
+ struct tm tm;
+ size_t len;
+ char thread_name[MAX_THREAD_NAME_LEN];
+
+ localtime_r(&msg->tv.tv_sec, &tm);
+ len = strftime(p, size, "%b %2d %H:%M:%S ", (const struct tm *)&tm);
+ p += len;
+ size -= len;
+
+ len = snprintf(p, size, "%s%6s %s[%s] %s(%d) %s%s%s",
+ colorize ? log_color[msg->prio] : "",
+ log_prio_str[msg->prio],
+ colorize ? TEXT_YELLOW : "",
+ format_thread_name(thread_name, sizeof(thread_name),
+ msg->worker_name, msg->worker_idx),
+ msg->func, msg->line,
+ colorize ? log_color[msg->prio] : "",
+ msg->str, colorize ? TEXT_NORMAL : "");
+ if (len < 0)
+ len = 0;
+ p += min(len, size - 1);
+
+ return p - buff;
+}
+
+static int default_log_formatter(char *buff, size_t size,
+ const struct logmsg *msg)
+{
+ size_t len = min(size, msg->str_len);
+
+ memcpy(buff, msg->str, len);
+
+ return len;
+}
+
+static int json_log_formatter(char *buff, size_t size,
+ const struct logmsg *msg)
+{
+ char *p = buff;
+ size_t len;
+
+ assert(logger_user_info);
+
+ len = snprintf(p, size, "{ \"user_info\": "
+ "{\"program_name\": \"%s\", \"port\": %d},"
+ "\"body\": {"
+ "\"second\": %lu, \"usecond\": %lu, "
+ "\"worker_name\": \"%s\", \"worker_idx\": %d, "
+ "\"func\": \"%s\", \"line\": %d, "
+ "\"msg\": \"",
+ log_name, logger_user_info->port,
+ msg->tv.tv_sec, msg->tv.tv_usec,
+ msg->worker_name[0] ? msg->worker_name : "main",
+ msg->worker_idx, msg->func, msg->line);
+ if (len < 0)
+ return 0;
+ len = min(len, size - 1);
+ p += len;
+ size -= len;
+
+ for (int i = 0; i < msg->str_len; i++) {
+ if (size <= 1)
+ break;
+
+ if (msg->str[i] == '"') {
+ *p++ = '\\';
+ size--;
+ }
+
+ if (size <= 1)
+ break;
+ *p++ = msg->str[i];
+ size--;
+ }
+
+ pstrcpy(p, size, "\"} }");
+ p += strlen(p);
+
+ return p - buff;
+}
+
+static void log_format_register(const char *name, formatter_fn formatter)
+{
+ struct log_format *f = malloc(sizeof(struct log_format));
+
+ f->name = name;
+ f->formatter = formatter;
+ list_add(&f->list, &log_formats);
+}
+
/*
* We need to set default log formatter because dog doesn't want to call
* select_log_formatter().
*/
-static void __attribute__((constructor(65535)))
+static void __attribute__((constructor))
init_log_formatter(void)
{
struct log_format *f;
+ log_format_register("json", json_log_formatter);
+ log_format_register("server", server_log_formatter);
+ log_format_register("default", default_log_formatter);
+
list_for_each_entry(f, &log_formats, list) {
if (!strcmp(f->name, "default")) {
format = f;
@@ -230,94 +322,6 @@ static void free_logarea(void)
shmdt(la);
}
-static int server_log_formatter(char *buff, size_t size,
- const struct logmsg *msg)
-{
- char *p = buff;
- struct tm tm;
- size_t len;
- char thread_name[MAX_THREAD_NAME_LEN];
-
- localtime_r(&msg->tv.tv_sec, &tm);
- len = strftime(p, size, "%b %2d %H:%M:%S ", (const struct tm *)&tm);
- p += len;
- size -= len;
-
- len = snprintf(p, size, "%s%6s %s[%s] %s(%d) %s%s%s",
- colorize ? log_color[msg->prio] : "",
- log_prio_str[msg->prio],
- colorize ? TEXT_YELLOW : "",
- format_thread_name(thread_name, sizeof(thread_name),
- msg->worker_name, msg->worker_idx),
- msg->func, msg->line,
- colorize ? log_color[msg->prio] : "",
- msg->str, colorize ? TEXT_NORMAL : "");
- if (len < 0)
- len = 0;
- p += min(len, size - 1);
-
- return p - buff;
-}
-log_format_register("server", server_log_formatter);
-
-static int default_log_formatter(char *buff, size_t size,
- const struct logmsg *msg)
-{
- size_t len = min(size, msg->str_len);
-
- memcpy(buff, msg->str, len);
-
- return len;
-}
-log_format_register("default", default_log_formatter);
-
-static int json_log_formatter(char *buff, size_t size,
- const struct logmsg *msg)
-{
- char *p = buff;
- size_t len;
-
- assert(logger_user_info);
-
- len = snprintf(p, size, "{ \"user_info\": "
- "{\"program_name\": \"%s\", \"port\": %d},"
- "\"body\": {"
- "\"second\": %lu, \"usecond\": %lu, "
- "\"worker_name\": \"%s\", \"worker_idx\": %d, "
- "\"func\": \"%s\", \"line\": %d, "
- "\"msg\": \"",
- log_name, logger_user_info->port,
- msg->tv.tv_sec, msg->tv.tv_usec,
- msg->worker_name[0] ? msg->worker_name : "main",
- msg->worker_idx, msg->func, msg->line);
- if (len < 0)
- return 0;
- len = min(len, size - 1);
- p += len;
- size -= len;
-
- for (int i = 0; i < msg->str_len; i++) {
- if (size <= 1)
- break;
-
- if (msg->str[i] == '"') {
- *p++ = '\\';
- size--;
- }
-
- if (size <= 1)
- break;
- *p++ = msg->str[i];
- size--;
- }
-
- pstrcpy(p, size, "\"} }");
- p += strlen(p);
-
- return p - buff;
-}
-log_format_register("json", json_log_formatter);
-
/* this one can block under memory pressure */
static void log_syslog(const struct logmsg *msg)
{
--
1.7.3.2
More information about the sheepdog
mailing list