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 < ...
随机推荐
-
VSCODE 插件初探
写在前面 分享一个vscode插件background(用于改变背景).点击直接跳到vscode插件开发步骤 做vscode的插件,很久就有这个想法了,但是一直因为这样,那样的事情耽误,放弃了N次.不 ...
-
BLE-NRF51822教程-RSSI获取
当手机和设备连接上后,设备端可以通过获取RSSI,在一定程度上判断手机离设备的相对距离的远近. 获取函数很简单直接调用sd_ble_gap_rssi_get 接口函数就行了,传入连接句柄和buff就能 ...
-
C语言中%*s,%*c 是什么意思(还有%*.*s)
在 scanf 和 printf 里效果是不一样的. 在printf,动态控制显示格式用的 printf("%*s",5,"123");执行一下,这条语句,输出 ...
-
C# string格式的日期时间字符串转为DateTime类型
(1 )Convert.ToDateTime(string) string格式有要求,必须是yyyy-MM-dd hh:mm:ss (2):Convert.ToDateTime(string, IFo ...
-
es6环境搭建
安装node环境 地址:https://nodejs.org/en/download/ 建立项目目录 建立一个项目目录es6-demo,并在目录下建立两个子文件夹src和dist: src:源代码es ...
-
XMPP(三)-安卓即时通讯客户端
由于时间原因,所以更新比较慢 ,还请大家谅解,此次是对上篇文章中的安卓客户端初级版本进行的一次更新优化,在这次更新后,就有那么一点样子了,可以拿的出手了,呵呵,还在关注的同学也可以及时下载更新.此次主 ...
-
pwnable.kr col
collision - 3 pt 连接上查看col.c源码 分析一下代码, 1.hashcode等于一个固定的值 2.check_password函数取输入数据,4个一组,将输入的字符转成int,然后 ...
-
Sencha Touch 实战开发培训 视频教程 第二期 第八节 (完结)
2014.4.23 晚上8:00左右开课. 本节课耗时超长,因为演示过程中出现了一些小错误,所以耗时接近2小时. 本期培训一共八节,前两节免费,后面的课程需要付费才可以观看. 本节内容: 开发cord ...
-
Windows10安装.net3.5
1.装载windows10映像 2.运行如下命令(注意修改盘符): Dism /online /enable-feature /featurename:NetFX3 /All /Source:F:\s ...
-
SQL优化:使用explain
前文说了EXPLAIN的输出的含义,本文实战一下. Database Schema DROP DATABASE dbTest; CREATE DATABASE dbTest; USE dbTest; ...