<legend id='quPlE'><style id='quPlE'><dir id='quPlE'><q id='quPlE'></q></dir></style></legend>

        <bdo id='quPlE'></bdo><ul id='quPlE'></ul>
      <tfoot id='quPlE'></tfoot>

    1. <i id='quPlE'><tr id='quPlE'><dt id='quPlE'><q id='quPlE'><span id='quPlE'><b id='quPlE'><form id='quPlE'><ins id='quPlE'></ins><ul id='quPlE'></ul><sub id='quPlE'></sub></form><legend id='quPlE'></legend><bdo id='quPlE'><pre id='quPlE'><center id='quPlE'></center></pre></bdo></b><th id='quPlE'></th></span></q></dt></tr></i><div id='quPlE'><tfoot id='quPlE'></tfoot><dl id='quPlE'><fieldset id='quPlE'></fieldset></dl></div>
    2. <small id='quPlE'></small><noframes id='quPlE'>

        在 Unix 上将 C++ std::clog 重定向到 syslog

        时间:2024-08-13

          <bdo id='4TdMa'></bdo><ul id='4TdMa'></ul>

        • <small id='4TdMa'></small><noframes id='4TdMa'>

          <i id='4TdMa'><tr id='4TdMa'><dt id='4TdMa'><q id='4TdMa'><span id='4TdMa'><b id='4TdMa'><form id='4TdMa'><ins id='4TdMa'></ins><ul id='4TdMa'></ul><sub id='4TdMa'></sub></form><legend id='4TdMa'></legend><bdo id='4TdMa'><pre id='4TdMa'><center id='4TdMa'></center></pre></bdo></b><th id='4TdMa'></th></span></q></dt></tr></i><div id='4TdMa'><tfoot id='4TdMa'></tfoot><dl id='4TdMa'><fieldset id='4TdMa'></fieldset></dl></div>
          <legend id='4TdMa'><style id='4TdMa'><dir id='4TdMa'><q id='4TdMa'></q></dir></style></legend>
            1. <tfoot id='4TdMa'></tfoot>
                <tbody id='4TdMa'></tbody>

                • 本文介绍了在 Unix 上将 C++ std::clog 重定向到 syslog的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我在 Unix 上开发一个 C++ 程序,该程序将消息发送到系统日志.

                  I work on Unix on a C++ program that send messages to syslog.

                  当前代码使用与 printf 类似的 syslog 系统调用.

                  The current code uses the syslog system call that works like printf.

                  现在我更愿意为此目的使用流,通常是内置的std::clog.但是 clog 只是将输出重定向到 stderr,而不是 syslog,这对我来说毫无用处,因为我也将 stderr 和 stdout 用于其他目的.

                  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.

                  我在另一个答案中看到很容易将其重定向到一个使用 rdbuf() 的文件,但我认为无法应用该方法来调用 syslog,因为 openlog 不返回我可以用来在其上绑定流的文件处理程序.

                  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.

                  还有其他方法可以做到这一点吗?(对于 Unix 编程看起来非常基础)?

                  Is there another method to do that ? (looks pretty basic for unix programming) ?

                  我正在寻找不使用外部库的解决方案.@Chris 提出的建议可能是一个好的开始,但要成为公认的答案仍然有点含糊.

                  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.

                  编辑:使用 Boost.IOStreams 没问题,因为我的项目无论如何都已经使用了 Boost.

                  Edit: using Boost.IOStreams is OK as my project already use Boost anyway.

                  与外部库链接是可能的,但也是一个问题,因为它是 GPL 代码.依赖也是一种负担,因为它们可能与其他组件冲突,在我的 Linux 发行版上不可用,引入第三方错误等.如果这是唯一的解决方案,我可能会考虑完全避免流......(可惜).

                  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).

                  推荐答案

                  我也需要像这样简单的东西,所以我把它放在一起:

                  I needed something simple like this too, so I just put this together:

                  log.h:

                  #include <streambuf>
                  #include <syslog.h>
                  enum LogPriority {
                      kLogEmerg   = LOG_EMERG,   // system is unusable
                      kLogAlert   = LOG_ALERT,   // action must be taken immediately
                      kLogCrit    = LOG_CRIT,    // critical conditions
                      kLogErr     = LOG_ERR,     // error conditions
                      kLogWarning = LOG_WARNING, // warning conditions
                      kLogNotice  = LOG_NOTICE,  // normal, but significant, condition
                      kLogInfo    = LOG_INFO,    // informational message
                      kLogDebug   = LOG_DEBUG    // debug-level message
                  };
                  
                  std::ostream& operator<< (std::ostream& os, const LogPriority& log_priority);
                  
                  class Log : public std::basic_streambuf<char, std::char_traits<char> > {
                  public:
                      explicit Log(std::string ident, int facility);
                  
                  protected:
                      int sync();
                      int overflow(int c);
                  
                  private:
                      friend std::ostream& operator<< (std::ostream& os, const LogPriority& log_priority);
                      std::string buffer_;
                      int facility_;
                      int priority_;
                      char ident_[50];
                  };
                  

                  log.cc:

                  #include <cstring>
                  #include <ostream>
                  #include "log.h"
                  
                  Log::Log(std::string ident, int facility) {
                      facility_ = facility;
                      priority_ = LOG_DEBUG;
                      strncpy(ident_, ident.c_str(), sizeof(ident_));
                      ident_[sizeof(ident_)-1] = '';
                  
                      openlog(ident_, LOG_PID, facility_);
                  }
                  
                  int Log::sync() {
                      if (buffer_.length()) {
                          syslog(priority_, "%s", buffer_.c_str());
                          buffer_.erase();
                          priority_ = LOG_DEBUG; // default to debug for each message
                      }
                      return 0;
                  }
                  
                  int Log::overflow(int c) {
                      if (c != EOF) {
                          buffer_ += static_cast<char>(c);
                      } else {
                          sync();
                      }
                      return c;
                  }
                  
                  std::ostream& operator<< (std::ostream& os, const LogPriority& log_priority) {
                      static_cast<Log *>(os.rdbuf())->priority_ = (int)log_priority;
                      return os;
                  }
                  

                  main() 中,我初始化了堵塞:

                  In main() I initialize clog:

                  std::clog.rdbuf(new Log("foo", LOG_LOCAL0));
                  

                  然后每当我想登录时,这很容易:

                  Then whenever I want to log, it's easy:

                  std::clog << kLogNotice << "test log message" << std::endl;
                  
                  std::clog << "the default is debug level" << std::endl;
                  

                  这篇关于在 Unix 上将 C++ std::clog 重定向到 syslog的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:ostream showbase 不显示“0x";对于零值 下一篇:从输入迭代器创建 C++ std::string 的性能

                  相关文章

                    <bdo id='8Um3E'></bdo><ul id='8Um3E'></ul>
                  <tfoot id='8Um3E'></tfoot>
                  <legend id='8Um3E'><style id='8Um3E'><dir id='8Um3E'><q id='8Um3E'></q></dir></style></legend>

                  <i id='8Um3E'><tr id='8Um3E'><dt id='8Um3E'><q id='8Um3E'><span id='8Um3E'><b id='8Um3E'><form id='8Um3E'><ins id='8Um3E'></ins><ul id='8Um3E'></ul><sub id='8Um3E'></sub></form><legend id='8Um3E'></legend><bdo id='8Um3E'><pre id='8Um3E'><center id='8Um3E'></center></pre></bdo></b><th id='8Um3E'></th></span></q></dt></tr></i><div id='8Um3E'><tfoot id='8Um3E'></tfoot><dl id='8Um3E'><fieldset id='8Um3E'></fieldset></dl></div>

                  <small id='8Um3E'></small><noframes id='8Um3E'>