extern_interface/logqueueconfig/log.h

288 lines
7.5 KiB
C++
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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