简单的C/C++日志模块实现

诸如log4cxx之类的日志库还是有些复杂,自己实现了一个简单的日志模块。

支持文件设置、日志级别、非原子打印,还附加了常用的线程锁相关宏,如下:

sys_logger.h

  1 #ifndef __sys_logger_h_
  2 #define __sys_logger_h_
  3
  4 #include <stdio.h>
  5 #include <iostream>
  6 #include <cstring>
  7 #include <stdarg.h>
  8 #include <time.h>
  9 #include <unistd.h>
 10 #include <pthread.h>
 11 #include <sys/time.h>
 12 #include <sys/syscall.h>
 13
 14 #define gettid() syscall(SYS_gettid)
 15
 16 #define LEVEL_SOCKET_DEBUG  0
 17 #define LEVEL_DEBUG         1
 18 #define LEVEL_INFO          2
 19 #define LEVEL_WARNING       3
 20 #define LEVEL_ERROR         4
 21
 22 #define LOG_BUF_SIZE        2048
 23 #define MAX_FILENAME_LEN    256
 24
 25
 26 using namespace std;
 27
 28 #define LOG_INFO_NOLOCK(format, ...)  29     SysLogger::GetInstance()->WriteLogNoLock(LEVEL_INFO,  30                                         __FILE__, __LINE__, gettid(),  31                                         format, ##__VA_ARGS__)
 32
 33 #define SOCKET_DEBUG(format, ...)  34     SysLogger::GetInstance()->WriteLog(LEVEL_SOCKET_DEBUG,  35                                         __FILE__, __LINE__, gettid(),  36                                         format, ##__VA_ARGS__)
 37
 38 #define LOG_DEBUG(format, ...)  39     SysLogger::GetInstance()->WriteLog(LEVEL_DEBUG,  40                                         __FILE__, __LINE__, gettid(),  41                                         format, ##__VA_ARGS__)
 42
 43 #define LOG_INFO(format, ...)  44     SysLogger::GetInstance()->WriteLog(LEVEL_INFO,  45                                         __FILE__, __LINE__, gettid(),  46                                         format, ##__VA_ARGS__)
 47
 48 #define LOG_WARNING(format, ...)  49     SysLogger::GetInstance()->WriteLog(LEVEL_WARNING,  50                                         __FILE__, __LINE__, gettid(),  51                                         format, ##__VA_ARGS__)
 52
 53 #define LOG_ERROR(format, ...)  54     SysLogger::GetInstance()->WriteLog(LEVEL_ERROR,  55                                         __FILE__, __LINE__, gettid(),  56                                         format, ##__VA_ARGS__)
 57
 58 // Pthread trylock, lock, unlock
 59 #define MUTEX_LOCK(mutex) {int oldstate; 60             pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); 61             pthread_mutex_lock(mutex); 62             pthread_setcancelstate(oldstate, NULL); 63 }
 64
 65 #define MUTEX_UNLOCK(mutex) {int oldstate; 66             pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); 67             pthread_mutex_unlock(mutex); 68             pthread_setcancelstate(oldstate, NULL); 69 }
 70
 71 inline int MutexTryLock(pthread_mutex_t* mutex)
 72 {
 73     int ret = 0;
 74     int oldstate;
 75     pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
 76     ret = pthread_mutex_trylock(mutex);
 77     pthread_setcancelstate(oldstate, NULL);
 78     return ret;
 79 }
 80
 81 inline void MutexLock(pthread_mutex_t* mutex)
 82 {
 83     int oldstate;
 84     pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
 85     pthread_mutex_lock(mutex);
 86     pthread_setcancelstate(oldstate, NULL);
 87 }
 88
 89 inline void MutexUnlock(pthread_mutex_t* mutex)
 90 {
 91     int oldstate;
 92     pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
 93     pthread_mutex_unlock(mutex);
 94     pthread_setcancelstate(oldstate, NULL);
 95 }
 96
 97 class SysLogger
 98 {
 99 public:
100     SysLogger();
101     ~SysLogger();
102
103     static SysLogger* GetInstance();
104
105     bool InitLogger(const char* file_name, int min_level);
106     void WriteLog(int level, const char* exec_file, int exec_line, int tid, const char* format, ...);
107     void WriteLogNoLock(int level, const char* exec_file, int exec_line, int tid, const char* format, ...);
108
109 private:
110     void set_log(int level, const char* exec_file, int exec_line, int tid, const char* format, va_list valst);
111
112 public:
113     static SysLogger*   instance_;
114
115 private:
116     int     min_level_;
117     char*   log_file_;
118     char*   log_buf_;
119     FILE*   log_fp_;
120     pthread_mutex_t*    mutex_;
121 };
122
123 #endif

sys_logger.cpp

  1 #include "sys_logger.h"
  2
  3 SysLogger* SysLogger::instance_ = NULL;
  4
  5 SysLogger* SysLogger::GetInstance()
  6 {
  7     if (instance_ == NULL) {
  8         instance_ = new SysLogger();
  9     }
 10
 11     return instance_;
 12 }
 13
 14 SysLogger::SysLogger()
 15 {
 16     min_level_ = 0;
 17     log_fp_ = NULL;
 18     log_file_ = new char[MAX_FILENAME_LEN];
 19     memset(log_file_, 0, MAX_FILENAME_LEN);
 20     log_buf_ = new char[LOG_BUF_SIZE];
 21     mutex_ = new pthread_mutex_t;
 22     pthread_mutex_init(mutex_, NULL);
 23 }
 24
 25 SysLogger::~SysLogger()
 26 {
 27     if (log_file_ != NULL) {
 28         delete[] log_file_;
 29         log_file_ = NULL;
 30     }
 31
 32     if (log_buf_ != NULL) {
 33         delete[] log_buf_;
 34         log_buf_ = NULL;
 35     }
 36
 37     if (log_fp_ != NULL) {
 38         fclose(log_fp_);
 39         log_fp_ = NULL;
 40     }
 41
 42     pthread_mutex_destroy(mutex_);
 43
 44     if (mutex_ != NULL) {
 45         delete mutex_;
 46     }
 47 }
 48
 49 bool SysLogger::InitLogger(const char* file_name, int min_level)
 50 {
 51     strncpy(log_file_, file_name, MAX_FILENAME_LEN - 1);
 52
 53     if (min_level >=0 && min_level <= 4) {
 54         min_level_ = min_level;
 55     }
 56
 57     log_fp_ = fopen(log_file_, "a");
 58
 59     if (log_fp_ == NULL) {
 60         return false;
 61     }
 62
 63     return true;
 64 }
 65
 66 void SysLogger::WriteLog(int level, const char* exec_file, int exec_line, int tid, const char* format, ...)
 67 {
 68     if (level < min_level_) {
 69         return;
 70     }
 71
 72     pthread_mutex_lock(mutex_);
 73     va_list valst;
 74     va_start(valst, format);
 75     set_log(level, exec_file, exec_line, tid, format, valst);
 76     va_end(valst);
 77
 78     fputs(log_buf_, log_fp_);
 79     fflush(log_fp_);
 80
 81     // if (log_fp_ != NULL) {
 82         // fclose(log_fp_);
 83         // log_fp_ = NULL;
 84     // }
 85
 86     pthread_mutex_unlock(mutex_);
 87 }
 88
 89 // Used for mod exit
 90 void SysLogger::WriteLogNoLock(int level, const char* exec_file, int exec_line, int tid, const char* format, ...)
 91 {
 92     if (level < min_level_) {
 93         return;
 94     }
 95
 96     va_list valst;
 97     va_start(valst, format);
 98     set_log(level, exec_file, exec_line, tid, format, valst);
 99     va_end(valst);
100     fputs(log_buf_, log_fp_);
101     fflush(log_fp_);
102
103     // if (log_fp_ != NULL) {
104         // fclose(log_fp_);
105         // log_fp_ = NULL;
106     // }
107 }
108
109 void SysLogger::set_log(int level, const char* exec_file, int exec_line, int tid, const char* format, va_list valst)
110 {
111     char exec_filename[MAX_FILENAME_LEN];
112     memset(exec_filename, 0, MAX_FILENAME_LEN);
113     const char* pch = strrchr(exec_file, ‘/‘);
114
115     if (pch == NULL) {
116         strncpy(exec_filename, exec_file, MAX_FILENAME_LEN - 1);
117     } else {
118         strncpy(exec_filename, pch + 1, MAX_FILENAME_LEN - 1);
119     }
120
121     char levstr[16];
122     memset(levstr, 0, 16);
123
124     switch (level) {
125         case LEVEL_SOCKET_DEBUG:
126         case LEVEL_DEBUG:
127             strcpy(levstr, "DEBUG");
128             break;
129         case LEVEL_INFO:
130             strcpy(levstr, "INFO");
131             break;
132         case LEVEL_WARNING:
133             strcpy(levstr, "WARN");
134             break;
135         case LEVEL_ERROR:
136             strcpy(levstr, "ERROR");
137             break;
138         default:
139             strcpy(levstr, "INFO");
140             break;
141     }
142
143     if (log_fp_ == NULL) {
144         log_fp_ = fopen(log_file_, "a");
145     }
146
147     memset(log_buf_, 0, LOG_BUF_SIZE);
148     struct timeval now = {0, 0};
149     gettimeofday(&now, NULL);
150     struct tm* sys_tm = localtime(&(now.tv_sec));
151
152     int n = snprintf(log_buf_, 128, "\n%d-%02d-%02d %02d:%02d:%02d,%03d <%s> [%s:%d] [%d] ",
153                         sys_tm->tm_year + 1900, sys_tm->tm_mon + 1, sys_tm->tm_mday,
154                         sys_tm->tm_hour, sys_tm->tm_min, sys_tm->tm_sec, now.tv_usec / 1000,
155                         levstr, exec_filename, exec_line, tid);
156     vsnprintf(log_buf_ + n, LOG_BUF_SIZE - n, format, valst);
157 }
时间: 2024-10-11 00:22:05

简单的C/C++日志模块实现的相关文章

简单的C/C++日志模块

诸如log4cxx之类的日志库还是有些复杂,自己实现了一个简单的日志模块,如下: 1 #ifndef __sys_logger_h_ 2 #define __sys_logger_h_ 3 4 #include <stdio.h> 5 #include <iostream> 6 #include <cstring> 7 #include <stdarg.h> 8 #include <time.h> 9 #include <unistd.h&

python日志模块-logging

日志模块 logging logging模块主要可以根据自定义日志信息,在程序运行的时候将日志打印在终端及记录日志到文件中.在这先了解一下logging支持的日志五个级别 debug() 调试级别,一般用于记录程序运行的详细信息 info() 事件级别,一般用于记录程序的运行过程 warnning() 警告级别,,一般用于记录程序出现潜在错误的情形 error() 错误级别,一般用于记录程序出现错误,但不影响整体运行 critical 严重错误级别 , 出现该错误已经影响到整体运行 简单用法,将

python 全栈 python基础 (二十一)logging日志模块 json序列化 正则表达式(re)

一.日志模块 两种配置方式:1.config函数 2.logger #1.config函数 不能输出到屏幕 #2.logger对象 (获取别人的信息,需要两个数据流:文件流和屏幕流需要将数据从两个数据流中接收) 1.函数式简单配置 import logging logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error mes

ns3 Tutorial 中的日志模块(翻译)

转载地址:http://blog.sina.com.cn/s/blog_8ecca79b0101d7fe.html 1  日志模块的使用 在运行 first.cc 脚本时,我们已经简单了解了日志模块.现在,我们将更深入地了解日志子系统是为哪些用户案例设计的. 1.1 日志概述 很多大型系统支持某种消息记录功能,ns3 也不例外.在某些情况下,只有错误消息会被记录到操作控制台(在基于 Unix 的系统中通常是标准错误输出).在其他系统中,警告消息可能跟详细的信息消息一起被输出.在某些情况下,日志功

python的logging日志模块(一)

最近修改了项目里的logging相关功能,用到了Python标准库里的logging模块,在此做一些记录.主要是从官方文档和stackoverflow上查询到的一些内容. 官方文档 技术博客 基本用法 下面的代码展示了logging最基本的用法. # -*- coding: utf-8 -*- import logging import sys # 获取logger实例,如果参数为空则返回root logger logger = logging.getLogger("AppName")

搭建一套自己实用的.net架构(2)【日志模块-log4net】

先谈谈简单的模块,日志.在系统中日志模块是必须的,什么系统日志,操作日志,调试日志.这里用的是log4net. 对log4net还不熟悉的小伙伴们赶快去搜索基础教程哦, 我这里就不温故了. 那么有人要问了,log4net确实很强大,而且我们也会用.还要单独写一篇文章来介绍,有必要吗? 我简单的举两个场景: 1:log4net写入DB 还需要在 log4net中配置数据库连接字符串,   我想log4net 和 我的 connectionStrings 用1个配置不行吗? 2:log4net写入参

Python入门之logging日志模块以及多进程日志

本篇文章主要对 python logging 的介绍加深理解.更主要是 讨论在多进程环境下如何使用logging 来输出日志, 如何安全地切分日志文件. 1. logging日志模块介绍 python的logging模块提供了灵活的标准模块,使得任何Python程序都可以使用这个第三方模块来实现日志记录.python logging 官方文档 logging框架中主要由四个部分组成: Loggers: 可供程序直接调用的接口 Handlers: 决定将日志记录分配至正确的目的地 Filters:

Python 全栈开发八 日志模块

日志是一种可以追踪某些软件运行时所发生事件的方法.软件开发人员可以向他们的代码中调用日志记录相关的方法来表明发生了某些事情.一个事件可以用一个可包含可选变量数据的消息来描述.此外,事件也有重要性的概念,这个重要性也可以被称为严重性级别(level). 1.日志的作用 通过log的分析,可以方便用户了解系统或软件.应用的运行情况:如果你的应用log足够丰富,也可以分析以往用户的操作行为.类型喜好.地域分布或其他更多信息:如果一个应用的log同时也分了多个级别,那么可以很轻易地分析得到该应用的健康状

日志模块

日志模块:logging模块 很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,logging的日志可以分为 debug(), info(), warning(), error() and critical() 5个级别,下面我们看一下怎么用. 最简单的用法 import logging logging.warn("content...") logg