diff --git a/core/src/main/java/io/grpc/internal/ChannelTracer.java b/core/src/main/java/io/grpc/internal/ChannelTracer.java index 6a9180adb1..654dead31a 100644 --- a/core/src/main/java/io/grpc/internal/ChannelTracer.java +++ b/core/src/main/java/io/grpc/internal/ChannelTracer.java @@ -64,6 +64,9 @@ final class ChannelTracer { reportEvent(new ChannelTrace.Event.Builder() .setDescription(channelType + " created") .setSeverity(ChannelTrace.Event.Severity.CT_INFO) + // passing the timestamp in as a parameter instead of computing it right here because when + // parent channel and subchannel both report the same event of the subchannel (e.g. creation + // event of the subchannel) we want the timestamps to be exactly the same. .setTimestampNanos(channelCreationTimeNanos) .build()); } diff --git a/core/src/main/java/io/grpc/internal/InternalSubchannel.java b/core/src/main/java/io/grpc/internal/InternalSubchannel.java index d86317df8e..1c8f59595e 100644 --- a/core/src/main/java/io/grpc/internal/InternalSubchannel.java +++ b/core/src/main/java/io/grpc/internal/InternalSubchannel.java @@ -38,6 +38,7 @@ import io.grpc.Metadata; import io.grpc.MethodDescriptor; import io.grpc.Status; import io.grpc.internal.Channelz.ChannelStats; +import io.grpc.internal.Channelz.ChannelTrace; import java.net.SocketAddress; import java.util.ArrayList; import java.util.Collection; @@ -70,6 +71,7 @@ final class InternalSubchannel implements Instrumented { private final CallTracer callsTracer; @CheckForNull private final ChannelTracer channelTracer; + private final TimeProvider timeProvider; // File-specific convention: methods without GuardedBy("lock") MUST NOT be called under the lock. private final Object lock = new Object(); @@ -161,7 +163,8 @@ final class InternalSubchannel implements Instrumented { BackoffPolicy.Provider backoffPolicyProvider, ClientTransportFactory transportFactory, ScheduledExecutorService scheduledExecutor, Supplier stopwatchSupplier, ChannelExecutor channelExecutor, Callback callback, - Channelz channelz, CallTracer callsTracer, @Nullable ChannelTracer channelTracer) { + Channelz channelz, CallTracer callsTracer, @Nullable ChannelTracer channelTracer, + TimeProvider timeProvider) { this.addressGroup = Preconditions.checkNotNull(addressGroup, "addressGroup"); this.authority = authority; this.userAgent = userAgent; @@ -174,6 +177,7 @@ final class InternalSubchannel implements Instrumented { this.channelz = channelz; this.callsTracer = callsTracer; this.channelTracer = channelTracer; + this.timeProvider = timeProvider; } /** @@ -314,6 +318,14 @@ final class InternalSubchannel implements Instrumented { Preconditions.checkState(state.getState() != SHUTDOWN, "Cannot transition out of SHUTDOWN to " + newState); state = newState; + if (channelTracer != null) { + channelTracer.reportEvent( + new ChannelTrace.Event.Builder() + .setDescription("Entering " + state + " state") + .setSeverity(ChannelTrace.Event.Severity.CT_INFO) + .setTimestampNanos(timeProvider.currentTimeNanos()) + .build()); + } channelExecutor.executeLater(new Runnable() { @Override public void run() { diff --git a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java index d2491ef5c3..9a9ac32ffe 100644 --- a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java +++ b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java @@ -385,6 +385,14 @@ final class ManagedChannelImpl extends ManagedChannel implements Instrumented executorPool, ScheduledExecutorService deadlineCancellationExecutor, ChannelExecutor channelExecutor, - CallTracer callsTracer, @Nullable ChannelTracer channelTracer, Channelz channelz) { + CallTracer callsTracer, @Nullable ChannelTracer channelTracer, Channelz channelz, + TimeProvider timeProvider) { this.authority = checkNotNull(authority, "authority"); this.executorPool = checkNotNull(executorPool, "executorPool"); this.executor = checkNotNull(executorPool.getObject(), "executor"); @@ -126,6 +130,7 @@ final class OobChannel extends ManagedChannel implements Instrumented