tizen 2.4 release
[adaptation/xorg/driver/xserver-xorg-module-xdbg.git] / lib / xdbg_log.c
1 /**************************************************************************
2
3 xdbg
4
5 Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
6
7 Contact: Boram Park <boram1288.park@samsung.com>
8          Sangjin LEE <lsj119@samsung.com>
9
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
20 of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 **************************************************************************/
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <sys/time.h>
37 #include <unistd.h>
38 #include <time.h>
39 #include <string.h>
40 #include <stdarg.h>
41 #include <dlog.h>
42 #include "xdbg_log.h"
43
44 #ifndef API
45 #define API __attribute__ ((visibility("default")))
46 #endif
47
48 #ifndef MIN
49 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
50 #endif
51
52 #define MAX_MODULE_NAME 4
53 #define MAX_MODULE_CNT  256
54 #define BUF_LEN         1024
55 #define MAX_MONTH 12
56
57 typedef struct
58 {
59     unsigned int module;
60     char *name;
61     int   loglevel;
62 } ModuleInfo;
63
64 static ModuleInfo modules[MAX_MODULE_CNT];
65 static int module_cnt = 0;
66 static int default_level = XLOG_LEVEL_DEFAULT;
67 static char *st_month[MAX_MONTH] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
68
69 static Bool dlog_enable;
70
71 extern void dLogWrapper (int loglevel, int is_module, const char * file, int line, const char * f, va_list args);
72 extern void kLogWrapper (int loglevel, int is_module, const char * file, int line, const char * f, va_list args);
73 static char* _LogGetName (unsigned int module);
74
75 static void*
76 _LogInitModule (unsigned int module, int loglevel)
77 {
78     if (module_cnt >= MAX_MODULE_CNT)
79         return NULL;
80
81     modules[module_cnt].module = module;
82     modules[module_cnt].name = _LogGetName (module);
83     modules[module_cnt].loglevel = loglevel;
84     module_cnt++;
85
86     return &modules[module_cnt-1];
87 }
88
89 static void
90 _LogModule (void * handle, int logoption, const char * file, int line, const char * f, va_list args)
91 {
92     ModuleInfo *h = (ModuleInfo*)handle;
93     char *ostr[XLOG_LEVEL_MAX] = {"DD", "TT", "II", "WW", "EE"};
94     char tmpBuf[BUF_LEN];
95     int loglevel = logoption & XLOG_MASK_LOGLEVEL;
96     const char *name;
97     struct timeval  tv;
98     struct tm      *tm=NULL;
99     struct tm      result;
100
101     if (!h)
102         return;
103
104     name = h->name;
105
106     if (logoption & XLOG_OPTION_KLOG)
107     {
108         snprintf(tmpBuf, BUF_LEN, "[%s]%s", (name)?name:"", f);
109         kLogWrapper (loglevel, logoption, file, line, tmpBuf, args);
110     }
111     else if (loglevel >= XLOG_LEVEL_INFO)
112     {
113         if( !dlog_enable )
114         {
115             /* get local time from tv */
116             gettimeofday(&tv, NULL);
117             tm = localtime_r(&tv.tv_sec, &result);
118
119             /* write to file */
120             if (tm)
121             {
122                 if (logoption & XLOG_OPTION_SECURE)
123                     snprintf(tmpBuf, BUF_LEN, "[%s %d %02d:%02d:%02d:%03ld] (%s) > [SECURE_LOG] [%s]%s", st_month[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec/1000, ostr[loglevel], (name)?name:"", f);
124                 else
125                     snprintf(tmpBuf, BUF_LEN, "[%s %d %02d:%02d:%02d:%03ld] (%s) [%s]%s", st_month[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec/1000, ostr[loglevel], (name)?name:"", f);
126             }
127             else
128                 snprintf(tmpBuf, BUF_LEN, "[failed to get local time] (%s) [%s]%s", ostr[loglevel], (name)?name:"", f);
129
130             LogVWrite (1, tmpBuf, args);
131         }
132         else
133         {
134             /* dlog already supports localtime stamp. So we just add clock time! */
135             /* write to file */
136             if (logoption & XLOG_OPTION_SECURE)
137                 snprintf(tmpBuf, BUF_LEN, "[%10.3f] (%s) > [SECURE_LOG] [%s]%s", GetTimeInMillis()/1000.0, ostr[loglevel], (name)?name:"", f);
138             else
139                 snprintf(tmpBuf, BUF_LEN, "[%10.3f] (%s) [%s]%s", GetTimeInMillis()/1000.0, ostr[loglevel], (name)?name:"", f);
140
141             dLogWrapper (loglevel, logoption, file, line, tmpBuf, args);
142         }
143     }
144
145     /* write to console */
146     if (loglevel >= h->loglevel)
147     {
148         char *buf = tmpBuf;
149         int   remain = BUF_LEN;
150         int   len = 0;
151         unsigned int tv_ms;
152
153         if( tm == NULL )
154         {
155             gettimeofday(&tv, NULL);
156             tm = localtime_r(&tv.tv_sec, &result);
157         }
158
159         tv_ms = tv.tv_usec/1000;
160         if (tm)
161             len = snprintf (buf, remain, "[%10.3f] [%s %d %02d:%02d:%02d:%03d] (%s) [%s]", GetTimeInMillis()/1000.0, st_month[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv_ms, ostr[loglevel], name?name:"");
162         else
163             len = snprintf (buf, remain, "[%10.3f] [Failed to get current time:%03d] (%s) [%s]", GetTimeInMillis()/1000.0, tv_ms, ostr[loglevel], name?name:"");
164         buf += len;
165         remain -= len;
166
167         len += vsnprintf (buf, remain, f, args);
168
169         fwrite(tmpBuf, len, 1, stderr);
170     }
171 }
172
173 API int
174 xDbgLogSetLevel (unsigned int module, int level)
175 {
176     int i;
177     ModuleInfo * h;
178
179     if (level < XLOG_LEVEL_0 || level > XLOG_LEVEL_4)
180         return FALSE;
181
182     if (module == XDBG_ALL_MODULE)
183     {
184         default_level = level;
185         for (i = 0; i < module_cnt; i++)
186             modules[i].loglevel = level;
187
188         return TRUE;
189     }
190
191     for (i = 0; i < module_cnt; i++)
192     {
193         if (module == modules[i].module)
194         {
195             modules[i].loglevel = level;
196             return TRUE;
197         }
198     }
199
200     h = _LogInitModule (module, level);
201     if (h == NULL)
202         return FALSE;
203
204     return TRUE;
205 }
206
207 API void
208 xDbgLogEnableDlog (Bool enable)
209 {
210     dlog_enable = (enable > 0) ? TRUE:FALSE;
211 }
212
213 API Bool
214 xDbgGetLogEnableDlog ()
215 {
216     return dlog_enable;
217 }
218
219 API void*
220 xDbgLog (unsigned int module, int logoption, const char * file, int line, const char * f, ...)
221 {
222     int loglevel = logoption & XLOG_MASK_LOGLEVEL;
223     ModuleInfo *h;
224     va_list args;
225     int i;
226
227     if (module == 0)
228         return NULL;
229
230     if (loglevel < XLOG_LEVEL_0 || loglevel > XLOG_LEVEL_4)
231         return NULL;
232
233     for (i = 0; i < module_cnt; i++)
234     {
235         h = &modules[i];
236         if (module == h->module)
237             goto check_level;
238     }
239
240     h= (ModuleInfo *)_LogInitModule (module, default_level);
241     if(h == NULL)
242         return NULL;
243
244 check_level:
245     if (loglevel < XLOG_LEVEL_INFO && loglevel < h->loglevel)
246         return h;
247
248     va_start (args, f);
249     _LogModule (h, logoption, file, line, f, args);
250     va_end (args);
251
252     return h;
253 }
254
255 API int
256 xDbgLogEnumModules (LOG_ENUM_MODE mode, char *buf, int *remain)
257 {
258     int i, len;
259     char *p = buf;
260
261     switch (mode)
262     {
263     case MODE_NAME_ONLY:
264         for (i = 0; i < module_cnt && *remain > 0; i++)
265         {
266             len = snprintf (p, *remain, "%s", modules[i].name);
267             p += len;
268             *remain -= len;
269
270             if (i != module_cnt - 1 && *remain > 0)
271             {
272                 len = snprintf (p, *remain, "/");
273                 p += len;
274                 *remain -= len;
275             }
276         }
277         break;
278     case MODE_WITH_STATUS:
279         for (i = 0; i < module_cnt && *remain > 0; i++)
280         {
281             len = snprintf (p, *remain, "   %12s:%d\n", modules[i].name, modules[i].loglevel);
282             p += len;
283             *remain -= len;
284         }
285         break;
286     default:
287         return 0;
288     }
289
290     return p - buf;
291 }
292
293 static char*
294 _LogGetName (unsigned int module)
295 {
296     char *name = malloc (MAX_MODULE_NAME+1);
297     char *p = name;
298     int i;
299
300     if (!name)
301         return NULL;
302
303     name[0] = '\0';
304
305     for (i = 0; i < MAX_MODULE_NAME; i++)
306     {
307         if (!_C(module, (i<<3)))
308             break;
309
310         *p = _C(module, (i<<3));
311         p++;
312     }
313
314     *p = '\0';
315
316     return name;
317 }
318
319 API unsigned int
320 xDbgLogGetModule (char *name)
321 {
322     unsigned int module = 0;
323     int i, len;
324
325     if (!name)
326         return 0;
327
328     if (!strcasecmp (name, "all"))
329         return XDBG_ALL_MODULE;
330
331     len = strlen (name);
332     for (i = 0; i < len; i++)
333     {
334         module |= _B(*name, (i<<3));
335         name++;
336     }
337
338     return module;
339 }