2 Copyright (C) 2016, 2017 "IoT.bzh"
4 author: José Bollo <jose.bollo@iot.bzh>
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
24 #if !defined(DEFAULT_VERBOSITY)
25 # define DEFAULT_VERBOSITY Verbosity_Level_Warning
29 void (*verbose_observer)(int loglevel, const char *file, int line, const char *function, const char *fmt, va_list args);
31 #define CROP_LOGLEVEL(x) ((x) < Log_Level_Emergency ? Log_Level_Emergency : (x) > Log_Level_Debug ? Log_Level_Debug : (x))
33 #if defined(VERBOSE_WITH_SYSLOG)
37 static void _vverbose_(int loglevel, const char *file, int line, const char *function, const char *fmt, va_list args)
41 if (file == NULL || vasprintf(&p, fmt, args) < 0)
42 vsyslog(loglevel, fmt, args);
44 syslog(CROP_LOGLEVEL(loglevel), "%s [%s:%d, function]", p, file, line, function);
49 void verbose_set_name(const char *name, int authority)
51 openlog(name, LOG_PERROR, authority ? LOG_AUTH : LOG_USER);
54 #elif defined(VERBOSE_WITH_SYSTEMD)
56 #define SD_JOURNAL_SUPPRESS_LOCATION
58 #include <systemd/sd-journal.h>
60 static const char *appname;
62 static int appauthority;
64 static void _vverbose_(int loglevel, const char *file, int line, const char *function, const char *fmt, va_list args)
69 sd_journal_printv(loglevel, fmt, args);
71 sprintf(lino, "%d", line);
72 sd_journal_printv_with_location(loglevel, file, lino, function, fmt, args);
76 void verbose_set_name(const char *name, int authority)
79 appauthority = authority;
90 static const char *appname;
92 static int appauthority;
94 static const char *prefixes[] = {
107 static const char chars[] = { '\n', '?', ':', ' ', '[', ',', ']' };
109 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
111 static void _vverbose_(int loglevel, const char *file, int line, const char *function, const char *fmt, va_list args)
116 struct iovec iov[20];
121 tty = 1 + isatty(STDERR_FILENO);
123 iov[0].iov_base = (void*)prefixes[CROP_LOGLEVEL(loglevel)] + (tty - 1 ? 4 : 0);
124 iov[0].iov_len = strlen(iov[0].iov_base);
126 iov[1].iov_base = (void*)&chars[2];
131 iov[n].iov_base = buffer;
133 rc = vsnprintf(buffer, sizeof buffer, fmt, args);
136 else if ((size_t)rc > sizeof buffer) {
137 rc = (int)sizeof buffer;
138 buffer[rc - 1] = buffer[rc - 2] = buffer[rc - 3] = '.';
140 iov[n++].iov_len = (size_t)rc;
142 if (file && (!fmt || tty == 1 || loglevel <= Log_Level_Warning)) {
143 iov[n].iov_base = (void*)&chars[3 + !fmt];
144 iov[n++].iov_len = 2 - !fmt;
145 iov[n].iov_base = (void*)file;
146 iov[n++].iov_len = strlen(file);
147 iov[n].iov_base = (void*)&chars[2];
148 iov[n++].iov_len = 1;
150 iov[n].iov_base = lino;
151 iov[n++].iov_len = snprintf(lino, sizeof lino, "%d", line);
153 iov[n].iov_base = (void*)&chars[1];
154 iov[n++].iov_len = 1;
156 iov[n].iov_base = (void*)&chars[5];
157 iov[n++].iov_len = 1;
159 iov[n].iov_base = (void*)function;
160 iov[n++].iov_len = strlen(function);
162 iov[n].iov_base = (void*)&chars[1];
163 iov[n++].iov_len = 1;
165 iov[n].iov_base = (void*)&chars[6];
166 iov[n++].iov_len = 1;
169 iov[n].iov_base = (void*)&chars[1];
170 iov[n++].iov_len = 1;
172 iov[n].iov_base = (void*)&chars[0];
173 iov[n++].iov_len = 1;
175 pthread_mutex_lock(&mutex);
176 writev(STDERR_FILENO, iov, n);
177 pthread_mutex_unlock(&mutex);
182 void verbose_set_name(const char *name, int authority)
185 appauthority = authority;
190 void verbose(int loglevel, const char *file, int line, const char *function, const char *fmt, ...)
195 vverbose(loglevel, file, line, function, fmt, ap);
199 void vverbose(int loglevel, const char *file, int line, const char *function, const char *fmt, va_list args)
201 void (*observer)(int loglevel, const char *file, int line, const char *function, const char *fmt, va_list args) = verbose_observer;
204 _vverbose_(loglevel, file, line, function, fmt, args);
208 _vverbose_(loglevel, file, line, function, fmt, args);
209 observer(loglevel, file, line, function, fmt, ap);