38
37
#include <pulse/utf8.h>
39
38
#include <pulse/xmalloc.h>
40
39
#include <pulse/util.h>
40
#include <pulse/timeval.h>
42
42
#include <pulsecore/macro.h>
43
43
#include <pulsecore/core-util.h>
44
#include <pulsecore/rtclock.h>
45
#include <pulsecore/once.h>
47
49
#define ENV_LOGLEVEL "PULSE_LOG"
48
50
#define ENV_LOGMETA "PULSE_LOG_META"
51
#define ENV_LOGTIME "PULSE_LOG_TIME"
50
53
static char *log_ident = NULL, *log_ident_local = NULL;
51
54
static pa_log_target_t log_target = PA_LOG_STDERR;
52
static void (*user_log_func)(pa_log_level_t l, const char *s) = NULL;
53
static pa_log_level_t maximal_level = PA_LOG_NOTICE;
55
static pa_log_func_t user_log_func = NULL;
56
static pa_log_level_t maximal_level = PA_LOG_ERROR;
55
58
#ifdef HAVE_SYSLOG_H
56
59
static const int level_to_syslog[] = {
95
void pa_log_set_target(pa_log_target_t t, void (*func)(pa_log_level_t l, const char*s)) {
101
void pa_log_set_target(pa_log_target_t t, pa_log_func_t func) {
96
102
pa_assert(t == PA_LOG_USER || !func);
111
char *text, *t, *n, *location;
118
int saved_errno = errno;
120
/* We don't use dynamic memory allocation here to minimize the hit
122
char text[1024], location[128], timestamp[32];
113
124
pa_assert(level < PA_LOG_LEVEL_MAX);
114
125
pa_assert(format);
116
127
if ((e = getenv(ENV_LOGLEVEL)))
117
128
maximal_level = atoi(e);
119
if (level > maximal_level)
130
if (level > maximal_level) {
122
text = pa_vsprintf_malloc(format, ap);
135
pa_vsnprintf(text, sizeof(text), format, ap);
124
137
if (getenv(ENV_LOGMETA) && file && line > 0 && func)
125
location = pa_sprintf_malloc("[%s:%i %s()] ", file, line, func);
138
pa_snprintf(location, sizeof(location), "[%s:%i %s()] ", file, line, func);
127
location = pa_sprintf_malloc("%s: ", pa_path_get_filename(file));
140
pa_snprintf(location, sizeof(location), "%s: ", pa_path_get_filename(file));
129
location = pa_xstrdup("");
144
if (getenv(ENV_LOGTIME)) {
145
static pa_usec_t start, last;
148
u = pa_rtclock_usec();
158
/* This is not thread safe, but this is a debugging tool only
162
pa_snprintf(timestamp, sizeof(timestamp), "(%4llu.%03llu|%4llu.%03llu) ",
163
(unsigned long long) (a / PA_USEC_PER_SEC),
164
(unsigned long long) (((a / PA_USEC_PER_MSEC)) % 1000),
165
(unsigned long long) (r / PA_USEC_PER_SEC),
166
(unsigned long long) (((r / PA_USEC_PER_MSEC)) % 1000));
131
171
if (!pa_utf8_valid(text))
132
172
pa_log_level(level, __FILE__": invalid UTF-8 string following below:");
201
/* We shouldn't be using dynamic allocation here to
202
* minimize the hit in RT threads */
161
203
local_t = pa_utf8_to_locale(t);
163
fprintf(stderr, "%c: %s%s%s%s\n", level_to_char[level], location, prefix, t, suffix);
205
fprintf(stderr, "%s%c: %s%s%s%s\n", timestamp, level_to_char[level], location, prefix, t, suffix);
165
fprintf(stderr, "%c: %s%s%s%s\n", level_to_char[level], location, prefix, local_t, suffix);
207
fprintf(stderr, "%s%c: %s%s%s%s\n", timestamp, level_to_char[level], location, prefix, local_t, suffix);
166
208
pa_xfree(local_t);
178
220
local_t = pa_utf8_to_locale(t);
180
syslog(level_to_syslog[level], "%s%s", location, t);
222
syslog(level_to_syslog[level], "%s%s%s", timestamp, location, t);
182
syslog(level_to_syslog[level], "%s%s", location, local_t);
224
syslog(level_to_syslog[level], "%s%s%s", timestamp, location, local_t);
183
225
pa_xfree(local_t);
191
233
case PA_LOG_USER: {
194
x = pa_sprintf_malloc("%s%s", location, t);
236
pa_snprintf(x, sizeof(x), "%s%s%s", timestamp, location, t);
195
237
user_log_func(level, x);