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 __cplusplusextern "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 _clogstaticconst Char cloglevelname[4] [8] = {"Debug", "Info", "Warning", "error"}; FILE *FP = Null;char Now_file_name[11];char *log_path; #ifdef win32critical_section g_cs; #elsepthread_mutex_t mutex1 = Pthread_mutex_initializer; #endif #endifvoid 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 Win32entercritIcalsection (&g_cs); #elsepthread_mutex_lock (&mutex1); #endif}void unlock () {#ifdef Win32leavecriticalsection (&g_cs); #elsepthread_mutex_unlock (&mutex1); #endif}long thread_id () {#ifdef Win32return GetCurrentThreadID (); #elsereturn 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 dirsvoid mkdir_p (char *dir) {//copychar * dir_c = (char*) malloc (strlen (dir) + 1), memcpy (Dir_c, dir, strlen (dir) + 1);d IR = Dir_c;char * TempPath = (char*) malloc (strlen (dir) + 1), int tempindex = 0;while (*dir_c! = ') ') {if (*dir_c = = ' \ \ ') *d Ir_c = '/'; if (*dir_c = = '/') {Tempindex = dir_c-dir;memcpy (TempPath, dir, tempindex); Temppath[tempindex] = ' n '; if (_ACC ESS (TempPath, 0)! = 0) _mkdir (temppath);} dir_c++;} if (_access (dir, 0)! = 0) _mkdir (dir); free (dir); Free (Temppath);} void Initclog (char *path) {#ifdef win32initializecriticalsection (&g_cs); #endifif (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] = ' mkdir_p '; File ();} void _clog (int level, char *msg, int line, char *file) {lock (), if (level<0 | | level>3) {stderr_message (level<0 | | l Evel>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) + + 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 10void Thread_fun () {int i = 0;for (; i <; i++) {CLog (Clog_debug, "This DEBUG message! "); CLog (Clog_info, "this info! ╮(╯▽╰)╭ "); CLog (clog_warning, "Warning! This warning!! "); CLog (Clog_error, "error!! ");}} #ifdef win32unsigned _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) _beginthre Adex (null, 0, THREADPROC, NULL, NULL, NULL);} for (i = 0; i < Thread_num; i++) {WaitForSingleObject (handle[i], INFINITE); CloseHandle (Handle[i]);}} #elsevoid *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] = PTH Read_create (&pthreadarray[i], NULL, LINUX_THREADFUN, NULL);} for (i = 0; i < Thread_num; i++) {Pthread_join (&pthreadarray[i], NULL);}} #endifint Main () {/*example:initclog ("d:/ntg/logs"), Disk Directoryinitclog ("logs"); The current directory under the log S Directoryinitclog ("Test/log/codelog"); The current directory is 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⊙) Ah! "); CLog (Clog_error, "error!! ");//orcloginfo (" This is info! "); Clogerror ("Error! "); Clogdebug ("debug!! "); Clogwarning ("Pointer is null! ");//multithreaded test start#ifdef win32win32_thread_test (); #elselinux_thread_test (); #endif//multithreaded test End//the program exits if the need to call Freeeclog Freefreeeclog (); System ("pause"); return 0;}
Cross-platform CLog (multi-threaded)