log_printf can be called concurently (removed static buffer)
[psensor.git] / src / lib / log.c
1 /*
2     Copyright (C) 2010-2011 jeanfi@gmail.com
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17     02110-1301 USA
18 */
19
20 #include <locale.h>
21 #include <libintl.h>
22 #define _(str) gettext(str)
23
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <sys/time.h>
27
28 #include "log.h"
29
30 static FILE *file;
31 int log_level =  LOG_WARN;
32
33 void log_open(const char *path)
34 {
35         file = fopen(path, "a");
36
37         if (file)
38                 log_printf(LOG_INFO, "Start logging");
39         else
40                 fprintf(stderr, _("Cannot open log file: %s\n"), path);
41 }
42
43 void log_close()
44 {
45         if (!file)
46                 return ;
47
48         fclose(file);
49
50         file = NULL;
51 }
52
53 #define LOG_BUFFER 4096
54 void log_printf(int lvl, const char *fmt, ...)
55 {
56         struct timeval tv;
57         char buffer[1 + LOG_BUFFER];
58         va_list ap;
59         char *lvl_str;
60
61         if (lvl > LOG_INFO && (!file || lvl > log_level))
62                 return ;
63
64         va_start(ap, fmt);
65         vsnprintf(buffer, LOG_BUFFER, fmt, ap);
66         buffer[LOG_BUFFER] = '\0';
67         va_end(ap);
68
69         if (gettimeofday(&tv, NULL) != 0)
70                 timerclear(&tv);
71
72         switch (lvl) {
73         case LOG_WARN:
74                 lvl_str = "[WARN]";
75                 break;
76         case LOG_ERR:
77                 lvl_str = "[ERR]";
78                 break;
79         case LOG_DEBUG:
80                 lvl_str = "[DEBUG]";
81                 break;
82         case LOG_INFO:
83                 lvl_str = "[INFO]";
84                 break;
85         default:
86                 lvl_str = "[??]";
87         }
88
89         if (file && lvl <= log_level) {
90                 fprintf(file, "[%ld] %s %s\n", tv.tv_sec, lvl_str, buffer);
91                 fflush(file);
92         }
93
94         if (lvl <= LOG_INFO)
95                 printf("[%ld] %s %s\n", tv.tv_sec, lvl_str, buffer);
96 }