1. 程式人生 > >c/c++列印帶完整附加資訊(帶時間戳、pid等)的日誌,類adb logcat -v threadtime格式

c/c++列印帶完整附加資訊(帶時間戳、pid等)的日誌,類adb logcat -v threadtime格式

近來在Linux下開發中用到c/c++和nodejs混合程式設計,看到adb logcat -v threadtime 打出來的Log那麼整齊規範,非常想把c/c++程式碼的log規範成這種效果一下,

需要這樣做有兩個原因:

1.有的人沒有用到adb, 或者log不輸出到控制檯,沒法用adb logcat -v threadtime。

2. adb logcat的時間戳是後加的,不是呼叫列印log當時的時間。我看到過logcat時間戳前後顛倒,或者間隔明顯不對的情況;系統io佔用較高情況下會出現這種問題。

於是嘗試自己printf加上時間戳,也就是這句話了:

#define MY_DEBUG(format, ...) printf("%s %d %d D %s: %s "#format "\n", timeString(), (int)getpid(), (int)syscall(SYS_gettid), TAG, __FUNCTION__, ##__VA_ARGS__)

巨集定義可以用...表示剩餘其他引數,在這個基礎上加上時間戳、pid、tid、TAG、functionname.

時間戳這個事確實沒有現成的,我通過timeString()函式自己根據clocktime算出來月、日、時、分、秒、毫秒,並格式化為固定寬度2位、3位。
獲取pid沒問題,但tid如果用gettid()經常報error: ‘gettid’ was not declared in this scope. 查了一下是個常見的glibc問題,索性用syscall(SYS_gettid)繞過。

上完整實驗程式碼:

#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <sys/syscall.h>
#define TAG "MY_TEST"
#define MY_DEBUG(format, ...) printf("%s %d %d D %s : %s "#format "\n", timeString(), (int)getpid(), (int)syscall(SYS_gettid), TAG, __FUNCTION__, ##__VA_ARGS__)
// #define LOG_D(format, ...) MY_DEBUG( D #format, ##__VA_ARGS__)


char * timeString() {
  struct timespec ts;
  clock_gettime( CLOCK_REALTIME, &ts);
  struct tm * timeinfo = localtime(&ts.tv_sec);
  static char timeStr[20];
  sprintf(timeStr, "%.2d-%.2d %.2d:%.2d:%.2d.%.3ld", timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, ts.tv_nsec / 1000000);
  return timeStr;
}


void testWait(int index, int second, int nanoSecond) {
    MY_DEBUG(wait time is: %ds %dns index: %d, second, nanoSecond, index);
  return;
}
int main(int argc, char** argv) {
  MY_DEBUG(test ok\n);
  for (int i = 0; i<4;i++) {
    testWait(i, 3, 2000020);
  }
  return 0;
}

adb logcat -v threadtime 輸出結果:

01-05 03:22:51.076 22982 22982 I CONSOLE : testWait wait time is: 3s 2000020ns 

編譯執行我的log後,g++  ./testWait.cpp  -o run -lrt 輸出結果:

$:~/test_code/lab$ g++  ./testWait.cpp  -o run -lrt

$:~/test_code/lab$ ./run 

12-26 10:45:32.360 7286 7286 D MY_TEST : main test ok

12-26 10:45:32.360 7286 7286 D MY_TEST : testWait wait time is: 3s 2000020ns index: 0

12-26 10:45:32.360 7286 7286 D MY_TEST : testWait wait time is: 3s 2000020ns index: 1

12-26 10:45:32.360 7286 7286 D MY_TEST : testWait wait time is: 3s 2000020ns index: 2

12-26 10:45:32.360 7286 7286 D MY_TEST : testWait wait time is: 3s 2000020ns index: 3

到這裡已經和logcat日誌一樣了,還剩下一個引號問題我一直沒有解決,細心的同學可能已經看到了,呼叫列印log時都沒有加引號
MY_DEBUG(wait time is: %ds %dns index: %d, second, nanoSecond, index);
因為加了引號後,輸出的testWait wait time……前後會各加一個“,看著不好看。不知道有啥辦法可以讓呼叫時的引號不打印出來。

12-26 10:44:12.869 4960 4960 D MY_TEST : testWait "wait time is: 3s 2000020ns index: 0"