简单的跨平台c/c++日志记录
CLog.h
#include <stdlib.h> #pragma once #ifndef _CLOG #define _CLOG #define CLOG_DEBUG 0 #define CLOG_INFO 1 #define CLOG_WARNING 2 #define CLOG_ERROR 3 #define stderr_message(exp, message) \ { \ fprintf(stderr,"-------------ERROR-----------------\n"); \ fprintf(stderr,"Failed:%s\nMessage:%s\nLine:%d\nFile:%s\n",#exp,message,__LINE__,__FILE__);\ fprintf(stderr,"-------------ERROR-----------------\n"); \ /*exit(EXIT_FAILURE);*/\ } //Clog(int level, char *msg) #define CLog(level,msg)\ {\ _CLog(level,msg,__LINE__,__FILE__);\ }\ //CLogDebug(char *msg) #define CLogDebug(msg)\ {\ CLog(CLOG_DEBUG,msg);\ }\ //CLogError(char *msg) #define CLogError(msg)\ {\ CLog(CLOG_ERROR,msg);\ }\ //CLogInfo(char *msg) #define CLogInfo(msg)\ {\ CLog(CLOG_INFO,msg);\ }\ //CLogWarning(char *msg) #define CLogWarning(msg)\ {\ CLog(CLOG_WARNING,msg);\ }\ #endif #ifdef __cplusplus extern "C" { #endif //init clog ! log_path is logfile path! void InitCLog(char *log_path); //this fun is logging! void _CLog(int level, char *msg,int line,char *file); //freee clog! void FreeeClog(); #ifdef __cplusplus } #endif
CLog.c
#include "CLog.h" #include <stdio.h> #include <stdarg.h> #include <time.h> #ifdef WIN32 #include <windows.h> #else #include <pthread.h> #endif #ifndef _CLOGSTATIC #define _CLOGSTATIC const char CLOGLevelName[4][8] = { "debug", "info", "warning", "error" }; FILE *fp = NULL; char now_file_name[11]; char *log_path; #ifdef WIN32 CRITICAL_SECTION g_cs; #else pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; #endif #endif void now_date_str(char *date_str) { time_t nowtime; struct tm *timeinfo; time(&nowtime); timeinfo = localtime(&nowtime); sprintf(date_str, "%d_%d_%d", timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday); } void now_datetime_str(char *datetime_str) { time_t nowtime; struct tm *timeinfo; time(&nowtime); timeinfo = localtime(&nowtime); sprintf(datetime_str, "%d_%d_%d %d:%d:%d", timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec ); } void lock() { #ifdef WIN32 EnterCriticalSection(&g_cs); #else pthread_mutex_lock(&mutex1); #endif } void unlock() { #ifdef WIN32 LeaveCriticalSection(&g_cs); #else pthread_mutex_unlock(&mutex1); #endif } long thread_id() { #ifdef WIN32 return GetCurrentThreadId(); #else return pthread_self(); #endif } void open_log_file() { char *filename = (char*)malloc(strlen(log_path) + strlen(now_file_name) + 1); sprintf(filename, "%s/%s.%s", log_path, now_file_name, "txt"); fp = fopen(filename, "ab+"); if (fp == NULL) { stderr_message(fp == NULL, "(clog) fopen error !"); return; } } //mk dirs void mkdir_p(char *dir) { //copy char * dir_c = (char*)malloc(strlen(dir) + 1); memcpy(dir_c, dir, strlen(dir) + 1); dir = dir_c; char * temppath = (char*)malloc(strlen(dir) + 1); int tempindex = 0; while (*dir_c != '\0') { if (*dir_c == '\\') *dir_c = '/'; if (*dir_c == '/') { tempindex = dir_c - dir; memcpy(temppath, dir, tempindex); temppath[tempindex] = '\0'; if (_access(temppath, 0) != 0) _mkdir(temppath); } dir_c++; } if (_access(dir, 0) != 0) _mkdir(dir); free(dir); free(temppath); } void InitCLog(char *path) { #ifdef WIN32 InitializeCriticalSection(&g_cs); #endif if (path == NULL) stderr_message(path == NULL, "(clog) logpath is null !"); now_date_str(now_file_name); int pathlength = strlen(path); log_path = (char*)malloc(pathlength*sizeof(char) + 1); strcpy(log_path, path); if (log_path[pathlength - 1] == '/') log_path[pathlength - 1] = '\0'; mkdir_p(log_path); open_log_file(); } void _CLog(int level, char *msg, int line, char *file) { lock(); if (level<0 || level>3) { stderr_message(level<0 || level>3, "(clog) level overflow!"); return; } if (fp == NULL) { stderr_message(fp == NULL, "(clog) clog not init!"); return; } char temp_now_file_name[11]; now_date_str(temp_now_file_name); if (strcmp(temp_now_file_name, now_file_name) != 0) { strcpy(now_file_name, temp_now_file_name); fclose(fp); open_log_file(); if (fp == NULL) { stderr_message(fp == NULL, "(clog) clog init error!"); return; } } char* info = (char*)malloc(strlen(msg) + 80 + strlen(file)); char datetimestr[21]; now_datetime_str(datetimestr); sprintf(info, "%s thread:%d %s \r\n%s\r\nfile:%s line:%d\r\n", datetimestr, thread_id(), CLOGLevelName[level], msg, file, line); fwrite(info, strlen(info), 1, fp); fflush(fp); free(info); unlock(); } void FreeeClog() { lock(); if (fp != NULL) fclose(fp); free(log_path); unlock(); }
Example:
#include "stdafx.h"//Without this header file under linux #include "CLog.h" #include <stdlib.h> #ifdef WIN32 #include <Windows.h> #include <process.h> #else #include <pthread.h> #endif #define thread_num 10 void thread_fun() { int i = 0; for (; i < 1000; i++) { CLog(CLOG_DEBUG, "this debug message!"); CLog(CLOG_INFO, "this info!╮(╯▽╰)╭"); CLog(CLOG_WARNING, "警告!this warning!!"); CLog(CLOG_ERROR, "Error!!"); } } #ifdef WIN32 unsigned _stdcall ThreadProc(void* param) { thread_fun(); return 0; } void win32_thread_test() { HANDLE handle[thread_num]; int i = 0; for (; i < thread_num; i++) { handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, NULL, NULL, NULL); } for (i = 0; i < thread_num; i++) { WaitForSingleObject(handle[i], INFINITE); CloseHandle(handle[i]); } } #else void *linux_threadfun(void *arg) { thread_fun(); } void linux_thread_test() { pthread_t pthreadarray[thread_num]; int i = 0; for (; i < thread_num; i++) { pthreadarray[i] = pthread_create(&pthreadarray[i], NULL, linux_threadfun, NULL); } for (i = 0; i < thread_num; i++) { pthread_join(&pthreadarray[i], NULL); } } #endif int main() { /*Example: InitCLog ("D:/ntg/logs"); disk directory InitCLog ("logs"); the current directory under the logs directory InitCLog ("test/log/codelog"); the current directory est/log/codelog directory */ InitCLog("D:/Logs"); //Loging Example: CLog(CLOG_DEBUG, "this debug message!"); CLog(CLOG_INFO, "this info!╮(╯▽╰)╭"); CLog(CLOG_WARNING, "this warning! ( ⊙ o ⊙ )啊!"); CLog(CLOG_ERROR, "Error!!"); //or CLogInfo("这是info!"); CLogError("报错!"); CLogDebug("debug!!"); CLogWarning("指针为null!"); //Multithreaded Test Start #ifdef WIN32 win32_thread_test(); #else linux_thread_test(); #endif //Multithreaded Test End //The program exits when the need to call FreeeClog free FreeeClog(); system("pause"); return 0; }
简单的跨平台c/c++日志记录的更多相关文章
- Ibatis.net 1.6.2 简单配置及Log4.Net日志记录
看似简单的Ibatis配置起来注意的地方还挺多.里面的设置及功能还算强大.昨晚配置了半宿,结果一运行还是各种错误.急的直冒汗.果断下载实例去研究.英文不好文档只能作为功能参考. 下面一步步进入Ibat ...
- 【转】使用Log4Net进行日志记录
首先说说为什么要进行日志记录.在一个完整的程序系统里面,日志系统是一个非常重要的功能组成部分.它可以记录下系统所产生的所有行为,并按照某种规范表达出来.我们可以使用日志系统所记录的信息为系统进行排错, ...
- php 简单通用的日志记录方法
使用file_put_contents 方法来实现简单便捷的日志记录功能 方法1: // use \r\n for new line on windows, just \n on linux func ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存
代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...
- Net Core平台灵活简单的日志记录框架NLog+SqlServer初体验
Net Core平台灵活简单的日志记录框架NLog+SqlServer初体验 前几天分享的"[Net Core平台灵活简单的日志记录框架NLog+Mysql组合初体验][http://www ...
- Net Core平台灵活简单的日志记录框架NLog+Mysql组合初体验
Net Core平台灵活简单的日志记录框架NLog初体验 前几天分享的"[Net Core集成Exceptionless分布式日志功能以及全局异常过滤][https://www.cnblog ...
- Z从壹开始前后端分离【 .NET Core2.0/3.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存
本文梯子 本文3.0版本文章 代码已上传Github+Gitee,文末有地址 大神反馈: 零.今天完成的深红色部分 一.AOP 之 实现日志记录(服务层) 1.定义服务接口与实现类 2.在API层中添 ...
- 简单的C#日志记录和弹出提示
记录这个博客的想法只有两点, 一,在使用webserver的时候如果你不好调用本地server端,那么你可以启用日志来查看异常.当然也可以调用本地的server端.这里简单说一下.不是本文的重点. 发 ...
- C++实现简单的日志记录
C++实现简单的日志记录 //dlogger.h #ifndef DLOGGER_H #define DLOGGER_H #include <iostream> #include < ...
随机推荐
- 命令安装VS
Installing Visual Studio Visual Studio 2015 Other Versions Visual Studio 2013 Visual Studio 2010 ...
- CentOS 7编译安装gcc5.3碰到的坑
下载最新的iso安装完毕后,发现gcc还是4.8版本的,就考虑升级到5.x 参考这个帖子 基本也没啥,但是执行download_prerequisites 时简直坑爹,三个压缩包都不超过2M 反复尝试 ...
- hdu acm 1425 sort(哈希表思想)
sort Time Limit: 6000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- js中的变量小例子
s中的变量function foo(){ n=99;}alert(n);//undefined,因为没有调用该函数 function foo(){ n=99;}foo();alert(n);//99, ...
- 织梦cms、帝国cms、PHPcms优缺点解析
php才是建站的主流,cms这类程序又是用的最多的,占据主流的cms主要就是织梦,帝国,phpcms这三种的,这三个程序都是开源程序.国内用户众多. 一.从美观性来说(以官方默认模版为准 ph ...
- d3 API axis
场景 1.画网格线 使用方法.innerTickSize(): 指定内刻度大小 或者 .tickSize(inner, outer): 2.内外刻度线 innerTickSize outerTickS ...
- foremost
foremost 恢复单个类型文件 删除一个 USB(/dev/sdba1)存储器中一个 png 文件然后使用 formost 恢复. #rm -f /dev/sdb1/1.png #foremost ...
- MyEclipse调用Matlab打包函数
本文部分内容参考了http://www.360doc.com/content/15/1103/16/1180274_510463048.shtml 一.检查Java环境 对于已经装上JAVA环境的计算 ...
- C++多态(一)
面试题目中关于多态的问题不少,例如重载.虚函数(覆盖).多态的概念等等,这里做一个梳理,包含如下内容: 一.多态的定义 (一)定义 能够呈现不同形态的特性或状态. (二)两种多态性 1.编译时的多态性 ...
- WLAN信道