基于Linux下的简易日志功能实现

日志功能相关头文件:

其中宏定义的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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值