tizen 2.3.1 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
100     if (!h)
101         return;
102
103     name = h->name;
104
105     if (logoption & XLOG_OPTION_KLOG)
106     {
107         snprintf(tmpBuf, BUF_LEN, "[%s]%s", (name)?name:"", f);
108         kLogWrapper (loglevel, logoption, file, line, tmpBuf, args);
109     }
110     else if (loglevel >= XLOG_LEVEL_INFO)
111     {
112         if( !dlog_enable )
113         {
114             /* get local time from tv */
115             gettimeofday(&tv, NULL);
116             tm = localtime(&tv.tv_sec);
117
118             /* write to file */
119             if (tm)
120             {
121                 if (logoption & XLOG_OPTION_SECURE)
122                     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);
123                 else
124                     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);
125             }
126             else
127                 snprintf(tmpBuf, BUF_LEN, "[failed to get local time] (%s) [%s]%s", ostr[loglevel], (name)?name:"", f);
128
129             LogVWrite (1, tmpBuf, args);
130         }
131         else
132         {
133             /* dlog already supports localtime stamp. So we just add clock time! */
134             /* write to file */
135             if (logoption & XLOG_OPTION_SECURE)
136                 snprintf(tmpBuf, BUF_LEN, "[%10.3f] (%s) > [SECURE_LOG] [%s]%s", GetTimeInMillis()/1000.0, ostr[loglevel], (name)?name:"", f);
137             else
138                 snprintf(tmpBuf, BUF_LEN, "[%10.3f] (%s) [%s]%s", GetTimeInMillis()/1000.0, ostr[loglevel], (name)?name:"", f);
139
140             dLogWrapper (loglevel, logoption, file, line, tmpBuf, args);
141         }
142     }
143
144     /* write to console */
145     if (loglevel >= h->loglevel)
146     {
147         char *buf = tmpBuf;
148         int   remain = BUF_LEN;
149         int   len = 0;
150         unsigned int tv_ms;
151
152         if( tm == NULL )
153         {
154             gettimeofday(&tv, NULL);
155             tm = localtime(&tv.tv_sec);
156         }
157
158         tv_ms = tv.tv_usec/1000;
159         if (tm)
160             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:"");
161         else
162             len = snprintf (buf, remain, "[%10.3f] [Failed to get current time:%03d] (%s) [%s]", GetTimeInMillis()/1000.0, tv_ms, ostr[loglevel], name?name:"");
163         buf += len;
164         remain -= len;
165
166         len += vsnprintf (buf, remain, f, args);
167
168         fwrite(tmpBuf, len, 1, stderr);
169     }
170 }
171
172 API int
173 xDbgLogSetLevel (unsigned int module, int level)
174 {
175     int i;
176     ModuleInfo * h;
177
178     if (level < XLOG_LEVEL_0 || level > XLOG_LEVEL_4)
179         return FALSE;
180
181     if (module == XDBG_ALL_MODULE)
182     {
183         default_level = level;
184         for (i = 0; i < module_cnt; i++)
185             modules[i].loglevel = level;
186
187         return TRUE;
188     }
189
190     for (i = 0; i < module_cnt; i++)
191     {
192         if (module == modules[i].module)
193         {
194             modules[i].loglevel = level;
195             return TRUE;
196         }
197     }
198
199     h = _LogInitModule (module, level);
200     if (h == NULL)
201         return FALSE;
202
203     return TRUE;
204 }
205
206 API void
207 xDbgLogEnableDlog (Bool enable)
208 {
209     dlog_enable = (enable > 0) ? TRUE:FALSE;
210 }
211
212 API Bool
213 xDbgGetLogEnableDlog ()
214 {
215     return dlog_enable;
216 }
217
218 API void*
219 xDbgLog (unsigned int module, int logoption, const char * file, int line, const char * f, ...)
220 {
221     int loglevel = logoption & XLOG_MASK_LOGLEVEL;
222     ModuleInfo *h;
223     va_list args;
224     int i;
225
226     if (module == 0)
227         return NULL;
228
229     if (loglevel < XLOG_LEVEL_0 || loglevel > XLOG_LEVEL_4)
230         return NULL;
231
232     for (i = 0; i < module_cnt; i++)
233     {
234         h = &modules[i];
235         if (module == h->module)
236             goto check_level;
237     }
238
239     h= (ModuleInfo *)_LogInitModule (module, default_level);
240     if(h == NULL)
241         return NULL;
242
243 check_level:
244     if (loglevel < XLOG_LEVEL_INFO && loglevel < h->loglevel)
245         return h;
246
247     va_start (args, f);
248     _LogModule (h, logoption, file, line, f, args);
249     va_end (args);
250
251     return h;
252 }
253
254 API int
255 xDbgLogEnumModules (LOG_ENUM_MODE mode, char *buf, int *remain)
256 {
257     int i, len;
258     char *p = buf;
259
260     switch (mode)
261     {
262     case MODE_NAME_ONLY:
263         for (i = 0; i < module_cnt && *remain > 0; i++)
264         {
265             len = snprintf (p, *remain, "%s", modules[i].name);
266             p += len;
267             *remain -= len;
268
269             if (i != module_cnt - 1 && *remain > 0)
270             {
271                 len = snprintf (p, *remain, "/");
272                 p += len;
273                 *remain -= len;
274             }
275         }
276         break;
277     case MODE_WITH_STATUS:
278         for (i = 0; i < module_cnt && *remain > 0; i++)
279         {
280             len = snprintf (p, *remain, "   %12s:%d\n", modules[i].name, modules[i].loglevel);
281             p += len;
282             *remain -= len;
283         }
284         break;
285     default:
286         return 0;
287     }
288
289     return p - buf;
290 }
291
292 static char*
293 _LogGetName (unsigned int module)
294 {
295     char *name = malloc (MAX_MODULE_NAME+1);
296     char *p = name;
297     int i;
298
299     if (!name)
300         return NULL;
301
302     name[0] = '\0';
303
304     for (i = 0; i < MAX_MODULE_NAME; i++)
305     {
306         if (!_C(module, (i<<3)))
307             break;
308
309         *p = _C(module, (i<<3));
310         p++;
311     }
312
313     *p = '\0';
314
315     return name;
316 }
317
318 API unsigned int
319 xDbgLogGetModule (char *name)
320 {
321     unsigned int module = 0;
322     int i, len;
323
324     if (!name)
325         return 0;
326
327     if (!strcasecmp (name, "all"))
328         return XDBG_ALL_MODULE;
329
330     len = strlen (name);
331     for (i = 0; i < len; i++)
332     {
333         module |= _B(*name, (i<<3));
334         name++;
335     }
336
337     return module;
338 }