【问题标题】:Spring MBeanExporter: Log an exception's stacktraceSpring MBeanExporter:记录异常的堆栈跟踪
【发布时间】:2010-09-03 19:22:55
【问题描述】:

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

我知道我可以在方法中使用 try-catch 来执行此操作,但这会导致混乱。我检查了 Spring 文档(Chapter 22 是 JMX 上的文档),但什么也没看到。我也没有在SO上看到任何东西。我还查看了 MBeanExporter 的源代码,似乎有一种方法可以为 MBean 注册注册侦听器,但不能用于 MBean 请求处理。

【问题讨论】:

    标签: java spring logging jmx


    【解决方案1】:

    在我基于 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;
                          }
                    }
              };
            }
    }
    

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 我没有使用任何注释 - Spring 似乎默认导出所有操作/属性。我会尝试在有问题的操作上添加注释,看看有什么作用,谢谢。
      • 在我的应用程序中,@ManagedOperation 方法没有被捕获和记录
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      • 2013-02-21
      • 1970-01-01
      • 2011-01-05
      • 1970-01-01
      相关资源
      最近更新 更多