2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <sys/types.h>
22 #include <time.h> // localtime_r
23 #include <sys/time.h> // gettimeofday
25 #include <string.h> // strrchr
34 #define G_UNLIKELY(x) x
41 _DEBUG_OUTPUT_DIRECTION_CONSOLE = (1 << 0),
42 _DEBUG_OUTPUT_DIRECTION_SYSLOG = (1 << 1),
43 _DEBUG_OUTPUT_DIRECTION_FILE = (1 << 2),
44 _DEBUG_OUTPUT_DIRECTION_DLOG = (1 << 3),
47 // Configuration for output
48 // console message slower than dlog about 30~40 ms
49 #define _DEBUG_OUTPUT_DIRECTION (_DEBUG_OUTPUT_DIRECTION_DLOG)
54 #define INI_PATH "/var/log"
58 #define _DEBUG_MODULE "IVUG"
61 #define _DEBUG_ERR_TRACE_FILE_NAME INI_PATH"/"_DEBUG_MODULE"_FATAL.txt"
62 #define _DEBUG_PREFIX "["_DEBUG_MODULE"]"
64 static bool bInit = false;
66 static char *get_time_string(unsigned long dwmSec)
68 static char buffer[30];
75 // Don't forget turn on compiler optimization options.
76 sec = ( dwmSec / 1000 );
77 msec = ( dwmSec % 1000 );
85 snprintf(buffer, (size_t)sizeof(buffer), "%1d:%02d:%02d.%03d", (int)hour,(int)min,(int)sec,(int)msec);
91 /*Retrieves the number of milliseconds that have elapsed since the system was started*/
92 static unsigned long get_sys_elapsed_time(void)
94 static struct timeval init_time = { 0 , 0 };
95 static bool bFirst = false;
96 struct timeval current_time;
98 if ( bFirst == false )
101 gettimeofday(&init_time, NULL);
104 gettimeofday(¤t_time, NULL);
106 // return (current_time.tv_sec - init_time.tv_sec) * 1000UL + (UINT32)((current_time.tv_usec - init_time.tv_usec) / 1000.0) ;
107 return ((current_time.tv_sec * 1E3 + current_time.tv_usec / 1E3) - (init_time.tv_sec * 1E3 + init_time.tv_usec / 1E3));
110 void _custom_debug_init()
112 get_sys_elapsed_time();
115 void _custom_debug_deinit()
121 _custom_err_trace_write( const char *func_name, int line_num, const char *fmt, ... )
130 current_time = time( NULL );
131 localtime_r( ¤t_time, &new_time );
133 f = fopen( _DEBUG_ERR_TRACE_FILE_NAME, "a" );
136 printf( "Failed to open file.[%s]\n", _DEBUG_ERR_TRACE_FILE_NAME );
140 fprintf( f, "[%.19s][%05d][%s]", asctime_r( &new_time, buf ), line_num, func_name );
143 vfprintf( f, fmt, ap );
152 _custom_err_trace_fvprintf( const char *func_name, int line_num, const char *fmt, va_list ap )
160 current_time = time( NULL );
161 localtime_r( ¤t_time, &new_time );
163 f = fopen( _DEBUG_ERR_TRACE_FILE_NAME, "a" );
166 printf( "Failed to open file.[%s]\n", _DEBUG_ERR_TRACE_FILE_NAME );
170 fprintf( f, "[%.19s][[F:%-16.16s L:%5d] ", asctime_r( &new_time, buf ), func_name, line_num );
171 vfprintf( f, fmt, ap );
178 typedef enum log_priority {
190 #define LOG(priority, tag, ...) \
191 #define LOG_VA(priority, tag, fmt, args) \
194 inline log_priority convert_to_dlog_priority(int msg_level)
216 static log_priority priority[] = {
219 DLOG_WARN, // MSG HIGH
225 if ( msg_level <= DBG_MSG_FATAL)
226 return priority[msg_level];
234 void __custom_debug_msg(debug_msg_type *debug_msg, const char *msg, ...)
238 static const char *level ;
240 if ( G_UNLIKELY(bInit == false) )
242 _custom_debug_init();
246 #define DIRECORY_SPLITTER '/'
247 const char*pFileName = NULL;
249 debug_msg->time = get_sys_elapsed_time();
251 pFileName = strrchr(debug_msg->fname, DIRECORY_SPLITTER);
252 pFileName = (NULL == pFileName)?debug_msg->fname:(pFileName+1);
254 level = debug_msg->szlevel;
257 char *time_string = get_time_string(debug_msg->time);
261 if ( _DEBUG_OUTPUT_DIRECTION & _DEBUG_OUTPUT_DIRECTION_CONSOLE )
264 printf(_DEBUG_PREFIX"%s[F:%-16.16s L:%5d][%s:%s] ", time_string , pFileName, debug_msg->nline , debug_msg->szcategory, level );
269 if ( _DEBUG_OUTPUT_DIRECTION & _DEBUG_OUTPUT_DIRECTION_DLOG )
271 static char buf[2048];
275 i = snprintf(buf, 2048, "%s[F:%-16.16s L:%5d][%08x][%s] ",time_string , pFileName, debug_msg->nline , pthread_self(), level);
277 i = snprintf(buf, 2048, "%s[F:%-16.16s L:%5d][%s] ",time_string , pFileName, debug_msg->nline , level);
279 vsnprintf( buf + i, 2048 - i, msg, va);
281 // Prevent Format string attack
282 print_log(convert_to_dlog_priority(debug_msg->msg_level), debug_msg->szcategory, "%s", buf);
283 // print_log(prio, _DEBUG_MODULE, "%s[F:%-16.16s L:%5d][%s:%s] ",time_string , pFileName, debug_msg->nline , szCategory[debug_msg->category], level );
284 // vprint_log(prio,_DEBUG_MODULE, msg, va);
288 if ( _DEBUG_OUTPUT_DIRECTION & _DEBUG_OUTPUT_DIRECTION_FILE )
290 fprintf(_DEBUG_PREFIX"%s[F:%-16.16s L:%5d][%s:%s] ",time_string , pFileName, debug_msg->nline , szCategory[debug_msg->category], level );
297 \r if ( G_UNLIKELY(debug_msg->msg_level == DBG_MSG_FATAL) )
301 _custom_err_trace_fvprintf(pFileName, debug_msg->nline, msg, va); // Save to file.
309 #ifdef FMRADIO_FEATURE_ENABLE_GSTREAMER_LOGGING
312 DEBUG_COLOR_DEFAULT = 0,
313 DEBUG_COLOR_BLACK = 30,
314 DEBUG_COLOR_RED = 31,
315 DEBUG_COLOR_GREEN = 32,
316 DEBUG_COLOR_YELLOW = 33,
317 DEBUG_COLOR_BLUE = 34,
318 DEBUG_COLOR_MAGENTA = 35,
319 DEBUG_COLOR_CYAN = 36,
320 DEBUG_COLOR_WHITE = 37,
323 static gchar *custom_print_object(GObject *object)
327 return g_strdup("Unknown");
330 if (*(GType *) ptr == GST_TYPE_CAPS)
332 return gst_caps_to_string((GstCaps *) ptr);
335 if (*(GType *) ptr == GST_TYPE_STRUCTURE)
337 return gst_structure_to_string((GstStructure *) ptr);
340 if (GST_IS_PAD(object))
342 return g_strdup_printf("%s:%s", GST_STR_NULL( GST_OBJECT_NAME( GST_PAD_PARENT(object))) , GST_STR_NULL( GST_PAD_NAME(object) ));
345 if (GST_IS_ELEMENT(object))
347 return g_strdup_printf("%s", GST_STR_NULL(GST_ELEMENT_NAME(object)));
350 if (G_IS_OBJECT(object))
352 return g_strdup_printf("%s(0x%0x)", G_OBJECT_TYPE_NAME(object), object);
355 return g_strdup_printf("0x%08x", object);
358 void custom_log_func(GstDebugCategory *category, GstDebugLevel level,
359 const gchar *file, const gchar *function, gint line,
360 GObject *object, GstDebugMessage *message, gpointer unused)
362 static const char *szLevel[] = {"LOW", "MED", "HIGH", "WARN", "ERROR", "FATAL"};
364 static const gint levelcolor[] = {
365 DEBUG_COLOR_DEFAULT, /* GST_LEVEL_NONE */
366 DEBUG_COLOR_RED, /* GST_LEVEL_ERROR */
367 DEBUG_COLOR_YELLOW, /* GST_LEVEL_WARNING */
368 DEBUG_COLOR_GREEN, /* GST_LEVEL_INFO */
369 DEBUG_COLOR_CYAN, /* GST_LEVEL_DEBUG */
370 DEBUG_COLOR_WHITE, /* GST_LEVEL_LOG */
373 if (level > gst_debug_category_get_threshold(category))
376 gchar *obj = custom_print_object(object);
378 #define DIRECORY_SPLITTER '/'
380 const char*pFileName = NULL;
382 pFileName = strrchr(file, DIRECORY_SPLITTER);
383 pFileName = (NULL == pFileName) ? file:(pFileName+1);
386 char *time_string = get_time_string(get_sys_elapsed_time());
388 log_print_rel(LOG_CAMCORDER,LOG_CLASS_ERR,
389 _DEBUG_PREFIX "%s[F:%-16.16s L:%5d][%s][%s][%s] %s\n", time_string, pFileName, line,
390 gst_debug_category_get_name(category), gst_debug_level_get_name(level),obj,
391 gst_debug_message_get(message));
397 #endif // FMRADIO_FEATURE_ENABLE_GSTREAMER_LOGGING