zlog学习笔记(zc_profile)

zc_profile.h

#ifndef __zlog_profile_h
#define __zlog_profile_h

#define EMPTY()

#define zc_assert(expr, rc) 
        if(!(expr)){ 
                zc_error(#expr"is null or 0"); 
                return rc; 
        }

/**
 * 枚举类型,列举出所有profile支持的flag
 */
enum zc_profile_flag{
        ZC_DEBUG = 0,
        ZC_WARN = 1,
        ZC_ERROR = 2
};

enum test {
        A = 1,
        B = 2,
        C = 3
};

#define zc_debug(...) 
        zc_profile_inner(ZC_DEBUG, __FILE__, __LINE__, __VA_ARGS__)

#define zc_warn(...) 
        zc_profile_inner(ZC_WARN, __FILE__, __LINE__, __VA_ARGS__)

#define zc_error(...) 
        zc_profile_inner(ZC_ERROR, __FILE__, __LINE__, __VA_ARGS__)

int zc_profile_inner(int flag, 
        const char *file, const long line, 
        const char *fmt, ...);

#endif

zc_profile.c

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>

#include "zc_profile.h"

/**
 * 获取当前时间字符串
 */
static void zc_time(char *time_str, size_t time_str_size){
        time_t tt;
        struct tm local_time;

        //获取当前系统时间戳
        time(&tt);
        //使用当前时间戳填充tm结构体, 相比localtime,线程安全
        localtime_r(&tt, &local_time);
        strftime(time_str, time_str_size, "%m-%d %T", &local_time);

        return ;
}

int zc_profile_inner(int flag, const char *file, const long line, const char *fmt, ...){
        va_list args;
        char time_str[20 + 1];
        FILE *fp = NULL;

        static char *debug_log = NULL;
        static char *error_log = NULL;
        //记录debug、error是否被初始化过
        static size_t init_flag = 0;

        if(!init_flag){
                init_flag = 1;
                //stdlib getenv 获取环境变量
                debug_log = getenv("ZLOG_PROFILE_DEBUG");
                error_log = getenv("ZLOG_PROFILE_ERROR");
        }

        switch(flag){
                case ZC_DEBUG:
                        if(debug_log == NULL){
                                return 0;
                        }
                        //以附加的方式打开只写文件
                        fp = fopen(debug_log, "a");
                        if(!fp){
                                return -1;
                        }
                        zc_time(time_str, sizeof(time_str));
                        //将格式化的字符写入文件
                        /**
                         * 将格式化的字符写入文件
                         *   sys/types.h
                         *   unistd.h
                         *      pid_t getpid(void)
                         */
                        fprintf(fp, "%s DEBUG (%d:%s:%ld) ", time_str, getpid(), file, line);
                        break;
                case ZC_WARN:
                        if(error_log == NULL){
                                return 0;
                        }
                        fp = fopen(debug_log, "a");
                        if(!fp){
                                return -1;
                        }
                        zc_time(time_str, sizeof(time_str));
                        fprintf(fp, "%s WARN (%d:%s:%ld) ", time_str, getpid(), file, line);
                        break;
                case ZC_ERROR:
                        if(error_log == NULL){
                                return 0;
                        }
                        fp = fopen(debug_log, "a");
                        if(!fp){
                                return -1;
                        }
                        zc_time(time_str, sizeof(time_str));
                        fprintf(fp, "%s ERROR (%d:%s:%ld) ", time_str, getpid(), file, line);
                        break;
        }

        va_start(args, fmt);
        vfprintf(fp, fmt, args);
        va_end(args);
        fprintf(fp, "
");

        fclose(fp);
        return 0;
}