src/lib/log.c
branchnew-lib-errors
changeset 217 7728d6ec3abf
parent 216 a10ba529ae39
child 218 5229a5d098b2
equal deleted inserted replaced
216:a10ba529ae39 217:7728d6ec3abf
       
     1 
       
     2 #include "log.h"
       
     3 #include "str.h"
       
     4 
       
     5 #include <stdio.h>
       
     6 #include <stdarg.h>
       
     7 #include <string.h>
       
     8 
       
     9 /**
       
    10  * The default log output func
       
    11  */
       
    12 void log_default_func (const char *line, void *arg)
       
    13 {
       
    14     (void) arg;
       
    15 
       
    16     // display
       
    17     printf("%s\n", line);
       
    18 }
       
    19 
       
    20 /**
       
    21  * The global log level
       
    22  */
       
    23 static enum log_level _log_level = LOG_LEVEL_DEFAULT;
       
    24 
       
    25 /**
       
    26  * The global log output func
       
    27  */
       
    28 static struct log_output_ctx {
       
    29     /** The function itself */
       
    30     log_output_func func;
       
    31 
       
    32     /** The arg */
       
    33     void *arg;
       
    34 } _log_output_ctx = { log_default_func, NULL };
       
    35 
       
    36 /**
       
    37  * List of log level names
       
    38  */
       
    39 const char *log_level_names[] = {
       
    40     "DEBUG",
       
    41     "INFO",
       
    42     "WARN",
       
    43     "ERROR",
       
    44     "FATAL",
       
    45     NULL
       
    46 };
       
    47 
       
    48 #define _LOG_LEVEL_NAME(ll) case LOG_ ## ll: return #ll;
       
    49 const char *log_level_name (enum log_level level)
       
    50 {
       
    51     switch (level) {
       
    52         _LOG_LEVEL_NAME(DEBUG)
       
    53         _LOG_LEVEL_NAME(INFO)
       
    54         _LOG_LEVEL_NAME(WARN)
       
    55         _LOG_LEVEL_NAME(ERROR)
       
    56         _LOG_LEVEL_NAME(FATAL)
       
    57         default: return "???";
       
    58     }
       
    59 }
       
    60 #undef _LOG_LEVEL_NAME
       
    61 
       
    62 void set_log_level (enum log_level level)
       
    63 {
       
    64     // meep meep
       
    65     _log_level = level;
       
    66 }
       
    67 
       
    68 void log_set_func (log_output_func func, void *arg)
       
    69 {
       
    70     // replace the current one
       
    71     _log_output_ctx.func = func ? func : log_default_func;
       
    72     _log_output_ctx.arg = arg;
       
    73 }
       
    74 
       
    75 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)
       
    76 {
       
    77     char buf[LOG_MSG_MAX], *buf_ptr = buf;
       
    78     size_t buf_size = sizeof(buf);
       
    79 
       
    80     // filter out?
       
    81     if (level < _log_level)
       
    82         return;
       
    83 
       
    84     // output the header
       
    85     buf_ptr += str_advance(NULL, &buf_size, str_append_fmt(buf_ptr, buf_size, "[%5s] %20s : ", tag, func));
       
    86     
       
    87     // output the user data
       
    88     if (user_fmt)
       
    89         buf_ptr += str_advance(NULL, &buf_size, str_append_fmt_va(buf_ptr, buf_size, user_fmt, user_fmtargs));
       
    90     
       
    91     // output the suffix
       
    92     if (log_fmt)
       
    93         buf_ptr += str_advance(NULL, &buf_size, str_append_fmt_va(buf_ptr, buf_size, log_fmt, log_fmtargs));
       
    94 
       
    95     // send it to the output func
       
    96     _log_output_ctx.func(buf, _log_output_ctx.arg);
       
    97 
       
    98 }
       
    99 
       
   100 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, ...)
       
   101 {
       
   102     va_list vargs;
       
   103 
       
   104     va_start(vargs, log_fmt);
       
   105     log_output_tag_va(level, tag, func, user_fmt, user_fmtargs, log_fmt, vargs);
       
   106     va_end(vargs);
       
   107 }
       
   108 
       
   109 void _log_msg (enum log_level level, const char *func, const char *format, ...)
       
   110 {
       
   111     va_list vargs;
       
   112     
       
   113     // formatted output: no suffix
       
   114     va_start(vargs, format);
       
   115     log_output_tag(level, log_level_name(level), func, format, vargs, NULL);
       
   116     va_end(vargs);
       
   117 }
       
   118 
       
   119 void _log_msg_va2 (enum log_level level, const char *func, const char *fmt1, va_list fmtargs1, const char *fmt2, va_list fmtargs2)
       
   120 {
       
   121     log_output_tag_va(level, log_level_name(level), func, fmt1, fmtargs1, fmt2, fmtargs2);
       
   122 }
       
   123 
       
   124 void _log_err (enum log_level level, const struct error_list *list, err_t code, const char *func, const char *format, ...)
       
   125 {
       
   126     va_list vargs;
       
   127 
       
   128     // formatted output: suffix error_name()
       
   129     va_start(vargs, format);
       
   130     log_output_tag(level, log_level_name(level), func, format, vargs, ": %s", error_name(list, code));
       
   131     va_end(vargs);
       
   132 }
       
   133 
       
   134 void _log_error (enum log_level level, const error_t *err, const char *func, const char *format, ...)
       
   135 {
       
   136     va_list vargs;
       
   137 
       
   138     // formatted output: suffix error_msg()
       
   139     va_start(vargs, format);
       
   140     log_output_tag(level, log_level_name(level), func, format, vargs, ": %s", error_msg(err));
       
   141     va_end(vargs);
       
   142 }
       
   143 
       
   144 void _log_perr (enum log_level level, const char *func, const char *format, ...)
       
   145 {
       
   146     va_list vargs;
       
   147 
       
   148     // formatted output: suffix strerror()
       
   149     va_start(vargs, format);
       
   150     log_output_tag(level, log_level_name(level), func, format, vargs, ": %s", strerror(errno));
       
   151     va_end(vargs);
       
   152 }
       
   153 
       
   154 void _log_exit (enum log_level level, int exit_code, const char *func, const char *format, ...)
       
   155 {
       
   156     va_list vargs;
       
   157 
       
   158     // formatted output without any suffix
       
   159     va_start(vargs, format);
       
   160     log_output_tag(level, "EXIT", func, format, vargs, NULL);
       
   161     va_end(vargs);
       
   162 
       
   163     // exit
       
   164     exit(exit_code);
       
   165 }