Java 如何停止在控制台上打印异常堆栈跟踪?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18849415/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to stop printing exception stack trace on Console?
提问by Suresh Atta
I wrote a servlet to handle the exceptions occurring in my web app and mapped them in web.xml
我写了一个 servlet 来处理我的 web 应用程序中发生的异常并将它们映射到 web.xml
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/exceptionHandler</location>
</error-page>
Here is what I have done in the Exception Handling servlet service
method:
这是我在异常处理 servletservice
方法中所做的:
@Override
protected void service(HttpServletRequest req, HttpServletResponse arg1)
throws ServletException, IOException {
Object attribute = req.getAttribute("javax.servlet.error.exception");
if(attribute instanceof SocketException){
// don't do anything
}else{
super.service(req, arg1);
}
}.
Problem:
问题:
The above approach is not working and the stack trace is printing to the console. This occurs when the user requests something and then closes their browser.
上述方法不起作用,堆栈跟踪正在打印到控制台。当用户请求某些内容然后关闭他们的浏览器时,就会发生这种情况。
Question:
题:
How do I stop printing the stacktrace to the JBoss console whenever a SocketException
occurs?
SocketException
发生这种情况时,如何停止将堆栈跟踪打印到 JBoss 控制台?
Reason for doing this:
这样做的原因:
I want to avoid seeing all of the log's SocketException
s at the end of th day because I can't do anything with that information.
我想避免SocketException
在一天结束时看到所有日志,因为我无法对这些信息做任何事情。
回答by MansoorShaikh
You probably will have to override fillInStackTrade method
您可能必须覆盖 fillInStackTrade 方法
public static class CustomException extends Exception {
@Override
public Throwable fillInStackTrace() {
return null;
}
}
}
回答by Suresh Atta
Here is what I done so war as work around.
这是我所做的战争作为解决方法。
Added one filter and hiHyman all the request and response.Catch the exception and check the type.
添加了一个过滤器,劫持了所有的请求和响应。捕获异常并检查类型。
/**
* HiHymans all the http request and response here.
* Catch the SocketException and do not print
* If other exceptions print to console
* date : 9-18-2013
*
* @author Suresh Atta
*
*/
public class ExceptionHandler implements Filter {
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
try{
arg2.doFilter(arg0, arg1);
}catch(SocketException e ){
// Please don't print this to log.
}
}
}
And in web.xml
,filter mapping
并在web.xml
,过滤器映射
<filter>
<filter-name>ExceptionHandler</filter-name>
<filter-class>com.nextenders.server.ExceptionHandler</filter-class>
</filter>
<filter-mapping>
<filter-name>ExceptionHandler</filter-name>
<dispatcher> REQUEST </dispatcher>
<url-pattern> /*</url-pattern>
</filter-mapping>
I'm not marking this as answer,since I'm not sure this is a standard way or not.Just a work around.
我没有将此标记为答案,因为我不确定这是否是标准方式。只是一种解决方法。
回答by Ravindra HV
As I understand it, exceptions are logged to the console when it is not caught before reaching the container. As such using a filter to catch unhandled exceptions makes sense.
据我了解,在到达容器之前没有捕获异常时,异常会记录到控制台。因此,使用过滤器来捕获未处理的异常是有意义的。
Struts2 also has an exception 'interceptor' as its last interceptor, by default. See defaultStack. We need do override this interceptor if we need custom exception handling.
默认情况下,Struts2 也有一个异常“拦截器”作为它的最后一个拦截器。请参阅defaultStack。如果我们需要自定义异常处理,我们需要覆盖这个拦截器。
The only thing I would do additionally would be to log the exceptions (atleast to an errors-ignore.txt file) rather than completely skipping them.
我唯一要做的就是记录异常(至少记录到一个 errors-ignore.txt 文件)而不是完全跳过它们。
回答by Prakash
Instead of adding java.lang.Exception
in your web.xml why won't you just try to add socket exception in web.xml itself like below
而不是java.lang.Exception
在你的 web.xml中添加你为什么不尝试在 web.xml 本身中添加套接字异常,如下所示
<error-page>
<exception-type>java.net.SocketException</exception-type>
<location>/exceptionHandler</location>
</error-page>
and just do nothing in your servlet
Orinstead add a empty jsp file like
并在您的 servlet 中什么都不做
或者添加一个空的 jsp 文件,例如
<error-page>
<exception-type>java.net.SocketException</exception-type>
<location>/error.jsp</location>
</error-page>
回答by Braj
Use Jboss Custom Logging Handlerto solve this problem.
使用Jboss Custom Logging Handler来解决这个问题。
If you don't want to log any SocketException
exception stack trace then just skip it while loggin into a file.
如果您不想记录任何SocketException
异常堆栈跟踪,则只需在登录文件时跳过它。
Steps to follow:
要遵循的步骤:
- A custom handler must inherit java.util.logging.Handler
- 自定义处理程序必须继承 java.util.logging.Handler
Here is the code:
这是代码:
package com.custom.jboss.logging;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.logging.ErrorManager;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
public class SocketExceptionCustomLoggingHandler extends Handler {
private String logFile;
public BufferedWriter out = null;
public SocketExceptionCustomLoggingHandler() {
super();
logFile = "";
}
@Override
public void publish(LogRecord record) {
if (!initialize()) {
return;
}
if (isLoggable(record)) {
process(record);
}
}
private synchronized boolean initialize() {
if (out == null && logFile != null && !logFile.equals("")) {
FileWriter fstream = null;
try {
fstream = new FileWriter(logFile, true);
out = new BufferedWriter(fstream);
} catch (IOException e) {
reportError(e.getMessage(), e, ErrorManager.OPEN_FAILURE);
}
logToFile("Log file initialized. Logging to: " + logFile);
}
return true;
}
private void process(LogRecord logRecord) {
String log = getFormatter().format(logRecord);
if (log.indexOf("java.net.SocketException") == -1) {
logToFile(log);
}
}
private void logToFile(String text) {
try {
if (out != null) {
out.write((new Date()).toString() + "\t" + text + "\n");
out.flush();
}
} catch (IOException e) {
reportError(e.getMessage(), e, ErrorManager.WRITE_FAILURE);
}
}
@Override
public void flush() {
try {
if (out != null) {
out.flush();
}
} catch (IOException e) {
reportError(e.getMessage(), e, ErrorManager.FLUSH_FAILURE);
}
}
@Override
public void close() {
if (out != null) {
try {
out.close();
} catch (IOException e) {
reportError(e.getMessage(), e, ErrorManager.CLOSE_FAILURE);
}
}
}
public void setLogFile(String logFile) {
this.logFile = logFile;
}
}
The file is then packaged into a jar and placed in the modules directory.
i.e.
Jboss-7.1.1/modules/com/custom/jboss/loggers/main
together with a module.xml file. The contents of the module.xml should look like this.<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.0" name="com.custom.jboss.loggers"> <resources> <resource-root path="SocketExceptionHandler.jar"/> <!-- Insert resources here --> </resources> <dependencies> <module name="org.jboss.logging"/> <module name="javax.api"/> </dependencies> </module>
Then modify the standalone.xml to support logging to the custom logger
<subsystem xmlns="urn:jboss:domain:logging:1.1"> ... <custom-handler name="SocketExceptionAppender" class="com.custom.jboss.logging.SocketExceptionCustomLoggingHandler" module="com.custom.jboss.loggers"> <level name="DEBUG"/> <formatter> <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/> </formatter> <properties> <property name="logFile" value="d:\temp\logfile.txt"/> </properties> </custom-handler> ... <root-logger> <level name="INFO"/> <handlers> <handler name="SocketExceptionAppender"/> </handlers> </root-logger> </subsystem>
Add more handler in root-logger if needed such as FILE, CONSOLE etc.
- Now all the logs will be logged in your custom log file via this custom handler where we have skipped
SocketException
- We can make this class more generic passing properties from standalone.xml such as used to pass log file path.
然后将该文件打包到一个 jar 中并放置在 modules 目录中。
即
Jboss-7.1.1/modules/com/custom/jboss/loggers/main
与module.xml 文件一起。module.xml 的内容应如下所示。<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.0" name="com.custom.jboss.loggers"> <resources> <resource-root path="SocketExceptionHandler.jar"/> <!-- Insert resources here --> </resources> <dependencies> <module name="org.jboss.logging"/> <module name="javax.api"/> </dependencies> </module>
然后修改standalone.xml支持日志到自定义logger
<subsystem xmlns="urn:jboss:domain:logging:1.1"> ... <custom-handler name="SocketExceptionAppender" class="com.custom.jboss.logging.SocketExceptionCustomLoggingHandler" module="com.custom.jboss.loggers"> <level name="DEBUG"/> <formatter> <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/> </formatter> <properties> <property name="logFile" value="d:\temp\logfile.txt"/> </properties> </custom-handler> ... <root-logger> <level name="INFO"/> <handlers> <handler name="SocketExceptionAppender"/> </handlers> </root-logger> </subsystem>
如果需要,在 root-logger 中添加更多处理程序,例如 FILE、CONSOLE 等。
- 现在,所有日志都将通过我们跳过的自定义处理程序记录在您的自定义日志文件中
SocketException
- 我们可以让这个类更通用的从 standalone.xml 传递属性,例如用于传递日志文件路径。
Please let me know if there is any issue.
如果有任何问题,请告诉我。
回答by Yuri
Another funky idea: you could create exception handler
另一个时髦的想法:你可以创建异常处理程序
class SocketExceptionSwallower implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
if (e instanceof SocketException) {
// swallow
} else {
e.printStackTrace();
}
}
}
and registered with
并注册
Thread.setDefaultUncaughtExceptionHandler(new SocketExceptionSwallower());
or
或者
Thread.currentThread().setUncaughtExceptionHandler(new SocketExceptionSwallower());
Simple, no overhead of another filter in chain, but it messes with threads and will probably break something in Java EE environment )
Might be useful in testing/experimenting or if you fully control threads in your own code
简单,没有链中另一个过滤器的开销,但它会干扰线程并且可能会破坏 Java EE 环境中的某些内容)
可能在测试/实验或您完全控制自己代码中的线程时有用
回答by UmeshA
You can use the Logger
. For this you need log4j
library and all the desired behavior and exceptions are written to log file. For this you need to give the log file path
您可以使用Logger
. 为此,您需要log4j
库并将所有所需的行为和异常写入日志文件。为此,您需要提供日志文件路径