2013-01-19 68 views
0

我試圖做一個基本方面(作爲概念證明,主要),我可以用它來跟蹤IO通過套接字完成。Aspectj切入點捕獲流關閉(試圖測量通過套接字發送/接收的字節)

以下代碼封裝了所有調用,以便從具有基於Commons-IO的CountingInputStream的套接字獲取輸入流。該部分起作用。

什麼是不工作(我懷疑這是因爲我fubar'ed我的切入點定義)正在從CountingInputStream中獲取字節數。

關閉/重置建議永遠不會被擊中。 (我把它作爲@Before的建議,然後將它切換到@Around - 但是這也不起作用...)

(一旦我獲得了基本的工作,我打算將其清理更多一點太)

package com.foo.io; 

import com.yammer.metrics.Metrics; 
import com.yammer.metrics.core.Counter; 
import com.yammer.metrics.core.Histogram; 
import com.yammer.metrics.core.MetricName; 
import com.yammer.metrics.core.MetricsRegistry; 
import org.apache.commons.io.input.CountingInputStream; 
import org.apache.commons.io.output.CountingOutputStream; 
import org.aspectj.lang.ProceedingJoinPoint; 
import org.aspectj.lang.annotation.*; 

import java.io.*; 
import java.net.Socket; 


@Aspect 
public class SocketStreamWrapper { 
    // can trivially create a map keeping track of bytes sent to/from a given address if this is desired 
    final Counter inboundByteCounter; 
    final Histogram inboundByteHistogram; 
    final Counter outboundByteCounter; 
    final Histogram outboundByteHistogram; 

    public SocketStreamWrapper() { 
     inboundByteCounter = Metrics.defaultRegistry().newCounter(new MetricName("inbound", "bytes", "counted")); 
     inboundByteHistogram = Metrics.defaultRegistry().newHistogram(new MetricName("inbound", "bytes", "histogram"), true); 
     outboundByteCounter = Metrics.defaultRegistry().newCounter(new MetricName("outbound", "bytes", "counted")); 
     outboundByteHistogram = Metrics.defaultRegistry().newHistogram(new MetricName("outbound", "bytes", "histogram"), true); 
    } 

    @Pointcut("call(* java.net.Socket.getInputStream()) && target(s)") 
    void input(Socket s) { 
    } 

    @Pointcut("call(* CountingInputStream.close()) && this(cis)") 
    void close(CountingInputStream cis) { 
    } 

    @Pointcut("call(* CountingInputStream.reset()) && this(cis)") 
    void reset(CountingInputStream cis) { 
    } 

    @Pointcut("call(* CountingInputStream+.read*()) && this(cis)") 
    void read(CountingInputStream cis) { 

    } 

    @Around("close(cis)") 
    public void closeCountingStream(ProceedingJoinPoint jp, CountingInputStream cis) throws Throwable { 
     inboundByteCounter.inc(cis.getByteCount()); 
     inboundByteHistogram.update(cis.getByteCount()); 
     cis.resetByteCount(); 
     jp.proceed(); 
    } 

    @Around("input(s)") 
    public Object wrapInputStream(ProceedingJoinPoint joinPoint, 
            Socket s) 
      throws Throwable { 
     InputStream in = (InputStream) joinPoint.proceed(); 
     return new CountingInputStream(in); 
    } 

    @Pointcut("call(* java.net.Socket.getOutputStream()) && target(s)") 
    void output(Socket s) { 
    } 

    @Around("output(s)") 
    public Object wrapOutputStream(ProceedingJoinPoint joinPoint, 
            Socket s) 
      throws Throwable { 
     OutputStream out = (OutputStream) joinPoint.proceed(); 
     return new CountingOutputStream(out); 
    } 
} 
+0

這似乎工作: '@Pointcut( 「調用(* java.net.Socket.getInputStream())&&目標(S)」) 無效輸入(套接字s){} @Pointcut( 「調用(* java.io.Closeable + .close(..))&& target(cis)」) void closeInputStream(CountingInputStream cis){ } @Pointcut(「call(* java.io.Closeable + .close ..))&& target(cis)「) void closeOutputStream(CountingOutputStream){ }' – Ryan

回答

1

,你需要使用目標而不是的原因,這是,目標狀態表示切入點適用於該方法被要求的對象,而不是調用的方法。在這種情況下,您的對象關閉重置讀取切入點的目標是CountingInputStream。

兩者之間的區別在概述:http://www.eclipse.org/aspectj/doc/next/progguide/semantics-pointcuts.html

作爲一個額外的點,你可能希望有CountingInputStream的子類有私人或受保護的範圍,這樣就可以直接定位,並避免意外與互動其他人使用CountingInputStreams。你的執行closeCountingStream調用resetByteCount()這會造成混淆和其他用例的延遲。

+0

感謝您的輸入! – Ryan

相關問題