Java Agent plugin with public api

I want to customer a java agent plugin,can use public api in java agent plugin?

Hi, yes you can, the documentation on agent API is here

I hava try,but it doesn't work.Here is my code:
package co.elastic.apm.agent.ice.client;

import Ice.Communicator;
import Ice.ImplicitContext;
import Ice.ObjectPrx;
import co.elastic.apm.agent.bci.ElasticApmInstrumentation;
import co.elastic.apm.api.*;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;

import java.util.Collection;

import static net.bytebuddy.matcher.ElementMatchers.*;

public class IceClientInstrumentation extends ElasticApmInstrumentation {

private static class IceClientAdvice {

    @Advice.OnMethodEnter(suppress = Throwable.class)
    private static void onBeforeExecute(@Advice.Argument(0) ObjectPrx objectPrx) {

            Communicator ic=objectPrx.ice_getCommunicator();
            final ImplicitContext implicitContext=ic.getImplicitContext();
            ic.getImplicitContext().put("test", "123");
            Span span = ElasticApm.currentSpan()
                .startSpan("external", "ice", null)
                .setName("testice");
            try (final Scope scope = span.activate()) {
                span.injectTraceHeaders(new HeaderInjector() {
                    @Override
                    public void addHeader(String headerName, String headerValue) {
                        implicitContext.put(headerName, headerValue);
                    }
                });
            } catch (Exception e) {
                span.captureException(e);
                throw e;
            } finally {
                span.end();
            }
    }
}

@Override
public Class<?> getAdviceClass() {
    return IceClientAdvice.class;
}

@Override
public ElementMatcher<? super TypeDescription> getTypeMatcher() {
    return any();
}

@Override
public ElementMatcher<? super MethodDescription> getMethodMatcher() {
    return named("checkedCast").and(takesArgument(0, named("Ice.ObjectPrx")));
}

@Override
public Collection<String> getInstrumentationGroupNames() {
    return null;
}

}

This is my server side:
package co.elastic.apm.agent.ice.client;

import Ice.Current;
import co.elastic.apm.agent.bci.ElasticApmInstrumentation;
import co.elastic.apm.api.*;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;

import java.util.Collection;
import java.util.Map;

import static net.bytebuddy.matcher.ElementMatchers.*;

public class IceServerInstrumentation extends ElasticApmInstrumentation{

private static class IceServerAdvice {

    @Advice.OnMethodEnter(suppress = Throwable.class)
    private static void onBeforeExecute(@Advice.AllArguments Current current) {

       final Map<String, String> map=current.ctx;
        Transaction transaction = ElasticApm.startTransactionWithRemoteParent(new HeaderExtractor() {
            @Override
            public String getFirstHeader(String headerName) {
                return map.get(headerName);
            }
        });
        try (final Scope scope = transaction.activate()) {
            String adapterName = current.adapter.getName();
            String operationName = current.operation;
            transaction.setName(adapterName + "#" + operationName);
            transaction.setType(Transaction.TYPE_REQUEST);
        } catch (Exception e) {
            transaction.captureException(e);
            throw e;
        } finally {
            transaction.end();
        }
    }
}

@Override
public Class<?> getAdviceClass() {
    return IceServerInstrumentation.IceServerAdvice.class;
}

@Override
public ElementMatcher<? super TypeDescription> getTypeMatcher() {
    return any();
}

@Override
public ElementMatcher<? super MethodDescription> getMethodMatcher() {
    return any();
}

@Override
public Collection<String> getInstrumentationGroupNames() {
    return null;
}

}

You cannot use the Public API (co.elastic.apm.api.*) when writing an internal plugin. Use the internal API for that (co.elastic.apm.agent.impl.ElasticApmTracer).

Ok,thanks.I have a question,byte buddy can interctor final class?

yes.

Can you provider a example?

Out of curiosity, are you trying to create a custom plugin for https://doc.zeroc.com/display/Ice35/Java+Mapping ?

yes.

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.