9

我正在创建一个 java 应用程序,其中可能会引发异常。我在 try-catch 块中处理这些异常并打印适当的消息,以便业务用户在发生故障时不必看到丑陋的堆栈跟踪。

但是现在当我调试时,我想以这样一种方式调用 JAR 文件,它会为我打印堆栈跟踪,这样我就可以知道问题到底出在哪里。

有人可以告诉我如何实现这一目标吗?

4

4 回答 4

19

您可以使用slf4j作为外观,以便能够快速更改实现并将logback作为日志记录的实现。slf4j 和 logback 的结合是目前非常高效的日志系统。如果您想使用其他实现,例如 log4j、JDK 1.4 或 Jacarta Commons 日志记录,您可以将实现(绑定)的 jar 更改为您想要的。它遵循如何使用 slf4j 和 logback 的快速用户手册。

设置你的环境

首先,您应该导入使用 slf4j 所需的必要 jar。

日食指南

  • 在 Eclipse 中转到您的项目并右键单击它。选择属性

  • 从左侧面板中选择Java Build Path

  • 选择选项卡

  • 单击添加外部罐子

  • 找到您提取的文件夹并从logback-1.0.7文件夹中添加logback-core-1.0.7.jarlogback-classic-1.0.7.jar和从slf4j-1.7.0中添加 slf4j-api-1.7.0.jar文件夹。单击确定返回项目。

Netbeans 指南

  • 转到您在 Netbeans 中的项目并右键单击它。选择属性

  • 从左侧面板中选择

  • 选择编译选项卡

  • 单击添加 Jar/文件夹

  • 找到您提取的文件夹并从logback-1.0.7文件夹中添加logback-core-1.0.7.jarlogback-classic-1.0.7.jar和从slf4j-1.7.0中添加 slf4j-api-1.7.0.jar文件夹。单击确定返回项目。

*如果您没有使用上述任何环境,您应该在类路径中手动添加上述 3 个 jar。根据您的操作系统,需要遵循不同的过程。


使用日志框架

首先,您应该导入所需的依赖项:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

您要记录的每个类都应该有一个私有记录器:

private final Logger logger = (Logger) LoggerFactory.getLogger(this.getClass())

通过为每个类使用单独的记录器,您可以提供更大的灵活性和更轻松地更改日志记录级别(WARN、ERROR、INFO、DEBUG)。

根据你想使用的日志级别,你应该有

logger.info("Your info message");

logger.error("Your error message");

logger.debug("Your debug message");

logger.warn("Your warn message");

还可以根据您的需要使用更复杂的方法调用。例如,如果您想调试并显示您应该使用的堆栈跟踪

logger.debug("Your debug message",e);
(e stands for a catched exception).

例如:

try{       
   //some code  
}catch (IOException e){
   logger.debug("An IOException was thrown at this method ",e);       
   logger.error("An IOException was thrown at this method ",e); 
}

*此时无需添加任何其他配置,您就有了一个简单的日志记录系统。如果您想要更高级的配置,请阅读我在下面发布的 logback 的高级设置。


logback 的高级设置

为了拥有更高级的日志记录系统,您应该创建一个包含所有日志记录配置的附加文件。对于这个例子,我将使用 logback.xml。有关 logback 不同文件的更多信息,请参阅logback 配置

此时您应该创建一个名为 resources 的文件夹并将其添加到项目的构建路径中。

日食指南

  • 创建一个名为 resources 的文件夹(您必须在项目中看到该文件夹​​)

  • 在 Eclipse 中转到您的项目并右键单击它。选择属性

  • 从左侧面板中选择Java Build Path

  • 选择选项卡

  • 单击添加文件夹

  • 勾选您创建的资源文件夹,然后单击确定。单击确定返回项目。

  • 此时您应该将资源文件夹视为一个包。

Netbeans 指南

  • 创建一个名为资源的文件夹(它在项目视图中尚不可见..仅在文件视图中)

  • 转到您在 Netbeans 中的项目并右键单击它。选择属性

  • 从左侧面板中选择来源

  • 在 Source package 文件夹中,单击Add Folder

  • 选择 资源文件夹,然后单击确定。

  • 您应该看到创建为包的文件夹。

*文件夹的名称可以是您喜欢的任何名称。为方便起见,我将其命名为资源。

以下适用于 Eclipse 和 Netbeans。

*如果您的类路径中没有以下文件,这些文件指定了日志框架中的特定设置,则在 DEBUG 中自动分配根 logger 级别。这意味着将记录所有日志记录级别。调试是更高的级别。

  • 创建一个名为 logback.xml 的文件夹并将其放在资源文件夹中。
  • 在 logback.xml 中放置以下标签。

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>   
        <encoder>
            <pattern>[%-5level] - %msg%n
            </pattern>
        </encoder>
    </appender>
    
    
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <append>false</append>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %class - %msg%n
            </pattern>
        </encoder>
        <File>log/log.txt</File>
    </appender>
    
    
    <logger name="org.test" level="INFO" additivity="false">
        <appender-ref ref="STDOUT" />
    </logger>
    
    <logger name="org.test" level="DEBUG" additivity="false">
        <appender-ref ref="FILE" />
    </logger>
    
    <root level="OFF">
    
    </root>
    

上面的配置包含 2 个不同的 appender,一个在控制台中,一个在名为 log.txt 的文件中。该文件将被放置在名为 log 的文件夹中。如果文件夹日志不存在,将自动创建。

您将使用的模式取决于您以及您的消息的信息量。在当前配置中,控制台附加程序的描述性较差,仅显示日志记录级别和消息,与包含日志记录级别、线程名称、类名、时间和消息的文件附加程序相比。值 append 设置为 false 以便在每次运行应用程序后创建一个新的日志文件。

上面的配置对同一个包使用了 2 个不同的记录器。第一个记录器仅在控制台中打印信息消息,第二个记录器将调试消息打印到文件中。这是通过使用放置在附加程序内的过滤器来实现的。

*在记录器名称中,您可以使用类的完全限定名称或包名称。在这种情况下,我假设包结构 org.test 并将类放在这个包中。如果您具有类的完全限定名称,则日志记录配置将仅应用于该类。如果您使用包名,则该包内的所有类都将遵循上述配置。

有许多不同的方法可以使用 appenders 和 loggers,这取决于您的需求和程序的复杂性。根据您描述的情况,我相信上述解决方案可以满足您的需求。

PS 有关更多描述性定义和更高级配置,您可以参考Logback 手册

于 2012-09-12T13:28:08.100 回答
14

为什么不使用日志记录级别。?

使用您的用户理解的业务代码调试您的技术错误和INFOERROR 。

于 2012-09-12T07:14:56.370 回答
1

此类事情通常由记录器和不同的日志级别处理。

您通常有 3 个日志级别,一般日志、警告和错误。当您输出时,您决定消息的级别

当你启动你的应用程序时,你会告诉你的记录器它应该显示哪个级别。对于您的用户,这将是错误的,只有最糟糕的事情应该是可见的,对于您自己,您将输出所有内容

于 2012-09-12T07:18:13.163 回答
-3

在两个不同的位置创建两个具有相同包/名称的类

public class PrintStackTraceUtil
 {
 public static void printStackTrace(Throwable err)
     {
     //ignore
     }
 }

public class PrintStackTraceUtil
 {
 public static void printStackTrace(Throwable err)
     {
     err.printStackTrace();
     }
 }

编译你的java程序时,只把这些路径之一放在你的源路径中

于 2012-09-12T07:20:29.477 回答