- 浏览: 718671 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (1042)
- 数据结构 (36)
- UML与设计模式 (42)
- c++ (87)
- rust (36)
- Qt (41)
- boost模板元编程 (43)
- Linux (77)
- 汇编 (4)
- 其它 (2)
- 烹饪 (3)
- unix c / socket (73)
- 软件工程 (4)
- shell (52)
- Python (37)
- c++ primer 5th(c++11) (22)
- 数据库/MySQL (27)
- 数据存储 (4)
- lisp (7)
- git (4)
- Utility (3)
- CDN与DNS (54)
- Http (53)
- php (7)
- nginx/lua/openresty (41)
- redis (11)
- TCP/IP (16)
- 互联网 (6)
- kernel (2)
- go (33)
- 区块链 (43)
- 比特股 (13)
- 以太坊 (23)
- 比特币 (23)
- 密码学 (10)
- EOS (53)
- DAG (1)
- docker (1)
- filecoin (7)
- solidity (64)
- ipfs (8)
- 零知识证明 (1)
- openzeppelin (3)
- java (1)
- defi (7)
最新评论
log.h
log.cpp
main
#ifndef __LOG_H__ #define __LOG_H__ #include <stdio.h> #include <pthread.h> namespace log { #define LOG_MAX_LENGTH 4096 #define FLUSH_LINE 2 #define EMERG 8 // #define ALERT 7 // #define CRIT 6 // #define WARNING 5 // #define ERR 4 //错误 #define NOTICE 3 //注意信息 #define INFO 2 //普通信息 #define DEBUG 1 //调试信息 #define NONE 0 // static const char g_alertStr[128] = "[Alert]:" ;//比warning级别要高,表示系统可能处于异常运行状态,如连接数据库失败,无法正常向数据库进行操作等 static const char g_errorStr[128] = "[Error]:" ;//可以确定是程序上bug,需开发人员检查程序逻辑 static const char g_warningStr[128] = "[Warning]:" ;//虽不是服务器端错误,但需要高度关注 static const char g_infoStr[128] = "[Info]:" ;//一些有用信息,它比普通信息要略高,但可能没有Warning那么严重 static const char g_messageStr[128] = "[Message]:" ;//普通信息 static const char g_sqlStr[128] = "[Sql]:";//数据库操作语句 #ifndef TIME_CHN_FMT #define TIME_CHN_FMT "%Y-%m-%d %H:%M:%S" #endif /* time_t转时间字符串 */ char* timeToString(time_t tmTime, const char *fmt,char *strTime, int len); class CLog { public: //the singleton static CLog* getInstance(); //初始化 int init(const char* path,const char* fileName, short level=DEBUG,unsigned int logFileMaxNum=50,unsigned int logFileMaxSize=10*1024*1024); //关闭 int close(); //写日志 void plog(short level, const char *fmt, ...); private: CLog(); virtual ~CLog(); //检测文件大小是否超过上限 bool fileSizeOverflow(const char *fileName); //创建新文件 void createNewFile(); private: FILE *mFile; //日志文件路径 char mFilePath[1024]; //日志缓冲区 char mLogBuf[LOG_MAX_LENGTH]; //lock pthread_mutex_t mWriteLogLock; //上一条日志重复次数 int mRepeatCount; //当前日志文件大小 unsigned int mCurrLogFileSize; //日志文件大小上限 unsigned int mLogFileMaxSize; //当前的日志级别 int mLogLevel; //是否已关毕 bool mClosed; //日志的最大文件数 unsigned int mLogFileMaxNum; //日志的当前文件数 unsigned int mLogFileCurrNum; }; }//end of namespace log #endif
log.cpp
#include "log.h" #include <iostream> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <stdarg.h> #include <string.h> using std::cout; using std::endl; namespace log { /* 时间转字符串 */ char* timeToString(time_t tmTime, const char *fmt,char *strTime, int len) { struct tm gmTime; localtime_r(&tmTime, &gmTime); strftime(strTime, (size_t) len, fmt, &gmTime); return strTime; } /* the singleton */ CLog* CLog::getInstance() { static CLog log; return &log; } CLog::CLog() { mFile = NULL; mRepeatCount = 0; mCurrLogFileSize = 0; mLogFileMaxSize = 0; mLogFileMaxNum = 0; memset(mLogBuf, 0, sizeof(mLogBuf)); mClosed = false; mLogFileCurrNum = 0; } CLog::~CLog() { close(); } /* 关闭 */ int CLog::close() { if(mClosed){ return -1; } if (mFile) { fflush(mFile); fclose(mFile); } pthread_mutex_destroy(&mWriteLogLock); mClosed = true; return 0; } /* 初始化 */ int CLog::init(const char *path, const char *fileName, short level, unsigned int logFileMaxNum, unsigned int logFileMaxSize) { if (path == NULL || fileName == NULL || logFileMaxNum<1 || level < NONE || logFileMaxSize<1){ return -1; } if(pthread_mutex_init(&mWriteLogLock, NULL)!=0) { pthread_mutex_destroy(&mWriteLogLock); return -1; } mLogFileMaxNum = logFileMaxNum; mLogFileMaxSize = logFileMaxSize; if(access(path,F_OK)<0) { #ifdef _WIN32 mkdir(path); #else mkdir(path,0777); #endif } char fileFullName[256]; memset(fileFullName,0,sizeof(fileFullName)); strcpy(fileFullName,path); strcat(fileFullName,fileName); memset(mFilePath, 0, sizeof(mFilePath)); strncpy(mFilePath, fileFullName, sizeof(mFilePath)-1); //备份老日志,创建新日志。 if(fileSizeOverflow(fileFullName)){ createNewFile(); } mFile = fopen(fileFullName, "a+"); if (mFile == NULL){ return -1; } mLogLevel = level; fprintf(mFile, "\n\n\n\n\n"); fprintf(mFile, "--------------------------------------------------------\n"); fprintf(mFile, " 日志建立日期: %s %s\n", __DATE__, __TIME__); fprintf(mFile, "--------------------------------------------------------\n"); fprintf(mFile, "\n"); fflush(mFile); return 0; } /* 写日志 */ void CLog::plog(short level, const char *fmt, ...) { //与配置文件中的日志级别对比,选择输出日志 if (0 == mLogLevel || level < mLogLevel){ return; } if (NULL == mFile) { mFile = fopen(mFilePath, "a+"); if (NULL == mFile){ return; } mCurrLogFileSize = 0; } pthread_mutex_lock(&mWriteLogLock); static int lastBufLen = 0; static char lastBuf[LOG_MAX_LENGTH]; static int flushCount = 0; time_t t = time(NULL); char timeStr[64]; memset(timeStr,0,sizeof(timeStr)); timeToString(t, TIME_CHN_FMT, timeStr, sizeof(timeStr)-1); char printf_buf[LOG_MAX_LENGTH]; memset(printf_buf,0,sizeof(printf_buf)); va_list args; va_start(args, fmt); vsprintf(printf_buf, fmt, args); va_end(args); int len = strlen(printf_buf) + 1; if (len == lastBufLen) { if (strcmp(lastBuf, printf_buf) == 0) { ++mRepeatCount; pthread_mutex_unlock(&mWriteLogLock); return; } } else { if (mRepeatCount > 0){ mCurrLogFileSize += fprintf(mFile, "[%s]: 上一条日志重复%u次。\n", timeStr, mRepeatCount); } lastBufLen = len; mRepeatCount = 0; memcpy(lastBuf, printf_buf, len); } mCurrLogFileSize += fprintf(mFile, "[%s] ", timeStr); mCurrLogFileSize += fprintf(mFile, "%s", printf_buf); if (INFO < level) { fflush(mFile); }else if (++flushCount >= FLUSH_LINE) { flushCount = 0; fflush(mFile); } if (mCurrLogFileSize > mLogFileMaxSize) { createNewFile(); mFile = fopen(mFilePath, "a+"); if (mFile) { mCurrLogFileSize = 0; timeToString(t, TIME_CHN_FMT, timeStr, sizeof(timeStr)-1); mCurrLogFileSize += fprintf(mFile, "[%s]: ", timeStr); mCurrLogFileSize += fprintf(mFile, "%s", printf_buf); } } //如果是调试模式,则会将日志输出在终端上 if(mLogLevel==DEBUG){ cout << printf_buf << endl; } pthread_mutex_unlock(&mWriteLogLock); } /* 重命名旧文件,创建新文件 */ void CLog::createNewFile() { char newFullName[1024]; memset(newFullName,0,sizeof(newFullName)); //如果是第一次则先遍历一次 if(mLogFileCurrNum==0) { for(unsigned int i=1;i<=mLogFileMaxNum;i++) { snprintf(newFullName,sizeof(newFullName), "%s.%02d", mFilePath, i); //不存在,则创建 if((access(newFullName,F_OK))<0) { mLogFileCurrNum = i; break; } //如果文件存在,则继续找,如果找到最后也存在则删除第一个 if(i==mLogFileMaxNum) { snprintf(newFullName,sizeof(newFullName), "%s.%02d", mFilePath, 1); unlink(newFullName); mLogFileCurrNum = 1; } } }else { mLogFileCurrNum++; if(mLogFileCurrNum>mLogFileMaxNum){ mLogFileCurrNum = 1; } snprintf(newFullName,sizeof(newFullName), "%s.%02d", mFilePath, mLogFileCurrNum); //已存在,则删除 if((access(newFullName,F_OK))>=0){ unlink(newFullName); } fclose(mFile); mFile = NULL; } if (0 != rename(mFilePath, newFullName)){ return; } int ret = creat(mFilePath, 0664); ::close(ret); } /* 检测文件大小是否超过上限 */ bool CLog::fileSizeOverflow(const char *fileName) { if (NULL == fileName){ return false; } char path[1024]; memset(path,0,sizeof(path)); strncpy(path, fileName, sizeof(path)-1); path[sizeof(path)-1] = '\0'; FILE *fp = fopen(path, "r"); if (fp == NULL){ return false; } int ret = fseek(fp, 0, SEEK_END); if (0 != ret) { fclose(fp); return false; } mCurrLogFileSize = ftell(fp); if (mCurrLogFileSize < mLogFileMaxSize) { fclose(fp); return false; } mCurrLogFileSize = 0; fclose(fp); return true; } }//end of namespace log
main
#include "log.h" #include <unistd.h> using namespace log; int main() { CLog::getInstance()->init("/usr/local/code/MyLog_debug/","test.log"/*,1,10,1024*1024*/); int i = 0; while(true) { i++; CLog::getInstance()->plog(NOTICE,"%s h:%d\n",g_messageStr,i); usleep(1000); } }
发表评论
-
滑动窗口与拥塞控制
2017-09-29 14:47 724滑动窗口:用作流量控制: 1.发送端和接收端各维护一个独立的发 ... -
rawsocket发送tcp包
2017-09-25 11:52 927testTcp.h #ifndef TESTTCP_H ... -
柔性数组
2017-09-20 09:53 444#include <iostream> #i ... -
rawsocket发送dns包
2017-09-14 15:18 563#include <stdio.h> #in ... -
rawsocket发送icmp包
2017-09-06 09:54 614#include <stdio.h> #in ... -
查看glibc版本
2016-12-07 14:13 492strings /lib64/libc.so.6 |grep ... -
netfilter
2016-10-04 20:31 444http://blog.chinaunix.net/uid-2 ... -
gdb的简单使用
2016-09-19 15:18 380注意编译的时间加上-g参数 1.调试运行 gdb a.out ... -
TCP各状态的意义
2016-03-01 14:06 385各个状态的意义如下: LISTEN - 侦听来自远方TCP端 ... -
trim
2015-05-14 14:45 319/* trim from start */ ... -
TIMEWAIT与CLOSEWAIT
2015-03-17 11:32 611http://blog.csdn.net/kobejayand ... -
TcpClient
2015-01-16 17:46 440TcpClient.h #ifndef TCPCLIENT ... -
信号量
2014-09-26 10:20 644#include <semaphore.h> ... -
共享内存
2014-09-17 10:39 534SharedMemory.h #ifndef SHARED ... -
记录锁
2014-09-11 16:32 397#include <errno.h> #in ... -
popen
2014-09-06 14:50 580#include <stdio.h> #in ... -
大小端存储
2014-09-05 09:29 563#include <stdio.h> i ... -
条件变量(cond)
2014-09-01 11:02 824#include <pthread.h> # ... -
读写锁
2014-09-01 10:33 665#include <pthread.h> # ... -
trylock
2014-09-01 10:07 635#include <pthread.h> # ...
相关推荐
log4cplus是C++编写的开源的日志系统,功能非常全面,用到自己开发的工程中会比较专业的,:),本文介绍了log4cplus基本概念,以及如何安装,配置。 ### 简介 ### log4cplus是C++编写的开源的日志系统,前身是java...
1、概述 log4net是.Net下一个非常优秀的开源日志记录组件。log4net记录日志的功能非常强大。它可以将日志分不同的等级,以不同的...<param name="File" value="C:/log-file.txt" />就写入C盘根目录下log-file.txt文件中
针对Log4j 2 远程代码执行漏洞,需要用到的升级资源包,适用于maven资源库,包括log4j,log4j-core,log4j-api,log4j-1.2-api,log4j-jpa等全套2.15.0 maven资源库jar包。如果是maven本地仓库使用,需要将zip包解压...
自己编译好的log4cpp的DLL 和 LIB 封装了一个使用类,从本地读取配置log级别等信息,可输出多个种类的日志文件,输出示例如下 [2017-02-20 16:09:51.910](NOTICE)Sys : 进入了CPfy_log4cppDlg::OnBnClickedButton1...
Apache log4j2零日漏洞,根据 log4j-2.15.0-rc2 版本编译生成log4j-api-2.15.0.jar 1.解压你的jar jar xvf XXX.jar 2. 删除旧版本jar cd ./BOOT-INF/lib rm -rf log4j-api-*.jar 3. 上传新版本log4j-api-2.15.0....
Apache log4j2零日漏洞,根据 log4j-2.15.0-rc2 版本编译生成log4j-api-2.15.0.jar 1.解压你的jar jar xvf XXX.jar 2. 删除旧版本jar cd ./BOOT-INF/lib rm -rf log4j-api-*.jar 3. 上传新版本log4j-api-...
设置log4j的根目录,值为 日志等级(DEBUG,INFO,WARN,ERROR,FATAL) , 输出目标名称 log4j.rootLogger=DEBUG,A1 设置输出方式,常用的有: ConsoleAppender 在控制器中输出信息 RollingFileApperder 在文件中输出...
apache-log4j-1.2.15.jar, apache-log4j-extras-1.0.jar, apache-log4j-extras-1.1.jar, apache-log4j.jar, log4j-1.2-api-2.0.2-javadoc.jar, log4j-1.2-api-2.0.2-sources.jar, log4j-1.2-api-2.0.2.jar, log4j-...
log_file=/data/nginx_logs/access.log log_reg=\[(.*) \+0800\] time_format=%d/%b/%Y:%H:%M:%S retain_seconds=3600 http_port=3344 log_level=INFO log_file: 需要监控的日志的路径 log_reg: 需要匹配的日期...
Log4j 是一个日志记录框架,Log4j 2 是对 Log4j 的升级,提供了重大改进,超越其前身 Log4j 1.x,并提供许多其它现代功能 ,例如对标记的支持、使用查找的属性替换、lambda 表达式与日志记录时无垃圾等。 Apache ...
log4j.rootLogger=debug,CONSOLE,testfile,A1,MAIL ################### # Console Appender ################### log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.Target=...
项目开发中经常需要记录log,上传一个各种场景都可以使用的记录log的DLL 将格式化字符串输出到log文件中,代码会在执行文件的目录,自动创建子目录 log\ 并在其中创建跟执行文件同名的log文件 当记录的log文件超过5...
赠送jar包:log4j-api-2.12.1.jar; 赠送原API文档:log4j-api-2.12.1-javadoc.jar; 赠送源代码:log4j-api-2.12.1-sources.jar; 赠送Maven依赖信息文件:log4j-api-2.12.1.pom; 包含翻译后的API文档:log4j-api-...
赠送jar包:log4j-api-2.17.1.jar; 赠送原API文档:log4j-api-2.17.1-javadoc.jar; 赠送源代码:log4j-api-2.17.1-sources.jar; 赠送Maven依赖信息文件:log4j-api-2.17.1.pom; 包含翻译后的API文档:log4j-api-...
语音增强 logmmse matlab算法 function logmmse(filename,outfile) %简单来说,这里对噪声谱估计两个步骤 %1、前6帧都当噪声计算,计算出初始噪声功率谱 %2、加上粗略的vad判决更新噪声谱 %后面就是MMSE-LSA也...
Java Log4j 1,2 所需Jar包,一个完整的软件,日志是必不可少的。程序从开发、测试、维护、运行等环节,都需 要向控制台或文件等位置输出大量信息。这些信息的输出,在很多时候是使用 System.out.println()无法完成的。 ...
log4j中配置日志文件相对路径方法分析 方法一、 解决的办法自然是用相对路径代替绝对路径,其实log4j的FileAppender本身就有这样的机制,如:log4j.appender.logfile.File=${WORKDIR}/logs/app.log 其中“${...
log4j相关支持的jar Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条...
赠送jar包:apache-log4j-extras-1.2.17.jar; 赠送原API文档:apache-log4j-extras-1.2.17-javadoc.jar; 赠送Maven依赖信息文件:apache-log4j-extras-1.2.17.pom; 包含翻译后的API文档:apache-log4j-extras-...
Log4J的组件 Log4j有三个主要的组件,分别是loggers,appenders和layouts.这三种类型的部件工作在一起就能允许开发者根据记录信息的类型和级别来记录日志信息,并且在系统运行时能够按照不同的格式将这三类信息存储在...