c++ - 如何将类似 iostream 的接口(interface)写入日志库?

标签 c++ c++11 logging iostream

我想为我非常简单的日志记录库编写一个方便的界面。拿下面两段代码。第一个是我现在所做的,第二个是我对直观界面的想法:

std::ostringstream stream;
stream<<"Some text "<<and_variables<<" formated using standard string stream"
logger.log(stream.str()); //then passed to the logger

logger.convinient_log()<<"Same text "<<with_variables<<" but passed directly";

我在这个想法背后的思想设计过程是从 logger.convinient_log() 函数返回某种类似于字符串流的临时对象。销毁对象(我希望它发生在行尾或类似的、方便的地方)将从自身收集字符串并调用实际的 logger.log()。关键是我想整体处理它,而不是逐个术语,以便 log() 可以添加例如。整行文本的前缀和后缀。

我很清楚,如果没有一些强大的魔法,这可能是完全不可能或不可能的。如果是这样的话,什么是几乎一样方便的方式来做到这一点以及如何实现它?我打赌会传递一些特殊变量,这些变量会强制执行 collect-call-logger.log() 操作。

如果您不知道确切的答案,也欢迎提供有关该主题的资源(例如,扩展 stringstream)。

最佳答案

这就是Boost.Log工作,例如。基本思想很简单:

struct log
{
    log() {
        uncaught = std::uncaught_exceptions();
    }

    ~log() {
        if (uncaught >= std::uncaught_exceptions()) {
            std::cout << "prefix: " << stream.str() << " suffix\n";
        }
    }

    std::stringstream stream;
    int uncaught;
};

template <typename T>
log& operator<<(log& record, T&& t) {
    record.stream << std::forward<T>(t);
    return record;
}

template <typename T>
log& operator<<(log&& record, T&& t) {
    return record << std::forward<T>(t);
}

// Usage:
log() << "Hello world! " << 42;

std::uncaught_exceptions()用于避免在中间抛出异常时记录不完整的消息。

关于c++ - 如何将类似 iostream 的接口(interface)写入日志库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40273809/

相关文章:

java - Log4j 每次都打印到控制台

c++ - 为什么 `size_t`在Windows 2019的VS 2019和Clang 9中没有标题的情况下可以工作?

c++ - 如何确保一个类的每个方法都先调用其他方法?

c++ - 容器迭代器是否未定义常规覆盖复制模式?

c++ - 关于shared_ptr的atomic_exchange_strong_explicit的实现

android - 如何随时随地保存 Android 日志

c++ - 如何找出文件所在的物理驱动器?

c++ - 为什么必须使用 'typename' 和 '::type' 前缀/后缀调用所有 type_traits 类?

c++ - 如何将 cv::Mat & Img 复制到 unsigned char* img?opencv

apache - 在 apache 访问日志中只写入破折号