linux - 日志

目录

log.h

log.c

log.demo.c

运行演示


log.h

#ifndef LOG_H
#define LOG_H
/* ************************************************************************************ */

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <sys/types.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>

//C++中建议将define 改为 const
#define LOG_PROCNAME      0x00000001              /* msglog 输出日志时打印程序名        */
#define LOG_PID           0x00000010              /* msglog 输出日志时打印进程 PID      */
#define LOG_PERROR        0x00000100              /* msglog 是否把告警内容输出到stderr  */
#define NLO_PROCNAME      0x11111110              /* msglog 不输出程序名                */
#define NLO_PID           0x11111101              /* msglog 不输出进程 PID              */
#define NLO_PERROR        0x11111011              /* msglog 不输出告警到stderr          */

//日志级别  日志级别越高打印的日志越多 
#define MSG_INFO          0x00000001              /* msglog 输出到告警日志文件中        */
#define MSG_WARN          0x00000010              /* msglog 输出到普通日志文件中        */
#define MSG_BOTH          MSG_INFO|MSG_WARN       /* msglog 输出到普通和告警日志文件中  */

#define LOG_MESSAGE_FILE  "/home/holo/epoll_fwq/log/tcpsvr"           /* 系统程序运行日志信息文件           */
#define LOG_MESSAGE_DFMT  "%m-%d %H:%M:%S"        /* 日志信息时间格式字串               */
#define LOG_POSTFIX_MESS  "%y%m"                  /* 程序运行日志信息文件后缀           */
#define LOG_WARNING_FILE  "/home/holo/epoll_fwq/log/log.sys_warn"   /* 系统程序运行告警日志文件           */
#define LOG_WARNING_DFMT  "%m-%d %H:%M:%S"        /* 告警信息时间格式字串               */
#define LOG_POSTFIX_WARN  ""                      /* 程序运行告警日志文件后缀(拓展名),默认没有   */

/* ************************************************************************************ */
int msglog(int mtype, char *outfmt, ...);//写日志文件函数
int msgLogFormat(int mopt, char *mdfmt, int wopt, char *wdfmt);//按照格式写日志文件,对日志格式化 参数中没有看到路径,说明用到了全局变量
int msgLogOpen(char *ident, char *mpre, char *mdate, char *wpre, char *wdate);//打开日志文件

int msgLogClose(void);//关闭日志文件

long begusec_process(void);                      /* 设置开始时间 0=ok                   */
long getusec_process(void);                      /* 获得时间 返回usecond 从 begusec_process历时  */

int msgInit(char *pName);	//获得文件名
#endif
/* ************************************************************************************ */
/* ************************************************************************************ */
/* ************************************************************************************ */
/* ************************************************************************************ */



log.c


#include "log.h"

static int  msgopt, wanopt;
static char msgdatefmt[100], wandatefmt[100], ident_name[100];
static struct timeval be_stime;
static FILE *msgfile = NULL, *wanfile = NULL;	//静态变量生命周期和进程相同
/* ************************************************************************************ */
/* ************************************************************************************ */
/* ************************************************************************************ */
//日志文件初始化,也可以通过msgLogOpen进行初始化
int msgInit(char *pName)
{
    if (msgLogOpen(pName, LOG_MESSAGE_FILE, LOG_POSTFIX_MESS,LOG_WARNING_FILE, LOG_POSTFIX_WARN) == 0)
    {
		//对日志文件格式化, 按照指定格式显示
        msgLogFormat(LOG_PROCNAME|LOG_PID, LOG_MESSAGE_DFMT, LOG_PROCNAME|LOG_PID, LOG_WARNING_DFMT);
    }
    else                                                                                                
    {
        printf("can not create log!\n");
        return -1;
    }
    return 0;
}
/* ************************************************************************************ */
/* 文件作用: 打开日志文件 */
int msgLogOpen(char *ident, char *mpre, char *mdate, char *wpre, char *wdate) 
{
    time_t now_time;
    char openfilename[200], timestring[100];

    now_time = time(NULL);
    if ((!msgfile) && (*mpre))
    {
        strcpy(openfilename, mpre);
        if (*mdate)
        {
            strftime(timestring, sizeof(timestring), mdate, localtime(&now_time));
            strcat(openfilename, ".");
            strcat(openfilename, timestring);
        }
		//返回文件指针, 保存到静态文件变量msgfile里
        if ((msgfile = fopen(openfilename, "a+b")) == NULL)		//a+b:追加+二进制  linux下没有b
        { /* 如果没有应该把目录建上 */
            printf("openfilename=%s\n", openfilename);
            return -1;
        }
        setlinebuf(msgfile);
    }
    if ((!wanfile) && (*wpre))
    {
        strcpy(openfilename, wpre);
        if (*wdate)
        {
            strftime(timestring, sizeof(timestring), wdate, localtime(&now_time));
            strcat(openfilename, ".");
            strcat(openfilename, timestring);
        }
        if ((wanfile = fopen(openfilename, "a+b")) == NULL)
        {
            return -1;
        }
        setlinebuf(wanfile);
    }
    if ((msgfile) && (wanfile))
    {
        if (*ident)
        {
            strcpy(ident_name, ident);
        } else {
            ident_name[0] = '\0';
        }
        msgopt = LOG_PROCNAME|LOG_PID;          /* 设置默认信息输出信息选项              */
        wanopt = LOG_PROCNAME|LOG_PID;          /* 设置默认告警输出信息选项              */
        strcpy(msgdatefmt, "%m-%d %H:%M:%S");   /* 默认信息输出时间格式 MM-DD HH24:MI:SS */
        strcpy(wandatefmt, "%m-%d %H:%M:%S");   /* 默认告警输出时间格式 MM-DD HH24:MI:SS */

        msglog(MSG_INFO,"File is msgfile=[%d],wanfile=[%d].",fileno(msgfile),fileno(wanfile));
        return 0;
    } else {
        return -1;
    }
}
/* ************************************************************************************ */
/* 自定义日志输出函数系列,可以按普通信息及告警信息分类输出程序日志                      */
/*
 * 函数作用:  写日志文件
 */
int msglog(int mtype, char *outfmt, ...) 
{
    time_t now_time;
    va_list ap;//变参的列表
    char logprefix[1024], tmpstring[1024];

    time(&now_time);
    if (mtype & MSG_INFO)
    { /*strftime会将localtime(&now_time)按照msgdatefmt格式,输出到logprefix.*/
        strftime(logprefix, sizeof(logprefix), msgdatefmt, localtime(&now_time));
        strcat(logprefix, " ");
        /*static int  msgopt,wanopt;*/
        if (msgopt&LOG_PROCNAME)
        {
            strcat(logprefix, ident_name);
            strcat(logprefix, " ");
        }
        if (msgopt&LOG_PID)
        {
            sprintf(tmpstring, "[%6d]", getpid());
            strcat(logprefix, tmpstring);
        }
        fprintf(msgfile, "%s: ", logprefix);	//调用底层的写日志函数
        va_start(ap, outfmt);	//处理可变参数的函数  ap:变参列表即 fpaintf里的"%s %s" 第二个参数
        vfprintf(msgfile, outfmt, ap);
        va_end(ap);
        fprintf(msgfile, "\n");
    }
    if (mtype & MSG_WARN)
    {
        strftime(logprefix, sizeof(logprefix), wandatefmt, localtime(&now_time));
        strcat(logprefix, " ");
        /*#define LOG_PROCNAME      0x00000001*/              /* msglog 输出日志时打印程序名        */
        if (wanopt & LOG_PROCNAME)
        {
            strcat(logprefix, ident_name);
            strcat(logprefix, " ");
        }
        if (wanopt & LOG_PID)
        {
            sprintf(tmpstring, "[%6d]", getpid());
            strcat(logprefix, tmpstring);
        }
        fprintf(wanfile, "%s: ", logprefix);
        va_start(ap, outfmt);
        vfprintf(wanfile, outfmt, ap);
        va_end(ap);
        fprintf(wanfile, "\n");	//用fprintf写日志的好处:可以格式化, 用sprintf和write组合起来可以代替fprintf
        if (wanopt & LOG_PERROR)
        {
            fprintf(stderr, "%s: ", logprefix);
            va_start(ap, outfmt);
            vfprintf(stderr, outfmt, ap);
            va_end(ap);
            fprintf(stderr, "\n");
        }
    }

    return 0;
}
/* ************************************************************************************ */
/* 
 * 函数作用: 设置日志格式,和选项  */
int msgLogFormat(int mopt, char *mdfmt, int wopt, char *wdfmt)   
{
    if (mopt >= 0)
    {
        msgopt = mopt;
    } else {
        msgopt = msgopt & mopt;
    }
    if (wopt >= 0)
    {
        wanopt = wopt;
    } else {
        wanopt = wanopt & wopt;
    }

    if (*mdfmt) strcpy(msgdatefmt, mdfmt);
    if (*wdfmt) strcpy(wandatefmt, wdfmt);

    return 0;
}
/* ************************************************************************************ */
int msgLogClose(void)                                           /* 关闭日志文件         */
{
    if (msgfile) fclose(msgfile);
    if (wanfile) fclose(wanfile);

    return 0;
}
/* ************************************************************************************ */
long begusec_process(void)                      /* 设置开始时间 0=ok                    */
{
    gettimeofday(&be_stime,NULL);

    return 0;
}
/* ************************************************************************************ */
// 函数作用: 返回进程执行了多少时间
long getusec_process(void)                      /* 返回usecond 从 begusec_process历时   */
{
    struct timeval ed_stime;

    gettimeofday(&ed_stime,NULL);

    return ((ed_stime.tv_sec-be_stime.tv_sec)*1000000+ed_stime.tv_usec-be_stime.tv_usec);
}
/* ************************************************************************************ */
/* ************************************************************************************ */
/* ************************************************************************************ */
/* ************************************************************************************ */

log.demo.c

#include "log.h"


int main(int argc,char *argv[])
{
    char *pName = argv[0];
    pName +=2; 		//跳过./
    printf("pName is %s\n",pName);
    msgInit("log_demo");
    msglog(MSG_INFO,"begin run program....");
    sleep(2);
    msglog(MSG_BOTH,"begin to game over...%ld",time(NULL));
    msgLogClose();
    return 0;
}

运行演示

log_demo.c:14:5: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 2 has type ‘__pid_t’ [-Wformat=]
     printf("%ld\n",getpid());
     ^
holo@holo:~/epoll_fwq$ ./log_demo 
pName is log_demo
97125
holo@holo:~/epoll_fwq$ cat log/tcpsvr.2311 
11-09 14:18:31 log_demo [ 93388]: File is msgfile=[3],wanfile=[4].
11-09 14:18:31 log_demo [ 93388]: begin run program....
11-09 14:18:33 log_demo [ 93388]: begin to game over...1699510713
11-09 14:23:55 log_demo [ 97125]: File is msgfile=[3],wanfile=[4].
11-09 14:23:55 log_demo [ 97125]: begin run program....
11-09 14:23:57 log_demo [ 97125]: begin to game over...1699511037
holo@holo:~/epoll_fwq$ cd log
holo@holo:~/epoll_fwq/log$ ls
log.sys_warn  tcpsvr.2311
holo@holo:~/epoll_fwq/log$ cat log.sys_warn 
11-09 14:18:33 log_demo [ 93388]: begin to game over...1699510713
11-09 14:23:57 log_demo [ 97125]: begin to game over...1699511037
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值