我怎么能输出重定向到一个日志提振? [英] How can I redirect output to a boost log?

查看:133
本文介绍了我怎么能输出重定向到一个日志提振?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用升压日志中的C ++程序,我打开一个用户提供的动态链接库。我想标准错误重定向到升压日志,让随时随地用户的库所做的:

I have a C++ program that uses boost log, and I load a user-provided dynamic link library. I'd like to redirect stderr to the boost log, so that anytime the user's library does:

std::cerr << "Some stuff";

这产生相同的结果**为:

It produces the same result** as:

BOOST_LOG_SEV(log,info) << "Some stuff";

这是可能的,这样的话我该怎么办呢?

Is this possible, and if so then how do I do it?

(另外,我不知道该怎么办的严重性......因为 CERR&LT;&LT; 不privide严重程度的信息,我开在该建议,以及...)

(Also, I'm not sure what to do about the severity... since cerr << doesn't privide severity information. I'm open to suggestions on that as well...)

**通过同样的结果我的意思是,它被记录到相同的日志文件中的日志消息的休息,相同的日志格式应用到这些行。

** By "same result" I mean that it gets logged to the same log file as the rest of the log messages, and the same log formatter is applied to those lines.

推荐答案

下面是我的C ++ 11的实现。这个类可以用于任何(不只是提高)来捕获标准输出/标准错误一行接一行的基础上,调用用户功能(可以是一个lambda)来处理它。

Here's my C++11 implementation. This class can be used for anything (not just boost) to capture stdout/stderr on a line-by-line basis and calling a user function (could be a lambda) to process it.

警告:如果您重定向标准错误标准输出和使用升压,然后重定向标准错误,然后再标准输出。否则,升压会写回环标准错误信息返回到标准输出,你会得到另一个提振日志条目内提振日志条目。

Warning: if you redirect stderr and stdout and are using Boost, then redirect stderr first, then stdout. Otherwise, Boost will write loopback the stderr message back to stdout, and you'll get a boost log entry inside another boost log entry.

cout << "testing out before 1 2 3 " << endl;
cerr << "testing err before 1 2 3 " << endl;
{
    StdErrHandler err([](const char* line){ 
          BOOST_LOG_TRIVIAL(error) << "ERROR:" << strlen(line) << " " << line; 
    });
    StdOutHandler out([](const char* line){
          BOOST_LOG_TRIVIAL(info) << "OUT:" << strlen(line) << " " << line; 
    });
    cout << "cout testing 1 2 3 " << endl;
    cerr << "cerr testing 1 2 3 " << endl;
}
cout << "testing out after 1 2 3 " << endl;
cerr << "testing err after 1 2 3 " << endl;

示例输出

pa-poca$ ./test
testing out before 1 2 3
testing err before 1 2 3
[2014-08-01 12:24:56.468335] [0x000007f89d8990d4] [error]   ERROR:19 cerr testing 1 2 3
[2014-08-01 12:24:56.468360] [0x000007f89d8990d4] [info]    OUT:19 cout testing 1 2 3
testing out after 1 2 3
testing err after 1 2 3

code

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>

class StdioHandler
{
private:
    pid_t pid = 0;
    int origfd;
    int streamid;
    int pipefd[2];
public:
    enum class Stream
    {
        stdout = STDOUT_FILENO,
        stderr = STDERR_FILENO
    };
    StdioHandler(Stream stream, std::function<void(const char*)> callback)
        :streamid(static_cast<int>(stream))
    {
            origfd = dup(streamid);

        pipe(pipefd); // create pipe
        pid = fork(); //spawn a child process to handle output of pipe
        if (pid == 0)
        {
            char line[256];
            FILE* output;

            close(pipefd[1]);
            output = fdopen(pipefd[0], "r");
            if (output)
            {
              while(fgets(line, sizeof(line), output)) 
              {

                 int n = strlen(line);
                 if (n > 0)
                     if (line[n-1] == '\n') line[n-1] = 0;
                 callback(line);
              }
              fclose(output);
            }
            abort();
        } else {
            // connect input of pipe to
            close(pipefd[0]);
            dup2(pipefd[1], streamid);
        }
    }

    ~StdioHandler()
    {
        int status;

        usleep(10000);

        close(pipefd[1]);
        kill(pid,SIGINT);

        waitpid(pid, &status, 0);

        dup2(origfd, streamid);
    }
};

class StdOutHandler : public StdioHandler
{
public:
    StdOutHandler(std::function<void(const char*)> callback) :
        StdioHandler(Stream::stdout, callback)
    {
    }
};

class StdErrHandler : public StdioHandler
{
public:
    StdErrHandler(std::function<void(const char*)> callback) :
        StdioHandler(Stream::stderr, callback)
    {
    }
};

这篇关于我怎么能输出重定向到一个日志提振?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆