【问题标题】:play - 2.2-Java : QOS : How to log event on start(before) & end(after) of the method using annotations , actions?播放 - 2.2-Java : QOS : 如何使用注释、操作在方法的开始(之前)和结束(之后)上记录事件?
【发布时间】:2014-02-20 20:05:45
【问题描述】:

我想在方法的开始和结束时生成事件以记录用于 QOS 和检测目的的时间戳。在 Spring 框架中,使用 AOP 很容易实现,而无需在每个方法中编写样板代码。

我想在游戏中做类似的事情。我查看了操作和 @with 注释,但它没有给出预期的结果。

在开始(之前)和完成(之后)方法上记录事件和时间戳的最佳方法是什么?

下面是我的动作类:

import play.libs.F.Promise;
import play.mvc.Action;
import play.mvc.Http;
import play.mvc.SimpleResult;

public class PublishEventAction extends Action<PublishEvent> {

    @Override
    public Promise<SimpleResult> call(Http.Context context) throws Throwable
    {


        try { 
            before(context); 
            Promise<SimpleResult> result = delegate.call(context); // This part calls your real action method 
            after(context); 
            return result; 
          } catch (RuntimeException e) { 
            throw e; 
          } catch (Throwable t) { 
            throw new RuntimeException(t); 
          } 


    }

    private void before(Http.Context context) { 
        // Do the before things here

        System.out.println("Before: " + context.request().path()+context.toString()+"current time : "+System.currentTimeMillis());
      } 

      private void after(Http.Context context) { 
        // Do the after things here
          System.out.println("After: " + context.request().path()+context.toString()+"current time : "+System.currentTimeMillis());
      } 

}

提前致谢!

【问题讨论】:

    标签: playframework playframework-2.0 playframework-2.2


    【解决方案1】:

    您可以在请求之前和之后拦截,如下所示并记录您的所有请求:

    public Action onRequest(final Http.Request request, Method method) {
    
        Action action =  new Action.Simple() {
            public Promise<Result> call(Http.Context ctx) throws Throwable {
                Long start = System.currentTimeMillis();
                Promise<Result> result = delegate.call(ctx);
    
                //This part is not executed immediately
                Long finish = System.currentTimeMillis();
                Logger.info("method=" + request.method() + " uri=" + request.uri() + " remote-address=" + request.remoteAddress() + " time=" + (finish-start));
    
                return result;
            }
        };
        return action;
    }
    

    【讨论】:

      【解决方案2】:

      您可以定义一个action composition。在播放文档中解释了如何在触发操作之前执行任何代码。但是你也可以像Google Groups 中描述的那样使用 AFTER。

      【讨论】:

      • 我试图达到同样的效果,但是当我的方法返回时 - Promise - @after 立即被执行。我想在结果可用后执行 after() 以捕获实际结果处理时间而不是对结果的承诺。我试过 onRedeem 但是它没有处理上下文。有什么建议吗?
      【解决方案3】:

      您可以在“应用”包的根目录创建一个扩展 GlobalSettings 的全局类并拦截每个请求:

      公共类 Global 扩展 GlobalSettings {

      public Action onRequest(Request request, Method actionMethod) {
          Logger.debug("Request starts:" + request.toString());
          Action action = super.onRequest(request, actionMethod);
          Logger.debug("Request ends.");
      
          return action;
      }
      

      }

      【讨论】:

        【解决方案4】:

        如前所述,您希望扩展全局设置对象。

        Play 的文档很可靠:Application Global SettingsIntercepting Requests

        import play.*;
        import play.mvc.Action;
        import play.mvc.Http.Request;
        import java.lang.reflect.Method;
        
        public class Global extends GlobalSettings {
        
            public Action onRequest(Request request, Method actionMethod) {
                System.out.println("before each request..." + request.toString());
                return super.onRequest(request, actionMethod);
            }
        
        }
        

        文档解释说,如果您想拦截特定操作,可以使用action composition 来实现。

        【讨论】:

          猜你喜欢
          • 2019-05-26
          • 1970-01-01
          • 1970-01-01
          • 2020-03-13
          • 1970-01-01
          • 2014-07-09
          • 2015-01-05
          • 2020-01-05
          • 1970-01-01
          相关资源
          最近更新 更多