diff options
Diffstat (limited to 'vendor/google.golang.org/grpc/internal/channelz')
10 files changed, 0 insertions, 1706 deletions
diff --git a/vendor/google.golang.org/grpc/internal/channelz/channel.go b/vendor/google.golang.org/grpc/internal/channelz/channel.go deleted file mode 100644 index 3ec662799..000000000 --- a/vendor/google.golang.org/grpc/internal/channelz/channel.go +++ /dev/null @@ -1,270 +0,0 @@ -/* - * - * Copyright 2024 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package channelz - -import ( - "fmt" - "sync/atomic" - - "google.golang.org/grpc/connectivity" -) - -// Channel represents a channel within channelz, which includes metrics and -// internal channelz data, such as channelz id, child list, etc. -type Channel struct { - Entity - // ID is the channelz id of this channel. - ID int64 - // RefName is the human readable reference string of this channel. - RefName string - - closeCalled bool - nestedChans map[int64]string - subChans map[int64]string - Parent *Channel - trace *ChannelTrace - // traceRefCount is the number of trace events that reference this channel. - // Non-zero traceRefCount means the trace of this channel cannot be deleted. - traceRefCount int32 - - // ChannelMetrics holds connectivity state, target and call metrics for the - // channel within channelz. - ChannelMetrics ChannelMetrics -} - -// Implemented to make Channel implement the Identifier interface used for -// nesting. -func (c *Channel) channelzIdentifier() {} - -// String returns a string representation of the Channel, including its parent -// entity and ID. -func (c *Channel) String() string { - if c.Parent == nil { - return fmt.Sprintf("Channel #%d", c.ID) - } - return fmt.Sprintf("%s Channel #%d", c.Parent, c.ID) -} - -func (c *Channel) id() int64 { - return c.ID -} - -// SubChans returns a copy of the map of sub-channels associated with the -// Channel. -func (c *Channel) SubChans() map[int64]string { - db.mu.RLock() - defer db.mu.RUnlock() - return copyMap(c.subChans) -} - -// NestedChans returns a copy of the map of nested channels associated with the -// Channel. -func (c *Channel) NestedChans() map[int64]string { - db.mu.RLock() - defer db.mu.RUnlock() - return copyMap(c.nestedChans) -} - -// Trace returns a copy of the Channel's trace data. -func (c *Channel) Trace() *ChannelTrace { - db.mu.RLock() - defer db.mu.RUnlock() - return c.trace.copy() -} - -// ChannelMetrics holds connectivity state, target and call metrics for the -// channel within channelz. -type ChannelMetrics struct { - // The current connectivity state of the channel. - State atomic.Pointer[connectivity.State] - // The target this channel originally tried to connect to. May be absent - Target atomic.Pointer[string] - // The number of calls started on the channel. - CallsStarted atomic.Int64 - // The number of calls that have completed with an OK status. - CallsSucceeded atomic.Int64 - // The number of calls that have a completed with a non-OK status. - CallsFailed atomic.Int64 - // The last time a call was started on the channel. - LastCallStartedTimestamp atomic.Int64 -} - -// CopyFrom copies the metrics in o to c. For testing only. -func (c *ChannelMetrics) CopyFrom(o *ChannelMetrics) { - c.State.Store(o.State.Load()) - c.Target.Store(o.Target.Load()) - c.CallsStarted.Store(o.CallsStarted.Load()) - c.CallsSucceeded.Store(o.CallsSucceeded.Load()) - c.CallsFailed.Store(o.CallsFailed.Load()) - c.LastCallStartedTimestamp.Store(o.LastCallStartedTimestamp.Load()) -} - -// Equal returns true iff the metrics of c are the same as the metrics of o. -// For testing only. -func (c *ChannelMetrics) Equal(o any) bool { - oc, ok := o.(*ChannelMetrics) - if !ok { - return false - } - if (c.State.Load() == nil) != (oc.State.Load() == nil) { - return false - } - if c.State.Load() != nil && *c.State.Load() != *oc.State.Load() { - return false - } - if (c.Target.Load() == nil) != (oc.Target.Load() == nil) { - return false - } - if c.Target.Load() != nil && *c.Target.Load() != *oc.Target.Load() { - return false - } - return c.CallsStarted.Load() == oc.CallsStarted.Load() && - c.CallsFailed.Load() == oc.CallsFailed.Load() && - c.CallsSucceeded.Load() == oc.CallsSucceeded.Load() && - c.LastCallStartedTimestamp.Load() == oc.LastCallStartedTimestamp.Load() -} - -func strFromPointer(s *string) string { - if s == nil { - return "" - } - return *s -} - -// String returns a string representation of the ChannelMetrics, including its -// state, target, and call metrics. -func (c *ChannelMetrics) String() string { - return fmt.Sprintf("State: %v, Target: %s, CallsStarted: %v, CallsSucceeded: %v, CallsFailed: %v, LastCallStartedTimestamp: %v", - c.State.Load(), strFromPointer(c.Target.Load()), c.CallsStarted.Load(), c.CallsSucceeded.Load(), c.CallsFailed.Load(), c.LastCallStartedTimestamp.Load(), - ) -} - -// NewChannelMetricForTesting creates a new instance of ChannelMetrics with -// specified initial values for testing purposes. -func NewChannelMetricForTesting(state connectivity.State, target string, started, succeeded, failed, timestamp int64) *ChannelMetrics { - c := &ChannelMetrics{} - c.State.Store(&state) - c.Target.Store(&target) - c.CallsStarted.Store(started) - c.CallsSucceeded.Store(succeeded) - c.CallsFailed.Store(failed) - c.LastCallStartedTimestamp.Store(timestamp) - return c -} - -func (c *Channel) addChild(id int64, e entry) { - switch v := e.(type) { - case *SubChannel: - c.subChans[id] = v.RefName - case *Channel: - c.nestedChans[id] = v.RefName - default: - logger.Errorf("cannot add a child (id = %d) of type %T to a channel", id, e) - } -} - -func (c *Channel) deleteChild(id int64) { - delete(c.subChans, id) - delete(c.nestedChans, id) - c.deleteSelfIfReady() -} - -func (c *Channel) triggerDelete() { - c.closeCalled = true - c.deleteSelfIfReady() -} - -func (c *Channel) getParentID() int64 { - if c.Parent == nil { - return -1 - } - return c.Parent.ID -} - -// deleteSelfFromTree tries to delete the channel from the channelz entry relation tree, which means -// deleting the channel reference from its parent's child list. -// -// In order for a channel to be deleted from the tree, it must meet the criteria that, removal of the -// corresponding grpc object has been invoked, and the channel does not have any children left. -// -// The returned boolean value indicates whether the channel has been successfully deleted from tree. -func (c *Channel) deleteSelfFromTree() (deleted bool) { - if !c.closeCalled || len(c.subChans)+len(c.nestedChans) != 0 { - return false - } - // not top channel - if c.Parent != nil { - c.Parent.deleteChild(c.ID) - } - return true -} - -// deleteSelfFromMap checks whether it is valid to delete the channel from the map, which means -// deleting the channel from channelz's tracking entirely. Users can no longer use id to query the -// channel, and its memory will be garbage collected. -// -// The trace reference count of the channel must be 0 in order to be deleted from the map. This is -// specified in the channel tracing gRFC that as long as some other trace has reference to an entity, -// the trace of the referenced entity must not be deleted. In order to release the resource allocated -// by grpc, the reference to the grpc object is reset to a dummy object. -// -// deleteSelfFromMap must be called after deleteSelfFromTree returns true. -// -// It returns a bool to indicate whether the channel can be safely deleted from map. -func (c *Channel) deleteSelfFromMap() (delete bool) { - return c.getTraceRefCount() == 0 -} - -// deleteSelfIfReady tries to delete the channel itself from the channelz database. -// The delete process includes two steps: -// 1. delete the channel from the entry relation tree, i.e. delete the channel reference from its -// parent's child list. -// 2. delete the channel from the map, i.e. delete the channel entirely from channelz. Lookup by id -// will return entry not found error. -func (c *Channel) deleteSelfIfReady() { - if !c.deleteSelfFromTree() { - return - } - if !c.deleteSelfFromMap() { - return - } - db.deleteEntry(c.ID) - c.trace.clear() -} - -func (c *Channel) getChannelTrace() *ChannelTrace { - return c.trace -} - -func (c *Channel) incrTraceRefCount() { - atomic.AddInt32(&c.traceRefCount, 1) -} - -func (c *Channel) decrTraceRefCount() { - atomic.AddInt32(&c.traceRefCount, -1) -} - -func (c *Channel) getTraceRefCount() int { - i := atomic.LoadInt32(&c.traceRefCount) - return int(i) -} - -func (c *Channel) getRefName() string { - return c.RefName -} diff --git a/vendor/google.golang.org/grpc/internal/channelz/channelmap.go b/vendor/google.golang.org/grpc/internal/channelz/channelmap.go deleted file mode 100644 index 64c791953..000000000 --- a/vendor/google.golang.org/grpc/internal/channelz/channelmap.go +++ /dev/null @@ -1,395 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package channelz - -import ( - "fmt" - "sort" - "sync" - "time" -) - -// entry represents a node in the channelz database. -type entry interface { - // addChild adds a child e, whose channelz id is id to child list - addChild(id int64, e entry) - // deleteChild deletes a child with channelz id to be id from child list - deleteChild(id int64) - // triggerDelete tries to delete self from channelz database. However, if - // child list is not empty, then deletion from the database is on hold until - // the last child is deleted from database. - triggerDelete() - // deleteSelfIfReady check whether triggerDelete() has been called before, - // and whether child list is now empty. If both conditions are met, then - // delete self from database. - deleteSelfIfReady() - // getParentID returns parent ID of the entry. 0 value parent ID means no parent. - getParentID() int64 - Entity -} - -// channelMap is the storage data structure for channelz. -// -// Methods of channelMap can be divided into two categories with respect to -// locking. -// -// 1. Methods acquire the global lock. -// 2. Methods that can only be called when global lock is held. -// -// A second type of method need always to be called inside a first type of method. -type channelMap struct { - mu sync.RWMutex - topLevelChannels map[int64]struct{} - channels map[int64]*Channel - subChannels map[int64]*SubChannel - sockets map[int64]*Socket - servers map[int64]*Server -} - -func newChannelMap() *channelMap { - return &channelMap{ - topLevelChannels: make(map[int64]struct{}), - channels: make(map[int64]*Channel), - subChannels: make(map[int64]*SubChannel), - sockets: make(map[int64]*Socket), - servers: make(map[int64]*Server), - } -} - -func (c *channelMap) addServer(id int64, s *Server) { - c.mu.Lock() - defer c.mu.Unlock() - s.cm = c - c.servers[id] = s -} - -func (c *channelMap) addChannel(id int64, cn *Channel, isTopChannel bool, pid int64) { - c.mu.Lock() - defer c.mu.Unlock() - cn.trace.cm = c - c.channels[id] = cn - if isTopChannel { - c.topLevelChannels[id] = struct{}{} - } else if p := c.channels[pid]; p != nil { - p.addChild(id, cn) - } else { - logger.Infof("channel %d references invalid parent ID %d", id, pid) - } -} - -func (c *channelMap) addSubChannel(id int64, sc *SubChannel, pid int64) { - c.mu.Lock() - defer c.mu.Unlock() - sc.trace.cm = c - c.subChannels[id] = sc - if p := c.channels[pid]; p != nil { - p.addChild(id, sc) - } else { - logger.Infof("subchannel %d references invalid parent ID %d", id, pid) - } -} - -func (c *channelMap) addSocket(s *Socket) { - c.mu.Lock() - defer c.mu.Unlock() - s.cm = c - c.sockets[s.ID] = s - if s.Parent == nil { - logger.Infof("normal socket %d has no parent", s.ID) - } - s.Parent.(entry).addChild(s.ID, s) -} - -// removeEntry triggers the removal of an entry, which may not indeed delete the -// entry, if it has to wait on the deletion of its children and until no other -// entity's channel trace references it. It may lead to a chain of entry -// deletion. For example, deleting the last socket of a gracefully shutting down -// server will lead to the server being also deleted. -func (c *channelMap) removeEntry(id int64) { - c.mu.Lock() - defer c.mu.Unlock() - c.findEntry(id).triggerDelete() -} - -// tracedChannel represents tracing operations which are present on both -// channels and subChannels. -type tracedChannel interface { - getChannelTrace() *ChannelTrace - incrTraceRefCount() - decrTraceRefCount() - getRefName() string -} - -// c.mu must be held by the caller -func (c *channelMap) decrTraceRefCount(id int64) { - e := c.findEntry(id) - if v, ok := e.(tracedChannel); ok { - v.decrTraceRefCount() - e.deleteSelfIfReady() - } -} - -// c.mu must be held by the caller. -func (c *channelMap) findEntry(id int64) entry { - if v, ok := c.channels[id]; ok { - return v - } - if v, ok := c.subChannels[id]; ok { - return v - } - if v, ok := c.servers[id]; ok { - return v - } - if v, ok := c.sockets[id]; ok { - return v - } - return &dummyEntry{idNotFound: id} -} - -// c.mu must be held by the caller -// -// deleteEntry deletes an entry from the channelMap. Before calling this method, -// caller must check this entry is ready to be deleted, i.e removeEntry() has -// been called on it, and no children still exist. -func (c *channelMap) deleteEntry(id int64) entry { - if v, ok := c.sockets[id]; ok { - delete(c.sockets, id) - return v - } - if v, ok := c.subChannels[id]; ok { - delete(c.subChannels, id) - return v - } - if v, ok := c.channels[id]; ok { - delete(c.channels, id) - delete(c.topLevelChannels, id) - return v - } - if v, ok := c.servers[id]; ok { - delete(c.servers, id) - return v - } - return &dummyEntry{idNotFound: id} -} - -func (c *channelMap) traceEvent(id int64, desc *TraceEvent) { - c.mu.Lock() - defer c.mu.Unlock() - child := c.findEntry(id) - childTC, ok := child.(tracedChannel) - if !ok { - return - } - childTC.getChannelTrace().append(&traceEvent{Desc: desc.Desc, Severity: desc.Severity, Timestamp: time.Now()}) - if desc.Parent != nil { - parent := c.findEntry(child.getParentID()) - var chanType RefChannelType - switch child.(type) { - case *Channel: - chanType = RefChannel - case *SubChannel: - chanType = RefSubChannel - } - if parentTC, ok := parent.(tracedChannel); ok { - parentTC.getChannelTrace().append(&traceEvent{ - Desc: desc.Parent.Desc, - Severity: desc.Parent.Severity, - Timestamp: time.Now(), - RefID: id, - RefName: childTC.getRefName(), - RefType: chanType, - }) - childTC.incrTraceRefCount() - } - } -} - -type int64Slice []int64 - -func (s int64Slice) Len() int { return len(s) } -func (s int64Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s int64Slice) Less(i, j int) bool { return s[i] < s[j] } - -func copyMap(m map[int64]string) map[int64]string { - n := make(map[int64]string) - for k, v := range m { - n[k] = v - } - return n -} - -func (c *channelMap) getTopChannels(id int64, maxResults int) ([]*Channel, bool) { - if maxResults <= 0 { - maxResults = EntriesPerPage - } - c.mu.RLock() - defer c.mu.RUnlock() - l := int64(len(c.topLevelChannels)) - ids := make([]int64, 0, l) - - for k := range c.topLevelChannels { - ids = append(ids, k) - } - sort.Sort(int64Slice(ids)) - idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) - end := true - var t []*Channel - for _, v := range ids[idx:] { - if len(t) == maxResults { - end = false - break - } - if cn, ok := c.channels[v]; ok { - t = append(t, cn) - } - } - return t, end -} - -func (c *channelMap) getServers(id int64, maxResults int) ([]*Server, bool) { - if maxResults <= 0 { - maxResults = EntriesPerPage - } - c.mu.RLock() - defer c.mu.RUnlock() - ids := make([]int64, 0, len(c.servers)) - for k := range c.servers { - ids = append(ids, k) - } - sort.Sort(int64Slice(ids)) - idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) - end := true - var s []*Server - for _, v := range ids[idx:] { - if len(s) == maxResults { - end = false - break - } - if svr, ok := c.servers[v]; ok { - s = append(s, svr) - } - } - return s, end -} - -func (c *channelMap) getServerSockets(id int64, startID int64, maxResults int) ([]*Socket, bool) { - if maxResults <= 0 { - maxResults = EntriesPerPage - } - c.mu.RLock() - defer c.mu.RUnlock() - svr, ok := c.servers[id] - if !ok { - // server with id doesn't exist. - return nil, true - } - svrskts := svr.sockets - ids := make([]int64, 0, len(svrskts)) - sks := make([]*Socket, 0, min(len(svrskts), maxResults)) - for k := range svrskts { - ids = append(ids, k) - } - sort.Sort(int64Slice(ids)) - idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= startID }) - end := true - for _, v := range ids[idx:] { - if len(sks) == maxResults { - end = false - break - } - if ns, ok := c.sockets[v]; ok { - sks = append(sks, ns) - } - } - return sks, end -} - -func (c *channelMap) getChannel(id int64) *Channel { - c.mu.RLock() - defer c.mu.RUnlock() - return c.channels[id] -} - -func (c *channelMap) getSubChannel(id int64) *SubChannel { - c.mu.RLock() - defer c.mu.RUnlock() - return c.subChannels[id] -} - -func (c *channelMap) getSocket(id int64) *Socket { - c.mu.RLock() - defer c.mu.RUnlock() - return c.sockets[id] -} - -func (c *channelMap) getServer(id int64) *Server { - c.mu.RLock() - defer c.mu.RUnlock() - return c.servers[id] -} - -type dummyEntry struct { - // dummyEntry is a fake entry to handle entry not found case. - idNotFound int64 - Entity -} - -func (d *dummyEntry) String() string { - return fmt.Sprintf("non-existent entity #%d", d.idNotFound) -} - -func (d *dummyEntry) ID() int64 { return d.idNotFound } - -func (d *dummyEntry) addChild(id int64, e entry) { - // Note: It is possible for a normal program to reach here under race - // condition. For example, there could be a race between ClientConn.Close() - // info being propagated to addrConn and http2Client. ClientConn.Close() - // cancel the context and result in http2Client to error. The error info is - // then caught by transport monitor and before addrConn.tearDown() is called - // in side ClientConn.Close(). Therefore, the addrConn will create a new - // transport. And when registering the new transport in channelz, its parent - // addrConn could have already been torn down and deleted from channelz - // tracking, and thus reach the code here. - logger.Infof("attempt to add child of type %T with id %d to a parent (id=%d) that doesn't currently exist", e, id, d.idNotFound) -} - -func (d *dummyEntry) deleteChild(id int64) { - // It is possible for a normal program to reach here under race condition. - // Refer to the example described in addChild(). - logger.Infof("attempt to delete child with id %d from a parent (id=%d) that doesn't currently exist", id, d.idNotFound) -} - -func (d *dummyEntry) triggerDelete() { - logger.Warningf("attempt to delete an entry (id=%d) that doesn't currently exist", d.idNotFound) -} - -func (*dummyEntry) deleteSelfIfReady() { - // code should not reach here. deleteSelfIfReady is always called on an existing entry. -} - -func (*dummyEntry) getParentID() int64 { - return 0 -} - -// Entity is implemented by all channelz types. -type Entity interface { - isEntity() - fmt.Stringer - id() int64 -} diff --git a/vendor/google.golang.org/grpc/internal/channelz/funcs.go b/vendor/google.golang.org/grpc/internal/channelz/funcs.go deleted file mode 100644 index 078bb8123..000000000 --- a/vendor/google.golang.org/grpc/internal/channelz/funcs.go +++ /dev/null @@ -1,230 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// Package channelz defines internal APIs for enabling channelz service, entry -// registration/deletion, and accessing channelz data. It also defines channelz -// metric struct formats. -package channelz - -import ( - "sync/atomic" - "time" - - "google.golang.org/grpc/internal" -) - -var ( - // IDGen is the global channelz entity ID generator. It should not be used - // outside this package except by tests. - IDGen IDGenerator - - db = newChannelMap() - // EntriesPerPage defines the number of channelz entries to be shown on a web page. - EntriesPerPage = 50 - curState int32 -) - -// TurnOn turns on channelz data collection. -func TurnOn() { - atomic.StoreInt32(&curState, 1) -} - -func init() { - internal.ChannelzTurnOffForTesting = func() { - atomic.StoreInt32(&curState, 0) - } -} - -// IsOn returns whether channelz data collection is on. -func IsOn() bool { - return atomic.LoadInt32(&curState) == 1 -} - -// GetTopChannels returns a slice of top channel's ChannelMetric, along with a -// boolean indicating whether there's more top channels to be queried for. -// -// The arg id specifies that only top channel with id at or above it will be -// included in the result. The returned slice is up to a length of the arg -// maxResults or EntriesPerPage if maxResults is zero, and is sorted in ascending -// id order. -func GetTopChannels(id int64, maxResults int) ([]*Channel, bool) { - return db.getTopChannels(id, maxResults) -} - -// GetServers returns a slice of server's ServerMetric, along with a -// boolean indicating whether there's more servers to be queried for. -// -// The arg id specifies that only server with id at or above it will be included -// in the result. The returned slice is up to a length of the arg maxResults or -// EntriesPerPage if maxResults is zero, and is sorted in ascending id order. -func GetServers(id int64, maxResults int) ([]*Server, bool) { - return db.getServers(id, maxResults) -} - -// GetServerSockets returns a slice of server's (identified by id) normal socket's -// SocketMetrics, along with a boolean indicating whether there's more sockets to -// be queried for. -// -// The arg startID specifies that only sockets with id at or above it will be -// included in the result. The returned slice is up to a length of the arg maxResults -// or EntriesPerPage if maxResults is zero, and is sorted in ascending id order. -func GetServerSockets(id int64, startID int64, maxResults int) ([]*Socket, bool) { - return db.getServerSockets(id, startID, maxResults) -} - -// GetChannel returns the Channel for the channel (identified by id). -func GetChannel(id int64) *Channel { - return db.getChannel(id) -} - -// GetSubChannel returns the SubChannel for the subchannel (identified by id). -func GetSubChannel(id int64) *SubChannel { - return db.getSubChannel(id) -} - -// GetSocket returns the Socket for the socket (identified by id). -func GetSocket(id int64) *Socket { - return db.getSocket(id) -} - -// GetServer returns the ServerMetric for the server (identified by id). -func GetServer(id int64) *Server { - return db.getServer(id) -} - -// RegisterChannel registers the given channel c in the channelz database with -// target as its target and reference name, and adds it to the child list of its -// parent. parent == nil means no parent. -// -// Returns a unique channelz identifier assigned to this channel. -// -// If channelz is not turned ON, the channelz database is not mutated. -func RegisterChannel(parent *Channel, target string) *Channel { - id := IDGen.genID() - - if !IsOn() { - return &Channel{ID: id} - } - - isTopChannel := parent == nil - - cn := &Channel{ - ID: id, - RefName: target, - nestedChans: make(map[int64]string), - subChans: make(map[int64]string), - Parent: parent, - trace: &ChannelTrace{CreationTime: time.Now(), Events: make([]*traceEvent, 0, getMaxTraceEntry())}, - } - cn.ChannelMetrics.Target.Store(&target) - db.addChannel(id, cn, isTopChannel, cn.getParentID()) - return cn -} - -// RegisterSubChannel registers the given subChannel c in the channelz database -// with ref as its reference name, and adds it to the child list of its parent -// (identified by pid). -// -// Returns a unique channelz identifier assigned to this subChannel. -// -// If channelz is not turned ON, the channelz database is not mutated. -func RegisterSubChannel(parent *Channel, ref string) *SubChannel { - id := IDGen.genID() - sc := &SubChannel{ - ID: id, - RefName: ref, - parent: parent, - } - - if !IsOn() { - return sc - } - - sc.sockets = make(map[int64]string) - sc.trace = &ChannelTrace{CreationTime: time.Now(), Events: make([]*traceEvent, 0, getMaxTraceEntry())} - db.addSubChannel(id, sc, parent.ID) - return sc -} - -// RegisterServer registers the given server s in channelz database. It returns -// the unique channelz tracking id assigned to this server. -// -// If channelz is not turned ON, the channelz database is not mutated. -func RegisterServer(ref string) *Server { - id := IDGen.genID() - if !IsOn() { - return &Server{ID: id} - } - - svr := &Server{ - RefName: ref, - sockets: make(map[int64]string), - listenSockets: make(map[int64]string), - ID: id, - } - db.addServer(id, svr) - return svr -} - -// RegisterSocket registers the given normal socket s in channelz database -// with ref as its reference name, and adds it to the child list of its parent -// (identified by skt.Parent, which must be set). It returns the unique channelz -// tracking id assigned to this normal socket. -// -// If channelz is not turned ON, the channelz database is not mutated. -func RegisterSocket(skt *Socket) *Socket { - skt.ID = IDGen.genID() - if IsOn() { - db.addSocket(skt) - } - return skt -} - -// RemoveEntry removes an entry with unique channelz tracking id to be id from -// channelz database. -// -// If channelz is not turned ON, this function is a no-op. -func RemoveEntry(id int64) { - if !IsOn() { - return - } - db.removeEntry(id) -} - -// IDGenerator is an incrementing atomic that tracks IDs for channelz entities. -type IDGenerator struct { - id int64 -} - -// Reset resets the generated ID back to zero. Should only be used at -// initialization or by tests sensitive to the ID number. -func (i *IDGenerator) Reset() { - atomic.StoreInt64(&i.id, 0) -} - -func (i *IDGenerator) genID() int64 { - return atomic.AddInt64(&i.id, 1) -} - -// Identifier is an opaque channelz identifier used to expose channelz symbols -// outside of grpc. Currently only implemented by Channel since no other -// types require exposure outside grpc. -type Identifier interface { - Entity - channelzIdentifier() -} diff --git a/vendor/google.golang.org/grpc/internal/channelz/logging.go b/vendor/google.golang.org/grpc/internal/channelz/logging.go deleted file mode 100644 index ee4d72125..000000000 --- a/vendor/google.golang.org/grpc/internal/channelz/logging.go +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * Copyright 2020 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package channelz - -import ( - "fmt" - - "google.golang.org/grpc/grpclog" -) - -var logger = grpclog.Component("channelz") - -// Info logs and adds a trace event if channelz is on. -func Info(l grpclog.DepthLoggerV2, e Entity, args ...any) { - AddTraceEvent(l, e, 1, &TraceEvent{ - Desc: fmt.Sprint(args...), - Severity: CtInfo, - }) -} - -// Infof logs and adds a trace event if channelz is on. -func Infof(l grpclog.DepthLoggerV2, e Entity, format string, args ...any) { - AddTraceEvent(l, e, 1, &TraceEvent{ - Desc: fmt.Sprintf(format, args...), - Severity: CtInfo, - }) -} - -// Warning logs and adds a trace event if channelz is on. -func Warning(l grpclog.DepthLoggerV2, e Entity, args ...any) { - AddTraceEvent(l, e, 1, &TraceEvent{ - Desc: fmt.Sprint(args...), - Severity: CtWarning, - }) -} - -// Warningf logs and adds a trace event if channelz is on. -func Warningf(l grpclog.DepthLoggerV2, e Entity, format string, args ...any) { - AddTraceEvent(l, e, 1, &TraceEvent{ - Desc: fmt.Sprintf(format, args...), - Severity: CtWarning, - }) -} - -// Error logs and adds a trace event if channelz is on. -func Error(l grpclog.DepthLoggerV2, e Entity, args ...any) { - AddTraceEvent(l, e, 1, &TraceEvent{ - Desc: fmt.Sprint(args...), - Severity: CtError, - }) -} - -// Errorf logs and adds a trace event if channelz is on. -func Errorf(l grpclog.DepthLoggerV2, e Entity, format string, args ...any) { - AddTraceEvent(l, e, 1, &TraceEvent{ - Desc: fmt.Sprintf(format, args...), - Severity: CtError, - }) -} diff --git a/vendor/google.golang.org/grpc/internal/channelz/server.go b/vendor/google.golang.org/grpc/internal/channelz/server.go deleted file mode 100644 index b5a824992..000000000 --- a/vendor/google.golang.org/grpc/internal/channelz/server.go +++ /dev/null @@ -1,121 +0,0 @@ -/* - * - * Copyright 2024 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package channelz - -import ( - "fmt" - "sync/atomic" -) - -// Server is the channelz representation of a server. -type Server struct { - Entity - ID int64 - RefName string - - ServerMetrics ServerMetrics - - closeCalled bool - sockets map[int64]string - listenSockets map[int64]string - cm *channelMap -} - -// ServerMetrics defines a struct containing metrics for servers. -type ServerMetrics struct { - // The number of incoming calls started on the server. - CallsStarted atomic.Int64 - // The number of incoming calls that have completed with an OK status. - CallsSucceeded atomic.Int64 - // The number of incoming calls that have a completed with a non-OK status. - CallsFailed atomic.Int64 - // The last time a call was started on the server. - LastCallStartedTimestamp atomic.Int64 -} - -// NewServerMetricsForTesting returns an initialized ServerMetrics. -func NewServerMetricsForTesting(started, succeeded, failed, timestamp int64) *ServerMetrics { - sm := &ServerMetrics{} - sm.CallsStarted.Store(started) - sm.CallsSucceeded.Store(succeeded) - sm.CallsFailed.Store(failed) - sm.LastCallStartedTimestamp.Store(timestamp) - return sm -} - -// CopyFrom copies the metrics data from the provided ServerMetrics -// instance into the current instance. -func (sm *ServerMetrics) CopyFrom(o *ServerMetrics) { - sm.CallsStarted.Store(o.CallsStarted.Load()) - sm.CallsSucceeded.Store(o.CallsSucceeded.Load()) - sm.CallsFailed.Store(o.CallsFailed.Load()) - sm.LastCallStartedTimestamp.Store(o.LastCallStartedTimestamp.Load()) -} - -// ListenSockets returns the listening sockets for s. -func (s *Server) ListenSockets() map[int64]string { - db.mu.RLock() - defer db.mu.RUnlock() - return copyMap(s.listenSockets) -} - -// String returns a printable description of s. -func (s *Server) String() string { - return fmt.Sprintf("Server #%d", s.ID) -} - -func (s *Server) id() int64 { - return s.ID -} - -func (s *Server) addChild(id int64, e entry) { - switch v := e.(type) { - case *Socket: - switch v.SocketType { - case SocketTypeNormal: - s.sockets[id] = v.RefName - case SocketTypeListen: - s.listenSockets[id] = v.RefName - } - default: - logger.Errorf("cannot add a child (id = %d) of type %T to a server", id, e) - } -} - -func (s *Server) deleteChild(id int64) { - delete(s.sockets, id) - delete(s.listenSockets, id) - s.deleteSelfIfReady() -} - -func (s *Server) triggerDelete() { - s.closeCalled = true - s.deleteSelfIfReady() -} - -func (s *Server) deleteSelfIfReady() { - if !s.closeCalled || len(s.sockets)+len(s.listenSockets) != 0 { - return - } - s.cm.deleteEntry(s.ID) -} - -func (s *Server) getParentID() int64 { - return 0 -} diff --git a/vendor/google.golang.org/grpc/internal/channelz/socket.go b/vendor/google.golang.org/grpc/internal/channelz/socket.go deleted file mode 100644 index 90103847c..000000000 --- a/vendor/google.golang.org/grpc/internal/channelz/socket.go +++ /dev/null @@ -1,137 +0,0 @@ -/* - * - * Copyright 2024 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package channelz - -import ( - "fmt" - "net" - "sync/atomic" - - "google.golang.org/grpc/credentials" -) - -// SocketMetrics defines the struct that the implementor of Socket interface -// should return from ChannelzMetric(). -type SocketMetrics struct { - // The number of streams that have been started. - StreamsStarted atomic.Int64 - // The number of streams that have ended successfully: - // On client side, receiving frame with eos bit set. - // On server side, sending frame with eos bit set. - StreamsSucceeded atomic.Int64 - // The number of streams that have ended unsuccessfully: - // On client side, termination without receiving frame with eos bit set. - // On server side, termination without sending frame with eos bit set. - StreamsFailed atomic.Int64 - // The number of messages successfully sent on this socket. - MessagesSent atomic.Int64 - MessagesReceived atomic.Int64 - // The number of keep alives sent. This is typically implemented with HTTP/2 - // ping messages. - KeepAlivesSent atomic.Int64 - // The last time a stream was created by this endpoint. Usually unset for - // servers. - LastLocalStreamCreatedTimestamp atomic.Int64 - // The last time a stream was created by the remote endpoint. Usually unset - // for clients. - LastRemoteStreamCreatedTimestamp atomic.Int64 - // The last time a message was sent by this endpoint. - LastMessageSentTimestamp atomic.Int64 - // The last time a message was received by this endpoint. - LastMessageReceivedTimestamp atomic.Int64 -} - -// EphemeralSocketMetrics are metrics that change rapidly and are tracked -// outside of channelz. -type EphemeralSocketMetrics struct { - // The amount of window, granted to the local endpoint by the remote endpoint. - // This may be slightly out of date due to network latency. This does NOT - // include stream level or TCP level flow control info. - LocalFlowControlWindow int64 - // The amount of window, granted to the remote endpoint by the local endpoint. - // This may be slightly out of date due to network latency. This does NOT - // include stream level or TCP level flow control info. - RemoteFlowControlWindow int64 -} - -// SocketType represents the type of socket. -type SocketType string - -// SocketType can be one of these. -const ( - SocketTypeNormal = "NormalSocket" - SocketTypeListen = "ListenSocket" -) - -// Socket represents a socket within channelz which includes socket -// metrics and data related to socket activity and provides methods -// for managing and interacting with sockets. -type Socket struct { - Entity - SocketType SocketType - ID int64 - Parent Entity - cm *channelMap - SocketMetrics SocketMetrics - EphemeralMetrics func() *EphemeralSocketMetrics - - RefName string - // The locally bound address. Immutable. - LocalAddr net.Addr - // The remote bound address. May be absent. Immutable. - RemoteAddr net.Addr - // Optional, represents the name of the remote endpoint, if different than - // the original target name. Immutable. - RemoteName string - // Immutable. - SocketOptions *SocketOptionData - // Immutable. - Security credentials.ChannelzSecurityValue -} - -// String returns a string representation of the Socket, including its parent -// entity, socket type, and ID. -func (ls *Socket) String() string { - return fmt.Sprintf("%s %s #%d", ls.Parent, ls.SocketType, ls.ID) -} - -func (ls *Socket) id() int64 { - return ls.ID -} - -func (ls *Socket) addChild(id int64, e entry) { - logger.Errorf("cannot add a child (id = %d) of type %T to a listen socket", id, e) -} - -func (ls *Socket) deleteChild(id int64) { - logger.Errorf("cannot delete a child (id = %d) from a listen socket", id) -} - -func (ls *Socket) triggerDelete() { - ls.cm.deleteEntry(ls.ID) - ls.Parent.(entry).deleteChild(ls.ID) -} - -func (ls *Socket) deleteSelfIfReady() { - logger.Errorf("cannot call deleteSelfIfReady on a listen socket") -} - -func (ls *Socket) getParentID() int64 { - return ls.Parent.id() -} diff --git a/vendor/google.golang.org/grpc/internal/channelz/subchannel.go b/vendor/google.golang.org/grpc/internal/channelz/subchannel.go deleted file mode 100644 index b20802e6e..000000000 --- a/vendor/google.golang.org/grpc/internal/channelz/subchannel.go +++ /dev/null @@ -1,153 +0,0 @@ -/* - * - * Copyright 2024 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package channelz - -import ( - "fmt" - "sync/atomic" -) - -// SubChannel is the channelz representation of a subchannel. -type SubChannel struct { - Entity - // ID is the channelz id of this subchannel. - ID int64 - // RefName is the human readable reference string of this subchannel. - RefName string - closeCalled bool - sockets map[int64]string - parent *Channel - trace *ChannelTrace - traceRefCount int32 - - ChannelMetrics ChannelMetrics -} - -func (sc *SubChannel) String() string { - return fmt.Sprintf("%s SubChannel #%d", sc.parent, sc.ID) -} - -func (sc *SubChannel) id() int64 { - return sc.ID -} - -// Sockets returns a copy of the sockets map associated with the SubChannel. -func (sc *SubChannel) Sockets() map[int64]string { - db.mu.RLock() - defer db.mu.RUnlock() - return copyMap(sc.sockets) -} - -// Trace returns a copy of the ChannelTrace associated with the SubChannel. -func (sc *SubChannel) Trace() *ChannelTrace { - db.mu.RLock() - defer db.mu.RUnlock() - return sc.trace.copy() -} - -func (sc *SubChannel) addChild(id int64, e entry) { - if v, ok := e.(*Socket); ok && v.SocketType == SocketTypeNormal { - sc.sockets[id] = v.RefName - } else { - logger.Errorf("cannot add a child (id = %d) of type %T to a subChannel", id, e) - } -} - -func (sc *SubChannel) deleteChild(id int64) { - delete(sc.sockets, id) - sc.deleteSelfIfReady() -} - -func (sc *SubChannel) triggerDelete() { - sc.closeCalled = true - sc.deleteSelfIfReady() -} - -func (sc *SubChannel) getParentID() int64 { - return sc.parent.ID -} - -// deleteSelfFromTree tries to delete the subchannel from the channelz entry relation tree, which -// means deleting the subchannel reference from its parent's child list. -// -// In order for a subchannel to be deleted from the tree, it must meet the criteria that, removal of -// the corresponding grpc object has been invoked, and the subchannel does not have any children left. -// -// The returned boolean value indicates whether the channel has been successfully deleted from tree. -func (sc *SubChannel) deleteSelfFromTree() (deleted bool) { - if !sc.closeCalled || len(sc.sockets) != 0 { - return false - } - sc.parent.deleteChild(sc.ID) - return true -} - -// deleteSelfFromMap checks whether it is valid to delete the subchannel from the map, which means -// deleting the subchannel from channelz's tracking entirely. Users can no longer use id to query -// the subchannel, and its memory will be garbage collected. -// -// The trace reference count of the subchannel must be 0 in order to be deleted from the map. This is -// specified in the channel tracing gRFC that as long as some other trace has reference to an entity, -// the trace of the referenced entity must not be deleted. In order to release the resource allocated -// by grpc, the reference to the grpc object is reset to a dummy object. -// -// deleteSelfFromMap must be called after deleteSelfFromTree returns true. -// -// It returns a bool to indicate whether the channel can be safely deleted from map. -func (sc *SubChannel) deleteSelfFromMap() (delete bool) { - return sc.getTraceRefCount() == 0 -} - -// deleteSelfIfReady tries to delete the subchannel itself from the channelz database. -// The delete process includes two steps: -// 1. delete the subchannel from the entry relation tree, i.e. delete the subchannel reference from -// its parent's child list. -// 2. delete the subchannel from the map, i.e. delete the subchannel entirely from channelz. Lookup -// by id will return entry not found error. -func (sc *SubChannel) deleteSelfIfReady() { - if !sc.deleteSelfFromTree() { - return - } - if !sc.deleteSelfFromMap() { - return - } - db.deleteEntry(sc.ID) - sc.trace.clear() -} - -func (sc *SubChannel) getChannelTrace() *ChannelTrace { - return sc.trace -} - -func (sc *SubChannel) incrTraceRefCount() { - atomic.AddInt32(&sc.traceRefCount, 1) -} - -func (sc *SubChannel) decrTraceRefCount() { - atomic.AddInt32(&sc.traceRefCount, -1) -} - -func (sc *SubChannel) getTraceRefCount() int { - i := atomic.LoadInt32(&sc.traceRefCount) - return int(i) -} - -func (sc *SubChannel) getRefName() string { - return sc.RefName -} diff --git a/vendor/google.golang.org/grpc/internal/channelz/syscall_linux.go b/vendor/google.golang.org/grpc/internal/channelz/syscall_linux.go deleted file mode 100644 index 5ac73ff83..000000000 --- a/vendor/google.golang.org/grpc/internal/channelz/syscall_linux.go +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package channelz - -import ( - "syscall" - - "golang.org/x/sys/unix" -) - -// SocketOptionData defines the struct to hold socket option data, and related -// getter function to obtain info from fd. -type SocketOptionData struct { - Linger *unix.Linger - RecvTimeout *unix.Timeval - SendTimeout *unix.Timeval - TCPInfo *unix.TCPInfo -} - -// Getsockopt defines the function to get socket options requested by channelz. -// It is to be passed to syscall.RawConn.Control(). -func (s *SocketOptionData) Getsockopt(fd uintptr) { - if v, err := unix.GetsockoptLinger(int(fd), syscall.SOL_SOCKET, syscall.SO_LINGER); err == nil { - s.Linger = v - } - if v, err := unix.GetsockoptTimeval(int(fd), syscall.SOL_SOCKET, syscall.SO_RCVTIMEO); err == nil { - s.RecvTimeout = v - } - if v, err := unix.GetsockoptTimeval(int(fd), syscall.SOL_SOCKET, syscall.SO_SNDTIMEO); err == nil { - s.SendTimeout = v - } - if v, err := unix.GetsockoptTCPInfo(int(fd), syscall.SOL_TCP, syscall.TCP_INFO); err == nil { - s.TCPInfo = v - } -} - -// GetSocketOption gets the socket option info of the conn. -func GetSocketOption(socket any) *SocketOptionData { - c, ok := socket.(syscall.Conn) - if !ok { - return nil - } - data := &SocketOptionData{} - if rawConn, err := c.SyscallConn(); err == nil { - rawConn.Control(data.Getsockopt) - return data - } - return nil -} diff --git a/vendor/google.golang.org/grpc/internal/channelz/syscall_nonlinux.go b/vendor/google.golang.org/grpc/internal/channelz/syscall_nonlinux.go deleted file mode 100644 index 0e6e18e18..000000000 --- a/vendor/google.golang.org/grpc/internal/channelz/syscall_nonlinux.go +++ /dev/null @@ -1,47 +0,0 @@ -//go:build !linux - -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package channelz - -import ( - "sync" -) - -var once sync.Once - -// SocketOptionData defines the struct to hold socket option data, and related -// getter function to obtain info from fd. -// Windows OS doesn't support Socket Option -type SocketOptionData struct { -} - -// Getsockopt defines the function to get socket options requested by channelz. -// It is to be passed to syscall.RawConn.Control(). -// Windows OS doesn't support Socket Option -func (s *SocketOptionData) Getsockopt(uintptr) { - once.Do(func() { - logger.Warning("Channelz: socket options are not supported on non-linux environments") - }) -} - -// GetSocketOption gets the socket option info of the conn. -func GetSocketOption(any) *SocketOptionData { - return nil -} diff --git a/vendor/google.golang.org/grpc/internal/channelz/trace.go b/vendor/google.golang.org/grpc/internal/channelz/trace.go deleted file mode 100644 index 2bffe4777..000000000 --- a/vendor/google.golang.org/grpc/internal/channelz/trace.go +++ /dev/null @@ -1,213 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package channelz - -import ( - "fmt" - "sync" - "sync/atomic" - "time" - - "google.golang.org/grpc/grpclog" -) - -const ( - defaultMaxTraceEntry int32 = 30 -) - -var maxTraceEntry = defaultMaxTraceEntry - -// SetMaxTraceEntry sets maximum number of trace entries per entity (i.e. -// channel/subchannel). Setting it to 0 will disable channel tracing. -func SetMaxTraceEntry(i int32) { - atomic.StoreInt32(&maxTraceEntry, i) -} - -// ResetMaxTraceEntryToDefault resets the maximum number of trace entries per -// entity to default. -func ResetMaxTraceEntryToDefault() { - atomic.StoreInt32(&maxTraceEntry, defaultMaxTraceEntry) -} - -func getMaxTraceEntry() int { - i := atomic.LoadInt32(&maxTraceEntry) - return int(i) -} - -// traceEvent is an internal representation of a single trace event -type traceEvent struct { - // Desc is a simple description of the trace event. - Desc string - // Severity states the severity of this trace event. - Severity Severity - // Timestamp is the event time. - Timestamp time.Time - // RefID is the id of the entity that gets referenced in the event. RefID is 0 if no other entity is - // involved in this event. - // e.g. SubChannel (id: 4[]) Created. --> RefID = 4, RefName = "" (inside []) - RefID int64 - // RefName is the reference name for the entity that gets referenced in the event. - RefName string - // RefType indicates the referenced entity type, i.e Channel or SubChannel. - RefType RefChannelType -} - -// TraceEvent is what the caller of AddTraceEvent should provide to describe the -// event to be added to the channel trace. -// -// The Parent field is optional. It is used for an event that will be recorded -// in the entity's parent trace. -type TraceEvent struct { - Desc string - Severity Severity - Parent *TraceEvent -} - -// ChannelTrace provides tracing information for a channel. -// It tracks various events and metadata related to the channel's lifecycle -// and operations. -type ChannelTrace struct { - cm *channelMap - clearCalled bool - // The time when the trace was created. - CreationTime time.Time - // A counter for the number of events recorded in the - // trace. - EventNum int64 - mu sync.Mutex - // A slice of traceEvent pointers representing the events recorded for - // this channel. - Events []*traceEvent -} - -func (c *ChannelTrace) copy() *ChannelTrace { - return &ChannelTrace{ - CreationTime: c.CreationTime, - EventNum: c.EventNum, - Events: append(([]*traceEvent)(nil), c.Events...), - } -} - -func (c *ChannelTrace) append(e *traceEvent) { - c.mu.Lock() - if len(c.Events) == getMaxTraceEntry() { - del := c.Events[0] - c.Events = c.Events[1:] - if del.RefID != 0 { - // start recursive cleanup in a goroutine to not block the call originated from grpc. - go func() { - // need to acquire c.cm.mu lock to call the unlocked attemptCleanup func. - c.cm.mu.Lock() - c.cm.decrTraceRefCount(del.RefID) - c.cm.mu.Unlock() - }() - } - } - e.Timestamp = time.Now() - c.Events = append(c.Events, e) - c.EventNum++ - c.mu.Unlock() -} - -func (c *ChannelTrace) clear() { - if c.clearCalled { - return - } - c.clearCalled = true - c.mu.Lock() - for _, e := range c.Events { - if e.RefID != 0 { - // caller should have already held the c.cm.mu lock. - c.cm.decrTraceRefCount(e.RefID) - } - } - c.mu.Unlock() -} - -// Severity is the severity level of a trace event. -// The canonical enumeration of all valid values is here: -// https://github.com/grpc/grpc-proto/blob/9b13d199cc0d4703c7ea26c9c330ba695866eb23/grpc/channelz/v1/channelz.proto#L126. -type Severity int - -const ( - // CtUnknown indicates unknown severity of a trace event. - CtUnknown Severity = iota - // CtInfo indicates info level severity of a trace event. - CtInfo - // CtWarning indicates warning level severity of a trace event. - CtWarning - // CtError indicates error level severity of a trace event. - CtError -) - -// RefChannelType is the type of the entity being referenced in a trace event. -type RefChannelType int - -const ( - // RefUnknown indicates an unknown entity type, the zero value for this type. - RefUnknown RefChannelType = iota - // RefChannel indicates the referenced entity is a Channel. - RefChannel - // RefSubChannel indicates the referenced entity is a SubChannel. - RefSubChannel - // RefServer indicates the referenced entity is a Server. - RefServer - // RefListenSocket indicates the referenced entity is a ListenSocket. - RefListenSocket - // RefNormalSocket indicates the referenced entity is a NormalSocket. - RefNormalSocket -) - -var refChannelTypeToString = map[RefChannelType]string{ - RefUnknown: "Unknown", - RefChannel: "Channel", - RefSubChannel: "SubChannel", - RefServer: "Server", - RefListenSocket: "ListenSocket", - RefNormalSocket: "NormalSocket", -} - -// String returns a string representation of the RefChannelType -func (r RefChannelType) String() string { - return refChannelTypeToString[r] -} - -// AddTraceEvent adds trace related to the entity with specified id, using the -// provided TraceEventDesc. -// -// If channelz is not turned ON, this will simply log the event descriptions. -func AddTraceEvent(l grpclog.DepthLoggerV2, e Entity, depth int, desc *TraceEvent) { - // Log only the trace description associated with the bottom most entity. - d := fmt.Sprintf("[%s]%s", e, desc.Desc) - switch desc.Severity { - case CtUnknown, CtInfo: - l.InfoDepth(depth+1, d) - case CtWarning: - l.WarningDepth(depth+1, d) - case CtError: - l.ErrorDepth(depth+1, d) - } - - if getMaxTraceEntry() == 0 { - return - } - if IsOn() { - db.traceEvent(e.id(), desc) - } -} |