log日志实现

实例

file.h

#ifndef _FILE_H
#define _FILE_H

#include <stdio.h>
#include <stdlib.h>

#define LOG_LEVEL_FATAL  0
#define LOG_LEVEL_ERROR  1
#define LOG_LEVEL_WARN  2
#define LOG_LEVEL_INFO  3
#define LOG_LEVEL_DEBUG  4
#define LOG_LEVEL_MAX   5

#define self_dbg printf
#define self_err printf
#define self_warn printf
#define self_info printf

typedef enum {
​    LOG_OFF = 0,
​    LOG_ON
} LOG_SWITCH;

struct log_config{
​    unsigned int global_log_level;
​    unsigned int log_buf_size;
​    LOG_SWITCH logfile_log_to_file_switch;
​    char logfile_log_files_dir[256];
​    unsigned int logfile_nr_rolling_files;
​    unsigned long long logfile_max_file_size;
​    unsigned int logfile_flush_to_disk_period;
};

struct log_config* get_log_configs(void);
static int get_exec_name(char *name);
static int log_files_dir_init(char* dir);
LOG_SWITCH get_log_file_switch_status(void);
void output_log_to_file(char *log, unsigned int size);
void log_to_file_init(void);

#endif

file.c

#include <fcntl.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include "file.h"

static unsigned int timer_counter;
static pthread_mutex_t log_dir_path_mutex;
static unsigned int log_dir_path_change;
static FILE *file_fp = NULL;
static unsigned long long log_file_size;

static struct log_config log_cfgs = {
​    .global_log_level = LOG_LEVEL_INFO,
​    .log_buf_size = 0x100000, // 1MBytes
​    .logfile_log_to_file_switch = LOG_OFF,
​    .logfile_nr_rolling_files = 8, // default save 8 log files
​    .logfile_max_file_size = 0xffffff,
​    .logfile_flush_to_disk_period = 1,
};

static int get_exec_name(char *name)
{
​    char path[1024]={0};
​    int ret = readlink("/proc/self/exe",path,sizeof(path)-1);
​    if(ret == -1)
​    {
​       printf("---- get exec name fail!!\n");
​        return -1;
​    }

​    path[ret]= '\0';

​    char *ptr = strrchr(path,'/');
​    strcpy(name, ptr+1);

​    return 0;
}

static void* timer_thread(void *arg)
{
  while(1) {
​       sleep(get_log_configs()->logfile_flush_to_disk_period);
​       timer_counter++;
  }

​    return NULL;
}

struct log_config* get_log_configs(void)
{
​    return &log_cfgs;
}

static int log_files_dir_init(char* dir)
{
​    char cmd[256];
​    char path_index[256];
​    char path_log_dir[256];
​    char process_name[256];
​    char path_log_file[256];
​    char path_link_cur_log[256];
​    FILE *fp;
​    unsigned int index;
​    char buf[32];
​    int n;

​    get_exec_name(process_name);
​    sprintf(path_log_dir, "%s/%s", dir, process_name);

​    if (-1 == access(path_log_dir, 0)) {
​       /* log dir is not exists, so create it */
​       sprintf(cmd, "mkdir -p %s", path_log_dir);
​       system(cmd);
​    }

​    sprintf(path_index, "%s/index", path_log_dir);
​    if (-1 == access(path_index, 0)) {
​       index = 0;
​    } else {
​       fp = fopen(path_index, "r");
​       if (NULL == fp) {
​           self_err("open file: %s error:%d\n", path_index, errno);
​           return -errno;
​       }
​       n = fread(buf, 1, sizeof(buf), fp);
​       self_dbg("read index file: n:%d content:%s\n", n, buf);
​       if (0 == n)
​           index = 0;
​       else {
​           index = strtoul(buf, NULL, 10);
​           index++;
​       }

​       fclose(fp);
​    }

​    fp = fopen(path_index, "w");
​    if (NULL == fp) {
​       self_err("open file: %s error:%d\n", path_index, errno);
​       return -errno;
​    }

​    sprintf(buf, "%d", index);
​    self_dbg("index:%d, write to index file buf:%s\n", index, buf);
​    fwrite(buf, 1, strlen(buf), fp);
​    fflush(fp);
​    fclose(fp);

​    if (index >= get_log_configs()->logfile_nr_rolling_files) {
​       sprintf(path_log_file, "%s/%s_%d.log", path_log_dir, process_name,
​              index - get_log_configs()->logfile_nr_rolling_files);
​       remove(path_log_file);
​    }

​    sprintf(path_log_file, "%s/%s_%d.log", path_log_dir, process_name, index);
​    file_fp = fopen(path_log_file, "w");
​    if (NULL == file_fp) {
​       self_err("open file: %s error:%d\n", path_log_file, errno);
​    }
​    log_file_size = 0;

​    sprintf(path_link_cur_log, "%s/current.log", path_log_dir);
​    self_dbg("path_log_file: %s path_link_cur_log:%s\n",
​              path_log_file, path_link_cur_log);

​    sprintf(cmd, "rm -f %s", path_link_cur_log);
​    self_dbg("cmd:%s\n", cmd);
​    system(cmd);

​    sprintf(cmd, "ln -s %s %s", path_log_file, path_link_cur_log);
​    self_dbg("cmd:%s\n", cmd);
​    system(cmd);

​    return 0;
}

LOG_SWITCH get_log_file_switch_status(void)
{
​    return get_log_configs()->logfile_log_to_file_switch;
}

void output_log_to_file(char *log, unsigned int size)
{
​    static unsigned int last_counter = 0;
​    struct log_config *cfg = get_log_configs();

​    if (log_dir_path_change) {
​       pthread_mutex_lock(&log_dir_path_mutex);
​       log_dir_path_change = 0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值