0
# Channelz Observability
1
2
Runtime introspection service providing detailed information about gRPC channels, servers, and connections for debugging and monitoring. Channelz enables deep visibility into gRPC communication patterns and connection health.
3
4
## Capabilities
5
6
### ChannelzService
7
8
Main service providing channelz observability data through gRPC endpoints.
9
10
```java { .api }
11
/**
12
* The channelz service provides stats about a running gRPC process.
13
* Enables runtime introspection of channels, servers, and connections.
14
*/
15
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/4206")
16
public final class ChannelzService extends ChannelzGrpc.ChannelzImplBase {
17
18
/**
19
* Creates a channelz service instance
20
* @param maxPageSize Maximum number of items returned per page in responses
21
* @return ChannelzService instance ready to be added to a server
22
*/
23
public static ChannelzService newInstance(int maxPageSize);
24
25
/**
26
* Returns top level channels (ManagedChannels)
27
* @param request Request specifying pagination options
28
* @param responseObserver Observer for receiving channel information
29
*/
30
public void getTopChannels(
31
GetTopChannelsRequest request,
32
StreamObserver<GetTopChannelsResponse> responseObserver
33
);
34
35
/**
36
* Returns a specific top level channel (ManagedChannel)
37
* @param request Request specifying channel ID
38
* @param responseObserver Observer for receiving channel details
39
*/
40
public void getChannel(
41
GetChannelRequest request,
42
StreamObserver<GetChannelResponse> responseObserver
43
);
44
45
/**
46
* Returns servers managed by this process
47
* @param request Request specifying pagination options
48
* @param responseObserver Observer for receiving server information
49
*/
50
public void getServers(
51
GetServersRequest request,
52
StreamObserver<GetServersResponse> responseObserver
53
);
54
55
/**
56
* Returns a specific server
57
* @param request Request specifying server ID
58
* @param responseObserver Observer for receiving server details
59
*/
60
public void getServer(
61
GetServerRequest request,
62
StreamObserver<GetServerResponse> responseObserver
63
);
64
65
/**
66
* Returns a subchannel
67
* @param request Request specifying subchannel ID
68
* @param responseObserver Observer for receiving subchannel details
69
*/
70
public void getSubchannel(
71
GetSubchannelRequest request,
72
StreamObserver<GetSubchannelResponse> responseObserver
73
);
74
75
/**
76
* Returns a socket
77
* @param request Request specifying socket ID
78
* @param responseObserver Observer for receiving socket details
79
*/
80
public void getSocket(
81
GetSocketRequest request,
82
StreamObserver<GetSocketResponse> responseObserver
83
);
84
85
/**
86
* Returns server sockets
87
* @param request Request specifying server ID and pagination
88
* @param responseObserver Observer for receiving server socket information
89
*/
90
public void getServerSockets(
91
GetServerSocketsRequest request,
92
StreamObserver<GetServerSocketsResponse> responseObserver
93
);
94
}
95
```
96
97
**Usage Examples:**
98
99
```java
100
import io.grpc.Server;
101
import io.grpc.ServerBuilder;
102
import io.grpc.protobuf.services.ChannelzService;
103
104
// Add channelz service to server for observability
105
Server server = ServerBuilder.forPort(8080)
106
.addService(ChannelzService.newInstance(100)) // Max 100 items per page
107
.addService(new MyBusinessService())
108
.build();
109
110
server.start();
111
```
112
113
### Integration with Monitoring Systems
114
115
Channelz provides detailed metrics that can be integrated with monitoring systems:
116
117
```java
118
import io.grpc.Server;
119
import io.grpc.ServerBuilder;
120
import io.grpc.protobuf.services.ChannelzService;
121
import io.grpc.protobuf.services.HealthStatusManager;
122
123
public class ObservableServer {
124
private final Server server;
125
private final HealthStatusManager healthManager;
126
127
public ObservableServer(int port) {
128
this.healthManager = new HealthStatusManager();
129
130
this.server = ServerBuilder.forPort(port)
131
// Add channelz for detailed observability
132
.addService(ChannelzService.newInstance(50))
133
134
// Add health checking
135
.addService(healthManager.getHealthService())
136
137
// Add business services
138
.addService(new UserService())
139
.addService(new OrderService())
140
.build();
141
}
142
143
public void start() throws IOException {
144
server.start();
145
146
healthManager.setStatus("", ServingStatus.SERVING);
147
148
System.out.println("Observable server started on port " + server.getPort());
149
System.out.println("Channelz available for monitoring and debugging");
150
}
151
152
public void shutdown() {
153
healthManager.enterTerminalState();
154
server.shutdown();
155
}
156
}
157
```
158
159
### Client-Side Channelz Usage
160
161
Accessing channelz data from a client for monitoring purposes:
162
163
```java
164
import io.grpc.ManagedChannel;
165
import io.grpc.ManagedChannelBuilder;
166
import io.grpc.channelz.v1.ChannelzGrpc;
167
import io.grpc.channelz.v1.GetTopChannelsRequest;
168
import io.grpc.channelz.v1.GetServersRequest;
169
170
public class ChannelzMonitor {
171
private final ChannelzGrpc.ChannelzBlockingStub channelzStub;
172
173
public ChannelzMonitor(String host, int port) {
174
ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port)
175
.usePlaintext()
176
.build();
177
178
this.channelzStub = ChannelzGrpc.newBlockingStub(channel);
179
}
180
181
public void printTopChannels() {
182
GetTopChannelsRequest request = GetTopChannelsRequest.newBuilder()
183
.setMaxResults(10)
184
.build();
185
186
GetTopChannelsResponse response = channelzStub.getTopChannels(request);
187
188
System.out.println("Top Channels:");
189
response.getChannelList().forEach(channel -> {
190
System.out.printf("Channel ID: %d, Target: %s, State: %s%n",
191
channel.getRef().getChannelId(),
192
channel.getData().getTarget(),
193
channel.getData().getState().getState()
194
);
195
});
196
}
197
198
public void printServers() {
199
GetServersRequest request = GetServersRequest.newBuilder()
200
.setMaxResults(10)
201
.build();
202
203
GetServersResponse response = channelzStub.getServers(request);
204
205
System.out.println("Servers:");
206
response.getServerList().forEach(server -> {
207
System.out.printf("Server ID: %d, Listen Sockets: %d, Calls: %d%n",
208
server.getRef().getServerId(),
209
server.getData().getListenSocketCount(),
210
server.getData().getCallsStarted()
211
);
212
});
213
}
214
}
215
```
216
217
### Debugging Connection Issues
218
219
Using channelz to diagnose connectivity problems:
220
221
```java
222
public class ChannelzDebugger {
223
private final ChannelzGrpc.ChannelzBlockingStub channelzStub;
224
225
public ChannelzDebugger(String host, int port) {
226
ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port)
227
.usePlaintext()
228
.build();
229
230
this.channelzStub = ChannelzGrpc.newBlockingStub(channel);
231
}
232
233
public void debugChannelState(long channelId) {
234
GetChannelRequest request = GetChannelRequest.newBuilder()
235
.setChannelId(channelId)
236
.build();
237
238
try {
239
GetChannelResponse response = channelzStub.getChannel(request);
240
ChannelData data = response.getChannel().getData();
241
242
System.out.println("Channel Debug Information:");
243
System.out.println("Target: " + data.getTarget());
244
System.out.println("State: " + data.getState().getState());
245
System.out.println("Calls Started: " + data.getCallsStarted());
246
System.out.println("Calls Succeeded: " + data.getCallsSucceeded());
247
System.out.println("Calls Failed: " + data.getCallsFailed());
248
System.out.println("Last Call Started: " + data.getLastCallStartedTimestamp());
249
250
// Print subchannel information
251
data.getSubchannelRefList().forEach(subchannelRef -> {
252
System.out.println("Subchannel ID: " + subchannelRef.getSubchannelId());
253
debugSubchannel(subchannelRef.getSubchannelId());
254
});
255
256
} catch (Exception e) {
257
System.err.println("Failed to get channel info: " + e.getMessage());
258
}
259
}
260
261
private void debugSubchannel(long subchannelId) {
262
GetSubchannelRequest request = GetSubchannelRequest.newBuilder()
263
.setSubchannelId(subchannelId)
264
.build();
265
266
try {
267
GetSubchannelResponse response = channelzStub.getSubchannel(request);
268
SubchannelData data = response.getSubchannel().getData();
269
270
System.out.println(" Subchannel State: " + data.getState().getState());
271
System.out.println(" Target: " + data.getTarget());
272
273
} catch (Exception e) {
274
System.err.println(" Failed to get subchannel info: " + e.getMessage());
275
}
276
}
277
}
278
```
279
280
## Integration with Admin Interface
281
282
Channelz is automatically included when using the admin interface:
283
284
```java
285
import io.grpc.Server;
286
import io.grpc.ServerBuilder;
287
import io.grpc.services.AdminInterface;
288
289
// Admin interface includes channelz automatically
290
Server server = ServerBuilder.forPort(8080)
291
.addServices(AdminInterface.getStandardServices()) // Includes channelz
292
.addService(new MyBusinessService())
293
.build();
294
```
295
296
## Performance Considerations
297
298
Channelz data collection has minimal performance impact but consider these guidelines:
299
300
```java
301
// Use reasonable page sizes to avoid memory issues
302
ChannelzService channelzService = ChannelzService.newInstance(50); // Reasonable page size
303
304
// For high-traffic servers, channelz provides valuable debugging info
305
// but monitor memory usage if you have many channels/connections
306
307
Server server = ServerBuilder.forPort(8080)
308
.addService(channelzService)
309
.addService(new HighTrafficService())
310
.build();
311
```