重定向 C++ std::clog 到 Unix 上的 syslog
我在 Unix 上开发一个 C++ 程序,该程序将消息发送到系统日志。
当前代码使用syslog系统调用,其工作方式类似于printf。
现在我更愿意使用流来实现此目的,通常是内置的 std::clog。但 clog 只是将输出重定向到 stderr,而不是 syslog,这对我来说毫无用处,因为我还使用 stderr 和 stdout 用于其他目的。
我在另一个答案中看到,使用以下命令将其重定向到文件非常容易rdbuf() 但我看不出有什么方法可以应用该方法来调用 syslog,因为 openlog 不会返回我可以用来在其上绑定流的文件处理程序。
还有另一种方法可以做到这一点吗? (对于 UNIX 编程来说看起来非常基础)?
编辑:我正在寻找一种不使用外部库的解决方案。 @Chris 的提议可能是一个好的开始,但对于成为公认的答案来说仍然有点模糊。
编辑:使用 Boost.IOStreams 是可以的,因为我的项目已经使用了 Boost。
与外部库链接是可能的,但也是一个问题,因为它是 GPL 代码。依赖关系也是一种负担,因为它们可能与其他组件冲突,在我的 Linux 发行版上不可用,引入第三方错误等。如果这是唯一的解决方案,我可能会考虑完全避免流......(遗憾)。
I work on Unix on a C++ program that send messages to syslog.
The current code uses the syslog system call that works like printf.
Now I would prefer to use a stream for that purpose instead, typically the built-in std::clog. But clog merely redirect output to stderr, not to syslog and that is useless for me as I also use stderr and stdout for other purposes.
I've seen in another answer that it's quite easy to redirect it to a file using rdbuf() but I see no way to apply that method to call syslog as openlog does not return a file handler I could use to tie a stream on it.
Is there another method to do that ? (looks pretty basic for unix programming) ?
Edit: I'm looking for a solution that does not use external library. What @Chris is proposing could be a good start but is still a bit vague to become the accepted answer.
Edit: using Boost.IOStreams is OK as my project already use Boost anyway.
Linking with external library is possible but is also a concern as it's GPL code. Dependencies are also a burden as they may conflict with other components, not be available on my Linux distribution, introduce third-party bugs, etc. If this is the only solution I may consider completely avoiding streams... (a pity).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我也需要像这样简单的东西,所以我只是把它放在一起:
log.h:
log.cc:
In
main()
Iinitial clog:然后每当我想记录时,这很容易:
I needed something simple like this too, so I just put this together:
log.h:
log.cc:
In
main()
I initialize clog:Then whenever I want to log, it's easy:
您可以定义一个调用 syslog 的 Streambuf。例如:
那么您只需编写以下内容即可重定向堵塞:
您可能还需要覆盖更多函数,这里有一个很好的 对 Streambuf API 的引用。
You could define an streambuf that calls syslog. For example:
then you would simply write the following to redirect clog:
There are a few more functions you would probably have to override, here's a good reference to the streambuf api.
另一个版本部分受到食者的启发。它本身并不重定向 std::clog ,而是使用熟悉的流语法。
要使用它,您可以执行以下操作:
Another version in part inspired by eater. It doesn't redirect std::clog per se, but uses familiar stream syntax.
To use it, you can do something like:
我设计了一个与上面显示的非常相似的 OStreamedLog 类,除了我的 OStreamedLog 对象设置为使用任意 ostringstream 对象,如 @Basilevs 建议的那样。
首先是Log的类定义,与上面提到的@eater和@Chris Kaminski非常相似。然后,我的 OStreamedLog 类定义,其中包含一个 Log 对象:
现在,当您需要记录时,只需调用:
当然,您可以将整个 Log 定义折叠到 OStreamedLog 类中,但您可能想在基类中执行其他操作日志对象并使用上面的包装器来区分不同类型的日志。例如,您可以拥有人类可读的诊断日志(以 ASCII 文本形式发送)、二进制日志(用于稍后处理)或 TLS 流日志(例如发送到北向服务器)。
I designed a OStreamedLog class very similar to what was shown above, except my OStreamedLog objects are set up to use an arbitrary ostringstream object, like @Basilevs suggested.
First, there is the class definition of Log, very similar to what @eater and @Chris Kaminski mentioned above. Then, my OStreamedLog class definition, which contains a Log object:
Now, when you need to log, just call:
Of course, you could collapse the whole Log definition into your OStreamedLog class, but you might want to do other things in your base Log object and use wrappers like above to differentiate the different types of logs. For example you could have human-readable diagnostic logs (sent as ASCII text), binary logs (for processing later) or a TLS-streaming log (to a northbound server, for example).