All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.undefinedlabs.scope.rules.consumer.MessageConsumerScopeAgentRule Maven / Gradle / Ivy

package com.undefinedlabs.scope.rules.consumer;

import com.undefinedlabs.scope.events.EventFieldsFactory;
import com.undefinedlabs.scope.events.exception.ThrowableEvent;
import com.undefinedlabs.scope.rules.AbstractScopeAgentRule;
import com.undefinedlabs.scope.rules.propagation.carriers.JmsTextMapExtractAdapter;
import com.undefinedlabs.scope.rules.transformer.ScopeAgentAdvicedTransformer;
import com.undefinedlabs.scope.utils.event.EventValues;
import com.undefinedlabs.scope.utils.sourcecode.ExceptionSourceCodeFactory;
import com.undefinedlabs.scope.utils.sourcecode.ExceptionSourceCodeFrame;
import com.undefinedlabs.scope.utils.tag.TagKeys;
import com.undefinedlabs.scope.utils.tag.TagValues;
import io.opentracing.References;
import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
import io.opentracing.propagation.Format;
import io.opentracing.util.GlobalTracer;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;

import javax.jms.Destination;
import javax.jms.Message;
import java.util.Collections;

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

public class MessageConsumerScopeAgentRule extends AbstractScopeAgentRule {

    @Override
    protected String instrumentedClassName() {
        return "javax.jms.MessageConsumer";
    }

    @Override
    protected Iterable transformers() {
        return Collections.singleton(new AgentBuilder.Default()
                .ignore(none())
                .with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
                .with(AgentBuilder.RedefinitionStrategy.REDEFINITION)
                .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
                .type(isSubTypeOf(instrumentedClass())).transform(new ScopeAgentAdvicedTransformer(MessageConsumerAdvice.class, named("receive")))
        );
    }

    public static class MessageConsumerAdvice {

        @Advice.OnMethodExit(onThrowable = Throwable.class)
        public static void exit(@Advice.This Object thiz, @Advice.Return Object messageObj, @Advice.Thrown Throwable throwable){
            try {
                final Message message = (Message) messageObj;

                final Tracer tracer = GlobalTracer.get();
                final SpanContext activeSpanCtxt = (tracer.activeSpan() != null) ? tracer.activeSpan().context() : null;
                final SpanContext extractedSpanCtxt = (message != null) ? tracer.extract(Format.Builtin.TEXT_MAP, new JmsTextMapExtractAdapter(message)) : null;

                final Destination destination = (message != null) ? message.getJMSDestination() : null;
                final String operationName = ("JMS:Receive " + ((destination != null ) ? destination.toString() : "")).trim();
                final Span span = tracer.buildSpan(operationName)
                        .addReference(References.FOLLOWS_FROM, extractedSpanCtxt != null ? extractedSpanCtxt : activeSpanCtxt)
                        .ignoreActiveSpan()
                        .withTag(TagKeys.SPAN_KIND, TagValues.Message.SPAN_KIND_CONSUMER)
                        .withTag(TagKeys.COMPONENT, TagValues.Component.JMS)
                        .withTag(TagKeys.Network.Messaging.MESSAGE_BUS_ID, (message != null) ? message.getJMSMessageID() : null)
                        .withTag(TagKeys.Network.Messaging.MESSAGE_BUS_CORRELATION_ID, (message != null) ? message.getJMSCorrelationID() : null)
                        .withTag(TagKeys.Network.Messaging.MESSAGE_BUS_EXPIRATION, (message != null) ? message.getJMSExpiration() : null)
                        .withTag(TagKeys.Network.Messaging.MESSAGE_BUS_DELIVERY_TIME, (message != null) ? message.getJMSExpiration() : null)
                        .withTag(TagKeys.Network.Messaging.MESSAGE_BUS_DESTINATION, (destination != null) ? destination.toString() : null)
                        .withTag(TagKeys.Network.Messaging.MESSAGE_BUS_DELIVERY_MODE, (message != null) ? message.getJMSDeliveryMode() : null)
                        .withTag(TagKeys.Network.Messaging.MESSAGE_BUS_PRIORITY, (message != null) ? message.getJMSPriority() : null)
                        .start();

                if(throwable != null) {
                    span.setTag(TagKeys.ERROR, true);

                    final ExceptionSourceCodeFrame exceptionSourceCodeFrame = ExceptionSourceCodeFactory.INSTANCE.createFrame(throwable);
                    final ThrowableEvent.Builder throwableEventBuilder = ThrowableEvent.newBuilder();
                    throwableEventBuilder
                            .withEventType(EventValues.General.ERROR)
                            .withThrowable(exceptionSourceCodeFrame.getUserThrowable())
                            .withSource(exceptionSourceCodeFrame.getSourceCodeFrame().getLinkPathWithMethodLine());

                    span.log(EventFieldsFactory.INSTANCE.createFields(throwableEventBuilder.build()));
                }

                span.finish();

            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy