• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 The gRPC Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package io.grpc.internal;
18 
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull;
21 
22 import io.grpc.InternalChannelz.ChannelStats;
23 import io.grpc.InternalChannelz.ChannelTrace;
24 import io.grpc.InternalChannelz.ChannelTrace.Event;
25 import java.util.ArrayDeque;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.List;
29 import javax.annotation.concurrent.GuardedBy;
30 
31 /**
32  * Tracks a collections of channel tracing events for a channel/subchannel.
33  */
34 final class ChannelTracer {
35   private final Object lock = new Object();
36   @GuardedBy("lock")
37   private final Collection<Event> events;
38   private final long channelCreationTimeNanos;
39 
40   @GuardedBy("lock")
41   private int eventsLogged;
42 
43   /**
44    * Creates a channel tracer and log the creation event of the underlying channel.
45    *
46    * @param channelType Chennel, Subchannel, or OobChannel
47    */
ChannelTracer(final int maxEvents, long channelCreationTimeNanos, String channelType)48   ChannelTracer(final int maxEvents, long channelCreationTimeNanos, String channelType) {
49     checkArgument(maxEvents > 0, "maxEvents must be greater than zero");
50     checkNotNull(channelType, "channelType");
51     events = new ArrayDeque<Event>() {
52       @GuardedBy("lock")
53       @Override
54       public boolean add(Event event) {
55         if (size() == maxEvents) {
56           removeFirst();
57         }
58         eventsLogged++;
59         return super.add(event);
60       }
61     };
62     this.channelCreationTimeNanos = channelCreationTimeNanos;
63 
64     reportEvent(new ChannelTrace.Event.Builder()
65         .setDescription(channelType + " created")
66         .setSeverity(ChannelTrace.Event.Severity.CT_INFO)
67         // passing the timestamp in as a parameter instead of computing it right here because when
68         // parent channel and subchannel both report the same event of the subchannel (e.g. creation
69         // event of the subchannel) we want the timestamps to be exactly the same.
70         .setTimestampNanos(channelCreationTimeNanos)
71         .build());
72   }
73 
reportEvent(Event event)74   void reportEvent(Event event) {
75     synchronized (lock) {
76       events.add(event);
77     }
78   }
79 
updateBuilder(ChannelStats.Builder builder)80   void updateBuilder(ChannelStats.Builder builder) {
81     List<Event> eventsSnapshot;
82     int eventsLoggedSnapshot;
83     synchronized (lock) {
84       eventsLoggedSnapshot = eventsLogged;
85       eventsSnapshot = new ArrayList<>(events);
86     }
87     builder.setChannelTrace(new ChannelTrace.Builder()
88         .setNumEventsLogged(eventsLoggedSnapshot)
89         .setCreationTimeNanos(channelCreationTimeNanos)
90         .setEvents(eventsSnapshot)
91         .build());
92   }
93 }
94