Skip to content
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

Add gRPC observation instrumentation #110

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ def VERSIONS = [
// wavefront
'com.wavefront:wavefront-sdk-java:3.0.+',
'com.wavefront:wavefront-internal-reporter-java:1.7.+',
// gRPC
'io.grpc:grpc-api:latest.release',
// test
'org.assertj:assertj-core:latest.release',
'org.awaitility:awaitility:latest.release',
Expand Down
3 changes: 3 additions & 0 deletions micrometer-tracing/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ dependencies {
optionalApi 'ch.qos.logback:logback-classic'
optionalApi 'org.apache.logging.log4j:log4j-core'

// gRPC
optionalApi 'io.grpc:grpc-api'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium Vulnerability:

maven : io.grpc/grpc-api : 1.50.2

0 Critical, 0 High, 1 Medium, 0 Low vulnerabilities have been found across 1 dependencies.
View the Lift console for details about these vulnerabilities.


ℹ️ Learn about @sonatype-lift commands

You can reply with the following commands. For example, reply with @sonatype-lift ignoreall to leave out all findings.

Command Usage
@sonatype-lift ignore Leave out the above finding from this PR
@sonatype-lift ignoreall Leave out all the existing findings from this PR
@sonatype-lift exclude <file|issue|path|tool> Exclude specified file|issue|path|tool from Lift findings by updating your config.toml file

Note: When talking to LiftBot, you need to refresh the page to see its response.
Click here to add LiftBot to another repo.


Was this a good recommendation?
[ 🙁 Not relevant ] - [ 😕 Won't fix ] - [ 😑 Not critical, will fix ] - [ 🙂 Critical, will fix ] - [ 😊 Critical, fixing now ]


testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.mockito:mockito-core'
Expand Down
3 changes: 3 additions & 0 deletions micrometer-tracing/gradle.lockfile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.micrometer.tracing.instrument.grpc;

import io.micrometer.common.util.internal.logging.InternalLogger;
import io.micrometer.common.util.internal.logging.InternalLoggerFactory;
import io.micrometer.core.instrument.binder.grpc.GrpcClientObservationContext;
import io.micrometer.tracing.Span;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler;
import io.micrometer.tracing.handler.TracingObservationHandler;
import io.micrometer.tracing.propagation.Propagator;

import java.net.URI;

/**
* {@link TracingObservationHandler} for gRPC in client side.
*
* @author Tadaya Tsuyukubo
*/
public class GrpcClientTracingObservationHandler
extends PropagatingSenderTracingObservationHandler<GrpcClientObservationContext> {

private static final InternalLogger log = InternalLoggerFactory
.getInstance(GrpcClientTracingObservationHandler.class);

public GrpcClientTracingObservationHandler(Tracer tracer, Propagator propagator) {
super(tracer, propagator);
}

@Override
public void customizeSenderSpan(GrpcClientObservationContext context, Span span) {
String authority = context.getAuthority();
try {
URI uri = new URI(null, authority, null, null, null);
span.remoteIpAndPort(uri.getHost(), uri.getPort());
}
catch (Exception ex) {
log.warn("Exception [{}], occurred while trying to parse the authority [{}] to host and port.", ex,
authority);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.micrometer.tracing.instrument.grpc;

import io.micrometer.common.util.internal.logging.InternalLogger;
import io.micrometer.common.util.internal.logging.InternalLoggerFactory;
import io.micrometer.core.instrument.binder.grpc.GrpcServerObservationContext;
import io.micrometer.tracing.Span;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.handler.PropagatingReceiverTracingObservationHandler;
import io.micrometer.tracing.handler.TracingObservationHandler;
import io.micrometer.tracing.propagation.Propagator;

import java.net.URI;

/**
* {@link TracingObservationHandler} for gRPC in server side.
*
* @author Tadaya Tsuyukubo
*/
public class GrpcServerTracingObservationHandler
extends PropagatingReceiverTracingObservationHandler<GrpcServerObservationContext> {

private static final InternalLogger log = InternalLoggerFactory
.getInstance(GrpcServerTracingObservationHandler.class);

public GrpcServerTracingObservationHandler(Tracer tracer, Propagator propagator) {
super(tracer, propagator);
}

@Override
public Span.Builder customizeExtractedSpan(GrpcServerObservationContext context, Span.Builder builder) {
String authority = context.getAuthority();
if (authority != null) {
try {
URI uri = new URI(null, authority, null, null, null);
builder.remoteIpAndPort(uri.getHost(), uri.getPort());
}
catch (Exception ex) {
log.warn("Exception [{}], occurred while trying to parse the authority [{}] to host and port.", ex,
authority);
}
}
return builder;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.micrometer.tracing.instrument.grpc;

import io.micrometer.core.instrument.binder.grpc.GrpcClientObservationContext;
import io.micrometer.tracing.Span;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.propagation.Propagator;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.stream.Stream;

import static org.junit.jupiter.params.provider.Arguments.arguments;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

/**
* Tests for {@link GrpcClientTracingObservationHandler}.
*
* @author Tadaya Tsuyukubo
*/
class GrpcClientTracingObservationHandlerTests {

@ParameterizedTest
@MethodSource
void customizeSenderSpan(String authority, String host, int port) {
Tracer tracer = mock(Tracer.class);
Propagator propagator = mock(Propagator.class);
GrpcClientTracingObservationHandler handler = new GrpcClientTracingObservationHandler(tracer, propagator);

GrpcClientObservationContext context = new GrpcClientObservationContext((carrier, key, value) -> {
});
context.setAuthority(authority);

Span span = mock(Span.class);
handler.customizeSenderSpan(context, span);

verify(span).remoteIpAndPort(host, port);
}

static Stream<Arguments> customizeSenderSpan() {
// @formatter:off
return Stream.of(
arguments("io.micrometer.grpc:12345", "io.micrometer.grpc", 12345),
arguments("localhost:12345", "localhost", 12345),
arguments("localhost", "localhost", -1)
);
// @formatter:on
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package io.micrometer.tracing.instrument.grpc;

import io.micrometer.core.instrument.binder.grpc.GrpcServerObservationContext;
import io.micrometer.tracing.Span;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.propagation.Propagator;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.stream.Stream;

import static org.junit.jupiter.params.provider.Arguments.arguments;
import static org.mockito.Mockito.*;

/**
* Tests for {@link GrpcServerTracingObservationHandler}.
*
* @author Tadaya Tsuyukubo
*/
class GrpcServerTracingObservationHandlerTests {

@ParameterizedTest
@MethodSource
void customizeExtractedSpan(String authority, String host, int port) {
Tracer tracer = mock(Tracer.class);
Propagator propagator = mock(Propagator.class);
GrpcServerTracingObservationHandler handler = new GrpcServerTracingObservationHandler(tracer, propagator);

GrpcServerObservationContext context = new GrpcServerObservationContext((carrier, key) -> null);
context.setAuthority(authority);

Span.Builder builder = mock(Span.Builder.class);
handler.customizeExtractedSpan(context, builder);

verify(builder).remoteIpAndPort(host, port);
}

@Test
void customizeExtractedSpanWithNull() {
Tracer tracer = mock(Tracer.class);
Propagator propagator = mock(Propagator.class);
GrpcServerTracingObservationHandler handler = new GrpcServerTracingObservationHandler(tracer, propagator);

GrpcServerObservationContext context = new GrpcServerObservationContext((carrier, key) -> null);
context.setAuthority(null);

Span.Builder builder = mock(Span.Builder.class);
handler.customizeExtractedSpan(context, builder);

verifyNoInteractions(builder);
}

static Stream<Arguments> customizeExtractedSpan() {
// @formatter:off
return Stream.of(
arguments("io.micrometer.grpc:12345", "io.micrometer.grpc", 12345),
arguments("localhost:12345", "localhost", 12345),
arguments("localhost", "localhost", -1)
);
// @formatter:on
}

}