登录C的问题

时间:2014-01-22 04:56:43

标签: c logging error-logging

我有很多函数,在输入每个函数时,我调用的是一个宏FUNC_ENTRY,它又调用默认的日志记录宏(LOGGING)。

具体来说,这是我的FUNC_ENTRY宏:

#define FUNC_ENTRY LOGGING(ONE, "Entry");

我的LOGGING宏定义如下:

#define LOGGING(prio, my_var, ...) \
{\
    char priority[6];\
    bzero(level,4); \
    if (prio == ONE) { sprintf(priority,"ONE");} \
    if (prio == TWO) { sprintf(priority,"TWO");} \
    if (prio == THREE) { sprintf(priority,"THREE");} \
    fprintf(fp,"%s:  %s:  %s:  %d: %s:%s|\n",__DATE__, __TIME__, __FILE__,__LINE__, __func__,level);\
    fflush(fp); \
    fprintf(fp,my_var,##__VA_ARGS__);\
    fflush(fp); \
    fprintf(fp,"\n");\
    fflush(fp); \
}

好的,现在我的问题是,每当我输入任何功能时,我的LOGGING宏应该打印"输入xyz功能"。截至目前,它只打印" Entry"。任何线索如何实现这一目标?

我调用FUNC_ENTRY宏的方式如下所示。 假设我有一个函数xyz;

void xyz {
  FUNC_ENTRY;
  /*other statements*/
}

2 个答案:

答案 0 :(得分:3)

有很多问题:

  1. 除非您认为经常编写有缺陷的代码,否则大多数目的都会有两个fflush(fp)次调用。

  2. '奇怪的是,您将level归零,声明并设置priority,但打印level仍为全零。

  3. 该片段足以保证功能。

  4. 您不希望在#define FUNCENTRY之后使用分号。

  5. '如果您未在宏中的字符串中包含Entry to xyz functionto,您认为应该function,这也很奇怪。

    < / LI>
  6. 在您的错误消息中编译文件的时间和日期似乎毫无意义(__DATE____TIME__是针对的)。

  7. 修复其中一些问题会导致:

    #define FUNC_ENTRY LOGGING(ONE, "Entry to %s function\n", __func__)
    
    #define LOGGING(prio, my_var, ...) \
    {\
        char priority[6];\
        memset(priority, '\0', sizeof(priority)); \
        if (prio == ONE) { sprintf(priority, "ERR");} \
        if (prio == TWO) { sprintf(priority, "TWO");} \
        if (prio == THREE) { sprintf(priority, "THREE");} \
        fprintf(fp,"%s:  %s:  %s:  %d: %s:%s|\n", __DATE__, __TIME__, __FILE__, __LINE__, __func__, priority);\
        fprintf(fp, my_var, ##__VA_ARGS__); \
        fprintf(fp,"\n"); \
        fflush(fp); \
    }
    

    我注意到, ##__VA_ARGS__是标准C上的GCC扩展。bzero()函数在POSIX 2004中被标记为过时,并且在POSIX 2008中缺失;最好不要使用它。

    目前尚不清楚,但从代码判断,您有一个全局(或至少是文件范围)变量FILE *fp;,它被初始化为您要写入的日志文件。伊克;同样哎呀!

    如果是我的代码(我想要拼写Entry to xyz function消息),我可能会使用:

    extern void err_logger(int level, int line, char const *file, char const *func, ...);
    

    #define FUNC_ENTRY LOGGING(ONE, "Entry to %s function\n", __func__)
    
    #define LOGGING(prio, ...) \
        err_logger(level, __LINE__, __FILE__, __func__, __VA_ARGS)
    

    err_logger()的实施可能是:

    void err_logger(int level, int line, char const *file, char const *func, ...)
    {
        char *priority = "";
        if (level == ONE)   priority = "ERR";
        if (level == TWO)   priority = "TWO";
        if (level == THREE) priority = "THREE";
        time_t t = time(0);
        char date_time[32];
        strftime(date_time, sizeof(date_time), "%Y-%m-%d %H:%M:%S", gmtime(&t));
        fprintf(logfp, "%s: %s: %d: %s: %s|\n", date_time, file, line, func, priority);
        va_list args;
        va_start(args, func);
        char *fmt = va_arg(args, char *);
        vfprintf(logfp, fmt, args);
        va_end(args);
        fflush(logfp);
    }
    

    logfp将成为日志文件流,并且对于保存err_logger()源的文件是私有的。

    我没有编译那段代码;可能会有一些小错误。但是,它确实为您提供了如何操作以及如何操作的一般概念 - 我认为。

答案 1 :(得分:1)

这些方面的东西:

#include <stdio.h>

#define T printf("Entering %s\n", __func__)

int main(void) 
{
  T;
  return 0;
}

不幸的是,您似乎无法在编译时将其连接到您的字符串(请参阅此处:Can I substitute __func__ into an identifier name in a C macro?)。可能有一些其他编译器特定或C ++特定的技巧,但否则你将需要在运行时构建你的字符串。