Skip to content

Commit 60b86bd

Browse files
authored
feat: Add OpenTelemetry Support (#198)
* feat: Add OpenTelemetry Support feat: Add OpenTelemetry Support feat: Add Support for Tracing Propagation Headers * feat: temp work * test: Add more tests * test: Add more tests * test: Add more tests * fix: Fix compile error due to merge from master * fix: Fix Backward compatibility by using deprecated classes for OCSpan and Tracer * test: Moar tests * feat: Add more tracing to OpenCensusTracer on requests * test: Moar tests * doc: Add documentation * fix: Fix removed test
1 parent 8ddc6d0 commit 60b86bd

24 files changed

+2527
-1281
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,6 @@ dependency-reduced-pom.xml
2727
# mvn release
2828
pom.xml.releaseBackup
2929
release.properties
30+
31+
# macOS
32+
.DS_Store

README.md

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
![lifecycle: beta](https://img.shields.io/badge/lifecycle-beta-509bf5.svg)
44
[![Maven Central](https://img.shields.io/maven-central/v/com.spotify/github-client)](https://mvnrepository.com/artifact/com.spotify/github-client)
55

6-
76
# github-java-client
87

98
A small Java library for talking to GitHub/GitHub Enterprise and interacting with projects.
@@ -74,6 +73,7 @@ log.info(repositoryClient.getCommit("sha").get().htmlUrl());
7473

7574
Another example of the mirrored structure is that some of the APIs are nested under a parent API.
7675
For example, endpoints related to check runs or issues are nested under the Repository client:
76+
7777
```java
7878
final ChecksClient checksClient = repositoryClient.createChecksApiClient();
7979
checksClient.createCheckRun(CHECK_RUN_REQUEST);
@@ -85,11 +85,51 @@ issueClient.createComment(ISSUE_ID, "comment body")
8585
```
8686

8787
And endpoints related to teams and memberships are nested under the Organisation client:
88+
8889
```java
8990
final TeamClient teamClient = organisationClient.createTeamClient();
9091
teamClient.getMembership("username");
9192
```
9293

94+
## Tracing
95+
96+
The GitHub client supports tracing via both OpenCensus and OpenTelemetry. Since OpenCensus is deprecated, we recommend
97+
using OpenTelemetry. Using OpenTelemetry also enables context propagation when using this library.
98+
To enable tracing, you need to provide a tracer when initializing the client.
99+
100+
### OpenTelemetry
101+
102+
```java
103+
import com.spotify.github.tracing.opentelemetry.OpenTelemetryTracer;
104+
105+
final GitHubClient githubClient =
106+
GitHubClient.create(baseUri, accessToken)
107+
// Uses GlobalOpenTelemetry.get() to fetch the default tracer
108+
.withTracer(new OpenTelemetryTracer());
109+
```
110+
111+
You can also provide a custom `OpenTelemetry` object if you want to use a specific one.
112+
113+
```java
114+
import com.spotify.github.tracing.opentelemetry.OpenTelemetryTracer;
115+
116+
final GitHubClient githubClient =
117+
GitHubClient.create(baseUri, accessToken)
118+
// Uses custom openTelemetry object to fetch the tracer
119+
.withTracer(new OpenTelemetryTracer(openTelemetry));
120+
```
121+
122+
### OpenCensus
123+
124+
```java
125+
import com.spotify.github.tracing.opencensus.OpenCensusTracer;
126+
127+
final GitHubClient githubClient =
128+
GitHubClient.create(baseUri, accessToken)
129+
// Uses Tracing.getTracer() to fetch the default tracer
130+
.withTracer(new OpenCensusTracer());
131+
```
132+
93133
## Supported Java versions
94134

95135
This library is written and published with Java version 11. In our CI workflows, we execute
@@ -107,6 +147,7 @@ mvn clean verify
107147
If you are a maintainer, you can release a new version by just triggering the workflow
108148
[prepare-release](./.github/workflows/prepare-release.yml) through the
109149
[web UI](https://github.com/spotify/github-java-client/actions/workflows/prepare-release.yml).
150+
110151
- Select whether the new release should be a `major`, `minor` or `patch` release
111152
- Trigger the release preparation on the `master` branch
112153
- Pushes of this workflow will trigger runs of the

pom.xml

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
<organization>
3030
<name>Spotify AB</name>
31-
<url>http://www.spotify.com</url>
31+
<url>https://www.spotify.com</url>
3232
</organization>
3333

3434
<distributionManagement>
@@ -42,23 +42,6 @@
4242
</repository>
4343
</distributionManagement>
4444

45-
<developers>
46-
<developer>
47-
<id>henriquetruta</id>
48-
<name>Henrique Truta</name>
49-
<email>[email protected]</email>
50-
<organization>Spotify AB</organization>
51-
<organizationUrl>http://www.spotify.com</organizationUrl>
52-
</developer>
53-
<developer>
54-
<id>hewhomustnotbenamed</id>
55-
<name>Abhimanyu Shegokar</name>
56-
<email>[email protected]</email>
57-
<organization>Spotify AB</organization>
58-
<organizationUrl>http://www.spotify.com</organizationUrl>
59-
</developer>
60-
</developers>
61-
6245
<repositories>
6346
<repository>
6447
<id>apache.snapshots</id>
@@ -102,6 +85,7 @@
10285
<objenesis.version>3.3</objenesis.version>
10386
<opencensus.version>0.31.1</opencensus.version>
10487
<okhttp.version>4.11.0</okhttp.version>
88+
<opentelemetry.version>1.42.1</opentelemetry.version>
10589

10690
<shade.id>${project.groupId}.githubclient.shade</shade.id>
10791
</properties>
@@ -120,6 +104,13 @@
120104
<scope>import</scope>
121105
<type>pom</type>
122106
</dependency>
107+
<dependency>
108+
<groupId>io.opentelemetry</groupId>
109+
<artifactId>opentelemetry-bom</artifactId>
110+
<version>${opentelemetry.version}</version>
111+
<type>pom</type>
112+
<scope>import</scope>
113+
</dependency>
123114
</dependencies>
124115
</dependencyManagement>
125116

@@ -179,6 +170,30 @@
179170
<artifactId>opencensus-api</artifactId>
180171
<version>${opencensus.version}</version>
181172
</dependency>
173+
174+
<dependency>
175+
<groupId>io.opentelemetry</groupId>
176+
<artifactId>opentelemetry-api</artifactId>
177+
</dependency>
178+
<dependency>
179+
<groupId>io.opentelemetry</groupId>
180+
<artifactId>opentelemetry-sdk</artifactId>
181+
</dependency>
182+
<dependency>
183+
<groupId>io.opentelemetry</groupId>
184+
<artifactId>opentelemetry-sdk-testing</artifactId>
185+
</dependency>
186+
<dependency>
187+
<groupId>io.opentelemetry.instrumentation</groupId>
188+
<artifactId>opentelemetry-okhttp-3.0</artifactId>
189+
<version>2.8.0-alpha</version>
190+
</dependency>
191+
<dependency>
192+
<groupId>commons-io</groupId>
193+
<artifactId>commons-io</artifactId>
194+
<version>2.7</version>
195+
<scope>compile</scope>
196+
</dependency>
182197
<dependency>
183198
<groupId>io.jsonwebtoken</groupId>
184199
<artifactId>jjwt-impl</artifactId>

src/main/java/com/spotify/github/opencensus/OpenCensusSpan.java

Lines changed: 16 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
* Licensed under the Apache License, Version 2.0 (the "License");
88
* you may not use this file except in compliance with the License.
99
* You may obtain a copy of the License at
10-
*
10+
*
1111
* http://www.apache.org/licenses/LICENSE-2.0
12-
*
12+
*
1313
* Unless required by applicable law or agreed to in writing, software
1414
* distributed under the License is distributed on an "AS IS" BASIS,
1515
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,45 +19,20 @@
1919
*/
2020

2121
package com.spotify.github.opencensus;
22-
import static java.util.Objects.requireNonNull;
23-
import com.spotify.github.Span;
24-
import com.spotify.github.v3.exceptions.RequestNotOkException;
25-
import io.opencensus.trace.AttributeValue;
26-
import io.opencensus.trace.Status;
2722

28-
class OpenCensusSpan implements Span {
23+
import io.opencensus.trace.Span;
2924

30-
public static final int NOT_FOUND = 404;
31-
public static final int INTERNAL_SERVER_ERROR = 500;
32-
private final io.opencensus.trace.Span span;
33-
34-
OpenCensusSpan(final io.opencensus.trace.Span span) {
35-
this.span = requireNonNull(span);
36-
}
37-
38-
@Override
39-
public Span success() {
40-
span.setStatus(Status.OK);
41-
return this;
42-
}
43-
44-
@Override
45-
public Span failure(final Throwable t) {
46-
if (t instanceof RequestNotOkException) {
47-
RequestNotOkException ex = (RequestNotOkException) t;
48-
span.putAttribute("http.status_code", AttributeValue.longAttributeValue(ex.statusCode()));
49-
span.putAttribute("message", AttributeValue.stringAttributeValue(ex.getRawMessage()));
50-
if (ex.statusCode() - INTERNAL_SERVER_ERROR >= 0) {
51-
span.putAttribute("error", AttributeValue.booleanAttributeValue(true));
52-
}
53-
}
54-
span.setStatus(Status.UNKNOWN);
55-
return this;
56-
}
57-
58-
@Override
59-
public void close() {
60-
span.end();
61-
}
25+
/**
26+
* OpenCensusSpan is a wrapper around OpenCensus Span. This class is kept for backward
27+
* compatibility.
28+
*
29+
* @deprecated This class has been moved to the package com.spotify.github.tracing.opencensus.
30+
* Please use com.spotify.github.tracing.opencensus.OpenCensusSpan instead.
31+
*/
32+
@Deprecated
33+
public class OpenCensusSpan extends com.spotify.github.tracing.opencensus.OpenCensusSpan {
34+
public OpenCensusSpan(final Span span) {
35+
super(span);
36+
}
37+
// This class is kept for backward compatibility
6238
}
63-

src/main/java/com/spotify/github/opencensus/OpenCensusTracer.java

Lines changed: 13 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
* -\-\-
33
* github-api
44
* --
5-
* Copyright (C) 2021 Spotify AB
5+
* Copyright (C) 2016 - 2021 Spotify AB
66
* --
77
* Licensed under the Apache License, Version 2.0 (the "License");
88
* you may not use this file except in compliance with the License.
99
* You may obtain a copy of the License at
10-
*
10+
*
1111
* http://www.apache.org/licenses/LICENSE-2.0
12-
*
12+
*
1313
* Unless required by applicable law or agreed to in writing, software
1414
* distributed under the License is distributed on an "AS IS" BASIS,
1515
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,52 +20,14 @@
2020

2121
package com.spotify.github.opencensus;
2222

23-
import com.spotify.github.Span;
24-
import com.spotify.github.Tracer;
25-
import io.opencensus.trace.Tracing;
26-
27-
import java.util.concurrent.CompletionStage;
28-
29-
import static io.opencensus.trace.AttributeValue.stringAttributeValue;
30-
import static io.opencensus.trace.Span.Kind.CLIENT;
31-
import static java.util.Objects.requireNonNull;
32-
33-
public class OpenCensusTracer implements Tracer {
34-
35-
private static final io.opencensus.trace.Tracer TRACER = Tracing.getTracer();
36-
37-
@Override
38-
public Span span(final String name, final String method, final CompletionStage<?> future) {
39-
return internalSpan(name, method, future);
40-
}
41-
42-
@SuppressWarnings("MustBeClosedChecker")
43-
private Span internalSpan(
44-
final String path,
45-
final String method,
46-
final CompletionStage<?> future) {
47-
requireNonNull(path);
48-
requireNonNull(future);
49-
50-
final io.opencensus.trace.Span ocSpan =
51-
TRACER.spanBuilder("GitHub Request").setSpanKind(CLIENT).startSpan();
52-
53-
ocSpan.putAttribute("component", stringAttributeValue("github-api-client"));
54-
ocSpan.putAttribute("peer.service", stringAttributeValue("github"));
55-
ocSpan.putAttribute("http.url", stringAttributeValue(path));
56-
ocSpan.putAttribute("method", stringAttributeValue(method));
57-
final Span span = new OpenCensusSpan(ocSpan);
58-
59-
future.whenComplete(
60-
(result, t) -> {
61-
if (t == null) {
62-
span.success();
63-
} else {
64-
span.failure(t);
65-
}
66-
span.close();
67-
});
68-
69-
return span;
70-
}
23+
/**
24+
* OpenCensusTracer is a wrapper around OpenCensus Tracer. This class is kept for backward
25+
* compatibility.
26+
*
27+
* @deprecated This class has been moved to the package com.spotify.github.tracing.opencensus.
28+
* Please use com.spotify.github.tracing.opencensus.OpenCensusTracer instead.
29+
*/
30+
@Deprecated
31+
public class OpenCensusTracer extends com.spotify.github.tracing.opencensus.OpenCensusTracer {
32+
// This class is kept for backward compatibility
7133
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*-
2+
* -\-\-
3+
* github-client
4+
* --
5+
* Copyright (C) 2016 - 2021 Spotify AB
6+
* --
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* -/-/-
19+
*/
20+
21+
package com.spotify.github.tracing;
22+
23+
import okhttp3.Request;
24+
25+
import java.util.concurrent.CompletionStage;
26+
27+
public abstract class BaseTracer implements Tracer {
28+
@Override
29+
public Span span(final String name, final String method, final CompletionStage<?> future) {
30+
return internalSpan(name, method, future);
31+
}
32+
33+
@Override
34+
public Span span(final String path, final String method) {
35+
return internalSpan(path, method, null);
36+
}
37+
38+
@Override
39+
public Span span(final Request request) {
40+
return internalSpan(request, null);
41+
}
42+
43+
@Override
44+
public Span span(final Request request, final CompletionStage<?> future) {
45+
return internalSpan(request, future);
46+
}
47+
48+
protected abstract Span internalSpan(
49+
String path,
50+
String method,
51+
CompletionStage<?> future);
52+
53+
protected abstract Span internalSpan(
54+
Request request,
55+
CompletionStage<?> future);
56+
57+
@Override
58+
public void attachSpanToFuture(final Span span, final CompletionStage<?> future) {
59+
future.whenComplete(
60+
(result, t) -> {
61+
if (t == null) {
62+
span.success();
63+
} else {
64+
span.failure(t);
65+
}
66+
span.close();
67+
});
68+
}
69+
}

0 commit comments

Comments
 (0)