2013-10-31 125 views
2

我想這個端口logging語句的工作,所以它會在linux上運行和Android我#define'ing它:__android_log_print等值的printf

__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) 

我已經交叉編譯我的應用程序上運行Linux和Android。但是,由於linux沒有相應的功能,我試圖自己做。

/** ANDROID */ 
#if defined(__ANDROID__) 
#include <android/log.h> 
#define LOG_ERROR ANDROID_LOG_ERROR 
#define LOG(PRIORITY, fmt, ...) __android_log_print(ANDROID_LOG_UNKNOWN, LOG_TAG, fmt, ##__VA_ARGS__) 
/** LINUX */ 
#elif defined(linux) || defined(__linux) || defined(__linux__) 
#define LOG_ERROR LINUX_LOG_ERROR 
#define LOG(PRIORITY, fmt, ...) printf(PRIORITY fmt, ##__VA_ARGS__) 
#endif 

然後在linux下

LOG(LOG_ERROR, "Testing loggging [ %d ]", test); 

運行時,使用它像這樣有沒有更好的方式來做到這一點?

非常感謝您的任何建議,

回答

0

我設法解決這種方式。這是完整的解決方案。 這將是一個頭文件

typedef enum levels_tag levels_e; 
enum levels_tag { 
    LOG_UNKNOWN = 0, 
    LOG_DEFAULT, 
    LOG_VERBOSE, 
    LOG_DEBUG, 
    LOG_INFO, 
    LOG_WARN, 
    LOG_ERROR, 
    LOG_FATAL, 
    LOG_SILENT, 
    LOG_LAST 
}; 

/* ANDRIOD IMPLEMENTATION */ 
#if defined(__ARM_EABI__) 
#include <android/log.h> 

levels_e levels[LOG_LAST] = {LOG_UNKNOWN, 
          LOG_DEFAULT, 
          LOG_VERBOSE, 
          LOG_DEBUG, 
          LOG_INFO, 
          LOG_WARN, 
          LOG_ERROR, 
          LOG_FATAL, 
          LOG_SILENT}; 

#define LOG_TAG "MODULE_LOG_SIP" 

#define LOGGING(PRIORITY, fmt, ...) __android_log_print(levels[PRIORITY], LOG_TAG, fmt, ##__VA_ARGS__) 

/* LINUX IMPLEMENTATION */ 
#elif defined(linux) || defined(__linux) || defined(__linux__) 

char *priority_levels[] = {"UNKNOWN", 
          "DEFAULT", 
          "VERBOSE", 
          "DEBUG", 
          "INFO", 
          "WARN", 
          "ERROR", 
          "FATAL", 
          "SILENT", 
          NULL }; 

#define LOGGING(PRIORITY, fmt, ...)          \ 
    do {                \ 
     char *priority = priority_levels[PRIORITY];      \ 
     printf("%s/%s:%d [%s] " fmt " \n", __FILE__, __func__, __LINE__, priority, ##__VA_ARGS__); \ 
    } while(0) 

#endif 

#define LOG(PRIORITY, fmt, ...) LOGGING(PRIORITY, fmt, ##__VA_ARGS__) 

而在你的源文件,你只需調用日誌宏是這樣的:

LOG(LOG_FATAL, "Failed to create and initialize application instance [ %d ]", errno); 

現在,如果你要編譯在Linux上,將使用中的printf聲明。如果你要在Android上編譯,它將使用__android_log_print語句。兩者都會產生相同的格式化輸出。

希望這可以幫助別人。

+0

爲什麼'do {...} while(0)'循環呢? – Oliv

+0

爲什麼你首先定義LOGGING然後LOG? – Oliv

0

您還可以使用系統日誌的家庭()函數,使輸出到系統日誌而不是標準輸出/標準錯誤(見syslog.h):

void openlog(const char *ident, int option, int facility); 
void syslog(int priority, const char *format, ...); 
void closelog(void); 

日誌可以在/ var/log中查看(文件取決於syslog的選項,默認情況下,在許多系統中日誌都在文件「messages」中)。有時候這種方式比stdout/stderr更好,但你必須使用openlog/closelog。不幸的是,與android優先級相比,syslog的優先級不同,因此它不允許具有透明優先級的簡單宏定義。
的Syslog優先級:
的Android日誌

#define LOG_EMERG 0 /* system is unusable */ 
#define LOG_ALERT 1 /* action must be taken immediately */ 
#define LOG_CRIT 2 /* critical conditions */ 
#define LOG_ERR  3 /* error conditions */ 
#define LOG_WARNING 4 /* warning conditions */ 
#define LOG_NOTICE 5 /* normal but significant condition */ 
#define LOG_INFO 6 /* informational */ 
#define LOG_DEBUG 7 /* debug-level messages */ 

重點:

/* 
* Android log priority values, in ascending priority order. 
*/ 
typedef enum android_LogPriority { 
    ANDROID_LOG_UNKNOWN = 0, 
    ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */ 
    ANDROID_LOG_VERBOSE, 
    ANDROID_LOG_DEBUG, 
    ANDROID_LOG_INFO, 
    ANDROID_LOG_WARN, 
    ANDROID_LOG_ERROR, 
    ANDROID_LOG_FATAL, 
    ANDROID_LOG_SILENT,  /* only for SetMinPriority(); must be last */ 
} android_LogPriority;