Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
简单记录器实现中的详细级别C++; 我现在正在为C++实现一个简单的记录器,因为我在C++中学习了。_C++_Logging_Verbosity - Fatal编程技术网

简单记录器实现中的详细级别C++; 我现在正在为C++实现一个简单的记录器,因为我在C++中学习了。

简单记录器实现中的详细级别C++; 我现在正在为C++实现一个简单的记录器,因为我在C++中学习了。,c++,logging,verbosity,C++,Logging,Verbosity,我已经得到了一个记录器基类,作为一些不同的附加器,下一步是实现详细级别。 问题是,我不确定自己是否正确理解了详细级别的概念,因此我想在开始实施之前先了解一下。 因此,根据我的理解,一般工程的详细程度如下: 用户首先创建两个记录器: f、 e: 之后,他可以设置详细级别,如: fl.setLoggerLevel(DEBUG); vl.setLoggerLevel(FATAL_ERROR); 之后,他可以随心所欲地记录日志,比如: fl.logg("New Object of Type ....

我已经得到了一个记录器基类,作为一些不同的附加器,下一步是实现详细级别。 问题是,我不确定自己是否正确理解了详细级别的概念,因此我想在开始实施之前先了解一下。 因此,根据我的理解,一般工程的详细程度如下:

用户首先创建两个记录器: f、 e:

之后,他可以设置详细级别,如:

fl.setLoggerLevel(DEBUG);
vl.setLoggerLevel(FATAL_ERROR);
之后,他可以随心所欲地记录日志,比如:

fl.logg("New Object of Type .... created");
ASSERT(1,2, "1==2");
而assert以致命错误级别写入VSLogger

在输出文件中,它可能如下所示:

13:36 Msg: New Object of Type .... created (LEVEL:DEBUG);
13:36 Msg: Assert (1==2) failed (LEVEL:FATAL_ERROR)
在Visual Studio中,它可能会如下所示:

13:36 Msg: New Object of Type .... created (LEVEL:DEBUG);
13:36 Msg: Assert (1==2) failed (LEVEL:FATAL_ERROR)

这是一个详细级别的意义还是我误解了详细级别的一般概念?

详细级别显示了要记录的消息(或者更确切地说,关键性消息)

例如


我不明白为什么用户必须使用两个记录器。消费代码不应该关心日志记录目标

另一个问题是,您的消费代码没有在任何地方传递严重性。无论何时调用日志函数,都会传递严重性。消费代码不关心当前的详细程度是什么,它只传递一个严重程度,并依赖于记录器的实现来知道严重程度是否超过详细程度级别。(此规则有一个例外,即检查详细级别以避免在高性能代码中创建日志消息的开销)

我希望有一个记录器作为用户,带有两个附加的输出,这可能会有不同的详细级别

在最简单的情况下,我将创建一个全局函数
Logger&GetLogger()
,它将生成用户代码,如
GetLogger().LogDebug(“类型为…的新对象已创建”)

首先创建一个接口:

public class ILogger
{
  public:
    virtual LogDebug(string message)=0;
    ...
}
然后创建一个支持订阅的实例:

public class DispatchingLogger:ILogger
{
  private:
    vector<ILogger*> loggers;
  public:
    override LogDebug(string message)
    {
      foreach(ILogger logger in loggers)
      {
        logger.LogDebug(message);
      }
    }

    void Subscribe(ILogger* logger)
    {
      loggers.add(logger);
    }
}
公共类调度记录器:ILogger
{
私人:
矢量记录器;
公众:
重写日志调试(字符串消息)
{
foreach(记录器中的ILogger记录器)
{
logger.LogDebug(消息);
}
}
无效订阅(ILogger*记录器)
{
添加(记录器);
}
}
然后,全局
GetLogger()
函数返回
DispatchingLogger
的单个实例。您可以订阅多个具有不同详细级别的实现。实现
ILogger
的用户类也可以注册


(我知道我的C++语法不正确,自从我用C++工作以来有点)

冗长通常会告诉你日志记录实际上是多少。您在这里描述的是日志级别。通常,您有一个日志记录程序,在每个日志的基础上指定日志级别,并可以设置实际记录的日志级别。谢谢。我想我理解你的观点(我在研究时在其他一些网站上发现了几乎相同的定义),但我不理解的是:日志记录器不能自己记录东西(至少如果它不是以某种方式硬编码的话)。因此,如果用户想要记录某个内容并提供日志级别,则必须始终调用logg函数。那么,记录器如何区分记录的内容和不记录的内容呢?我是否必须说只记录至少是错误级别的事情?如果是这样,为什么我甚至要记录与信息级别相关的事情,而不是日志记录器从不记录它们呢?您可以调用
logger.verbosity(INFO | WARNING | DEBUG)log
函数中的详细标志进行检查:
void log(unsigned level,char const*msg){if(!(verbosity_flag&level))return;/*else log*/}
我现在知道了。非常感谢。我现在会尝试先实现所有的东西,如果还有不清楚的地方或者我认为可能会做些什么的话,我可能会在几天后带着代码回来better@Xeo:我将避免使用详细级别的掩码。Logger中的常见实现是,每个日志级别都包含较高的级别。也就是说,如果您将日志级别设置为
INFO
,您将自动期望看到任何
警告和
错误
消息,而不是
调试
,而这通常通过将级别映射到数字并进行比较来实现:
如果(日志级别>=msg\u级别)返回(如果我们被配置为记录
警告
(比如2)并获得级别
信息
(比如3)的消息,那么不要记录)首先感谢您的帖子。拥有两个或更多记录器的原因是用户可以定义自己的记录器。到目前为止,我只实现了VisualStudio、文件或标准输出附件。例如,用户可以从我的记录器基类派生并添加TCP记录器。但是我也明白你的意思,拥有多个记录器实现,并且只向消费代码公开一个记录器实例是不同的问题。你可以同时拥有两者。在您的示例中,您向VS和文件记录器订阅广播事件。这几乎与我当前使用的实现相同。我有一个带有三个函数的Logdispatch命名空间:addLogger()、removeLogger()和logg()。每次实例化新记录器时调用addLogger(),每次删除记录器时将其删除。我使用的是侵入式列表,而不是向量。也许我以后还会考虑基于策略的设计,但目前我想先让它工作起来。