轻量级c语言开源日记库log.c先容 - 实现差异级别和参数化日记打印 ...

打印 上一主题 下一主题

主题 844|帖子 844|积分 2532

媒介



  • c语言没有现成的日记库,如果要记载日记,必要自己封装一个日记库。如果要实现日记级别和参数打印,照旧比力贫苦的,正好在github找到了一个c语言开源日记库,可以实现日记级别打印,参数打印,而且还会记载日期和行号,最重要的是代码非常少,只有100多行,可以直接包罗在我们自己的工程代码中,不必要任何依赖。
源码地点



  • github源码连接
使用先容



  • 直接把工程目录下的log.c和log.h下载下来,包罗到工程代码中即可,没有其他依赖。
  • 日记级别由低到高,分别为 LOG_TRACE、LOG_DEBUG、LOG_INFO、LOG_WARN、LOG_ERROR、LOG_FATAL
  • 如果设置日记级别为LOG_TRACE,则所有级别日记都会打印,如果设置日记级别为LOG_WARN,则只会打印LOG_WARN以及更高级别(即LOG_ERROR和LOG_FATAL)的日记
演示



  • 测试代码

      1.   #include "log.h"
      2.   #include <stdio.h>
      3.   int main() {
      4.       FILE *fp = fopen("log.txt", "a+");
      5.       if(fp == NULL){
      6.               printf("create log file failed.\n");
      7.               return -1;
      8.       }
      9.       //设置日志级别(在终端打印)
      10.       log_set_level(LOG_TRACE);
      11.       //设置日志级别(在文件中打印)
      12.       log_add_fp(fp, LOG_INFO);
      13.       log_trace("start trace.");
      14.       log_debug("start debug.");
      15.       log_info("start info.");
      16.       log_warn("start warn.");
      17.       log_error("start error.");
      18.       log_fatal("start fatal");
      19.       // 支持参数打印
      20.       log_info("number is %d, string is %s", 10010, "helloword");
      21.       fclose(fp);
      22.   }
      复制代码

  • 演示效果

源码



  • 如果访问github有题目,我把源码贴到下面了。
  • log.h

      1.   #ifndef LOG_H
      2.   #define LOG_H
      3.   #include <stdio.h>
      4.   #include <stdarg.h>
      5.   #include <stdbool.h>
      6.   #include <time.h>
      7.   #define LOG_VERSION "0.1.0"
      8.   typedef struct {
      9.       va_list ap;
      10.       const char *fmt;
      11.       const char *file;
      12.       struct tm *time;
      13.       void *udata;
      14.       int line;
      15.       int level;
      16.   } log_Event;
      17.   typedef void (*log_LogFn)(log_Event *ev);
      18.   typedef void (*log_LockFn)(bool lock, void *udata);
      19.   enum { LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL };
      20.   #define log_trace(...) log_log(LOG_TRACE, __FILE__, __LINE__, __VA_ARGS__)
      21.   #define log_debug(...) log_log(LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
      22.   #define log_info(...)  log_log(LOG_INFO,  __FILE__, __LINE__, __VA_ARGS__)
      23.   #define log_warn(...)  log_log(LOG_WARN,  __FILE__, __LINE__, __VA_ARGS__)
      24.   #define log_error(...) log_log(LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
      25.   #define log_fatal(...) log_log(LOG_FATAL, __FILE__, __LINE__, __VA_ARGS__)
      26.   const char* log_level_string(int level);
      27.   void log_set_lock(log_LockFn fn, void *udata);
      28.   void log_set_level(int level);
      29.   void log_set_quiet(bool enable);
      30.   int log_add_callback(log_LogFn fn, void *udata, int level);
      31.   int log_add_fp(FILE *fp, int level);
      32.   void log_log(int level, const char *file, int line, const char *fmt, ...);
      33.   #endif
      复制代码

  • log.c

      1.   #include "log.h"
      2.   #define MAX_CALLBACKS 32
      3.   typedef struct {
      4.       log_LogFn fn;
      5.       void *udata;
      6.       int level;
      7.   } Callback;
      8.   static struct {
      9.       void *udata;
      10.       log_LockFn lock;
      11.       int level;
      12.       bool quiet;
      13.       Callback callbacks[MAX_CALLBACKS];
      14.   } L;
      15.   static const char *level_strings[] = {"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
      16.   #ifdef LOG_USE_COLOR
      17.   static const char *level_colors[] = {"\x1b[94m", "\x1b[36m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[35m"};
      18.   #endif
      19.   static void stdout_callback(log_Event *ev) {
      20.       char buf[16];
      21.       buf[strftime(buf, sizeof(buf), "%H:%M:%S", ev->time)] = '\0';
      22.       #ifdef LOG_USE_COLOR
      23.           fprintf(ev->udata, "%s %s%-5s\x1b[0m \x1b[90m%s:%d:\x1b[0m ", buf, level_colors[ev->level], level_strings[ev->level], ev->file, ev->line);
      24.       #else
      25.           fprintf(ev->udata, "%s %-5s %s:%d: ", buf, level_strings[ev->level], ev->file, ev->line);
      26.       #endif
      27.       vfprintf(ev->udata, ev->fmt, ev->ap);
      28.       fprintf(ev->udata, "\n");
      29.       fflush(ev->udata);
      30.   }
      31.   static void file_callback(log_Event *ev) {
      32.       char buf[64];
      33.       buf[strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", ev->time)] = '\0';
      34.       fprintf(ev->udata, "%s %-5s %s:%d: ", buf, level_strings[ev->level], ev->file, ev->line);
      35.       vfprintf(ev->udata, ev->fmt, ev->ap);
      36.       fprintf(ev->udata, "\n");
      37.       fflush(ev->udata);
      38.   }
      39.   static void lock(void)   {
      40.       if (L.lock) {
      41.           L.lock(true, L.udata);
      42.       }
      43.   }
      44.   static void unlock(void) {
      45.       if (L.lock) {
      46.           L.lock(false, L.udata);
      47.       }
      48.   }
      49.   const char* log_level_string(int level) {
      50.       return level_strings[level];
      51.   }
      52.   void log_set_lock(log_LockFn fn, void *udata) {
      53.       L.lock = fn;
      54.       L.udata = udata;
      55.   }
      56.   void log_set_level(int level) {
      57.       L.level = level;
      58.   }
      59.   void log_set_quiet(bool enable) {
      60.       L.quiet = enable;
      61.   }
      62.   int log_add_callback(log_LogFn fn, void *udata, int level) {
      63.       for (int i = 0; i < MAX_CALLBACKS; i++) {
      64.           if (!L.callbacks[i].fn) {
      65.               L.callbacks[i] = (Callback) { fn, udata, level };
      66.               return 0;
      67.           }
      68.       }
      69.       return -1;
      70.   }
      71.   int log_add_fp(FILE *fp, int level) {
      72.       return log_add_callback(file_callback, fp, level);
      73.   }
      74.   static void init_event(log_Event *ev, void *udata) {
      75.       if (!ev->time) {
      76.           time_t t = time(NULL);
      77.           ev->time = localtime(&t);
      78.       }
      79.       ev->udata = udata;
      80.   }
      81.   void log_log(int level, const char *file, int line, const char *fmt, ...) {
      82.       log_Event ev = {
      83.           .fmt   = fmt,
      84.           .file  = file,
      85.           .line  = line,
      86.           .level = level,
      87.       };
      88.       lock();
      89.       if (!L.quiet && level >= L.level) {
      90.           init_event(&ev, stderr);
      91.           va_start(ev.ap, fmt);
      92.           stdout_callback(&ev);
      93.           va_end(ev.ap);
      94.       }
      95.       for (int i = 0; i < MAX_CALLBACKS && L.callbacks[i].fn; i++) {
      96.           Callback *cb = &L.callbacks[i];
      97.           if (level >= cb->level) {
      98.               init_event(&ev, cb->udata);
      99.               va_start(ev.ap, fmt);
      100.               cb->fn(&ev);
      101.               va_end(ev.ap);
      102.           }
      103.       }
      104.       unlock();
      105.   }
      复制代码

  • windows平台编译时有报错,结构体赋值语法不支持,我做了修改。
  • 修改后的 log.c

      1. #include "log.h"
      2. #define MAX_CALLBACKS 32
      3. typedef struct {
      4.      log_LogFn fn;
      5.      void *udata;
      6.      int level;
      7. } Callback;
      8. static struct {
      9.      void *udata;
      10.      log_LockFn lock;
      11.      int level;
      12.      bool quiet;
      13.      Callback callbacks[MAX_CALLBACKS];
      14. } L;
      15. static const char *level_strings[] = {"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
      16. #ifdef LOG_USE_COLOR
      17. static const char *level_colors[] = {"\x1b[94m", "\x1b[36m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[35m"};
      18. #endif
      19. static void stdout_callback(log_Event *ev) {
      20.      char buf[100] = {0};
      21.      time_t timep;
      22.      time(&timep);
      23.      struct tm *pt = gmtime(&timep);
      24.      sprintf(buf, "%d-%02d-%02d %02d:%02d:%02d", 1900 + pt->tm_year, 1 + pt->tm_mon, pt->tm_mday, (8 + pt->tm_hour) % 24, pt->tm_min, pt->tm_sec);
      25. #ifdef LOG_USE_COLOR
      26.      fprintf((FILE *)ev->udata, "%s %s%-5s\x1b[0m \x1b[90m%s:%d:\x1b[0m ", buf, level_colors[ev->level], level_strings[ev->level], ev->file, ev->line);
      27. #else
      28.      fprintf((FILE *)ev->udata, "%s %-5s %s:%d: ", buf, level_strings[ev->level], ev->file, ev->line);
      29. #endif
      30.      vfprintf((FILE *)ev->udata, ev->fmt, ev->ap);
      31.      fprintf((FILE *)ev->udata, "\n");
      32.      fflush((FILE *)ev->udata);
      33. }
      34. static void file_callback(log_Event *ev) {
      35.      char buf[100] = {0};
      36.      time_t timep;
      37.      time(&timep);
      38.      struct tm *pt = gmtime(&timep);
      39.      sprintf(buf, "%d-%02d-%02d %02d:%02d:%02d", 1900 + pt->tm_year, 1 + pt->tm_mon, pt->tm_mday, (8 + pt->tm_hour) % 24, pt->tm_min, pt->tm_sec);
      40.      fprintf((FILE *)ev->udata, "%s %-5s %s:%d: ", buf, level_strings[ev->level], ev->file, ev->line);
      41.      vfprintf((FILE *)ev->udata, ev->fmt, ev->ap);
      42.      fprintf((FILE *)ev->udata, "\n");
      43.      fflush((FILE *)ev->udata);
      44. }
      45. static void lock(void) {
      46.      if (L.lock) {
      47.          L.lock(true, L.udata);
      48.      }
      49. }
      50. static void unlock(void) {
      51.      if (L.lock) {
      52.          L.lock(false, L.udata);
      53.      }
      54. }
      55. const char *log_level_string(int level) { return level_strings[level]; }
      56. void log_set_lock(log_LockFn fn, void *udata) {
      57.      L.lock = fn;
      58.      L.udata = udata;
      59. }
      60. void log_set_level(int level) { L.level = level; }
      61. void log_set_quiet(bool enable) { L.quiet = enable; }
      62. int log_add_callback(log_LogFn fn, void *udata, int level) {
      63.      for (int i = 0; i < MAX_CALLBACKS; i++) {
      64.          if (!L.callbacks[i].fn) {
      65.              L.callbacks[i].fn = fn;
      66.              L.callbacks[i].udata = udata;
      67.              L.callbacks[i].level = level;
      68.              return 0;
      69.          }
      70.      }
      71.      return -1;
      72. }
      73. int log_add_fp(FILE *fp, int level) { return log_add_callback(file_callback, fp, level); }
      74. static void init_event(log_Event *ev, void *udata) {
      75.      if (!ev->time) {
      76.          time_t t = time(NULL);
      77.          ev->time = gmtime(&t);
      78.      }
      79.      ev->udata = udata;
      80. }
      81. void log_log(int level, const char *file, int line, const char *fmt, ...) {
      82.      log_Event ev;
      83.      ev.fmt = fmt;
      84.      ev.file = file;
      85.      ev.line = line;
      86.      ev.level = level;
      87.      lock();
      88.      if (!L.quiet && level >= L.level) {
      89.          init_event(&ev, stderr);
      90.          va_start(ev.ap, fmt);
      91.          stdout_callback(&ev);
      92.          va_end(ev.ap);
      93.      }
      94.      for (int i = 0; i < MAX_CALLBACKS && L.callbacks[i].fn; i++) {
      95.          Callback *cb = &L.callbacks[i];
      96.          if (level >= cb->level) {
      97.              init_event(&ev, cb->udata);
      98.              va_start(ev.ap, fmt);
      99.              cb->fn(&ev);
      100.              va_end(ev.ap);
      101.          }
      102.      }
      103.      unlock();
      104. }
      复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

八卦阵

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表