日志功能相关头文件:
其中宏定义的AbsolutePath "/home/linux/11.30"是用于存储日志文件的路径
结构体struct DATE是用来对日志文件进行日期的区分,以保证同一天会将相关内容存入同一个文件,而不同日期下则会创建新的日志文件,便于进行查询。
枚举类型enum LogLevel用于对日志存储的内容进行分类。
#ifndef _LOG_H
#define _LOG_H
#include<stdio.h>
#include<dirent.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<time.h>
#include<string.h>
#include<fcntl.h>
#include<stdlib.h>
#include<unistd.h>
#include<stdarg.h>
#define AbsolutePath "/home/linux/11.30"
typedef struct DATE
{
int year;
int month;
int day;
}date_t;
typedef enum LogLevel
{
LOG_FATAL,
LOG_ERROR,
LOG_WARNING,
LOG_MESSAGE,
}Loglevel_t;
extern char *TIME(void);
extern int LogInit();
extern int LogWrite(int level, char *pcontent, ...);
extern int LogSetLevel(Loglevel_t level);
extern int LogDeinit(void);
extern int LogTreePrint(const char *filename);
#endif
日志源代码:
#include "log.h"
date_t filedate;
static FILE *fp = NULL;
Loglevel_t gCurLevel = LOG_MESSAGE;
char *TIME(void)
{
time_t t;
struct tm *ptm = NULL;
char *buffer = malloc(64);
time(&t);
ptm = localtime(&t);
sprintf(buffer, "%04d-%02d-%02d %02d:%02d:%02d", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);/***获得当前年月日时分秒***/
return buffer;
}
/***日志初始化***/
/**日志使用前需要进行初始化操作**/
int LogInit()
{
char dirpath[32] = {0};
char filename[64] = {0};
int year = 0;
int month = 0;
int day = 0;
char *DATE = TIME();
sscanf(DATE, "%4d-%2d-%2d", &year, &month, &day);
sprintf(dirpath, "%s/%d-%d-%d", AbsolutePath, year, month, day);
mkdir(dirpath, 0777);
sprintf(filename, "%s/debug_%d-%d-%d.log", dirpath, year, month, day);
filedate.year = year;
filedate.month = month;
filedate.day = day;
fp = fopen(filename, "a");
if(NULL == fp)
{
return -1;
}
free(DATE);
return 0;
}
/***调用该函数可以格式化写入内容到日志中***/
int LogWrite(int level, char *pcontent, ...)
{
va_list ap;
int year = 0;
int month = 0;
int day = 0;
char *perrorstr[4] = {"Serious Error", "Error", "Warning", "Message"};
if(level > gCurLevel)
{
return 0;
}
char *newTime = TIME();
sscanf(newTime, "%4d-%2d-%2d", &year, &month, &day);
if(filedate.year != year ||filedate.month != month || filedate.day != day)
{
LogDeinit();
LogInit();
}
fprintf(fp, "[%s][%s]", newTime, perrorstr[level]);
va_start(ap, pcontent);
vfprintf(fp, pcontent, ap);
va_end(ap);
fflush(fp);
free(newTime);
return 0;
}
int LogSetLevel(Loglevel_t level)
{
LogWrite(LOG_FATAL, "The log levl has changed from %d to %d\n",gCurLevel, level);
gCurLevel = level;
return 0;
}
/***日志文件关闭***/
/**程序即将结束前调用该函数**/
int LogDeinit(void)
{
if(NULL != fp)
{
fclose(fp);
fp = NULL;
}
return 0;
}
/***显示所有日志文件路径***/
int LogTreePrint(const char *filename)
{
DIR *dp = opendir(filename);
struct dirent *dir = NULL;
char filepath[1024] = {0};
if(dp == NULL)
{
perror("fail to opendir");
exit(0);
}
while(1)
{
dir = readdir(dp);
if(dir == NULL)
{
break;
}
if(*dir->d_name == '.')
{
continue;
}
sprintf(filepath,"%s/%s", filename, dir->d_name);
printf("%s\n",filepath);
if (dir->d_type == DT_DIR)
{
LogTreePrint(filepath);
}
}
return 0;
}