java - लॉगिंग के लिए AspectJ के साथ AOP का उपयोग कैसे करें?




logging (4)

मैं अपने सभी सार्वजनिक तरीकों से "ट्रेस" संदेश जोड़ना चाहता हूं:

public void foo(s:String, n:int) { // log is a log4j logger or any other library
  log.trace(String.format("Enter foo with s: %s, n: %d", s, n))
  ...
  log.trace("Exit foo") 
}

अब मैं उन सभी log.trace को स्वचालित रूप से एओपी (और बाइट कोड उपकरण) के साथ अपने तरीकों में log.trace चाहता हूं। मैं AspectJ बारे में सोच रहा हूँ। क्या इस का कोई मतलब निकलता है? क्या आप किसी भी खुले स्रोत को जानते हैं, जो वास्तव में करता है?


आप अपनी आवश्यकता बनाने के लिए विभिन्न पॉइंटकट का उपयोग कर सकते हैं। यह documentation आपकी मदद करेगा।

सीधे आगे समाधान


आप इस ओपन सोर्स http://code.google.com/p/perfspy/ को आजमा सकते हैं। PerfSpy एक रनटाइम लॉगिंग, प्रदर्शन निगरानी और कोड निरीक्षण उपकरण है। यह रनटाइम पर आपके एप्लिकेशन कोड के चारों ओर बुनाई के लिए ApsectJ का उपयोग करता है, और प्रत्येक विधि और उसके इनपुट पैरामीटर और मानों के निष्पादन समय को लॉग करता है। इसमें एक यूआई एप्लीकेशन है, जिसमें आप विधि आमंत्रण और उनके इनपुट और पेड़ के रूप में मूल्यों को वापस देख सकते हैं। इसके साथ, आप प्रदर्शन की बाधाओं को खोज सकते हैं और जटिल कोड प्रवाह को समझ सकते हैं।


विधियों से अपवादों को दर्ज करने, बाहर निकलने और लॉग इन करने के लिए मेरा सरल कार्यान्वयन यहां दिया गया है

टिप्पणी

package test;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface Audit {

}

इंटरसेप्टर

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.logging.Level;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;


@Aspect
public class ExceptionInterceptor {

    private static final java.util.logging.Logger LOGGER = java.util.logging.Logger.getLogger(ExceptionInterceptor.class.getName());

    @Around("execution(* * (..))"
            + " && @annotation(test.Audit)"
    )
    public Object intercept(final ProceedingJoinPoint point) throws Throwable {
        final Method method
                = MethodSignature.class.cast(point.getSignature()).getMethod();
        String mName = method.getName();
        String cName = method.getDeclaringClass().getSimpleName();
        LOGGER.log(Level.INFO, "Entering {0}:{1}", new Object[]{cName, mName});
        Object out = null;
        try {
            out = point.proceed();
        } catch (Throwable t) {
            logExceptions(t, point);
        }
        LOGGER.log(Level.INFO, "Exiting {0}:{1}", new Object[]{cName, mName});
        return out;
    }

    private void logExceptions(Throwable t, final ProceedingJoinPoint point) {
        final Method method
                = MethodSignature.class.cast(point.getSignature()).getMethod();
        String mName = method.getName();
        String cName = method.getDeclaringClass().getSimpleName();
        Object[] params = point.getArgs();
        StringBuilder sb = new StringBuilder();
        sb.append("Exception caught for [");
        sb.append(cName);
        sb.append(".");
        sb.append(mName);
        for (int i = 0; i < params.length; i++) {
            Object param = params[i];

            sb.append("\n");
            sb.append("  [Arg=").append(i);
            if (param != null) {
                String type = param.getClass().getSimpleName();

                sb.append(", ").append(type);

                // Handle Object Array (Policy Override)
                if (param instanceof Object[]) {
                    sb.append("=").append(Arrays.toString((Object[]) param));
                } else {
                    sb.append("=").append(param.toString());
                }
            } else {
                sb.append(", null");
            }
            sb.append("]");
            sb.append("\n");
        }
        LOGGER.log(Level.SEVERE, sb.toString(), t);

    }
}

इसका इस्तेमाल कैसे करें

@Audit  
public void testMethod(Int a,int b, String c){
}

मेवेन निर्भरता संकलन

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.7</version>
    </dependency> 

बुनाई

        <plugin>
            <groupId>com.jcabi</groupId>
            <artifactId>jcabi-maven-plugin</artifactId>
            <executions>
                <execution>
                    <phase>compile</phase>
                    <goals>
                        <goal>ajc</goal>
                    </goals>
                </execution>
            </executions>
        </plugin> 

@Loggable एनोटेशन और jcabi-aspects से एक jcabi-aspects लिए एक तैयार तंत्र है (मैं एक डेवलपर हूं):

@Loggable(Loggable.DEBUG)
public String load(URL url) {
  return url.openConnection().getContent();
}

प्रश्न की आवश्यकताओं के अनुसार, प्रवेश और निकास दोनों को लॉग इन करने के लिए:

@Loggable(Loggable.DEBUG, prepend=true)
public String load(URL url) {
  return url.openConnection().getContent();
}

सभी लॉग एसएलएफ 4 जे पर जाते हैं। अधिक जानकारी के लिए इस पोस्ट को देखें।







aspectj