2012-04-07 41 views
7

我通常在我的沙盒appid上全天运行appstats。但是,我有一个复杂的操作(基本上是重建库存数据库),导致appstats炸毁我的实例,抛出OutOfMemoryErrors。即使更大的实例大小,它仍然失败。 Appstats只需要太多的RAM。如何暂停App Engine/Java上的单个请求的appstats?

我不需要这个请求上的appstats。理想情况下,我将调用任何ThreadLocal对象负责appstats集合的方法,并告诉它将其拇指旋转几分钟。

我曾考虑过扩展AppstatsFilter来忽略某些URL,但这个违规的请求作为延迟任务来执行,并且通过路径识别它有点复杂。

如何告诉appstats暂停?

为防万一,不清楚:在禁用appstats的情况下上传我的应用程序版本,运行我的任务,然后上传带有启用的appstats的版本是我现在要做的。我不想这样做。

+0

我假设只是选择你想监控的网址不是一个选项? FWIW我希望能够做你不止一次要求的内容,但我咬紧牙关,只是把我们需要监控的网址列表放到配置中。 – 2012-04-07 04:06:42

+0

不幸的是我想排除的URL是/ _ah/queue/__ deferred__。我可以将DeferredTaskServlet安装在一个额外的URL上,并将这个特定的请求发送给它,但是这似乎离保留很远。 – stickfigure 2012-04-07 18:11:58

+0

你有没有想过这个? – Keith 2013-05-12 17:54:35

回答

1

好问题。对于Python,答案很简单:

from google.appengine.ext.appstats import recording 

class ...(webapp.RequestHandler): 
    def get(self): 
    recording.dont_record() 
    ... 

也许在Java中有类似的API?

此外,Python版本还有一个灵活的方式来筛选出哪些请求要记录;我认为在Java版本中,可以通过在web.xml中使用和条目来完成类似的事情。 (见的Java将Appstats文档。)

+0

我在SDK源代码中找不到Java等价物,不幸的是相关的url是标准的__deferred__任务url。像这样的方法正是我正在寻找的东西! – stickfigure 2012-04-07 18:13:53

1

杰夫,我不知道这是否可以帮助你降低OutOfMemoryError异常的发生: How to reduce the memory usage of Appstats on Google App Engine Java

<filter> 
    <filter-name>appstats</filter-name> 
    <filter-class>com.google.appengine.tools.appstats.AppstatsFilter</filter-class> 
    <init-param> 
     <param-name>maxLinesOfStackTrace</param-name> 
     <param-value>16</param-value> 
    </init-param> 
</filter> 
+1

不是一个理想的解决方案,但肯定有帮助 - 谢谢! – stickfigure 2012-05-23 06:12:45

2

我所做的是我自己写的CustomAppstatsFilter排除某些网址的。

public class CustomAppstatsFilter extends AppstatsFilter { 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, 
     FilterChain chain) throws IOException, ServletException { 

    if (request instanceof HttpServletRequest) { 
     String url = ((HttpServletRequest) request).getRequestURL().toString(); 

     // We do not want these to show up in appstats 
     if ((url.contains("appstats")) 
       || url.contains("_ah/") 
       || url.contains("cron/") 
       || url.contains("batch/")) { 
      chain.doFilter(request, response); 
      return; 
     } else { 
      super.doFilter(request, response, chain); 
     } 
    } 
    } 
} 

编辑 - 这可以结合ZiglioNZ伟大的答案。

<!-- Appstats filter for profiling application --> 
<filter> 
    <filter-name>appstats</filter-name> 
    <filter-class>my.company.filter.CustomAppstatsFilter</filter-class> 
    <init-param> 
     <param-name>maxLinesOfStackTrace</param-name> 
     <param-value>5</param-value> 
    </init-param> 
</filter> 
<filter-mapping> 
    <!-- excludes are in CustomAppstatsFilter --> 
    <filter-name>appstats</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
+0

这几乎可以做到这一点,但URL是延迟任务执行URL,它适用于所有延迟任务。我需要的东西是Python的dont_record(),它可以在我的代码中运行。 – stickfigure 2014-02-18 20:58:44

+0

像[本文](https://developers.google.com/appengine/articles/deferred)一样,如果您需要完全控制任务如何排队和执行,您需要使用Task Queue API。 ;-) – lucdc 2014-02-21 12:23:22

+0

我不需要或不想完全控制任务如何排队和执行;那就是用大锤在苍蝇上打苍蝇。我只是想让appstats更优雅地失败。 Python有一个API,但显然Java不会:( – stickfigure 2014-02-21 22:04:04

相关问题