windows log
linux
Header file ( logutils.h )
#ifndef __LINUX_LOGUTILS_H__
#define __LINUX_LOGUTILS_H__
#define NCTRACE NcTrace
#define MYTRACE NcTrace
#define NCTRACE2 NcTrace2
#define MYTRACE2 NcTrace2
#define HDTRACE HdTrace
//2016-07-03
//Linux Version. -- UNICODE is yet to be done.
//2014-8 Option to Send text to window display and Control( Stop ).
//See GenericWin.
// Init with window display. add InitDefaultLogFile
//2013-5 Add file name for NCTRACE.
bool NcSetLogFile ( const char * sFile );
void NcSetLogFileSize ( int iSize );
int get_executable_path( char* process_path, size_t len);
bool NcTrace( const char * lpszFormat , ... );
bool NcTrace2(const char * lpszLogFileName, const char * lpszFormat, ... );
//bool HdTrace( const char * lpszFormat , ... );
#endif
implementation: (logutils.cpp)
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "logutils.h"
//2016-07-03
//Linux VERSION. -- UNICODE is yet to be done.
//2013-6-9 Updated -- Add Log File name. In Unicode Build use ANSI form compatible.
//2014-8-20 Updated --
// Init with window display. add InitDefaultLogFile
static int LOG_FILE_SIZE = (4*1024*1024);
#define CHAR_TYPE char
#define MAX_PATH 256
static CHAR_TYPE g_szAppPath[MAX_PATH] = { 0 } ;
static CHAR_TYPE g_szBakFile[MAX_PATH] = { 0 } ;
static bool g_bInitNcTrace = false;
static pthread_mutex_t s_mtx_log;
void NcSetLogFileSize( int iSize )
{
if ( iSize >= ( 64<<10 ) )
LOG_FILE_SIZE = iSize;
}
bool NcSetLogFile( const CHAR_TYPE * sFile )
{
if ( !g_bInitNcTrace )
{
pthread_mutex_init( &s_mtx_log, NULL );
}
pthread_mutex_lock( &s_mtx_log );
if ( !sFile || strlen( sFile ) < 2 )
return false;
if ( sFile != g_szAppPath )
strcpy( g_szAppPath, sFile );
strcpy( g_szBakFile, sFile );
CHAR_TYPE * pDot = (CHAR_TYPE *)strrchr( g_szBakFile, ('.') );
if ( pDot )
{
pDot[0] = 0;
}
strcat( g_szBakFile, "_0.txt" );
g_bInitNcTrace = true;
pthread_mutex_unlock( &s_mtx_log );
return true;
}
static int get_executable_dir( char* processdir, size_t len)
{
char* path_end;
int ifunc;
ifunc = readlink("/proc/self/exe", processdir, len );
if( ifunc <= 0 )
return -1;
path_end = strrchr(processdir, '/');
if(path_end == NULL)
return -1;
path_end ++;
*path_end = '\0';
return 0;
}
int get_executable_path( char* process_path,size_t len)
{
int ifunc;
//返回值: 進程路徑的長度 (char). 但是沒有null 結束。
ifunc = readlink("/proc/self/exe", process_path, len );
if( ifunc <= 0 )
return -1;
process_path[ifunc] = 0;
return 0;
}
static bool InitDefaultLogFile()
{
//獲得程序運行目錄
//if( GetModuleFileName( NULL, g_szAppPath, MAX_PATH ) == 0 )
// return FALSE;
if ( g_bInitNcTrace )
return true;
if ( get_executable_path( g_szAppPath, 256 ) != 0 )
return false;
strcpy( g_szBakFile, g_szAppPath );
strcat( g_szAppPath, (".txt" ) );
NcSetLogFile( g_szAppPath );
return true;
}
static FILE * OpenAutoLogFile()
{
int ifunc;
//當日志文件大於100K時,存儲到*0.txt中
struct stat st_file;
ifunc = stat( g_szAppPath, &st_file );
if ( ifunc == 0 && st_file.st_size > LOG_FILE_SIZE )
{
remove( g_szBakFile );
rename( g_szAppPath, g_szBakFile );
}
FILE* fOut = fopen( g_szAppPath , "a" );
return fOut;
}
bool locked_NcTrace( FILE *fOut , const CHAR_TYPE * lpszFormat ,va_list args )
{
int ifunc;
try
{
// 進程ID
int iCurrentProcessID = getpid();
// 記錄時間
char szTime[128] = { 0 };
//SYSTEMTIME localTime = { 0 };
//GetLocalTime( &localTime );
struct timeval tv;
ifunc = gettimeofday( &tv, NULL );
struct tm * ptime = localtime( &tv.tv_sec );
int iYear = ptime->tm_year + 1900;
int iMonth = ptime->tm_mon + 1;
sprintf( szTime , ("[%x] %4d-%02d-%02d %02d:%02d:%02d:%03d : "), iCurrentProcessID
, iYear, iMonth, ptime->tm_mday , ptime->tm_hour, ptime->tm_min, ptime->tm_sec, (int)tv.tv_usec/1000 );
// 格式化字符串
char szInfo[2*1024] = { 0 };
vsnprintf(szInfo, 2*1024, lpszFormat, args);
fwrite( szTime , sizeof(char) , strlen( szTime ) , fOut ) ;
fwrite( szInfo , sizeof(char) , strlen( szInfo ) , fOut ) ;
fwrite( "\n" , 1 , 1 , fOut ) ;
}
catch (...)
{
return false;
}
return true;
}
bool NcTrace( const CHAR_TYPE * lpszFormat , ... )
{
InitDefaultLogFile();
pthread_mutex_lock ( &s_mtx_log );
va_list va;
va_start(va, lpszFormat);
FILE *fp = OpenAutoLogFile();
if ( fp )
{
locked_NcTrace( fp,lpszFormat, va );
fclose( fp );
}
va_end( va );
pthread_mutex_unlock ( &s_mtx_log );
return true;
}
static FILE * OpenLogFile(const CHAR_TYPE * sLogFile )
{
int ifunc;
//當日志文件大於100K時,存儲到*0.txt中
struct stat st_file;
memset( &st_file, 0, sizeof(struct stat ) );
ifunc = stat( sLogFile, &st_file );
if ( ifunc == 0 && st_file.st_size > LOG_FILE_SIZE )
{
remove( sLogFile );
}
FILE* fOut = fopen( sLogFile , "a" );
return fOut;
}
bool NcTrace2(const char * lpszLogFileName, const char * lpszFormat, ... )
{
InitDefaultLogFile();
pthread_mutex_lock ( &s_mtx_log );
va_list va;
va_start(va, lpszFormat);
FILE *fp = OpenLogFile( lpszLogFileName );
if ( fp )
{
locked_NcTrace( fp, lpszFormat, va );
fclose( fp );
}
va_end( va );
pthread_mutex_unlock ( &s_mtx_log );
return true;
}