split polypcore/util.[ch] into polypcore/core-util.[ch] and polyp/util.[ch]
[profile/ivi/pulseaudio.git] / src / polypcore / log.c
1 /* $Id$ */
2
3 /***
4   This file is part of polypaudio.
5  
6   polypaudio is free software; you can redistribute it and/or modify
7   it under the terms of the GNU Lesser General Public License as
8   published by the Free Software Foundation; either version 2 of the
9   License, or (at your option) any later version.
10  
11   polypaudio is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   General Public License for more details.
15  
16   You should have received a copy of the GNU Lesser General Public
17   License along with polypaudio; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <assert.h>
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <string.h>
31
32 #ifdef HAVE_SYSLOG_H
33 #include <syslog.h>
34 #endif
35
36 #include <polyp/xmalloc.h>
37
38 #include <polypcore/core-util.h>
39
40 #include "log.h"
41
42 #define ENV_LOGLEVEL "POLYP_LOG"
43
44 static char *log_ident = NULL;
45 static pa_log_target_t log_target = PA_LOG_STDERR;
46 static void (*user_log_func)(pa_log_level_t l, const char *s) = NULL;
47 static pa_log_level_t maximal_level = PA_LOG_NOTICE;
48
49 #ifdef HAVE_SYSLOG_H
50 static const int level_to_syslog[] = {
51     [PA_LOG_ERROR] = LOG_ERR,
52     [PA_LOG_WARN] = LOG_WARNING,
53     [PA_LOG_NOTICE] = LOG_NOTICE,
54     [PA_LOG_INFO] = LOG_INFO,
55     [PA_LOG_DEBUG] = LOG_DEBUG
56 };
57 #endif
58
59 void pa_log_set_ident(const char *p) {
60     if (log_ident)
61         pa_xfree(log_ident);
62
63     log_ident = pa_xstrdup(p);
64 }
65
66 void pa_log_set_maximal_level(pa_log_level_t l) {
67     assert(l < PA_LOG_LEVEL_MAX);
68     maximal_level = l;
69 }
70
71 void pa_log_set_target(pa_log_target_t t, void (*func)(pa_log_level_t l, const char*s)) {
72     assert(t == PA_LOG_USER || !func);
73     log_target = t;
74     user_log_func = func;
75 }
76
77 void pa_log_levelv(pa_log_level_t level, const char *format, va_list ap) {
78     const char *e;
79     char *text, *t, *n;
80     
81     assert(level < PA_LOG_LEVEL_MAX);
82
83     if ((e = getenv(ENV_LOGLEVEL)))
84         maximal_level = atoi(e);
85     
86     if (level > maximal_level)
87         return;
88
89     text = pa_vsprintf_malloc(format, ap);
90
91     for (t = text; t; t = n) {
92         if ((n = strchr(t, '\n'))) {
93             *n = 0;
94             n++;
95         }
96
97         if (!*t)
98             continue;
99     
100         switch (log_target) {
101             case PA_LOG_STDERR: {
102                 const char *prefix = "", *suffix = "";
103
104 #ifndef OS_IS_WIN32                
105                 /* Yes indeed. Useless, but fun! */
106                 if (isatty(STDERR_FILENO)) {
107                     if (level <= PA_LOG_ERROR) {
108                         prefix = "\x1B[1;31m";
109                         suffix = "\x1B[0m";
110                     } else if (level <= PA_LOG_WARN) {
111                         prefix = "\x1B[1m";
112                         suffix = "\x1B[0m";
113                     }
114                 }
115 #endif
116
117                 fprintf(stderr, "%s%s%s\n", prefix, t, suffix);
118                 break;
119             }
120                 
121 #ifdef HAVE_SYSLOG_H            
122             case PA_LOG_SYSLOG:
123                 openlog(log_ident ? log_ident : "???", LOG_PID, LOG_USER);
124                 syslog(level_to_syslog[level], "%s", t);
125                 closelog();
126                 break;            
127 #endif
128                 
129             case PA_LOG_USER: 
130                 user_log_func(level, t);
131                 break;
132                 
133             case PA_LOG_NULL:
134             default:
135                 break;
136         }
137     }
138
139     pa_xfree(text);
140
141 }
142
143 void pa_log_level(pa_log_level_t level, const char *format, ...) {
144     va_list ap;
145     va_start(ap, format);
146     pa_log_levelv(level, format, ap);
147     va_end(ap);
148 }
149
150 void pa_log_debug(const char *format, ...) {
151     va_list ap;
152     va_start(ap, format);
153     pa_log_levelv(PA_LOG_DEBUG, format, ap);
154     va_end(ap);
155 }
156
157 void pa_log_info(const char *format, ...) {
158     va_list ap;
159     va_start(ap, format);
160     pa_log_levelv(PA_LOG_INFO, format, ap);
161     va_end(ap);
162 }
163
164 void pa_log_notice(const char *format, ...) {
165     va_list ap;
166     va_start(ap, format);
167     pa_log_levelv(PA_LOG_INFO, format, ap);
168     va_end(ap);
169 }
170
171 void pa_log_warn(const char *format, ...) {
172     va_list ap;
173     va_start(ap, format);
174     pa_log_levelv(PA_LOG_WARN, format, ap);
175     va_end(ap);
176 }
177
178 void pa_log_error(const char *format, ...) {
179     va_list ap;
180     va_start(ap, format);
181     pa_log_levelv(PA_LOG_ERROR, format, ap);
182     va_end(ap);
183 }