【问题标题】:Simple C++ Logging简单的 C++ 日志记录
【发布时间】:2016-04-22 00:16:29
【问题描述】:

我的任务是:

发展一个可以集成到你的 Logger 类 项目/开发,很可能通过声明一个全局实例;这将用于捕获和保存日志信息。

有 2 个级别可以接受:

  1. Lo​​gger - 本质上只是在 来源,没有类。
  2. Lo​​gger - 打包在一个类中,具有默认行为(不可配置)。由_DEBUG 控制并写入std::clog(可以重定向)。

我真的不知道从哪里开始,并且花了好几个小时试图在某个地方寻求帮助。

【问题讨论】:

  • 为什么不使用一些已经存在的开源库,比如 log4cpp?至少你可以从他们的实现中学到一些东西。
  • 我认为您的问题必须更清楚。如果要调试,可以将数据传递给std::cerr 并退出或设置断点。您可以将消息重定向到文件。第一点中的“无课”是什么意思。记录器必须是无类的还是你有没有类从不出现的代码?例如,我将创建一个名为 Logger 的 Singleton 类,并让处理那里的所有内容。这些非常方便,我在我的项目中使用它们,具有不同的日志详细级别。
  • 我已经复制并粘贴了上面的说明。这是我得到的唯一帮助。这就是我不确定的原因。

标签: c++ class debugging logging


【解决方案1】:

您的任务可能是使用更复杂的 Logger 类,由于诸如

  • 在调试时能够在多行代码中中断字符串
  • 错误日志和调试日志的不同方法
  • 能够从该 Logger 实例打开/关闭日志记录,从而使整个项目中的所有调试消息都过时(例如,无需对所有调试消息进行注释)
  • 添加特定于您的案例的其他方法(您将在下面看到)

这是我用于 Windows 项目的 Logger 类。它支持前面提到的所有功能。随意使用它。

#include "Logger.h"

Logger::Logger(
    wstring wstrComponentName,
    wstring wstrFunctionName) :
    _wstrApplicationName(APPLICATION_NAME),
    _wstrComponentName(StripFileName(wstrComponentName)),
    _wstrFunctionName(wstrFunctionName)
{}

// This function doesn't support string, but wstring for it's arguments
VOID
Logger::Debug(
    LPCWSTR format,
    ...
    )
{
    wstring wstrBase = 
        _wstrApplicationName + wstring(L": ") +
        _wstrComponentName + wstring(L": ") +
        _wstrFunctionName + wstring(L": ");

    va_list args;
    va_start(args, format);

    wchar_t* msg = new wchar_t[_1kB];
    wvsprintf(msg, format, args);

    va_end(args);

    wstring wstrOutput = wstrBase + msg;

    delete[] msg;

    OutputDebugString(wstrOutput.c_str());
}

// This function doesn't support string, but wstring for it's arguments
VOID
Logger::Error(
    LPCWSTR format,
    ...
    )
{
    wstring wstrBase = wstring(L"[ERROR] ") +
        _wstrApplicationName + wstring(L": ") +
        _wstrComponentName + wstring(L": ") +
        _wstrFunctionName + wstring(L": ");

    va_list args;
    va_start(args, format);

    wchar_t* msg = new wchar_t[_1kB];
    wvsprintf(msg, format, args);

    va_end(args);

    wstring wstrOutput = wstrBase + msg;

    delete[] msg;

    OutputDebugString(wstrOutput.c_str());
}

wstring
Logger::StripFileName(
    __in wstring wstrFileName
    )
{
    DWORD dwLeftLimit = 0;
    DWORD dwRightLimit = wstrFileName.length();
    wstring wstrResult(L"FileName unavailable");

    if (wstrFileName.rfind(L"\\") != wstring::npos)
    {
        dwLeftLimit = wstrFileName.rfind(L"\\") + 1;
    }

    if (wstrFileName.rfind(L".") != wstring::npos)
    {
        dwRightLimit = wstrFileName.rfind(L".");
    }

    if (dwRightLimit > dwLeftLimit)
    {
        wstrResult = wstrFileName.substr(
            dwLeftLimit,
            dwRightLimit - dwLeftLimit
            );
    }

    return wstrResult;
}

【讨论】:

  • 函数 wvsprintf 不是很 C++,我会将这个 msg 变量设为静态,这样您就可以避免许多分配和释放。
猜你喜欢
  • 2011-01-29
  • 2011-12-29
  • 2018-06-13
  • 1970-01-01
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
  • 2012-03-27
  • 2019-10-12
相关资源
最近更新 更多