extern_interface/logqueueconfig/log.h

288 lines
7.5 KiB
C
Raw Permalink Normal View History

2024-11-28 08:31:00 +00:00
#ifndef __HIT_LOG_HEADER
#define __HIT_LOG_HEADER
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <memory.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include "dataqueue.h"
#define INFO_BUF_LEN 4096//2048
typedef void* voidPtr;
extern "C" voidPtr __attribute__((visibility("default"))) OpenLogFile(const char* strPath, const char* strFileName, bool bLogByDay);
//-----------------------------------------------------------------------------------------------------------------
extern "C" int __attribute__((visibility("default"))) WriteLog(void* pLogFile, const char* fmt, ...);
//-----------------------------------------------------------------------------------------------------------------
extern "C" void __attribute__((visibility("default"))) CloseLog(void* pLogFile);
namespace QUEUE_LOG_COFIG
{
static uint64_t g_iLogFileMaxSize = 2L * 1024 * 1024 * 1024;
static uint64_t g_iCheckLogInterval = 20;//20s
inline int checkdir(const char* sPathName)
{
char DirName[256];
strcpy(DirName, sPathName);
int i, len = strlen(DirName);
if (DirName[len - 1] != '/')
strcat(DirName, "/");
len = strlen(DirName);
for (i = 1; i < len; i++)
{
if (DirName[i] == '/')
{
DirName[i] = 0;
if (access(DirName, 0) != 0)
{
if (mkdir(DirName, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1)
{
perror(" mkdir error");
return -1;
}
}
DirName[i] = '/';
}
}
return 0;
}
/*
** log class, it is not thread safe.
*/
void* WriteLogThread(void* param);
struct InfoItem
{
struct tm t;
bool bLogTime;
char strInfo[INFO_BUF_LEN];
int GetLen() { return (uint64_t)(&strInfo[0]) - (uint64_t)(this) + strlen(strInfo) + 1; }
};
class CLogFile
{
private:
char* log_filename;
char* log_dirpath;
char* log_fullpath_filename;
int m_bRecordByDay;
int current_day;
FILE* file_handle;
DataQueue m_InfoQueue; //
bool m_bExit;
bool m_bUseQueue;
bool m_bWriteFinish;
pthread_t m_pWriteThreadHandle;
private:
void set_log_fullpath_filename(struct tm* t)
{
if (log_fullpath_filename == NULL)
log_fullpath_filename = (char*)calloc(strlen(log_dirpath) + 1 + 8 + 1 + strlen(log_filename) + 1 + 10, sizeof(char));
if (m_bRecordByDay)
{
current_day = t->tm_mday;
sprintf(log_fullpath_filename, "%s%02d%02d%02d/", log_dirpath, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
}
else
sprintf(log_fullpath_filename, "%s", log_dirpath);
checkdir(log_fullpath_filename);
strcat(log_fullpath_filename, log_filename);
}
void open_log_file()
{
file_handle = fopen(log_fullpath_filename, "a");
if (file_handle == NULL)
{//2019.07.18------------------
fprintf(stderr, "\n----------------------------------------------------------------\n");
fprintf(stderr, "***Fatal error: can't open file: %s", log_fullpath_filename);
fprintf(stderr, "----------------------------------------------------------------\n");
fflush(stderr);
exit(1);
}
}
struct tm* get_time()
{
time_t clock;
time(&clock);
struct tm* t = localtime(&clock);
return t;
}
void print_time()
{
struct tm* t = get_time();
fprintf(file_handle, "%4d-%02d-%02d %02d:%02d:%02d\n",
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
}
public:
FILE* GetFileHande() { return file_handle; }
CLogFile(const char* dir, const char* name, int byDay, bool bUseQueue = false)
{
m_bRecordByDay = byDay;
m_bUseQueue = bUseQueue;
file_handle = NULL;
m_bWriteFinish = true;
m_bExit = false;
log_dirpath = (char*)calloc(strlen(dir) + 10, sizeof(char));
log_filename = (char*)calloc(strlen(name) + 10, sizeof(char));
strcpy(log_dirpath, dir);
int i, len = strlen(log_dirpath);
if (log_dirpath[len - 1] != '/')
strcat(log_dirpath, "/");
strcpy(log_filename, name);
log_fullpath_filename = NULL;
struct tm* t = get_time();
set_log_fullpath_filename(t);
open_log_file();
if (bUseQueue)
{
m_InfoQueue.InitQueue(32 * 1024, 8 * 2048);
pthread_create(&m_pWriteThreadHandle, NULL, WriteLogThread, this);
}
}
~CLogFile()
{
m_bExit = true;
pthread_join(m_pWriteThreadHandle, NULL);
close_log_file();
free(log_filename);
free(log_dirpath);
free(log_fullpath_filename);
}
void append_one_item(int print_time_flag, const char* fmt, ...)
{//append the new info into the queue
char fmtbuf[INFO_BUF_LEN];
va_list arglist;
if (m_bExit) return;
InfoItem tmpInfoItem;
va_start(arglist, fmt);
vsprintf(fmtbuf, fmt, arglist);
va_end(arglist);
snprintf(tmpInfoItem.strInfo, sizeof(tmpInfoItem.strInfo), fmtbuf);
tmpInfoItem.t = *get_time();
tmpInfoItem.bLogTime = print_time_flag;
if (m_bUseQueue)
m_InfoQueue.EnQueue((void*)(&tmpInfoItem), tmpInfoItem.GetLen());
else
{
writeItem2File(&tmpInfoItem);
}
}
void checksize(uint64_t iSize)
{
uint64_t iFileBytes = ftell(file_handle);
if (iFileBytes > iSize)
{
char strBackupName[500];
char strCurTime[20];
time_t tt;
tt = time(NULL);
strftime(strCurTime, sizeof(strCurTime), "%Y.%m.%d-%H.%M.%S", localtime(&tt));//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>YYYY-MM-DD hh:mm:ss<73><73><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>
sprintf(strBackupName, "%s-bak%s", log_fullpath_filename, strCurTime);
close_log_file();
rename(log_fullpath_filename, strBackupName);//<2F><>ԭ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>µ<EFBFBD><C2B5>ļ<EFBFBD><C4BC><EFBFBD>
open_log_file();
}
};
void writeItem2File(InfoItem* pInfoItem)
{
if (file_handle == NULL)
{//2019.07.18
return;
}
int iBytes;
if ((m_bRecordByDay) && (pInfoItem->t.tm_mday != current_day))
{//change_to_new_day
close_log_file();
current_day = pInfoItem->t.tm_mday;
set_log_fullpath_filename(&(pInfoItem->t));
open_log_file();
char strCmd[300];
sprintf(strCmd, "find %s -type d -mtime +30 -exec rm -rf {} \\;", log_dirpath);
system(strCmd);
}
if (pInfoItem->bLogTime)
{
iBytes = fprintf(file_handle, "%s %4d.%02d.%02d %02d:%02d:%02d\n",
pInfoItem->strInfo,
pInfoItem->t.tm_year + 1900, pInfoItem->t.tm_mon + 1, pInfoItem->t.tm_mday,
pInfoItem->t.tm_hour, pInfoItem->t.tm_min, pInfoItem->t.tm_sec);
}
else
iBytes = fprintf(file_handle, "%s", pInfoItem->strInfo);
if (iBytes < 0)
fprintf(stderr, "***writing \"%s\" to log failed! errno:%d, %s\n", pInfoItem->strInfo, errno, strerror(errno));
else
fflush(file_handle);
}
void writeQueue2File()
{
unsigned int iWiteItems = 0;
InfoItem* pInfoItem;
struct tm* t;
m_bWriteFinish = false;
unsigned n = 0;
int iBytes;
while (!m_bExit)
{
iBytes = m_InfoQueue.DeQueue((void**)(&pInfoItem));
if (iBytes <= 0)
{
sleep(1);//10ms
continue;
}
writeItem2File(pInfoItem);
if ((++n % g_iCheckLogInterval == 0) && (!m_bRecordByDay))
checksize(g_iLogFileMaxSize);// 2L * 1024 * 1024 * 1024);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2GB
}
t = get_time();
fprintf(file_handle, "...finish and exit! @%4d.%02d.%02d %02d:%02d:%02d\n\n",
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
fflush(file_handle);
m_bWriteFinish = true;
}
void close_log_file()
{
if (file_handle != NULL)
{
fflush(file_handle);
fclose(file_handle);
file_handle = NULL;
}
}
void clear_expired_logs()
{
}
};
//void * WriteLogThread(void* param)
//{
// CLogFile *pLog = (CLogFile*)(param);
// pLog->writeQueue2File();//
//}
//---------------------------------------------------------------------------------------------------
}
#endif