[sheepdog] [PATCH v3 3/3] let logger work on rhel5 environment

Liu Yuan namei.unix at gmail.com
Wed Aug 21 12:00:47 CEST 2013


On Wed, Aug 21, 2013 at 05:54:12PM +0800, Robin Dong wrote:
> 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));

Use xmalloc().

Thanks
Yuan



More information about the sheepdog mailing list