Spring MBeanExporter:记录异常的堆栈跟踪

时间:2010-09-03 19:22:55

标签: java spring logging jmx

在Spring MVC中,如果异常的堆栈跟踪一直返回到框架(例如,如果存在NullPointerException),则会记录该异常的堆栈跟踪。使用Spring的MBeanExporter有一种简单的方法吗?

我知道我可以在方法中尝试捕捉,但这会导致混乱。我检查了Spring文档(Chapter 22是JMX上的文档)并没有看到任何内容。我也没有看到任何东西。我还查看了MBeanExporter的源代码,似乎有一种方法可以为MBean注册注册侦听器,但不能用于MBean请求处理。

2 个答案:

答案 0 :(得分:2)

在我的基于Spring 3.1的应用程序中,@ ManagedAttributes和@ManagedOperations都没有被捕获或记录。

所以我经历了MBeanExporter的扩展,每当MBean方法调用失败时它都会失败:

public class LoggingFailedCallsMBeanExporter extends MBeanExporter {

    protected ModelMBean createModelMBean() throws MBeanException {
        // super method does:
        // return (this.exposeManagedResourceClassLoader ? new SpringModelMBean() : new RequiredModelMBean());
        ModelMBean superModelMBean = super.createModelMBean();

        // but this.exposeManagedResourceClassLoader is not visible, so we switch on the type of the returned ModelMBean
        if (superModelMBean instanceof SpringModelMBean) {
              return new SpringModelMBean() {
                    @Override
                    public Object invoke(String opName, Object[] opArgs, String[] sig) throws MBeanException, ReflectionException {
                          try {
                                return super.invoke(opName, opArgs, sig);
                          } catch (MBeanException e) {
                                LOGGER.warn("Issue on a remote call", e);
                                throw e;
                          } catch (ReflectionException e) {
                                LOGGER.warn("Issue on a remote call", e);
                                throw e;
                          } catch (RuntimeException e) {
                                LOGGER.warn("Issue on a remote call", e);
                                throw e;
                          } catch (Error e) {
                                LOGGER.warn("Issue on a remote call", e);
                                throw e;
                          }
                    }
              };
        } else {
            return new RequiredModelMBean() {
                @Override
                public Object invoke(String opName, Object[] opArgs, String[] sig) throws MBeanException, ReflectionException {
                      try {
                            return super.invoke(opName, opArgs, sig);
                      } catch (MBeanException e) {
                            LOGGER.warn("Issue on a remote call", e);
                            throw e;
                      } catch (ReflectionException e) {
                            LOGGER.warn("Issue on a remote call", e);
                            throw e;
                      } catch (RuntimeException e) {
                            LOGGER.warn("Issue on a remote call", e);
                            throw e;
                      } catch (Error e) {
                            LOGGER.warn("Issue on a remote call", e);
                            throw e;
                      }
                }
          };
        }
}

答案 1 :(得分:0)

MBeanExporter是一个非常灵活的东西,可以处理许多不同的情况。由于您没有向我们展示示例代码,因此我假设您使用了注释@ManagedOperation@ManagedAttribute,因为这些注释似乎是最常见的。

如果你有一个用@ManagedAttribute注释的getter方法,并且这个getter抛出一个异常,那么这将不会被记录在任何地方,它将被传播到客户端以供它处理。这有时很烦人,但似乎无法将其配置为其他方式。

但是,

@ManagedOperation方法会捕获并记录它们的异常。我不知道为什么会有这种区别,但就是这样。