Linux系统和Android系统用户层C/C++开发 debug日志记录驱动源码

该驱动适用于采用linux和android系统平台的C/C++开发。

格式化的日志字符串输入参数,日志时间精确到毫秒。

使用示例:int var1 = 7;
         int var2 = 1;
         log("android %d.%d",var1,var2);
          
         执行上述代码,会在当前文件目录下生成log.txt日志文件,并记录日志:
         2018-08-15 05:37:45-384 android 7.1

源代码如下:

log.h

//
// Created by taxiang&xuezi on 2018/4/2.
//

#ifndef NDKAPPECG_LOG_H
#define NDKAPPECG_LOG_H

#ifdef  LOG_GLOBALS       //声明和定义切换   方便管理,减少各*.c/*.c++驱动模块之间的冗余度
#define LOG_EXT
#else
#define LOG_EXT extern
#endif

#define LOG_PDBG          1//控制控制台消息的打印和关闭,user_debug版开启,user版关闭
#define LOG_DBG           2//控制日志的打印和关闭,user_debug版开启,user版可根据需要关闭 

LOG_EXT int log(const char *format, ...);
#endif //NDKAPPECG_LOG_H



log.c/log.cpp

//
// Created by taxiang&xuezi on 2018/4/2.
//

#define LOG_GLOBALS//注意这个位置的定义,参考log.h注释自己体会吧,这样以后你就不会忘记了 ^_^/
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <time.h>


#ifdef LOG_PDBG//这个其实可以参照log()的方法修改成更简单的,在此保持多样性,同时留给你练习掌握的空间 ^_^/
#define LOG_PRINT0(X)  printf(X);      
#define LOG_PRINT1(X,A)  printf (X,A);
#define LOG_PRINT2(X,A,B)  printf (X,A,B);
#define LOG_PRINT3(X,A,B,C)  printf (X,A,B,C);
#else
#define LOG_PRINT0(X)
#define LOG_PRINT1(X,A)
#define LOG_PRINT2(X,A,B)
#define LOG_PRINT3(X,A,B,C)
#endif



#ifdef LOG_DBG
static pthread_mutex_t fileMutex = PTHREAD_MUTEX_INITIALIZER;
/*******************************************************************************
* 函数名称: int safe_vasprintf(char **strp, const char *fmt, va_list ap)
* 函数功能:
* 输入参数:
* 输出参数:
* 返回值  :
*******************************************************************************/
int safe_vasprintf(char **strp, const char *fmt, va_list ap)
{
    int retval = vasprintf(strp, fmt, ap);
    if(retval == -1){
        LOG_PRINT1("failed to vasprintf: %s.  bailing out\n", strerror(errno));
        return 1;
    }

    return retval;
}

/*******************************************************************************
* 函数名称: int log(const char *format, ...)
* 函数功能: 记录日志到指定文件
* 输入参数: 格式化日志字符串
* 输出参数: 
* 返回值  :
*******************************************************************************/
int log(const char *format, ...)
{
    pthread_mutex_lock(&fileMutex);

    FILE *fp = NULL;
    va_list vlist;
    char *log_buf = NULL;

    fp = fopen("log.txt", "a+");
    if(fp == NULL){
        pthread_mutex_unlock(&fileMutex);
        LOG_PRINT3("%s [%s:%d]\n", strerror(errno), __FILE__, __LINE__);
        return -1;
    }

    va_start(vlist, format);
    safe_vasprintf(&log_buf, format, vlist);
    va_end(vlist);
    if(log_buf == NULL){
        pthread_mutex_unlock(&fileMutex);
        LOG_PRINT3("%s [%s:%d]\n", strerror(errno), __FILE__, __LINE__);
        return -2;
    }

    time_t t;
    struct tm *tm_now = NULL;
    struct timeval tv;
    time(&t);
    tm_now = localtime(&t);
    gettimeofday(&tv,NULL);
    fprintf(fp, "%04d-%02d-%02d %02d:%02d:%02d-%03d %s\n",
            tm_now->tm_year + 1900,
            tm_now->tm_mon + 1,
            tm_now->tm_mday,
            tm_now->tm_hour,
            tm_now->tm_min,
            tm_now->tm_sec,
            (s32)(tv.tv_usec/1000),
            log_buf);

    free(log_buf);
    fflush(fp);
    fsync(fileno(fp));
    fclose(fp);

    pthread_mutex_unlock(&fileMutex);

    return 0;
}
#else
/*******************************************************************************
* 函数名称: int log(const char *format, ...)
* 函数功能:
* 输入参数:
* 输出参数:
* 返回值  :
*******************************************************************************/
int log(const char *format, ...)
{
    return 0;
}
#endif





希望能帮到你,记得帮我点赞呀 ^_^/ ^_^/ ^_^/ ^_^/ ^_^/ ^_^/ ^_^/
 

猜你喜欢

转载自blog.csdn.net/weixin_40779546/article/details/81698031