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 17, 2024
1 parent 936d075 commit d49b54a
Show file tree
Hide file tree
Showing 13 changed files with 1,445 additions and 1,180 deletions.
42 changes: 19 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,17 @@
<artifactId>opencensus-api</artifactId>
<version>${opencensus.version}</version>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</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 +248,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
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);
}

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,23 @@
* -/-/-
*/

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.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 +62,13 @@ public Span failure(final Throwable t) {
public void close() {
span.end();
}

@Override
public Request decorateRequest(final Request request) {
return request.newBuilder()
.header("traceparent", span.getContext().getTraceId().toString())
.header("tracestate", span.getContext().getTracestate().toString())
.build();

Check warning on line 71 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#L68-L71

Added lines #L68 - L71 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,11 +18,12 @@
* -/-/-
*/

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.Span;
import com.spotify.github.tracing.Tracer;
import io.opencensus.trace.Tracing;
import okhttp3.Request;

import java.util.concurrent.CompletionStage;

Expand All @@ -39,13 +40,35 @@ public Span span(final String name, final String method, final CompletionStage<?
return internalSpan(name, method, future);
}

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

Check warning on line 45 in src/main/java/com/spotify/github/tracing/opencensus/OpenCensusTracer.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/opencensus/OpenCensusTracer.java#L45

Added line #L45 was not covered by tests
}

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

Check warning on line 50 in src/main/java/com/spotify/github/tracing/opencensus/OpenCensusTracer.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/opencensus/OpenCensusTracer.java#L50

Added line #L50 was not covered by tests
}

@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();
});
}

@SuppressWarnings("MustBeClosedChecker")
private 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 +79,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
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*-
* -\-\-
* 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.opentelemetry;

import com.spotify.github.v3.exceptions.RequestNotOkException;
import com.spotify.github.tracing.Span;
import io.opentelemetry.api.trace.StatusCode;
import okhttp3.Request;

import static java.util.Objects.requireNonNull;

public class OpenTelemetrySpan implements Span {
public static final int NOT_FOUND = 404;
public static final int INTERNAL_SERVER_ERROR = 500;
private final io.opentelemetry.api.trace.Span span;

OpenTelemetrySpan(final io.opentelemetry.api.trace.Span span) {
this.span = requireNonNull(span);
}

Check warning on line 37 in src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java#L35-L37

Added lines #L35 - L37 were not covered by tests

@Override
public Span success() {
span.setStatus(StatusCode.OK);
return this;

Check warning on line 42 in src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java#L41-L42

Added lines #L41 - L42 were not covered by tests
}

@Override
public Span failure(final Throwable t) {
if (t instanceof RequestNotOkException) {
RequestNotOkException ex = (RequestNotOkException) t;
span.setAttribute("http.status_code", ex.statusCode());
span.setAttribute("message", ex.getRawMessage());

Check warning on line 50 in src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java#L48-L50

Added lines #L48 - L50 were not covered by tests
if (ex.statusCode() - INTERNAL_SERVER_ERROR >= 0) {
span.setAttribute("error", true);

Check warning on line 52 in src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java#L52

Added line #L52 was not covered by tests
}
}
span.setStatus(StatusCode.UNSET);
return this;

Check warning on line 56 in src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java#L55-L56

Added lines #L55 - L56 were not covered by tests
}

@Override
public void close() {
span.end();
}

Check warning on line 62 in src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java#L61-L62

Added lines #L61 - L62 were not covered by tests

public io.opentelemetry.api.trace.Span getRawSpan() {
return span;

Check warning on line 65 in src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java#L65

Added line #L65 was not covered by tests
}

@Override
public Request decorateRequest(final Request request) {
return request.newBuilder()
.header("traceparent", span.getSpanContext().getTraceId())
.header("tracestate", span.getSpanContext().getTraceState().toString())
.build();

Check warning on line 73 in src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/spotify/github/tracing/opentelemetry/OpenTelemetrySpan.java#L70-L73

Added lines #L70 - L73 were not covered by tests
}
}
Loading

0 comments on commit d49b54a

Please sign in to comment.