Skip to content

Add OpenTracing module #418

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ include 'temporal-sdk'
include 'temporal-testing'
include 'temporal-testing-junit4'
include 'temporal-testing-junit5'
include 'temporal-opentracing'
18 changes: 18 additions & 0 deletions temporal-opentracing/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Temporal Java SDK

Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved

Copyright (c) 2017 Uber Technologies, Inc. All Rights Reserved

AWS Simple Workflow Flow Library
Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
41 changes: 41 additions & 0 deletions temporal-opentracing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Temporal [OpenTracing](https://opentracing.io/) support module

This module provides a set of Interceptors that adds support for OpenTracing Span Context propagation to Temporal.

## Usage

You want to register two interceptors - one on the Temporal client side, another on the worker side:

1. Client configuration:
```java
WorkflowClientOptions.newBuilder()
//...
.setInterceptors(new OpenTracingClientInterceptor())
.build();
```
2. Worker configuration:
```java
WorkerFactoryOptions.newBuilder()
//...
.setWorkerInterceptors(new OpenTracingWorkerInterceptor())
.build();
```

## [OpenTelemetry](https://opentelemetry.io/)

OpenTracing has been merged into OpenTelemetry and nowadays OpenTelemetry should be a preferred solution.
There is still plenty of OpenTracing usage everywhere and there is an official OpenTracing -> OpenTelemetry bridge,
but no OpenTelemetry -> OpenTracing bridges.

To give the best coverage in the simplest way, this module is implemented based on OpenTracing for now.
OpenTelemetry users are advised to use the
[OpenTracing -> OpenTelemetry bridge](https://github.com/open-telemetry/opentelemetry-java/tree/main/opentracing-shim)
to hook their OpenTelemetry setup and make it available for OpenTracing API:

```java
io.opentracing.Tracer tracer = OpenTracingShim.createTracerShim();
//or io.opentracing.Tracer tracer = OpenTracingShim.createTracerShim(openTelemetry);
GlobalTracer.registerIfAbsent(tracer);
```


178 changes: 178 additions & 0 deletions temporal-opentracing/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
// Run 'gradle checkUpdates' to find out which dependencies have newer versions
plugins {
id 'java-library'
id 'net.ltgt.errorprone' version '1.3.0'
id 'net.minecrell.licenser' version '0.4.1'
id 'com.palantir.git-version' version '0.12.3'
id 'maven-publish'
id 'signing'
id 'de.marcphilipp.nexus-publish' version '0.4.0'
id 'name.remal.check-updates' version '1.2.2'
}

apply plugin: 'maven-publish'
apply plugin: 'de.marcphilipp.nexus-publish'
apply plugin: 'java'

if (hasProperty('signing.keyId')) {
apply plugin: 'signing'
signing {
sign configurations.archives
}
}

group = 'io.temporal'
version = getVersionName()
archivesBaseName = "temporal-opentracing"

description = '''Temporal Java SDK OpenTracing Support Module'''

java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
withJavadocJar()
withSourcesJar()
}

ext {
opentracingVersion = '0.33.0'
}

dependencies {
errorproneJavac('com.google.errorprone:javac:9+181-r4173-1')
errorprone('com.google.errorprone:error_prone_core:2.5.1')

api project(':temporal-sdk')
api group: 'io.opentracing', name: 'opentracing-api', version: "$opentracingVersion"

implementation group: 'com.google.guava', name: 'guava', version: '30.1.1-jre'
implementation group: 'io.opentracing', name: 'opentracing-util', version: "$opentracingVersion"

testImplementation project(":temporal-testing")
testImplementation project(':temporal-testing-junit4')
testImplementation group: 'junit', name: 'junit', version: '4.13.2'
testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'
testImplementation group: 'org.mockito', name: 'mockito-core', version: '3.8.0'
testImplementation group: 'io.opentracing', name: 'opentracing-mock', version: "$opentracingVersion"
}

license {
header rootProject.file('license-header.txt')
exclude '**/*.puml'
}

compileJava {
dependsOn 'googleJavaFormat'
options.encoding = 'UTF-8'
options.compilerArgs << '-Xlint:none' << '-Xlint:deprecation' << '-Werror'
}

compileTestJava {
options.encoding = 'UTF-8'
options.compilerArgs << '-Xlint:none' << '-Xlint:deprecation' << '-Werror'
}

if (JavaVersion.current().isJava8Compatible()) {
allprojects {
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
}
}
}

javadoc {
options.encoding = 'UTF-8'
if (JavaVersion.current().isJava9Compatible()) {
options.addBooleanOption('html5', true)
}
}

task sourceJar(type: Jar) {
from sourceSets.main.allSource
classifier "sources"
}

test {
dependsOn 'checkLicenseMain'
testLogging {
events 'passed', 'skipped', 'failed'
exceptionFormat 'full'
// Uncomment the following line if you want to see test logs in gradlew run.
showStandardStreams true
}
forkEvery = 1
maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
}

publishing {
publications {
mavenJava(MavenPublication) {
from components.java
versionMapping {
usage('java-api') {
fromResolutionOf('runtimeClasspath')
}
usage('java-runtime') {
fromResolutionResult()
}
}
pom {
name = 'Temporal Java SDK OpenTracing Support Module'
packaging = 'jar'
// optionally artifactId can be defined here
description = 'Contains a set of classes that adds OpenTracing support to Temporal'
url = 'https://github.com/temporalio/temporal-java-sdk'

scm {
connection = 'scm:[email protected]:temporalio/temporal-java-sdk.git'
developerConnection = 'scm:[email protected]:temporalio/temporal-java-sdk.git'
url = 'https://github.com/temporalio/temporal-java-sdk.git'
}

licenses {
license {
name = 'The Apache License, Version 2.0'
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}

developers {
developer {
id = 'mfateev'
name = 'Maxim Fateev'
email = '[email protected]'
}
developer {
id = 'samarabbas'
name = 'Samar Abbas'
email = '[email protected]'
}
}
}
}

}

signing {
sign publishing.publications.mavenJava
}

// Uncomment to test local publishing and comment nexusPublishing
// repositories {
// maven {
// def releasesRepoUrl = "$System.env.HOME/repos/releases"
// def snapshotsRepoUrl = "$System.env.HOME/repos/snapshots"
// url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
// }
// }

}

nexusPublishing {
repositories {
sonatype {
username = project.hasProperty('ossrhUsername') ? project.property('ossrhUsername') : ''
password = project.hasProperty('ossrhPassword') ? project.property('ossrhPassword') : ''
}
}
}
16 changes: 16 additions & 0 deletions temporal-opentracing/license-header.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved.

Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Modifications copyright (C) 2017 Uber Technologies, Inc.

Licensed under the Apache License, Version 2.0 (the "License"). You may not
use this file except in compliance with the License. A copy of the License is
located at

http://aws.amazon.com/apache2.0

or in the "license" file accompanying this file. This file is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied. See the License for the specific language governing
permissions and limitations under the License.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved.
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.opentracing;

import io.temporal.common.interceptors.WorkflowClientCallsInterceptor;
import io.temporal.common.interceptors.WorkflowClientInterceptorBase;
import io.temporal.opentracing.internal.OpenTracingWorkflowClientCallsInterceptor;
import io.temporal.opentracing.internal.SpanFactory;

public class OpenTracingClientInterceptor extends WorkflowClientInterceptorBase {
private final OpenTracingOptions options;

public OpenTracingClientInterceptor() {
this(OpenTracingOptions.getDefaultInstance());
}

public OpenTracingClientInterceptor(OpenTracingOptions options) {
this.options = options;
}

@Override
public WorkflowClientCallsInterceptor workflowClientCallsInterceptor(
WorkflowClientCallsInterceptor next) {
return new OpenTracingWorkflowClientCallsInterceptor(next, options, new SpanFactory(options));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved.
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.opentracing;

import com.google.common.base.MoreObjects;
import io.opentracing.Tracer;
import io.opentracing.util.GlobalTracer;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nonnull;

public class OpenTracingOptions {
private static final OpenTracingOptions DEFAULT_INSTANCE =
OpenTracingOptions.newBuilder().build();

private final Tracer tracer;
private final Map<SpanOperationType, String> customSpanOperationNamePrefixes;

public static OpenTracingOptions getDefaultInstance() {
return DEFAULT_INSTANCE;
}

private OpenTracingOptions(
Tracer tracer, Map<SpanOperationType, String> customSpanOperationNamePrefixes) {
if (tracer == null) throw new IllegalArgumentException("tracer shouldn't be null");
this.tracer = tracer;
this.customSpanOperationNamePrefixes = customSpanOperationNamePrefixes;
}

@Nonnull
public String getSpanOperationNamePrefix(SpanOperationType spanOperationType) {
return customSpanOperationNamePrefixes.getOrDefault(
spanOperationType, spanOperationType.getDefaultPrefix());
}

@Nonnull
public Tracer getTracer() {
return tracer;
}

public static Builder newBuilder() {
return new Builder();
}

public static final class Builder {
private Tracer tracer;
private final Map<SpanOperationType, String> customSpanOperationNamePrefixes = new HashMap<>();

private Builder() {}

public void setTracer(Tracer tracer) {
this.tracer = tracer;
}

public Builder setSpanOperationNamePrefix(
SpanOperationType spanOperationType, String customPrefix) {
this.customSpanOperationNamePrefixes.put(spanOperationType, customPrefix);
return this;
}

public OpenTracingOptions build() {
return new OpenTracingOptions(
MoreObjects.firstNonNull(tracer, GlobalTracer.get()), customSpanOperationNamePrefixes);
}
}
}
Loading