JavaRush /Java 博客 /Random-ZH /为什么需要日志记录?

为什么需要日志记录?

已在 Random-ZH 群组中发布
你好!在撰写讲座时,我会特别注意某个特定主题是否一定会在实际工作中使用。 为什么需要日志记录 - 1 所以,注意!我们今天要讨论的主题肯定会对您从第一天工作起的所有项目都有用。 我们将讨论日志记录。 这个话题一点也不难(我什至可以说很简单)。但在你的第一份工作中,已经有足够的压力来处理显而易见的事情,所以最好现在彻底解决它:)所以,让我们开始吧。什么是日志记录? 日志记录是在某处记录有关程序操作的数据。写入这些数据的地方称为“日志”。同时出现两个问题:在哪里记录数据以及记录什么数据?让我们从“哪里”开始。您可以在许多不同的地方记录程序运行数据。例如,在学习过程中,您经常使用System.out.println(). 这是真正的日志记录,尽管是最简单的一种。当然,这对于客户或产品支持团队来说不是很方便:他们显然不想安装 IDE 并监视控制台:) 还有一种更熟悉的记录信息的格式 - 在文本文件中。人们以这种方式更容易阅读它们,当然也更容易存储!现在第二个问题:程序运行的哪些数据应该记录在日志中? 但在这里一切都取决于你!Java 日志系统非常灵活。您可以对其进行配置,以便记录程序的整个进度。一方面,这很好。但另一方面,想象一下如果所有内容都写在 Facebook 或 Twitter 日志上,日志会达到多大。如此大的公司可能有能力存储如此大量的信息。但想象一下,在 500 GB 文本日志中搜索有关一个严重错误的信息会有多困难?这比大海捞针还要糟糕。因此,可以配置Java中的日志记录,以便仅将错误数据写入日志(log)。或者甚至只是严重错误!不过,说“用 Java 登录”并不完全正确。事实上,在将此功能添加到语言之前,程序员就已经产生了对日志记录的需求。当 Java 拥有自己的日志库时,每个人都已经在使用 log4j 库了。Java 中日志记录的出现历史实际上非常悠久且内容丰富;有空时,您可以阅读Habré 上的这篇文章。简而言之,Java有自己的日志库,但几乎没有人使用它:)后来,当出现几个不同的日志库,并且所有程序员开始使用不同的日志库时,就出现了兼容性问题。为了防止人们使用十几个具有不同接口的不同库做同样的事情,创建了slf4j 抽象框架(“Java 服务日志外观”)。之所以称为抽象,是因为尽管您使用 slf4j 类并调用它们的方法,但它们在底层运行着所有以前的日志框架:log4j、标准 java.util.logging 等。如果您当前需要其他库没有的 log4j 的某些特定功能,但您不希望将项目严格链接到该特定库,则只需使用 slf4j。她已经“拉”了 log4j 方法。如果您改变主意并决定不再需要 log4j 功能,则只需重新配置“包装器”(即 slf4j)即可使用另一个库。您的代码不会停止工作,因为您在其中调用 slf4j 的方法,而不是特定库的方法。一个小题外话。为了使以下示例正常工作,您需要从此处下载 slf4j 库,并从此处下载 log4j 库。接下来,我们需要解压存档并通过 Intellij IDEA 将我们需要的 jar 文件添加到类路径中。菜单项:文件->项目结构-> 选择必要的 jar 并将它们添加到项目中(我们下载的档案中有很多 jar,请在图片中查看您需要的 jar) 为什么需要日志记录 - 2为什么需要日志记录 - 3注意 - 本说明适用于那些不知道如何使用Maven的同学。如果您知道如何使用它,最好尝试从它开始:通常会更容易。 如果您使用Maven,请添加以下依赖项:
<dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.14.0</version>
</dependency>
太好了,我们已经整理好了设置:) 让我们看看 slf4j 是如何工作的。我们怎样才能确保程序的进度被记录在某处呢?为此,我们需要两个东西 -记录器附加器。让我们从第一个开始。记录器是一个完全管理记录保存的对象。创建记录器非常简单:它是使用静态方法完成的 - LoggerFactory.getLogger()。作为该方法的参数,您需要传递一个将记录其工作的类。让我们运行我们的代码:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyTestClass {

   public static final Logger LOGGER = LoggerFactory.getLogger(MyTestClass.class);

   public static void main(String[] args) {

       LOGGER.info("Test log record!!!");
       LOGGER.error("В программе возникла ошибка!");
   }
}
控制台输出: ERROR StatusLogger 未找到 Log4j 2 配置文件。使用默认配置(仅将错误记录到控制台)或用户以编程方式提供的配置。设置系统属性“log4j2.debug”以显示 Log4j 2 内部初始化日志记录。有关如何配置 Log4j 2 15:49:08.907 [main] 错误 MyTestClass - 程序中发生错误! 我们在这里看到什么?首先我们看到一条错误消息。出现这种情况是因为我们目前缺乏必要的设置。因此,我们的记录器现在只能输出错误消息(ERROR)并且只能输出到控制台。该方法logger.info()没有被执行。但logger.error()它成功了!控制台显示当前日期、发生错误的方法 ( main)、单词 ERROR 和我们的消息! ERROR 是日志记录级别。 一般来说,如果日志条目标有“ERROR”一词,则意味着程序中的该点发生了错误。如果某个条目标有“INFO”一词,则意味着它只是有关程序正常操作的当前信息。SLF4J 库有很多不同的日志记录级别,允许您灵活配置日志记录。它们非常易于管理:所有必要的逻辑都已包含在类中Logger。您只需要调用必要的方法即可。如果您想发布常规消息,请致电logger.info()。错误信息 - logger.error()。显示警告 -logger.warn() 现在我们来谈谈追加器附加程序是您的数据所在的地方。您可以说数据源的反面是“B 点”。默认情况下,数据输出到控制台。请注意,在前面的示例中,我们无需配置任何内容:文本出现在控制台本身中,但 log4j 库中的记录器只能将错误级别消息输出到控制台。人们从文本文件中读取日志并将日志存储在同一个文件中显然更方便。要更改记录器的默认行为,我们需要配置文件追加器。首先,您需要在 src 文件夹中创建一个log4j.xml文件,如果您使用 Maven,则在 resources 文件夹中创建一个 log4j.xml 文件,或者在 resources 文件夹中创建一个 log4j.xml 文件(如果您使用 Maven)。您已经熟悉 xml 格式了,我们最近有一个关于它的讲座:) 其内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
   <Appenders>
       <File name="MyFileAppender" fileName="C:\Users\Username\Desktop\testlog.txt" immediateFlush="false" append="false">
           <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
       </File>
   </Appenders>
   <Loggers>
       <Root level="INFO">
           <AppenderRef ref="MyFileAppender"/>
       </Root>
   </Loggers>
</Configuration>
看起来并不是特别复杂:)但是我们还是看一下内容吧。
<Configuration status="INFO">
这就是所谓的状态记录器。它与我们的记录器无关,由 log4j 内部使用。你可以设置status=”TRACE”而不是status=”INFO”,所有关于log4j内部工作的信息都会输出到控制台(status-logger将数据输出到控制台,即使我们程序的appender是file -基于)。我们现在不需要这个,所以我们让一切保持原样。
<Appenders>
   <File name="MyFileAppender" fileName="C:\Users\Евгений\Desktop\testlog.txt" append="true">
       <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
   </File>
</Appenders>
在这里我们创建我们的appender。该标签<File>表明它将是一个文件。 name="MyFileAppender"- 我们的附加程序的名称。 fileName="C:\Users\Username\Desktop\testlog.txt"— 将写入所有数据的日志文件的路径。 append="true"— 是否需要将附加数据写入文件末尾。在我们的例子中就是这种情况。如果设置为false,则每次程序再次启动时,旧的日志内容将被删除。 <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>- 这些是格式设置。在这里我们可以使用正则表达式来自定义日志中文本的格式。
<Loggers>
       <Root level="INFO">
           <AppenderRef ref="MyFileAppender"/>
       </Root>
</Loggers>
这里我们指定日志记录级别(根级别)。我们设置了 INFO 级别:也就是说,所有高于 INFO 级别的消息(根据我们上面查看的表)都不会包含在日志中。我们的程序中将有 3 条消息:一条信息、一条警告和一条错误。使用当前配置,所有 3 条消息都将写入日志。如果将根级别更改为 ERROR,则只会记录来自 LOGGER.error() 的最后一条消息。此外,此处还放置了附加程序的链接。要创建这样的链接,您需要在标签内<Root>创建一个标签<ApprenderRef>并向其添加参数ref=”Name твоего аппендера”。我们在这里创建了附加程序的名称,以防您忘记: <File name="MyFileAppender" 这是我们程序的代码!
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyTestClass {

   public static final Logger LOGGER = LoggerFactory.getLogger(MyTestClass.class);

   public static void main(String[] args) {

       LOGGER.info("Начало работы программы!!!");

       try {
           LOGGER.warn("Внимание! Программа пытается разделить одно число на другое");
           System.out.println(12/0);
       } catch (ArithmeticException x) {

           LOGGER.error("Ошибка! Произошло деление на ноль!");
       }
   }
}
当然,它有点歪(捕获 RuntimeException 是一个平庸的想法),但它非常适合我们的目的:) 让我们main()连续运行我们的方法 4 次并查看我们的 testlog.txt 文件。无需提前创建:库会自动创建。一切顺利!:) 现在您已经配置了记录器。您可以尝试一下之前编写的一些程序,向所有方法添加记录器调用,然后查看生成的日志:) 对于其他阅读,我强烈推荐这篇文章。那里深入讨论了日志记录的主题,一口气读完并不容易。但它包含许多有用的附加信息。例如,您将学习如何配置记录器,以便在我们的 testlog.txt 文件达到一定大小时创建一个新的文本文件:) 这就是我们课程的结束!今天你学到了一个非常重要的话题,这些知识一定会对你以后的工作有用。再见!:)
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION