我正在创建一个 java 应用程序,其中可能会引发异常。我在 try-catch 块中处理这些异常并打印适当的消息,以便业务用户在发生故障时不必看到丑陋的堆栈跟踪。
但是现在当我调试时,我想以这样一种方式调用 JAR 文件,它会为我打印堆栈跟踪,这样我就可以知道问题到底出在哪里。
有人可以告诉我如何实现这一目标吗?
我正在创建一个 java 应用程序,其中可能会引发异常。我在 try-catch 块中处理这些异常并打印适当的消息,以便业务用户在发生故障时不必看到丑陋的堆栈跟踪。
但是现在当我调试时,我想以这样一种方式调用 JAR 文件,它会为我打印堆栈跟踪,这样我就可以知道问题到底出在哪里。
有人可以告诉我如何实现这一目标吗?
您可以使用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.jar、logback-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.jar、logback-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.xml。有关 logback 不同文件的更多信息,请参阅logback 配置。
此时您应该创建一个名为 resources 的文件夹并将其添加到项目的构建路径中。
日食指南
创建一个名为 resources 的文件夹(您必须在项目中看到该文件夹)
在 Eclipse 中转到您的项目并右键单击它。选择属性。
从左侧面板中选择Java Build Path
选择源选项卡
单击添加文件夹
勾选您创建的资源文件夹,然后单击确定。单击确定返回项目。
此时您应该将资源文件夹视为一个包。
Netbeans 指南
创建一个名为资源的文件夹(它在项目视图中尚不可见..仅在文件视图中)
转到您在 Netbeans 中的项目并右键单击它。选择属性。
从左侧面板中选择来源
在 Source package 文件夹中,单击Add Folder。
选择 资源文件夹,然后单击确定。
您应该看到创建为包的文件夹。
*文件夹的名称可以是您喜欢的任何名称。为方便起见,我将其命名为资源。
以下适用于 Eclipse 和 Netbeans。
*如果您的类路径中没有以下文件,这些文件指定了日志框架中的特定设置,则在 DEBUG 中自动分配根 logger 级别。这意味着将记录所有日志记录级别。调试是更高的级别。
在 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 手册
为什么不使用日志记录级别。?
使用您的用户理解的业务代码调试您的技术错误和INFO或ERROR 。
此类事情通常由记录器和不同的日志级别处理。
您通常有 3 个日志级别,一般日志、警告和错误。当您输出时,您决定消息的级别
当你启动你的应用程序时,你会告诉你的记录器它应该显示哪个级别。对于您的用户,这将是错误的,只有最糟糕的事情应该是可见的,对于您自己,您将输出所有内容
在两个不同的位置创建两个具有相同包/名称的类
public class PrintStackTraceUtil
{
public static void printStackTrace(Throwable err)
{
//ignore
}
}
和
public class PrintStackTraceUtil
{
public static void printStackTrace(Throwable err)
{
err.printStackTrace();
}
}
编译你的java程序时,只把这些路径之一放在你的源路径中