Skip to content

Commit c458542

Browse files
committed
OpenTracing module is implemented
Issue temporalio#258
1 parent ba691a2 commit c458542

23 files changed

+2012
-0
lines changed

settings.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ include 'temporal-sdk'
44
include 'temporal-testing'
55
include 'temporal-testing-junit4'
66
include 'temporal-testing-junit5'
7+
include 'temporal-opentracing'

temporal-opentracing/LICENSE.txt

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Temporal Java SDK
2+
3+
Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
4+
5+
Copyright (c) 2017 Uber Technologies, Inc. All Rights Reserved
6+
7+
AWS Simple Workflow Flow Library
8+
Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved
9+
10+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
11+
file except in compliance with the License. You may obtain a copy of the License at
12+
13+
http://www.apache.org/licenses/LICENSE-2.0
14+
15+
Unless required by applicable law or agreed to in writing, software distributed under
16+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
17+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
18+
specific language governing permissions and limitations under the License.

temporal-opentracing/README.md

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Temporal [OpenTracing](https://opentracing.io/) support module
2+
3+
This module provides a set of Interceptors that adds support for OpenTracing Span Context propagation to Temporal.
4+
5+
## Usage
6+
7+
You want to register two interceptors - one on the Temporal client side, another on the worker side:
8+
9+
1. Client configuration:
10+
```java
11+
WorkflowClientOptions.newBuilder()
12+
//...
13+
.setInterceptors(new OpenTracingClientInterceptor())
14+
.build();
15+
```
16+
2. Worker configuration:
17+
```java
18+
WorkerFactoryOptions.newBuilder()
19+
//...
20+
.setWorkerInterceptors(new OpenTracingWorkerInterceptor())
21+
.build();
22+
```
23+
24+
## [OpenTelemetry](https://opentelemetry.io/)
25+
26+
OpenTracing has been merged into OpenTelemetry and nowadays OpenTelemetry should be a preferred solution.
27+
There is still plenty of OpenTracing usage everywhere and there is an official OpenTracing -> OpenTelemetry bridge,
28+
but no OpenTelemetry -> OpenTracing bridges.
29+
30+
To give the best coverage in the simplest way, this module is implemented based on OpenTracing for now.
31+
OpenTelemetry users are advised to use the
32+
[OpenTracing -> OpenTelemetry bridge](https://github.com/open-telemetry/opentelemetry-java/tree/main/opentracing-shim)
33+
to hook their OpenTelemetry setup and make it available for OpenTracing API:
34+
35+
```java
36+
io.opentracing.Tracer tracer = OpenTracingShim.createTracerShim();
37+
//or io.opentracing.Tracer tracer = OpenTracingShim.createTracerShim(openTelemetry);
38+
GlobalTracer.registerIfAbsent(tracer);
39+
```
40+
41+

temporal-opentracing/build.gradle

+178
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
// Run 'gradle checkUpdates' to find out which dependencies have newer versions
2+
plugins {
3+
id 'java-library'
4+
id 'net.ltgt.errorprone' version '1.3.0'
5+
id 'net.minecrell.licenser' version '0.4.1'
6+
id 'com.palantir.git-version' version '0.12.3'
7+
id 'maven-publish'
8+
id 'signing'
9+
id 'de.marcphilipp.nexus-publish' version '0.4.0'
10+
id 'name.remal.check-updates' version '1.2.2'
11+
}
12+
13+
apply plugin: 'maven-publish'
14+
apply plugin: 'de.marcphilipp.nexus-publish'
15+
apply plugin: 'java'
16+
17+
if (hasProperty('signing.keyId')) {
18+
apply plugin: 'signing'
19+
signing {
20+
sign configurations.archives
21+
}
22+
}
23+
24+
group = 'io.temporal'
25+
version = getVersionName()
26+
archivesBaseName = "temporal-opentracing"
27+
28+
description = '''Temporal Java SDK OpenTracing Support Module'''
29+
30+
java {
31+
sourceCompatibility = JavaVersion.VERSION_1_8
32+
targetCompatibility = JavaVersion.VERSION_1_8
33+
withJavadocJar()
34+
withSourcesJar()
35+
}
36+
37+
ext {
38+
opentracingVersion = '0.33.0'
39+
}
40+
41+
dependencies {
42+
errorproneJavac('com.google.errorprone:javac:9+181-r4173-1')
43+
errorprone('com.google.errorprone:error_prone_core:2.5.1')
44+
45+
api project(':temporal-sdk')
46+
api group: 'io.opentracing', name: 'opentracing-api', version: "$opentracingVersion"
47+
48+
implementation group: 'com.google.guava', name: 'guava', version: '30.1.1-jre'
49+
implementation group: 'io.opentracing', name: 'opentracing-util', version: "$opentracingVersion"
50+
51+
testImplementation project(":temporal-testing")
52+
testImplementation project(':temporal-testing-junit4')
53+
testImplementation group: 'junit', name: 'junit', version: '4.13.2'
54+
testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'
55+
testImplementation group: 'org.mockito', name: 'mockito-core', version: '3.8.0'
56+
testImplementation group: 'io.opentracing', name: 'opentracing-mock', version: "$opentracingVersion"
57+
}
58+
59+
license {
60+
header rootProject.file('license-header.txt')
61+
exclude '**/*.puml'
62+
}
63+
64+
compileJava {
65+
dependsOn 'googleJavaFormat'
66+
options.encoding = 'UTF-8'
67+
options.compilerArgs << '-Xlint:none' << '-Xlint:deprecation' << '-Werror'
68+
}
69+
70+
compileTestJava {
71+
options.encoding = 'UTF-8'
72+
options.compilerArgs << '-Xlint:none' << '-Xlint:deprecation' << '-Werror'
73+
}
74+
75+
if (JavaVersion.current().isJava8Compatible()) {
76+
allprojects {
77+
tasks.withType(Javadoc) {
78+
options.addStringOption('Xdoclint:none', '-quiet')
79+
}
80+
}
81+
}
82+
83+
javadoc {
84+
options.encoding = 'UTF-8'
85+
if (JavaVersion.current().isJava9Compatible()) {
86+
options.addBooleanOption('html5', true)
87+
}
88+
}
89+
90+
task sourceJar(type: Jar) {
91+
from sourceSets.main.allSource
92+
classifier "sources"
93+
}
94+
95+
test {
96+
dependsOn 'checkLicenseMain'
97+
testLogging {
98+
events 'passed', 'skipped', 'failed'
99+
exceptionFormat 'full'
100+
// Uncomment the following line if you want to see test logs in gradlew run.
101+
showStandardStreams true
102+
}
103+
forkEvery = 1
104+
maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
105+
}
106+
107+
publishing {
108+
publications {
109+
mavenJava(MavenPublication) {
110+
from components.java
111+
versionMapping {
112+
usage('java-api') {
113+
fromResolutionOf('runtimeClasspath')
114+
}
115+
usage('java-runtime') {
116+
fromResolutionResult()
117+
}
118+
}
119+
pom {
120+
name = 'Temporal Java SDK OpenTracing Support Module'
121+
packaging = 'jar'
122+
// optionally artifactId can be defined here
123+
description = 'Contains a set of classes that adds OpenTracing support to Temporal'
124+
url = 'https://github.com/temporalio/temporal-java-sdk'
125+
126+
scm {
127+
connection = 'scm:[email protected]:temporalio/temporal-java-sdk.git'
128+
developerConnection = 'scm:[email protected]:temporalio/temporal-java-sdk.git'
129+
url = 'https://github.com/temporalio/temporal-java-sdk.git'
130+
}
131+
132+
licenses {
133+
license {
134+
name = 'The Apache License, Version 2.0'
135+
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
136+
}
137+
}
138+
139+
developers {
140+
developer {
141+
id = 'mfateev'
142+
name = 'Maxim Fateev'
143+
144+
}
145+
developer {
146+
id = 'samarabbas'
147+
name = 'Samar Abbas'
148+
149+
}
150+
}
151+
}
152+
}
153+
154+
}
155+
156+
signing {
157+
sign publishing.publications.mavenJava
158+
}
159+
160+
// Uncomment to test local publishing and comment nexusPublishing
161+
// repositories {
162+
// maven {
163+
// def releasesRepoUrl = "$System.env.HOME/repos/releases"
164+
// def snapshotsRepoUrl = "$System.env.HOME/repos/snapshots"
165+
// url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
166+
// }
167+
// }
168+
169+
}
170+
171+
nexusPublishing {
172+
repositories {
173+
sonatype {
174+
username = project.hasProperty('ossrhUsername') ? project.property('ossrhUsername') : ''
175+
password = project.hasProperty('ossrhPassword') ? project.property('ossrhPassword') : ''
176+
}
177+
}
178+
}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved.
2+
3+
Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
5+
Modifications copyright (C) 2017 Uber Technologies, Inc.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License"). You may not
8+
use this file except in compliance with the License. A copy of the License is
9+
located at
10+
11+
http://aws.amazon.com/apache2.0
12+
13+
or in the "license" file accompanying this file. This file is distributed on
14+
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
15+
express or implied. See the License for the specific language governing
16+
permissions and limitations under the License.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved.
3+
*
4+
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.opentracing;
21+
22+
import io.temporal.common.interceptors.WorkflowClientCallsInterceptor;
23+
import io.temporal.common.interceptors.WorkflowClientInterceptorBase;
24+
import io.temporal.opentracing.internal.OpenTracingWorkflowClientCallsInterceptor;
25+
26+
public class OpenTracingClientInterceptor extends WorkflowClientInterceptorBase {
27+
private final OpenTracingOptions openTracingOptions;
28+
29+
public OpenTracingClientInterceptor() {
30+
this(OpenTracingOptions.getDefaultInstance());
31+
}
32+
33+
public OpenTracingClientInterceptor(OpenTracingOptions openTracingOptions) {
34+
this.openTracingOptions = openTracingOptions;
35+
}
36+
37+
@Override
38+
public WorkflowClientCallsInterceptor workflowClientCallsInterceptor(
39+
WorkflowClientCallsInterceptor next) {
40+
return new OpenTracingWorkflowClientCallsInterceptor(next, openTracingOptions);
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved.
3+
*
4+
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.opentracing;
21+
22+
import com.google.common.base.MoreObjects;
23+
import io.opentracing.Tracer;
24+
import io.opentracing.util.GlobalTracer;
25+
import java.util.HashMap;
26+
import java.util.Map;
27+
import javax.annotation.Nonnull;
28+
29+
public class OpenTracingOptions {
30+
private static final OpenTracingOptions DEFAULT_INSTANCE =
31+
OpenTracingOptions.newBuilder().build();
32+
33+
private final Tracer tracer;
34+
private final Map<SpanOperationType, String> customSpanOperationNamePrefixes;
35+
36+
public static OpenTracingOptions getDefaultInstance() {
37+
return DEFAULT_INSTANCE;
38+
}
39+
40+
private OpenTracingOptions(
41+
Tracer tracer, Map<SpanOperationType, String> customSpanOperationNamePrefixes) {
42+
if (tracer == null) throw new IllegalArgumentException("tracer shouldn't be null");
43+
this.tracer = tracer;
44+
this.customSpanOperationNamePrefixes = customSpanOperationNamePrefixes;
45+
}
46+
47+
@Nonnull
48+
public String getSpanOperationNamePrefix(SpanOperationType spanOperationType) {
49+
return customSpanOperationNamePrefixes.getOrDefault(
50+
spanOperationType, spanOperationType.getDefaultPrefix());
51+
}
52+
53+
@Nonnull
54+
public Tracer getTracer() {
55+
return tracer;
56+
}
57+
58+
public static Builder newBuilder() {
59+
return new Builder();
60+
}
61+
62+
public static final class Builder {
63+
private Tracer tracer;
64+
private final Map<SpanOperationType, String> customSpanOperationNamePrefixes = new HashMap<>();
65+
66+
private Builder() {}
67+
68+
public void setTracer(Tracer tracer) {
69+
this.tracer = tracer;
70+
}
71+
72+
public Builder setSpanOperationNamePrefix(
73+
SpanOperationType spanOperationType, String customPrefix) {
74+
this.customSpanOperationNamePrefixes.put(spanOperationType, customPrefix);
75+
return this;
76+
}
77+
78+
public OpenTracingOptions build() {
79+
return new OpenTracingOptions(
80+
MoreObjects.firstNonNull(tracer, GlobalTracer.get()), customSpanOperationNamePrefixes);
81+
}
82+
}
83+
}

0 commit comments

Comments
 (0)