当前位置: 代码网 > 服务器>网站运营>运维 > 程序中的log4j、stderr、stdout日志区别

程序中的log4j、stderr、stdout日志区别

2024年08月06日 运维 我要评论
在实际使用中:- 专业的开发者通常更喜欢用 Log4j 这样的系统,因为它更强大,可以更好地管理所有类型的日志。- stderr 和 stdout 更简单,常用于快速输出或者在简单的程序中。记住,好的日志习惯就像是给未来的自己或其他开发者留下清晰的"路标",帮助理解和解决问题。选择合适的日志方式,可以让程序更容易维护和调试。

使用 databricks 的过程中,发现他将日志分为 log4j、stderr、stdout日志。了解日志是调试程序关键技能。顺着这个思路,我认真学习了一下这几个日志的区别。

image.png

这些日志文件有不同的用途和记录内容:

  1. log4j-active.log:这是由log4j框架生成的日志文件。log4j是一个用于java应用程序的日志记录库,能够灵活地控制日志输出的格式和目标(如文件、控制台等)。这个日志文件通常包含应用程序运行时的各种详细信息,包括调试信息、错误消息、警告等。

  2. stderr:标准错误输出日志文件。这个文件通常记录程序运行过程中产生的错误信息和异常。这些错误信息对于调试和解决程序问题非常重要。标准错误输出通常用于分离错误消息和正常的程序输出,便于识别和处理。

  3. stdout:标准输出日志文件。这个文件记录程序的正常输出信息,比如运行结果、状态信息等。标准输出通常显示程序的正常执行流程和结果,用于监控程序的运行状态。

总结起来:

  • log4j-active.log:记录应用程序的详细运行日志,包括调试信息和错误。
  • stderr:记录程序运行过程中的错误和异常。
  • stdout:记录程序的正常输出信息和运行状态。

当然可以,下面是一些java代码示例,展示如何使用log4j记录日志,以及如何向标准输出和标准错误输出写信息。

java 中的日志

目录结构

your-project
│
├── src
│   ├── main
│   │   ├── java
│   │   │   └── log4jexample.java
│   │   └── resources
│   │       └── log4j.properties
│   └── test
│       ├── java
│       └── resources
│
├── pom.xml
└── ...

使用log4j记录日志

首先,需要在项目中引入log4j依赖(如果使用maven):

<dependency>
    <groupid>log4j</groupid>
    <artifactid>log4j</artifactid>
    <version>1.2.17</version>
</dependency>

然后,确保log4j.properties文件放在项目的src/main/resources目录下。如果这个目录不存在,可以手动创建。配置log4j.properties文件:

# 设置日志级别为debug
log4j.rootlogger=debug, file

# 配置文件输出
log4j.appender.file=org.apache.log4j.rollingfileappender
log4j.appender.file.file=log4j-active.log
log4j.appender.file.maxfilesize=5mb
log4j.appender.file.maxbackupindex=10
log4j.appender.file.layout=org.apache.log4j.patternlayout
log4j.appender.file.layout.conversionpattern=%d{iso8601} [%t] %-5p %c - %m%n

最后,编写java代码使用log4j记录日志:

import org.apache.log4j.logger;

public class log4jexample {
    private static final logger logger = logger.getlogger(log4jexample.class);

    public static void main(string[] args) {
        logger.debug("this is a debug message");
        logger.info("this is an info message");
        logger.warn("this is a warn message");
        logger.error("this is an error message");
        logger.fatal("this is a fatal message");
    }
}

目录结构如下:
image.png

运行后日志
image.png

向标准输出和标准错误输出写信息

使用java的system.out和system.err可以分别向标准输出和标准错误输出写信息:

public class stdouterrexample {
    public static void main(string[] args) {
        // 向标准输出写信息
        system.out.println("this is a standard output message");

        // 向标准错误输出写信息
        system.err.println("this is a standard error message");

        // 模拟一个错误
        try {
            int result = 10 / 0;
        } catch (arithmeticexception e) {
            system.err.println("caught an exception: " + e.getmessage());
        }
    }
}

image.png

运行结果

  1. log4j-active.log 文件将包含:

    2024-07-09 10:00:00 [main] debug log4jexample - this is a debug message
    2024-07-09 10:00:00 [main] info  log4jexample - this is an info message
    2024-07-09 10:00:00 [main] warn  log4jexample - this is a warn message
    2024-07-09 10:00:00 [main] error log4jexample - this is an error message
    2024-07-09 10:00:00 [main] fatal log4jexample - this is a fatal message
    
  2. stdout 输出:

    this is a standard output message
    
  3. stderr 输出:

    this is a standard error message
    caught an exception: / by zero
    

通过这些示例代码,可以看到如何在java应用程序中使用log4j记录日志,以及如何使用标准输出和标准错误输出来记录不同类型的信息。

以python为例

  1. log4j-active.log (log4j 输出):
    这是使用log4j库记录的应用程序日志。通常用于记录应用程序的运行状态、错误等信息。
import logging
from logging import filehandler

logger = logging.getlogger('myapp')
logger.setlevel(logging.debug)
handler = filehandler('log4j-active.log')
logger.addhandler(handler)

logger.info("应用程序启动")
logger.error("发生错误:连接数据库失败")
  1. stderr (标准错误):
    用于输出错误信息和诊断信息。在python中,可以通过sys.stderr来写入。
import sys

def divide(a, b):
    if b == 0:
        print("错误:除数不能为零", file=sys.stderr)
        return none
    return a / b

result = divide(10, 0)
  1. stdout (标准输出):
    用于输出程序的正常信息。在python中,print()函数默认输出到stdout。
print("这是标准输出信息")

# 也可以显式地使用sys.stdout
import sys
sys.stdout.write("另一种写入标准输出的方式\n")

主要区别:

  • log4j-active.log: 专门的日志文件,可配置级别,便于长期存储和分析。
  • stderr: 用于即时的错误报告,通常显示在控制台。
  • stdout: 用于常规程序输出,也通常显示在控制台。

在实际应用中,stderr和stdout经常被重定向到文件中进行日志记录。log4j提供了更灵活的日志管理功能。

高阶讲解

  1. log4j 详解

log4j 提供了更复杂的日志管理功能,包括不同的日志级别和灵活的输出配置。

import org.apache.log4j.*;

public class advancedlog4jexample {
    private static final logger logger = logger.getlogger(advancedlog4jexample.class);

    public static void main(string[] args) {
        // 配置 log4j
        configurelog4j();

        // 使用不同级别的日志
        logger.trace("这是一个 trace 级别的消息");
        logger.debug("这是一个 debug 级别的消息");
        logger.info("这是一个 info 级别的消息");
        logger.warn("这是一个 warn 级别的消息");
        logger.error("这是一个 error 级别的消息");
        logger.fatal("这是一个 fatal 级别的消息");

        // 记录异常
        try {
            throw new runtimeexception("模拟的异常");
        } catch (runtimeexception e) {
            logger.error("捕获到异常", e);
        }
    }

    private static void configurelog4j() {
        // 创建控制台附加器
        consoleappender consoleappender = new consoleappender();
        consoleappender.setlayout(new patternlayout("%d [%t] %-5p %c - %m%n"));
        consoleappender.setthreshold(level.info);
        consoleappender.activateoptions();
        logger.getrootlogger().addappender(consoleappender);

        // 创建文件附加器
        try {
            fileappender fileappender = new fileappender(
                new patternlayout("%d %-5p [%c{1}] %m%n"), 
                "log4j-active.log", 
                true);
            fileappender.setthreshold(level.debug);
            logger.getrootlogger().addappender(fileappender);
        } catch (exception e) {
            e.printstacktrace();
        }
    }
}
  1. system.err 和 system.out 的高级用法

虽然 system.err 和 system.out 相对简单,但它们也有一些高级用法:

import java.io.*;

public class advancedsystemioexample {
    public static void main(string[] args) throws ioexception {
        // 重定向 system.out 到文件
        printstream outfile = new printstream(new fileoutputstream("stdout.log"));
        system.setout(outfile);

        // 重定向 system.err 到文件
        printstream errfile = new printstream(new fileoutputstream("stderr.log"));
        system.seterr(errfile);

        // 现在标准输出会被写入 stdout.log
        system.out.println("这条消息会被写入 stdout.log 文件");

        // 标准错误会被写入 stderr.log
        system.err.println("这条错误消息会被写入 stderr.log 文件");

        // 使用自定义的 printstream
        printstream customout = new printstream(system.out) {
            @override
            public void println(string x) {
                super.println("自定义前缀: " + x);
            }
        };

        system.setout(customout);
        system.out.println("这条消息会有自定义前缀");

        // 恢复原始的标准输出和错误流
        system.setout(system.out);
        system.seterr(system.err);
    }
}
  1. 日志使用的最佳实践
  • 使用适当的日志级别:trace 用于非常详细的信息,debug 用于调试,info 用于一般信息,warn 用于警告,error 用于错误,fatal 用于严重错误。
  • 避免在生产环境中使用 system.out 和 system.err,而应该使用成熟的日志框架。
  • 在记录异常时,同时记录异常消息和堆栈跟踪。
  • 使用参数化日志消息来提高性能:
    logger.debug("user {} logged in from ip {}", username, ipaddress);
    
  • 定期归档和轮转日志文件以管理磁盘空间。
  • 在多线程环境中使用线程安全的日志框架(如 log4j)。
  1. 日志与应用程序性能

过度的日志记录可能会影响应用程序的性能。应该权衡日志的详细程度和应用程序的性能需求。在性能关键的部分,可以使用条件日志记录:

if (logger.isdebugenabled()) {
    logger.debug("complex object state: " + expensivetostringmethod());
}

这样可以避免在日志级别不够的情况下执行昂贵的字符串操作。

总结

  1. log4j-active.log (log4j 输出):
    这就像是一本详细的日记本。你可以在里面记录各种重要程度的信息,从小事到大事都有。它很灵活,你可以决定记录什么,怎么记,记到哪里。比如,你可以只记录重要的事,或者把所有细节都记下来。这本日记可以保存很久,方便以后查阅。

  2. stderr (标准错误):
    想象这是一个紧急警报系统。当出现严重问题时,它会立即发出警报。就像火警警报器,它的目的是立刻引起注意。通常,这些警报会直接显示在屏幕上,让你能立即看到。

  3. stdout (标准输出):
    这更像是一个普通的广播系统。它用来传达程序正常运行时的信息,就像商场里的广播。它不像警报那么紧急,但仍然是传递信息的重要渠道。

总的来说:

  • log4j 就像一个全面的日志系统,可以记录各种级别的信息,便于长期存储和分析。
  • stderr 是用来报告紧急问题的,就像警报器。
  • stdout 用于日常的信息输出,像普通广播。

在实际使用中:

  • 专业的开发者通常更喜欢用 log4j 这样的系统,因为它更强大,可以更好地管理所有类型的日志。
  • stderr 和 stdout 更简单,常用于快速输出或者在简单的程序中。

记住,好的日志习惯就像是给未来的自己或其他开发者留下清晰的"路标",帮助理解和解决问题。选择合适的日志方式,可以让程序更容易维护和调试。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com