2012-04-07 40 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

相關問題