【问题标题】:How to redirect outputs of invoked commands/programs to log4j?如何将调用命令/程序的输出重定向到 log4j?
【发布时间】:2015-09-01 07:38:19
【问题描述】:

我编写程序并使用日志记录工具(例如,Java 的log4j 或 Python 的logging)处理我的日志,因此我自己生成的所有日志都可以转到由日志记录工具管理的日志文件。

我还会在我的程序中调用命令或第三方程序,默认情况下它将所有输出写入控制台。如何将这些输出重定向到由日志记录工具管理的日志文件(如果可能,使它们符合日志记录格式)?

【问题讨论】:

    标签: java python linux logging


    【解决方案1】:

    将外部进程的所有标准输出重定向到 Python 中的文件:

    #!/usr/bin/env python
    from subprocess import check_call, STDOUT
    
    with open('log', 'ab', 0) as file:
        check_call(['program', 'arg 1', 'arg 2'], stdout=file, stderr=STDOUT)
    

    输出按原样重定向。要使其符合日志记录格式,您可能需要它显式地通过您的程序:

    #!/usr/bin/env python3
    import logging
    from subprocess import Popen, PIPE, STDOUT
    
    logging.basicConfig(filename='log',level=logging.DEBUG)
    with Popen(['program', 'arg 1', 'arg 2'], stdout=PIPE, stderr=STDOUT, bufsize=1,
               universal_newlines=True) as process:
        for line in process.stdout:
            logging.debug('program output %s', line.rstrip('\n'))
    

    代码使用locale.getpreferredencoding(False) 解码程序的标准输出,并使用logging 模块将行附加到日志文件(您可以使用标准logging 工具配置您喜欢的任何日志格式)。

    【讨论】:

    • 在 Python 中,我想使用一个旋转文件记录器,在这种情况下,我不需要像 那样显式打开一个文件,其中 open('log', 'ab', 0) 作为文件.... .我希望将外部进程的所有输出重定向到日志模块,让日志模块为我做所有事情。我们该怎么做?
    【解决方案2】:

    在 java 中,您可以使用 log4j 中的IoBuilder 来构建您的 PrintStream。 IoBuilder 包含在 Apache 的 Log4j 流接口中,是 Log4J 的补充。

    拥有 PrintStream 后,您可以设置系统的默认 PrintStream...

     IoBuilder builder = IoBuilder.forLogger(MyClass.class);
     PrintStream myPrintStream = builder.buildPrintStream();
     System.out = myPrintStream;
    

    这样,如果其他库使用System.out.print()println(),它将通过您的记录器以您的记录器格式记录。

    【讨论】:

    • 它不会对外部进程(“第三方程序”)的输出产生任何影响。您将需要在文件描述符级别重定向的东西。这是code example in Python
    猜你喜欢
    • 1970-01-01
    • 2013-01-02
    • 2018-10-06
    • 2016-06-05
    • 1970-01-01
    • 2018-10-15
    • 2018-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多