2011-09-14 100 views
7

我有一個用C編寫的守護進程。我將事件記錄在日誌文件中,但現在我想在將事件寫入日誌文件時添加日期和時間。我怎樣才能做到這一點?如何在日誌文件中引入日期和時間

當前日誌文件: -

Event one occurred: result: 
Event two occurred: result: 

我想日誌文件看起來像: -

Sep 14 11:35:55 Event one occurred: result: 
Sep 14 11:35:55 Event two occurred: result: 

我的環境是C和Linux。

+0

@Jonathan萊弗勒,我面臨的,因爲很長一段時間,這些調整問題,有沒有參考頁至REF,並採取照顧自己? – Thangaraj

+1

你的意思是你的問題中的佈局?輸入評論時,有一個幫助超鏈接;當輸入問題或答案時,會有一個橙色問號提供打字區域上方的幫助。縮進4個空格將以下代碼作爲代碼處理;避免製表符。項目符號列表具有以星號或短劃線('*'或'-')開頭的行;你可以嵌套它們(子項目縮進2個或更多的空格),並且你可以有與它們相關的代碼(前綴爲8個空格,而不是4個,但是對於第一級項目符號)。編號列表有從'1'開始的行(這個點很重要)。等等 –

+0

@Jonathan Leffler,謝謝 – Thangaraj

回答

12

您需要查看使用dategmtimelocaltime以獲取實際日期和時間。

然後strftime可以爲你格式化。

示例程序如下:

#include <stdio.h> 
#include <time.h> 

int main (void) { 
    char buff[20]; 
    struct tm *sTm; 

    time_t now = time (0); 
    sTm = gmtime (&now); 

    strftime (buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", sTm); 
    printf ("%s %s\n", buff, "Event occurred now"); 

    return 0; 
} 

此輸出:

2011-09-14 04:52:11 Event occurred now 

我喜歡使用UTC而不是本地時間,因爲它可以讓你綁從地理上分離機一起事件,而不必擔心時區差異。換句話說,使用gmtime而不是localtime,除非你是非常確定你不會穿越時區。

我也傾向於選擇YYYY-MM-DD HH:MM:SS格式,因爲它比月份名稱更容易排序,這對於提取和操作工具來說至關重要。

+0

這些庫的使用是否會導致可移植性問題? – Thangaraj

+0

這些都是純粹的C89功能 - 它們大概就像你可以合理希望的那樣便攜。守護進程的許多其他部分不易攜帶,這是肯定的。 –

+0

@Thangaraj:不,它們都是在ISO C中定義的,就像你可以得到的便攜一樣:-) – paxdiablo

4

爲了得到當前的時間,你可以使用time.h例如...

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main(void) 
{ 
    time_t now; 
    time(&now); 

    printf("%s", ctime(&now)); // use ctime to format time to a string. 

    return EXIT_SUCCESS; 
} 

您還可以使用strftime由paxdiablo更多的時間/日期格式的可能性建議。

當然,對於您的情況,ctime(&now)的結果將進入您的日誌條目字符數組/字符串而不是printf

+0

它可能會更好(雖然基本上等價)使用:'time_t now = time(0);'。 –

+0

@Jonathan Leffler - 學術真的但是是的,基本相同。無論如何,paxdiablo的答案比我現在的答案更完整,我只是發佈這個來鼓勵他添加一個代碼示例。 ;) – ocodo

+0

gr8後...幫助我很多...謝謝 – 2vision2

6

根據@paxdiablo的回答添加我的日誌功能。使用本地時間,但可能只是通過修改getFormattedTime()

COMMON.H

// Returns the local date/time formatted as 2014-03-19 11:11:52 
char* getFormattedTime(void); 

// Remove path from filename 
#define __SHORT_FILE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) 

// Main log macro 
#define __LOG__(format, loglevel, ...) printf("%s %-5s [%s] [%s:%d] " format "\n", getFormattedTime(), loglevel, __func__, __SHORT_FILE__, __LINE__, ## __VA_ARGS__) 

// Specific log macros with 
#define LOGDEBUG(format, ...) __LOG__(format, "DEBUG", ## __VA_ARGS__) 
#define LOGWARN(format, ...) __LOG__(format, "WARN", ## __VA_ARGS__) 
#define LOGERROR(format, ...) __LOG__(format, "ERROR", ## __VA_ARGS__) 
#define LOGINFO(format, ...) __LOG__(format, "INFO", ## __VA_ARGS__) 

common.c中

#include <time.h> // time_t, tm, time, localtime, strftime 

// Returns the local date/time formatted as 2014-03-19 11:11:52 
char* getFormattedTime(void) { 

    time_t rawtime; 
    struct tm* timeinfo; 

    time(&rawtime); 
    timeinfo = localtime(&rawtime); 

    // Must be static, otherwise won't work 
    static char _retval[20]; 
    strftime(_retval, sizeof(_retval), "%Y-%m-%d %H:%M:%S", timeinfo); 

    return _retval; 
} 

您可以使用它們像這樣使用GMT:

LOGDEBUG("This is a log"); 
LOGDEBUG("This is a log with params %d", 42); 

哪個產生輸出:

2014-03-19 13:22:14 DEBUG [main] [main.c:54] This is a log 
2014-03-19 13:22:14 DEBUG [main] [main.c:55] This is a log with params 42 
1

根據@inolasco的回答,靜態變量不是線程安全的。改用局部變量。

void getFormattedTime(char * const p, int sz) { 
    time_t rawtime; 
    struct tm* timeinfo; 
    time(&rawtime); 
    timeinfo = localtime(&rawtime); 
    strftime(p, sz, "%Y-%m-%d %H:%M:%S", timeinfo); 
} 

int mylog(const char* fmt, ...) { 
    // TODO: log to file also. 
    // TODO: create a new log file daily 
    va_list argptr; 
    va_start(argptr, fmt); 
    vfprintf(stderr, fmt, argptr);//log to stderr 
    va_end(argptr); 
} 


#ifdef _WIN32 
#define __SHORT_FILE__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) 
#else 
#define __SHORT_FILE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) 
#endif 

#define ___LOG___(fmt,level,path, ...) do{\ 
    /* using local var and using a long name to avoid conflict*/ \ 
    char LAgGV3nzJsTholGvGL2eTNXmhsqYe___xxooxxoo___[24];\ 
    getFormattedTime(LAgGV3nzJsTholGvGL2eTNXmhsqYe___xxooxxoo___,\ 
     sizeof(LAgGV3nzJsTholGvGL2eTNXmhsqYe___xxooxxoo___));\ 
    mylog("%s [%s] [%s:%d] [%s] " fmt "\n", \ 
     LAgGV3nzJsTholGvGL2eTNXmhsqYe___xxooxxoo___, \ 
     level,\ 
     path,\ 
     __LINE__, \ 
     __func__, \ 
     ## __VA_ARGS__);\ 
}while(0) 

#define trace(fmt, ...) ___LOG___(fmt, "TRACE",__SHORT_FILE__, ## __VA_ARGS__) 
#define debug(fmt, ...) ___LOG___(fmt, "DEBUG",__SHORT_FILE__, ## __VA_ARGS__) 
#define info(fmt, ...) ___LOG___(fmt, "INFO",__SHORT_FILE__, ## __VA_ARGS__) 
#define warn(fmt, ...) ___LOG___(fmt, "WARN",__SHORT_FILE__, ## __VA_ARGS__) 
#define error(fmt, ...) ___LOG___(fmt, "ERROR",__SHORT_FILE__, ## __VA_ARGS__) 
#define tracel(fmt, ...) ___LOG___(fmt, "TRACE",  __FILE__, ## __VA_ARGS__) 
#define debugl(fmt, ...) ___LOG___(fmt, "DEBUG",  __FILE__, ## __VA_ARGS__) 
#define infol(fmt, ...) ___LOG___(fmt, "INFO",  __FILE__, ## __VA_ARGS__) 
#define warnl(fmt, ...) ___LOG___(fmt, "WARN",  __FILE__, ## __VA_ARGS__) 
#define errorl(fmt, ...) ___LOG___(fmt, "ERROR",  __FILE__, ## __VA_ARGS__) 

稱他們是這樣的:

info("%s", "a log"); 
infol("%s", "a log"); 

產品:

2017-09-06 15:55:42 [INFO] [main.c:25] [main] a log 
2017-09-06 15:58:08 [INFO] [d:\main.c:25] [main] a log 
相關問題