src/shared/log.c
changeset 0 cff7fac35cc2
child 62 959daee41c03
equal deleted inserted replaced
-1:000000000000 0:cff7fac35cc2
       
     1 #include "log.h"
       
     2 
       
     3 #include <stdio.h>
       
     4 #include <stdarg.h>
       
     5 #include <string.h>
       
     6 #include <stdlib.h>
       
     7 #include <errno.h>
       
     8 
       
     9 /**
       
    10  * The global log level
       
    11  */
       
    12 static enum log_level _log_level = LOG_LEVEL_DEFAULT;
       
    13 
       
    14 /**
       
    15  * List of log level names
       
    16  */
       
    17 const char *log_level_names[] = {
       
    18     "DEBUG",
       
    19     "INFO",
       
    20     "WARN",
       
    21     "ERROR",
       
    22     "FATAL",
       
    23     NULL
       
    24 };
       
    25 
       
    26 #define _LOG_LEVEL_NAME(ll) case LOG_ ## ll: return #ll;
       
    27 const char *log_level_name (enum log_level level)
       
    28 {
       
    29     switch (level) {
       
    30         _LOG_LEVEL_NAME(DEBUG)
       
    31         _LOG_LEVEL_NAME(INFO)
       
    32         _LOG_LEVEL_NAME(WARN)
       
    33         _LOG_LEVEL_NAME(ERROR)
       
    34         _LOG_LEVEL_NAME(FATAL)
       
    35         default: return "???";
       
    36     }
       
    37 }
       
    38 #undef _LOG_LEVEL_NAME
       
    39 
       
    40 void set_log_level (enum log_level level)
       
    41 {
       
    42     // meep meep
       
    43     _log_level = level;
       
    44 }
       
    45 
       
    46 size_t str_append_fmt_va (char *buf_ptr, size_t *buf_size, const char *fmt, va_list args)
       
    47 {
       
    48     int ret;
       
    49 
       
    50     if (*buf_size && (ret = vsnprintf(buf_ptr, *buf_size, fmt, args)) < 0)
       
    51         return 0;
       
    52 
       
    53     if (ret > *buf_size)
       
    54         *buf_size = 0;
       
    55 
       
    56     else
       
    57         *buf_size -= ret;
       
    58 
       
    59     return ret;
       
    60 }
       
    61 
       
    62 size_t str_append_fmt (char *buf_ptr, size_t *buf_size, const char *fmt, ...)
       
    63 {
       
    64     va_list vargs;
       
    65     size_t ret;
       
    66     
       
    67     va_start(vargs, fmt);
       
    68     ret = str_append_fmt_va(buf_ptr, buf_size, fmt, vargs);
       
    69     va_end(vargs);
       
    70 
       
    71     return ret;
       
    72 }
       
    73 
       
    74 void log_output_tag_va (enum log_level level, const char *tag, const char *func, const char *user_fmt, va_list user_fmtargs, const char *log_fmt, va_list log_fmtargs)
       
    75 {
       
    76     char buf[LOG_MSG_MAX], *buf_ptr = buf;
       
    77     size_t buf_size = sizeof(buf);
       
    78 
       
    79     // filter out?
       
    80     if (level < _log_level)
       
    81         return;
       
    82 
       
    83     buf_ptr += str_append_fmt(buf_ptr, &buf_size, "[%5s] %20s : ", tag, func);
       
    84 
       
    85     // output the user data
       
    86     if (user_fmt)
       
    87         buf_ptr += str_append_fmt_va(buf_ptr, &buf_size, user_fmt, user_fmtargs);
       
    88     
       
    89     // output the suffix
       
    90     if (log_fmt)
       
    91         buf_ptr += str_append_fmt_va(buf_ptr, &buf_size, log_fmt, log_fmtargs);
       
    92 
       
    93     // display
       
    94     // XXX: handle SIGINTR?
       
    95     fprintf(stderr, "%s\n", buf);
       
    96 }
       
    97 
       
    98 void log_output_tag (enum log_level level, const char *tag, const char *func, const char *user_fmt, va_list user_fmtargs, const char *log_fmt, ...)
       
    99 {
       
   100     va_list vargs;
       
   101 
       
   102     va_start(vargs, log_fmt);
       
   103     log_output_tag_va(level, tag, func, user_fmt, user_fmtargs, log_fmt, vargs);
       
   104     va_end(vargs);
       
   105 }
       
   106 
       
   107 void _log_msg (enum log_level level, const char *func, const char *format, ...)
       
   108 {
       
   109     va_list vargs;
       
   110     
       
   111     // formatted output: no suffix
       
   112     va_start(vargs, format);
       
   113     log_output_tag(level, log_level_name(level), func, format, vargs, NULL);
       
   114     va_end(vargs);
       
   115 }
       
   116 
       
   117 void _log_msg_va2 (enum log_level level, const char *func, const char *fmt1, va_list fmtargs1, const char *fmt2, va_list fmtargs2)
       
   118 {
       
   119     log_output_tag_va(level, log_level_name(level), func, fmt1, fmtargs1, fmt2, fmtargs2);
       
   120 }
       
   121 
       
   122 void _log_errno (enum log_level level, const char *func, const char *format, ...)
       
   123 {
       
   124     va_list vargs;
       
   125 
       
   126     // formatted output: suffix strerror()
       
   127     va_start(vargs, format);
       
   128     log_output_tag(level, log_level_name(level), func, format, vargs, ": %s", strerror(errno));
       
   129     va_end(vargs);
       
   130 }
       
   131 
       
   132 void _log_exit (enum log_level level, int exit_code, const char *func, const char *format, ...)
       
   133 {
       
   134     va_list vargs;
       
   135 
       
   136     // formatted output without any suffix
       
   137     va_start(vargs, format);
       
   138     log_output_tag(level, "EXIT", func, format, vargs, NULL);
       
   139     va_end(vargs);
       
   140 
       
   141     // exit
       
   142     exit(exit_code);
       
   143 }
       
   144