summaryrefslogtreecommitdiffstats
path: root/src/libcephfs_proxy/proxy_log.c
blob: dc1afed63de6c6215bc4dbd47c3965f646132d2f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <stdio.h>
#include <stdarg.h>

#include "proxy_log.h"
#include "proxy_helpers.h"
#include "proxy_list.h"

#define PROXY_LOG_BUFFER_SIZE 4096

static __thread char proxy_log_buffer[PROXY_LOG_BUFFER_SIZE];

static pthread_rwlock_t proxy_log_mutex = PTHREAD_RWLOCK_INITIALIZER;
static list_t proxy_log_handlers = LIST_INIT(&proxy_log_handlers);

static void proxy_log_write(int32_t level, int32_t err, const char *msg)
{
	proxy_log_handler_t *handler;

	proxy_rwmutex_rdlock(&proxy_log_mutex);

	list_for_each_entry(handler, &proxy_log_handlers, list) {
		handler->callback(handler, level, err, msg);
	}

	proxy_rwmutex_unlock(&proxy_log_mutex);
}

__public void proxy_log_register(proxy_log_handler_t *handler,
				 proxy_log_callback_t callback)
{
	handler->callback = callback;

	proxy_rwmutex_wrlock(&proxy_log_mutex);

	list_add_tail(&handler->list, &proxy_log_handlers);

	proxy_rwmutex_unlock(&proxy_log_mutex);
}

__public void proxy_log_deregister(proxy_log_handler_t *handler)
{
	proxy_rwmutex_wrlock(&proxy_log_mutex);

	list_del_init(&handler->list);

	proxy_rwmutex_unlock(&proxy_log_mutex);
}

static void proxy_log_msg(char *buffer, const char *text)
{
	int32_t len;

	len = strlen(text) + 1;

	memcpy(buffer, text, len);
}

int32_t proxy_log_args(int32_t level, int32_t err, const char *fmt,
		       va_list args)
{
	static __thread bool busy = false;
	int32_t len;

	if (busy) {
		return -err;
	}
	busy = true;

	len = vsnprintf(proxy_log_buffer, sizeof(proxy_log_buffer), fmt, args);
	if (len < 0) {
		proxy_log_msg(proxy_log_buffer,
			      "<log message formatting failed>");
	} else if (len >= sizeof(proxy_log_buffer)) {
		proxy_log_msg(proxy_log_buffer + sizeof(proxy_log_buffer) - 6,
			      "[...]");
	}

	proxy_log_write(level, err, proxy_log_buffer);

	busy = false;

	return -err;
}

int32_t proxy_log(int32_t level, int32_t err, const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	err = proxy_log_args(level, err, fmt, args);
	va_end(args);

	return err;
}

void proxy_abort_args(int32_t err, const char *fmt, va_list args)
{
	proxy_log_args(LOG_CRIT, err, fmt, args);
	abort();
}

void proxy_abort(int32_t err, const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	proxy_abort_args(err, fmt, args);
	va_end(args);
}