Skip to content

Commit

Permalink
Instrument jsf action calls (#2018)
Browse files Browse the repository at this point in the history
  • Loading branch information
laurit authored Jan 20, 2021
1 parent c6cc263 commit 9825ab0
Show file tree
Hide file tree
Showing 46 changed files with 1,205 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import static io.opentelemetry.api.trace.Span.Kind.INTERNAL
import static io.opentelemetry.api.trace.Span.Kind.SERVER

import io.opentelemetry.instrumentation.test.AgentTestRunner
import io.opentelemetry.instrumentation.test.RetryOnAddressAlreadyInUseTrait
import io.opentelemetry.instrumentation.test.utils.PortUtils
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import org.apache.camel.CamelContext
Expand All @@ -18,7 +19,7 @@ import org.springframework.boot.SpringApplication
import org.springframework.context.ConfigurableApplicationContext
import spock.lang.Shared

class RestCamelTest extends AgentTestRunner {
class RestCamelTest extends AgentTestRunner implements RetryOnAddressAlreadyInUseTrait {

@Shared
ConfigurableApplicationContext server
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package test
import static io.opentelemetry.api.trace.Span.Kind.SERVER

import io.opentelemetry.instrumentation.test.AgentTestRunner
import io.opentelemetry.instrumentation.test.RetryOnAddressAlreadyInUseTrait
import io.opentelemetry.instrumentation.test.utils.OkHttpUtils
import io.opentelemetry.instrumentation.test.utils.PortUtils
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
Expand All @@ -19,7 +20,7 @@ import org.springframework.boot.SpringApplication
import org.springframework.context.ConfigurableApplicationContext
import spock.lang.Shared

class SingleServiceCamelTest extends AgentTestRunner {
class SingleServiceCamelTest extends AgentTestRunner implements RetryOnAddressAlreadyInUseTrait {

@Shared
ConfigurableApplicationContext server
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import static io.opentelemetry.api.trace.Span.Kind.INTERNAL
import static io.opentelemetry.api.trace.Span.Kind.SERVER

import io.opentelemetry.instrumentation.test.AgentTestRunner
import io.opentelemetry.instrumentation.test.RetryOnAddressAlreadyInUseTrait
import io.opentelemetry.instrumentation.test.utils.PortUtils
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import org.apache.camel.CamelContext
Expand All @@ -20,7 +21,7 @@ import org.springframework.boot.SpringApplication
import org.springframework.context.ConfigurableApplicationContext
import spock.lang.Shared

class TwoServicesWithDirectClientCamelTest extends AgentTestRunner {
class TwoServicesWithDirectClientCamelTest extends AgentTestRunner implements RetryOnAddressAlreadyInUseTrait {

@Shared
int portOne
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import static Jms2Test.producerSpan

import com.google.common.io.Files
import io.opentelemetry.instrumentation.test.AgentTestRunner
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicReference
import javax.jms.Session
Expand Down Expand Up @@ -101,7 +102,9 @@ class SpringTemplateJms2Test extends AgentTestRunner {
def "send and receive message generates spans"() {
setup:
AtomicReference<String> msgId = new AtomicReference<>()
CountDownLatch countDownLatch = new CountDownLatch(1)
Thread.start {
countDownLatch.countDown()
TextMessage msg = template.receive(destination)
assert msg.text == messageText
msgId.set(msg.getJMSMessageID())
Expand All @@ -111,6 +114,8 @@ class SpringTemplateJms2Test extends AgentTestRunner {
session -> template.getMessageConverter().toMessage("responded!", session)
}
}
// wait for thread to start, we expect the first span to be from receive
countDownLatch.await()
TextMessage receivedMessage = template.sendAndReceive(destination) {
session -> template.getMessageConverter().toMessage(messageText, session)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apply from: "$rootDir/gradle/instrumentation-library.gradle"

dependencies {
compileOnly group: 'jakarta.faces', name: 'jakarta.faces-api', version: '2.3.2'
compileOnly group: 'jakarta.el', name: 'jakarta.el-api', version: '3.0.3'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.jsf;

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.servlet.ServletContextPath;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import javax.faces.FacesException;
import javax.faces.component.ActionSource2;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

public abstract class JsfTracer extends BaseTracer {

public Span startSpan(ActionEvent event) {
// https://jakarta.ee/specifications/faces/2.3/apidocs/index.html?javax/faces/component/ActionSource2.html
// ActionSource2 was added in JSF 1.2 and is implemented by components that have an action
// attribute such as a button or a link
if (event.getComponent() instanceof ActionSource2) {
ActionSource2 actionSource = (ActionSource2) event.getComponent();
if (actionSource.getActionExpression() != null) {
// either an el expression in the form #{bean.method()} or navigation case name
String expressionString = actionSource.getActionExpression().getExpressionString();
// start span only if expression string is really an expression
if (expressionString.startsWith("#{") || expressionString.startsWith("${")) {
return tracer.spanBuilder(expressionString).startSpan();
}
}
}

return null;
}

public void updateServerSpanName(Context context, FacesContext facesContext) {
Span serverSpan = getCurrentServerSpan();
if (serverSpan == null) {
return;
}

UIViewRoot uiViewRoot = facesContext.getViewRoot();
if (uiViewRoot == null) {
return;
}

// JSF spec 7.6.2
// view id is a context relative path to the web application resource that produces the view,
// such as a JSP page or a Facelets page.
String viewId = uiViewRoot.getViewId();
serverSpan.updateName(ServletContextPath.prepend(context, viewId));
}

@Override
protected Throwable unwrapThrowable(Throwable throwable) {
while (throwable.getCause() != null && throwable instanceof FacesException) {
throwable = throwable.getCause();
}

return super.unwrapThrowable(throwable);
}
}
19 changes: 19 additions & 0 deletions instrumentation/jsf/jsf-testing-common/jsf-testing-common.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apply from: "$rootDir/gradle/java.gradle"

dependencies {
api deps.testLogging

compileOnly group: 'jakarta.faces', name: 'jakarta.faces-api', version: '2.3.2'
compileOnly group: 'jakarta.el', name: 'jakarta.el-api', version: '3.0.3'

implementation(project(':testing-common')) {
exclude group: 'org.eclipse.jetty', module: 'jetty-server'
}
implementation group: 'org.jsoup', name: 'jsoup', version: '1.13.1'

def jettyVersion = '9.4.35.v20201120'
api group: 'org.eclipse.jetty', name: 'jetty-annotations', version: jettyVersion
implementation group: 'org.eclipse.jetty', name: 'apache-jsp', version: jettyVersion
implementation group: 'org.glassfish', name: 'jakarta.el', version: '3.0.2'
implementation group: 'jakarta.websocket', name: 'jakarta.websocket-api', version: '1.1.1'
}
Loading

0 comments on commit 9825ab0

Please sign in to comment.