aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZHANG Dapeng <zdapeng@google.com>2018-05-15 11:33:44 -0700
committerGitHub <noreply@github.com>2018-05-15 11:33:44 -0700
commit561583be1476e54f37812246329be43470262a55 (patch)
treeaf71d75ef5cd65ea4f0a31b5ccf5667519ad7609
parent04a90bcad2044b78390da2d29c9166361bf84b59 (diff)
downloadgrpc-grpc-java-561583be1476e54f37812246329be43470262a55.tar.gz
core,services: Add ChannelTracing data object
Added `ChannelTrace` as an inner class of `Channelz`. This is in preparation for the implementation of [Channel Tracing](https://github.com/grpc/proposal/blob/master/A3-channel-tracing.md)
-rw-r--r--core/src/main/java/io/grpc/internal/Channelz.java148
-rw-r--r--services/src/main/java/io/grpc/services/ChannelzProtoUtil.java43
-rw-r--r--services/src/test/java/io/grpc/services/ChannelzProtoUtilTest.java73
-rw-r--r--services/src/test/java/io/grpc/services/ChannelzTestHelper.java19
4 files changed, 253 insertions, 30 deletions
diff --git a/core/src/main/java/io/grpc/internal/Channelz.java b/core/src/main/java/io/grpc/internal/Channelz.java
index 9d78b691f..3c993725f 100644
--- a/core/src/main/java/io/grpc/internal/Channelz.java
+++ b/core/src/main/java/io/grpc/internal/Channelz.java
@@ -16,6 +16,9 @@
package io.grpc.internal;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import io.grpc.ConnectivityState;
@@ -244,7 +247,7 @@ public final class Channelz {
/** Creates an instance. */
public RootChannelList(List<Instrumented<ChannelStats>> channels, boolean end) {
- this.channels = Preconditions.checkNotNull(channels);
+ this.channels = checkNotNull(channels);
this.end = end;
}
}
@@ -255,7 +258,7 @@ public final class Channelz {
/** Creates an instance. */
public ServerList(List<Instrumented<ServerStats>> servers, boolean end) {
- this.servers = Preconditions.checkNotNull(servers);
+ this.servers = checkNotNull(servers);
this.end = end;
}
}
@@ -292,7 +295,7 @@ public final class Channelz {
this.callsSucceeded = callsSucceeded;
this.callsFailed = callsFailed;
this.lastCallStartedMillis = lastCallStartedMillis;
- this.listenSockets = Preconditions.checkNotNull(listenSockets);
+ this.listenSockets = checkNotNull(listenSockets);
}
public static final class Builder {
@@ -324,7 +327,7 @@ public final class Channelz {
/** Sets the listen sockets. */
public Builder setListenSockets(List<Instrumented<SocketStats>> listenSockets) {
- Preconditions.checkNotNull(listenSockets);
+ checkNotNull(listenSockets);
this.listenSockets = Collections.unmodifiableList(
new ArrayList<Instrumented<SocketStats>>(listenSockets));
return this;
@@ -351,6 +354,7 @@ public final class Channelz {
public static final class ChannelStats {
public final String target;
public final ConnectivityState state;
+ @Nullable public final ChannelTrace channelTrace;
public final long callsStarted;
public final long callsSucceeded;
public final long callsFailed;
@@ -361,9 +365,10 @@ public final class Channelz {
/**
* Creates an instance.
*/
- public ChannelStats(
+ private ChannelStats(
String target,
ConnectivityState state,
+ @Nullable ChannelTrace channelTrace,
long callsStarted,
long callsSucceeded,
long callsFailed,
@@ -376,17 +381,19 @@ public final class Channelz {
+ "neither can have both");
this.target = target;
this.state = state;
+ this.channelTrace = channelTrace;
this.callsStarted = callsStarted;
this.callsSucceeded = callsSucceeded;
this.callsFailed = callsFailed;
this.lastCallStartedMillis = lastCallStartedMillis;
- this.subchannels = Preconditions.checkNotNull(subchannels);
- this.sockets = Preconditions.checkNotNull(sockets);
+ this.subchannels = checkNotNull(subchannels);
+ this.sockets = checkNotNull(sockets);
}
public static final class Builder {
private String target;
private ConnectivityState state;
+ private ChannelTrace channelTrace;
private long callsStarted;
private long callsSucceeded;
private long callsFailed;
@@ -404,6 +411,11 @@ public final class Channelz {
return this;
}
+ public Builder setChannelTrace(ChannelTrace channelTrace) {
+ this.channelTrace = channelTrace;
+ return this;
+ }
+
public Builder setCallsStarted(long callsStarted) {
this.callsStarted = callsStarted;
return this;
@@ -427,14 +439,14 @@ public final class Channelz {
/** Sets the subchannels. */
public Builder setSubchannels(List<WithLogId> subchannels) {
Preconditions.checkState(sockets.isEmpty());
- this.subchannels = Collections.unmodifiableList(Preconditions.checkNotNull(subchannels));
+ this.subchannels = Collections.unmodifiableList(checkNotNull(subchannels));
return this;
}
/** Sets the sockets. */
public Builder setSockets(List<WithLogId> sockets) {
Preconditions.checkState(subchannels.isEmpty());
- this.sockets = Collections.unmodifiableList(Preconditions.checkNotNull(sockets));
+ this.sockets = Collections.unmodifiableList(checkNotNull(sockets));
return this;
}
@@ -445,6 +457,7 @@ public final class Channelz {
return new ChannelStats(
target,
state,
+ channelTrace,
callsStarted,
callsSucceeded,
callsFailed,
@@ -455,6 +468,109 @@ public final class Channelz {
}
}
+ @Immutable
+ public static final class ChannelTrace {
+ public final long numEventsLogged;
+ public final long creationTimeNanos;
+ public final List<Event> events;
+
+ private ChannelTrace(long numEventsLogged, long creationTimeNanos, List<Event> events) {
+ this.numEventsLogged = numEventsLogged;
+ this.creationTimeNanos = creationTimeNanos;
+ this.events = events;
+ }
+
+ public static final class Builder {
+ private long numEventsLogged;
+ private long creationTimeNanos;
+ private List<Event> events = Collections.emptyList();
+
+ public Builder setNumEventsLogged(long numEventsLogged) {
+ this.numEventsLogged = numEventsLogged;
+ return this;
+ }
+
+ public Builder setCreationTimeNanos(long creationTimeNanos) {
+ this.creationTimeNanos = creationTimeNanos;
+ return this;
+ }
+
+ public Builder setEvents(List<Event> events) {
+ this.events = Collections.unmodifiableList(new ArrayList<Event>(events));
+ return this;
+ }
+
+ public ChannelTrace build() {
+ return new ChannelTrace(numEventsLogged, creationTimeNanos, events);
+ }
+ }
+
+ @Immutable
+ public static final class Event {
+ public final String description;
+ public final Severity severity;
+ public final long timestampNanos;
+
+ // the oneof child_ref field in proto: one of channelRef and channelRef
+ @Nullable public final WithLogId channelRef;
+ @Nullable public final WithLogId subchannelRef;
+
+ public enum Severity {
+ CT_UNKNOWN, CT_INFO, CT_WARNING, CT_ERROR
+ }
+
+ private Event(
+ String description, Severity severity, long timestampNanos,
+ @Nullable WithLogId channelRef, @Nullable WithLogId subchannelRef) {
+ checkArgument(
+ channelRef == null || subchannelRef == null,
+ "at least one of channelRef and subchannelRef must be null");
+ this.description = checkNotNull(description, "description");
+ this.severity = checkNotNull(severity, "severity");
+ this.timestampNanos = timestampNanos;
+ this.channelRef = channelRef;
+ this.subchannelRef = subchannelRef;
+ }
+
+ public static final class Builder {
+ private String description;
+ private Severity severity;
+ private long timestampNanos;
+ private WithLogId channelRef;
+ private WithLogId subchannelRef;
+
+ public Builder setDescription(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public Builder setTimestampNaonos(long timestampNanos) {
+ this.timestampNanos = timestampNanos;
+ return this;
+ }
+
+ public Builder setSeverity(Severity severity) {
+ this.severity = severity;
+ return this;
+ }
+
+ public Builder setChannelRef(WithLogId channelRef) {
+ this.channelRef = channelRef;
+ return this;
+ }
+
+ public Builder setSubchannelRef(WithLogId subchannelRef) {
+ this.subchannelRef = subchannelRef;
+ return this;
+ }
+
+ public Event build() {
+ return new Event(description, severity, timestampNanos, channelRef, subchannelRef);
+ }
+ }
+ }
+ }
+
public static final class Security {
@Nullable
public final Tls tls;
@@ -462,13 +578,13 @@ public final class Channelz {
public final OtherSecurity other;
public Security(Tls tls) {
- this.tls = Preconditions.checkNotNull(tls);
+ this.tls = checkNotNull(tls);
this.other = null;
}
public Security(OtherSecurity other) {
this.tls = null;
- this.other = Preconditions.checkNotNull(other);
+ this.other = checkNotNull(other);
}
}
@@ -483,7 +599,7 @@ public final class Channelz {
* @param any a com.google.protobuf.Any object
*/
public OtherSecurity(String name, @Nullable Object any) {
- this.name = Preconditions.checkNotNull(name);
+ this.name = checkNotNull(name);
Preconditions.checkState(
any == null || any.getClass().getName().endsWith("com.google.protobuf.Any"),
"the 'any' object must be of type com.google.protobuf.Any");
@@ -553,9 +669,9 @@ public final class Channelz {
SocketOptions socketOptions,
Security security) {
this.data = data;
- this.local = Preconditions.checkNotNull(local, "local socket");
+ this.local = checkNotNull(local, "local socket");
this.remote = remote;
- this.socketOptions = Preconditions.checkNotNull(socketOptions);
+ this.socketOptions = checkNotNull(socketOptions);
this.security = security;
}
}
@@ -827,7 +943,7 @@ public final class Channelz {
@Nullable Integer lingerSeconds,
@Nullable TcpInfo tcpInfo,
Map<String, String> others) {
- Preconditions.checkNotNull(others);
+ checkNotNull(others);
this.soTimeoutMillis = timeoutMillis;
this.lingerSeconds = lingerSeconds;
this.tcpInfo = tcpInfo;
@@ -861,7 +977,7 @@ public final class Channelz {
}
public Builder addOption(String name, String value) {
- others.put(name, Preconditions.checkNotNull(value));
+ others.put(name, checkNotNull(value));
return this;
}
diff --git a/services/src/main/java/io/grpc/services/ChannelzProtoUtil.java b/services/src/main/java/io/grpc/services/ChannelzProtoUtil.java
index 0403bf0b7..431a0ce9d 100644
--- a/services/src/main/java/io/grpc/services/ChannelzProtoUtil.java
+++ b/services/src/main/java/io/grpc/services/ChannelzProtoUtil.java
@@ -34,6 +34,9 @@ import io.grpc.channelz.v1.ChannelConnectivityState;
import io.grpc.channelz.v1.ChannelConnectivityState.State;
import io.grpc.channelz.v1.ChannelData;
import io.grpc.channelz.v1.ChannelRef;
+import io.grpc.channelz.v1.ChannelTrace;
+import io.grpc.channelz.v1.ChannelTraceEvent;
+import io.grpc.channelz.v1.ChannelTraceEvent.Severity;
import io.grpc.channelz.v1.GetServerSocketsResponse;
import io.grpc.channelz.v1.GetServersResponse;
import io.grpc.channelz.v1.GetTopChannelsResponse;
@@ -55,6 +58,7 @@ import io.grpc.channelz.v1.Subchannel;
import io.grpc.channelz.v1.SubchannelRef;
import io.grpc.internal.Channelz;
import io.grpc.internal.Channelz.ChannelStats;
+import io.grpc.internal.Channelz.ChannelTrace.Event;
import io.grpc.internal.Channelz.RootChannelList;
import io.grpc.internal.Channelz.ServerList;
import io.grpc.internal.Channelz.ServerSocketsList;
@@ -67,6 +71,7 @@ import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.security.cert.CertificateEncodingException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
@@ -348,21 +353,49 @@ final class ChannelzProtoUtil {
}
static ChannelData extractChannelData(Channelz.ChannelStats stats) {
- return ChannelData
- .newBuilder()
- .setTarget(stats.target)
+ ChannelData.Builder builder = ChannelData.newBuilder();
+ builder.setTarget(stats.target)
.setState(toChannelConnectivityState(stats.state))
.setCallsStarted(stats.callsStarted)
.setCallsSucceeded(stats.callsSucceeded)
.setCallsFailed(stats.callsFailed)
- .setLastCallStartedTimestamp(Timestamps.fromMillis(stats.lastCallStartedMillis))
- .build();
+ .setLastCallStartedTimestamp(Timestamps.fromMillis(stats.lastCallStartedMillis));
+ if (stats.channelTrace != null) {
+ builder.setTrace(toChannelTrace(stats.channelTrace));
+ }
+ return builder.build();
}
static ChannelConnectivityState toChannelConnectivityState(ConnectivityState s) {
return ChannelConnectivityState.newBuilder().setState(toState(s)).build();
}
+ private static ChannelTrace toChannelTrace(Channelz.ChannelTrace channelTrace) {
+ return ChannelTrace.newBuilder()
+ .setNumEventsLogged(channelTrace.numEventsLogged)
+ .setCreationTimestamp(Timestamps.fromNanos(channelTrace.creationTimeNanos))
+ .addAllEvents(toChannelTraceEvents(channelTrace.events))
+ .build();
+ }
+
+ private static List<ChannelTraceEvent> toChannelTraceEvents(List<Event> events) {
+ List<ChannelTraceEvent> channelTraceEvents = new ArrayList<ChannelTraceEvent>();
+ for (Event event : events) {
+ ChannelTraceEvent.Builder builder = ChannelTraceEvent.newBuilder()
+ .setDescription(event.description)
+ .setSeverity(Severity.valueOf(event.severity.name()))
+ .setTimestamp(Timestamps.fromNanos(event.timestampNanos));
+ if (event.channelRef != null) {
+ builder.setChannelRef(toChannelRef(event.channelRef));
+ }
+ if (event.subchannelRef != null) {
+ builder.setSubchannelRef(toSubchannelRef(event.subchannelRef));
+ }
+ channelTraceEvents.add(builder.build());
+ }
+ return Collections.unmodifiableList(channelTraceEvents);
+ }
+
static State toState(ConnectivityState state) {
if (state == null) {
return State.UNKNOWN;
diff --git a/services/src/test/java/io/grpc/services/ChannelzProtoUtilTest.java b/services/src/test/java/io/grpc/services/ChannelzProtoUtilTest.java
index 407d8734b..8bdbb15f2 100644
--- a/services/src/test/java/io/grpc/services/ChannelzProtoUtilTest.java
+++ b/services/src/test/java/io/grpc/services/ChannelzProtoUtilTest.java
@@ -41,6 +41,8 @@ import io.grpc.channelz.v1.ChannelConnectivityState;
import io.grpc.channelz.v1.ChannelConnectivityState.State;
import io.grpc.channelz.v1.ChannelData;
import io.grpc.channelz.v1.ChannelRef;
+import io.grpc.channelz.v1.ChannelTrace;
+import io.grpc.channelz.v1.ChannelTraceEvent;
import io.grpc.channelz.v1.GetChannelRequest;
import io.grpc.channelz.v1.GetServerSocketsResponse;
import io.grpc.channelz.v1.GetServersResponse;
@@ -62,6 +64,8 @@ import io.grpc.channelz.v1.Subchannel;
import io.grpc.channelz.v1.SubchannelRef;
import io.grpc.internal.Channelz;
import io.grpc.internal.Channelz.ChannelStats;
+import io.grpc.internal.Channelz.ChannelTrace.Event;
+import io.grpc.internal.Channelz.ChannelTrace.Event.Severity;
import io.grpc.internal.Channelz.RootChannelList;
import io.grpc.internal.Channelz.ServerList;
import io.grpc.internal.Channelz.ServerSocketsList;
@@ -79,6 +83,7 @@ import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.security.cert.Certificate;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Map.Entry;
import org.junit.Test;
@@ -310,6 +315,12 @@ public final class ChannelzProtoUtilTest {
.setPort(1000))
.build();
+ private final ChannelTrace channelTrace = ChannelTrace
+ .newBuilder()
+ .setNumEventsLogged(1234)
+ .setCreationTimestamp(Timestamps.fromNanos(1000))
+ .build();
+
@Test
public void toChannelRef() {
assertEquals(channelRef, ChannelzProtoUtil.toChannelRef(channel));
@@ -832,6 +843,68 @@ public final class ChannelzProtoUtilTest {
.containsExactly(sockOptAdditional, otherOption);
}
+ @Test
+ public void channelTrace_withoutEvents() {
+ ChannelStats stats = toBuilder(channel.stats)
+ .setChannelTrace(new Channelz.ChannelTrace.Builder()
+ .setNumEventsLogged(1234)
+ .setCreationTimeNanos(1000)
+ .build())
+ .build();
+
+ ChannelData protoStats = channelData.toBuilder().setTrace(channelTrace).build();
+ assertEquals(ChannelzProtoUtil.extractChannelData(stats), protoStats);
+ }
+
+ @Test
+ public void channelTrace_withEvents() {
+ Event event1 = new Event.Builder()
+ .setDescription("event1")
+ .setSeverity(Severity.CT_ERROR)
+ .setTimestampNaonos(12)
+ .setSubchannelRef(subchannel)
+ .build();
+ Event event2 = new Event.Builder()
+ .setDescription("event2")
+ .setTimestampNaonos(34)
+ .setSeverity(Severity.CT_INFO)
+ .setChannelRef(channel)
+ .build();
+
+ ChannelStats stats =
+ toBuilder(channel.stats)
+ .setChannelTrace(
+ new Channelz.ChannelTrace.Builder()
+ .setNumEventsLogged(1234)
+ .setCreationTimeNanos(1000)
+ .setEvents(Arrays.asList(event1, event2))
+ .build())
+ .build();
+
+ ChannelTraceEvent protoEvent1 = ChannelTraceEvent
+ .newBuilder()
+ .setDescription("event1")
+ .setTimestamp(Timestamps.fromNanos(12))
+ .setSeverity(ChannelTraceEvent.Severity.CT_ERROR)
+ .setSubchannelRef(subchannelRef)
+ .build();
+ ChannelTraceEvent protoEvent2 = ChannelTraceEvent
+ .newBuilder()
+ .setDescription("event2")
+ .setTimestamp(Timestamps.fromNanos(34))
+ .setSeverity(ChannelTraceEvent.Severity.CT_INFO)
+ .setChannelRef(channelRef)
+ .build();
+ ChannelData protoStats = channelData
+ .toBuilder()
+ .setTrace(channelTrace
+ .toBuilder()
+ .addAllEvents(Arrays.asList(protoEvent1, protoEvent2))
+ .build())
+ .build();
+ assertEquals(ChannelzProtoUtil.extractChannelData(stats), protoStats);
+ }
+
private static ChannelStats.Builder toBuilder(ChannelStats stats) {
ChannelStats.Builder builder = new ChannelStats.Builder()
.setTarget(stats.target)
diff --git a/services/src/test/java/io/grpc/services/ChannelzTestHelper.java b/services/src/test/java/io/grpc/services/ChannelzTestHelper.java
index b326fa0bc..0acdd0287 100644
--- a/services/src/test/java/io/grpc/services/ChannelzTestHelper.java
+++ b/services/src/test/java/io/grpc/services/ChannelzTestHelper.java
@@ -148,15 +148,16 @@ final class ChannelzTestHelper {
static final class TestChannel implements Instrumented<ChannelStats> {
private final LogId id = LogId.allocate("channel-or-subchannel");
- ChannelStats stats = new ChannelStats(
- /*target=*/ "sometarget",
- /*state=*/ ConnectivityState.READY,
- /*callsStarted=*/ 1,
- /*callsSucceeded=*/ 2,
- /*callsFailed=*/ 3,
- /*lastCallStartedMillis=*/ 4,
- /*subchannels=*/ Collections.<WithLogId>emptyList(),
- /*sockets=*/ Collections.<WithLogId>emptyList());
+ ChannelStats stats = new ChannelStats.Builder()
+ .setTarget("sometarget")
+ .setState(ConnectivityState.READY)
+ .setCallsStarted(1)
+ .setCallsSucceeded(2)
+ .setCallsFailed(3)
+ .setLastCallStartedMillis(4)
+ .setSubchannels(Collections.<WithLogId>emptyList())
+ .setSockets(Collections.<WithLogId>emptyList())
+ .build();
@Override
public ListenableFuture<ChannelStats> getStats() {