简单的跨平台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 < ...
随机推荐
- 【Visual Lisp】人机交互与数据处理(表除外)-lisp
;;本专题所讲述的内容是人机交互以及常规数据处理技术;;★★★01.人机交互★★★;;△△△键盘输入交互△△△(getint "请输入整数");;从键盘输入整数,如果不是整数则重复 ...
- bdb mvcc: buffer 何时可以被 看到; mvcc trans何时被移除
# txn.h struct __db_txnregion SH_TAILQ_HEAD(__active) active_txn; SH_TAILQ_HEAD(__mvcc) mvcc_txn; # ...
- Spring笔记--0907
包含ioc和aop两大核心概念 aop----事务管理 spring框架运用的设计模式(查一下) ---------------------------------------Ioc(控制反转)和Di ...
- Windows XP和Word 2007不能正常使用VSTO插件
今天帮助同事解决了一个小问题,就是在WindowsXP上,为Word2007开发的插件不能正常显示. 通过搜索关键词 WindowsXp Word 2007 VSTO找到了两个解决方案. http:/ ...
- Android中将布局文件转成bitmap
在实践中发现,有些需要打印的小票高度小于屏幕的高度,而有些小票内容过多高度高于屏幕高度. 小于屏幕高度的布局文件转成bitmap较为容易,高于屏幕高度的布局文件转成长图bitmap较为复杂. 一.小于 ...
- unity发布安卓 截图保存到本地
using System.IO; //获取系统时间并命名相片名 System.DateTime now = System.DateTime.Now; string times = now.ToStri ...
- LAMP自定义编译安装
httpd 2.4.4 + mysql-5.5.28 + php-5.4.13编译安装过程: 一.编译安装apache 1.解决依赖关系 httpd-2.4.4需要较新版本的apr和apr-util, ...
- linux配置java环境变量(详细) -copy
一. 解压安装jdk 在shell终端下进入jdk-6u14-linux-i586.bin文件所在目录, 执行命令 ./jdk-6u14-linux-i586.bin 这时会出现一段协议,连继敲回车, ...
- DOM何时Ready
由于script标签在被加载完成后会立即执行其中代码,如果在代码中要访问HTMLElement,可是这时候元素还没有加载进来,所以对元素的操作统统无效. 最早的时候使用window.onload = ...
- 谈谈javascript语法里一些难点问题(二)
3) 作用域链相关的问题 作用域链是javascript语言里非常红的概念,很多学习和使用javascript语言的程序员都知道作用域链是理解javascript里很重要的一些概念的关键,这些概 ...