Skip to content

Commit

Permalink
feat: Add OpenTelemetry Support
Browse files Browse the repository at this point in the history
feat: Add OpenTelemetry Support
feat: Add Support for Tracing Propagation Headers
  • Loading branch information
Abhi347 committed Sep 23, 2024
1 parent 936d075 commit 92c9da5
Show file tree
Hide file tree
Showing 18 changed files with 1,806 additions and 1,195 deletions.
50 changes: 27 additions & 23 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,6 @@
</repository>
</distributionManagement>

<developers>
<developer>
<id>henriquetruta</id>
<name>Henrique Truta</name>
<email>[email protected]</email>
<organization>Spotify AB</organization>
<organizationUrl>http://www.spotify.com</organizationUrl>
</developer>
<developer>
<id>hewhomustnotbenamed</id>
<name>Abhimanyu Shegokar</name>
<email>[email protected]</email>
<organization>Spotify AB</organization>
<organizationUrl>http://www.spotify.com</organizationUrl>
</developer>
</developers>

<repositories>
<repository>
<id>apache.snapshots</id>
Expand Down Expand Up @@ -102,6 +85,7 @@
<objenesis.version>3.3</objenesis.version>
<opencensus.version>0.31.1</opencensus.version>
<okhttp.version>4.11.0</okhttp.version>
<opentelemetry.version>1.42.1</opentelemetry.version>

<shade.id>${project.groupId}.githubclient.shade</shade.id>
</properties>
Expand All @@ -120,6 +104,13 @@
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>${opentelemetry.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Expand Down Expand Up @@ -179,6 +170,25 @@
<artifactId>opencensus-api</artifactId>
<version>${opencensus.version}</version>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-testing</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
Expand Down Expand Up @@ -246,12 +256,6 @@
<version>${okhttp.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.7</version>
<scope>compile</scope>
</dependency>
</dependencies>

<profiles>
Expand Down
60 changes: 60 additions & 0 deletions src/main/java/com/spotify/github/tracing/BaseTracer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*-
* -\-\-
* github-client
* --
* Copyright (C) 2016 - 2021 Spotify AB
* --
* 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.
* -/-/-
*/

package com.spotify.github.tracing;

import okhttp3.Request;

import java.util.concurrent.CompletionStage;

public abstract class BaseTracer implements Tracer {
@Override
public Span span(final String name, final String method, final CompletionStage<?> future) {
return internalSpan(name, method, future);
}

@Override
public Span span(final String path, final String method) {
return internalSpan(path, method, null);

Check warning on line 35 in src/main/java/com/spotify/github/tracing/BaseTracer.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/BaseTracer.java#L35

Added line #L35 was not covered by tests
}

@Override
public Span span(final Request request) {
return internalSpan(request.url().toString(), request.method(), null);

Check warning on line 40 in src/main/java/com/spotify/github/tracing/BaseTracer.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/BaseTracer.java#L40

Added line #L40 was not covered by tests
}

protected abstract Span internalSpan(
String path,
String method,
CompletionStage<?> future);

@Override
public void attachSpanToFuture(final Span span, final CompletionStage<?> future) {
future.whenComplete(
(result, t) -> {
if (t == null) {
span.success();
} else {
span.failure(t);
}
span.close();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
* -/-/-
*/

package com.spotify.github;
package com.spotify.github.tracing;

import okhttp3.Request;

public interface Span extends AutoCloseable {

Expand All @@ -29,5 +31,7 @@ public interface Span extends AutoCloseable {
/** Close span. Must be called for any opened span. */
@Override
void close();

Request decorateRequest(Request request);
}

33 changes: 33 additions & 0 deletions src/main/java/com/spotify/github/tracing/TraceHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*-
* -\-\-
* github-api
* --
* Copyright (C) 2021 Spotify AB
* --
* 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.
* -/-/-
*/

package com.spotify.github.tracing;

public class TraceHelper {
// Tracing Headers
public static final String HEADER_CLOUD_TRACE_CONTEXT = "X-Cloud-Trace-Context";
public static final String HEADER_TRACE_PARENT = "traceparent";
public static final String HEADER_TRACE_STATE = "tracestate";

// Private constructor to prevent instantiation
private TraceHelper() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");

Check warning on line 31 in src/main/java/com/spotify/github/tracing/TraceHelper.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/TraceHelper.java#L30-L31

Added lines #L30 - L31 were not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
* 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.
Expand All @@ -18,15 +18,26 @@
* -/-/-
*/

package com.spotify.github;
package com.spotify.github.tracing;

import okhttp3.Request;

import java.util.concurrent.CompletionStage;

public interface Tracer {

/** Create scoped span. Span will be closed when future completes. */
/**
* Create scoped span. Span will be closed when future completes.
*/
Span span(
String path, String method, CompletionStage<?> future);

Span span(
String path, String method);

Span span(
Request request);

void attachSpanToFuture(Span span, CompletionStage<?> future);
}

Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
* 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.
Expand All @@ -18,20 +18,24 @@
* -/-/-
*/

package com.spotify.github.opencensus;
package com.spotify.github.tracing.opencensus;

import static java.util.Objects.requireNonNull;
import com.spotify.github.Span;

import com.spotify.github.tracing.Span;
import com.spotify.github.tracing.TraceHelper;
import com.spotify.github.v3.exceptions.RequestNotOkException;
import io.opencensus.trace.AttributeValue;
import io.opencensus.trace.Status;
import okhttp3.Request;

class OpenCensusSpan implements Span {
public class OpenCensusSpan implements Span {

public static final int NOT_FOUND = 404;
public static final int INTERNAL_SERVER_ERROR = 500;
private final io.opencensus.trace.Span span;

OpenCensusSpan(final io.opencensus.trace.Span span) {
public OpenCensusSpan(final io.opencensus.trace.Span span) {
this.span = requireNonNull(span);
}

Expand Down Expand Up @@ -59,5 +63,14 @@ public Span failure(final Throwable t) {
public void close() {
span.end();
}

@Override
public Request decorateRequest(final Request request) {
return request.newBuilder()
.header(TraceHelper.HEADER_CLOUD_TRACE_CONTEXT, span.getContext().getTraceId().toString())
.header(TraceHelper.HEADER_TRACE_PARENT, span.getContext().getTraceId().toString())
.header(TraceHelper.HEADER_TRACE_STATE, span.getContext().getTracestate().toString())
.build();

Check warning on line 73 in src/main/java/com/spotify/github/tracing/opencensus/OpenCensusSpan.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/opencensus/OpenCensusSpan.java#L69-L73

Added lines #L69 - L73 were not covered by tests
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
* 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.
Expand All @@ -18,10 +18,10 @@
* -/-/-
*/

package com.spotify.github.opencensus;
package com.spotify.github.tracing.opencensus;

import com.spotify.github.Span;
import com.spotify.github.Tracer;
import com.spotify.github.tracing.BaseTracer;
import com.spotify.github.tracing.Span;
import io.opencensus.trace.Tracing;

import java.util.concurrent.CompletionStage;
Expand All @@ -30,22 +30,16 @@
import static io.opencensus.trace.Span.Kind.CLIENT;
import static java.util.Objects.requireNonNull;

public class OpenCensusTracer implements Tracer {
public class OpenCensusTracer extends BaseTracer {

private static final io.opencensus.trace.Tracer TRACER = Tracing.getTracer();

@Override
public Span span(final String name, final String method, final CompletionStage<?> future) {
return internalSpan(name, method, future);
}

@SuppressWarnings("MustBeClosedChecker")
private Span internalSpan(
protected Span internalSpan(
final String path,
final String method,
final CompletionStage<?> future) {
requireNonNull(path);
requireNonNull(future);

final io.opencensus.trace.Span ocSpan =
TRACER.spanBuilder("GitHub Request").setSpanKind(CLIENT).startSpan();
Expand All @@ -56,15 +50,9 @@ private Span internalSpan(
ocSpan.putAttribute("method", stringAttributeValue(method));
final Span span = new OpenCensusSpan(ocSpan);

future.whenComplete(
(result, t) -> {
if (t == null) {
span.success();
} else {
span.failure(t);
}
span.close();
});
if (future != null) {
attachSpanToFuture(span, future);
}

return span;
}
Expand Down
Loading

0 comments on commit 92c9da5

Please sign in to comment.