Linux/Android系統開發 日誌驅動源碼, 格式化輸入

該驅動適用於採用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



 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章