Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

703 lignes
23 KiB

  1. /*
  2. *
  3. * Copyright 2018 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package channelz
  19. import (
  20. "net"
  21. "sync"
  22. "sync/atomic"
  23. "time"
  24. "google.golang.org/grpc/connectivity"
  25. "google.golang.org/grpc/credentials"
  26. "google.golang.org/grpc/grpclog"
  27. )
  28. // entry represents a node in the channelz database.
  29. type entry interface {
  30. // addChild adds a child e, whose channelz id is id to child list
  31. addChild(id int64, e entry)
  32. // deleteChild deletes a child with channelz id to be id from child list
  33. deleteChild(id int64)
  34. // triggerDelete tries to delete self from channelz database. However, if child
  35. // list is not empty, then deletion from the database is on hold until the last
  36. // child is deleted from database.
  37. triggerDelete()
  38. // deleteSelfIfReady check whether triggerDelete() has been called before, and whether child
  39. // list is now empty. If both conditions are met, then delete self from database.
  40. deleteSelfIfReady()
  41. // getParentID returns parent ID of the entry. 0 value parent ID means no parent.
  42. getParentID() int64
  43. }
  44. // dummyEntry is a fake entry to handle entry not found case.
  45. type dummyEntry struct {
  46. idNotFound int64
  47. }
  48. func (d *dummyEntry) addChild(id int64, e entry) {
  49. // Note: It is possible for a normal program to reach here under race condition.
  50. // For example, there could be a race between ClientConn.Close() info being propagated
  51. // to addrConn and http2Client. ClientConn.Close() cancel the context and result
  52. // in http2Client to error. The error info is then caught by transport monitor
  53. // and before addrConn.tearDown() is called in side ClientConn.Close(). Therefore,
  54. // the addrConn will create a new transport. And when registering the new transport in
  55. // channelz, its parent addrConn could have already been torn down and deleted
  56. // from channelz tracking, and thus reach the code here.
  57. grpclog.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)
  58. }
  59. func (d *dummyEntry) deleteChild(id int64) {
  60. // It is possible for a normal program to reach here under race condition.
  61. // Refer to the example described in addChild().
  62. grpclog.Infof("attempt to delete child with id %d from a parent (id=%d) that doesn't currently exist", id, d.idNotFound)
  63. }
  64. func (d *dummyEntry) triggerDelete() {
  65. grpclog.Warningf("attempt to delete an entry (id=%d) that doesn't currently exist", d.idNotFound)
  66. }
  67. func (*dummyEntry) deleteSelfIfReady() {
  68. // code should not reach here. deleteSelfIfReady is always called on an existing entry.
  69. }
  70. func (*dummyEntry) getParentID() int64 {
  71. return 0
  72. }
  73. // ChannelMetric defines the info channelz provides for a specific Channel, which
  74. // includes ChannelInternalMetric and channelz-specific data, such as channelz id,
  75. // child list, etc.
  76. type ChannelMetric struct {
  77. // ID is the channelz id of this channel.
  78. ID int64
  79. // RefName is the human readable reference string of this channel.
  80. RefName string
  81. // ChannelData contains channel internal metric reported by the channel through
  82. // ChannelzMetric().
  83. ChannelData *ChannelInternalMetric
  84. // NestedChans tracks the nested channel type children of this channel in the format of
  85. // a map from nested channel channelz id to corresponding reference string.
  86. NestedChans map[int64]string
  87. // SubChans tracks the subchannel type children of this channel in the format of a
  88. // map from subchannel channelz id to corresponding reference string.
  89. SubChans map[int64]string
  90. // Sockets tracks the socket type children of this channel in the format of a map
  91. // from socket channelz id to corresponding reference string.
  92. // Note current grpc implementation doesn't allow channel having sockets directly,
  93. // therefore, this is field is unused.
  94. Sockets map[int64]string
  95. // Trace contains the most recent traced events.
  96. Trace *ChannelTrace
  97. }
  98. // SubChannelMetric defines the info channelz provides for a specific SubChannel,
  99. // which includes ChannelInternalMetric and channelz-specific data, such as
  100. // channelz id, child list, etc.
  101. type SubChannelMetric struct {
  102. // ID is the channelz id of this subchannel.
  103. ID int64
  104. // RefName is the human readable reference string of this subchannel.
  105. RefName string
  106. // ChannelData contains subchannel internal metric reported by the subchannel
  107. // through ChannelzMetric().
  108. ChannelData *ChannelInternalMetric
  109. // NestedChans tracks the nested channel type children of this subchannel in the format of
  110. // a map from nested channel channelz id to corresponding reference string.
  111. // Note current grpc implementation doesn't allow subchannel to have nested channels
  112. // as children, therefore, this field is unused.
  113. NestedChans map[int64]string
  114. // SubChans tracks the subchannel type children of this subchannel in the format of a
  115. // map from subchannel channelz id to corresponding reference string.
  116. // Note current grpc implementation doesn't allow subchannel to have subchannels
  117. // as children, therefore, this field is unused.
  118. SubChans map[int64]string
  119. // Sockets tracks the socket type children of this subchannel in the format of a map
  120. // from socket channelz id to corresponding reference string.
  121. Sockets map[int64]string
  122. // Trace contains the most recent traced events.
  123. Trace *ChannelTrace
  124. }
  125. // ChannelInternalMetric defines the struct that the implementor of Channel interface
  126. // should return from ChannelzMetric().
  127. type ChannelInternalMetric struct {
  128. // current connectivity state of the channel.
  129. State connectivity.State
  130. // The target this channel originally tried to connect to. May be absent
  131. Target string
  132. // The number of calls started on the channel.
  133. CallsStarted int64
  134. // The number of calls that have completed with an OK status.
  135. CallsSucceeded int64
  136. // The number of calls that have a completed with a non-OK status.
  137. CallsFailed int64
  138. // The last time a call was started on the channel.
  139. LastCallStartedTimestamp time.Time
  140. }
  141. // ChannelTrace stores traced events on a channel/subchannel and related info.
  142. type ChannelTrace struct {
  143. // EventNum is the number of events that ever got traced (i.e. including those that have been deleted)
  144. EventNum int64
  145. // CreationTime is the creation time of the trace.
  146. CreationTime time.Time
  147. // Events stores the most recent trace events (up to $maxTraceEntry, newer event will overwrite the
  148. // oldest one)
  149. Events []*TraceEvent
  150. }
  151. // TraceEvent represent a single trace event
  152. type TraceEvent struct {
  153. // Desc is a simple description of the trace event.
  154. Desc string
  155. // Severity states the severity of this trace event.
  156. Severity Severity
  157. // Timestamp is the event time.
  158. Timestamp time.Time
  159. // RefID is the id of the entity that gets referenced in the event. RefID is 0 if no other entity is
  160. // involved in this event.
  161. // e.g. SubChannel (id: 4[]) Created. --> RefID = 4, RefName = "" (inside [])
  162. RefID int64
  163. // RefName is the reference name for the entity that gets referenced in the event.
  164. RefName string
  165. // RefType indicates the referenced entity type, i.e Channel or SubChannel.
  166. RefType RefChannelType
  167. }
  168. // Channel is the interface that should be satisfied in order to be tracked by
  169. // channelz as Channel or SubChannel.
  170. type Channel interface {
  171. ChannelzMetric() *ChannelInternalMetric
  172. }
  173. type dummyChannel struct{}
  174. func (d *dummyChannel) ChannelzMetric() *ChannelInternalMetric {
  175. return &ChannelInternalMetric{}
  176. }
  177. type channel struct {
  178. refName string
  179. c Channel
  180. closeCalled bool
  181. nestedChans map[int64]string
  182. subChans map[int64]string
  183. id int64
  184. pid int64
  185. cm *channelMap
  186. trace *channelTrace
  187. // traceRefCount is the number of trace events that reference this channel.
  188. // Non-zero traceRefCount means the trace of this channel cannot be deleted.
  189. traceRefCount int32
  190. }
  191. func (c *channel) addChild(id int64, e entry) {
  192. switch v := e.(type) {
  193. case *subChannel:
  194. c.subChans[id] = v.refName
  195. case *channel:
  196. c.nestedChans[id] = v.refName
  197. default:
  198. grpclog.Errorf("cannot add a child (id = %d) of type %T to a channel", id, e)
  199. }
  200. }
  201. func (c *channel) deleteChild(id int64) {
  202. delete(c.subChans, id)
  203. delete(c.nestedChans, id)
  204. c.deleteSelfIfReady()
  205. }
  206. func (c *channel) triggerDelete() {
  207. c.closeCalled = true
  208. c.deleteSelfIfReady()
  209. }
  210. func (c *channel) getParentID() int64 {
  211. return c.pid
  212. }
  213. // deleteSelfFromTree tries to delete the channel from the channelz entry relation tree, which means
  214. // deleting the channel reference from its parent's child list.
  215. //
  216. // In order for a channel to be deleted from the tree, it must meet the criteria that, removal of the
  217. // corresponding grpc object has been invoked, and the channel does not have any children left.
  218. //
  219. // The returned boolean value indicates whether the channel has been successfully deleted from tree.
  220. func (c *channel) deleteSelfFromTree() (deleted bool) {
  221. if !c.closeCalled || len(c.subChans)+len(c.nestedChans) != 0 {
  222. return false
  223. }
  224. // not top channel
  225. if c.pid != 0 {
  226. c.cm.findEntry(c.pid).deleteChild(c.id)
  227. }
  228. return true
  229. }
  230. // deleteSelfFromMap checks whether it is valid to delete the channel from the map, which means
  231. // deleting the channel from channelz's tracking entirely. Users can no longer use id to query the
  232. // channel, and its memory will be garbage collected.
  233. //
  234. // The trace reference count of the channel must be 0 in order to be deleted from the map. This is
  235. // specified in the channel tracing gRFC that as long as some other trace has reference to an entity,
  236. // the trace of the referenced entity must not be deleted. In order to release the resource allocated
  237. // by grpc, the reference to the grpc object is reset to a dummy object.
  238. //
  239. // deleteSelfFromMap must be called after deleteSelfFromTree returns true.
  240. //
  241. // It returns a bool to indicate whether the channel can be safely deleted from map.
  242. func (c *channel) deleteSelfFromMap() (delete bool) {
  243. if c.getTraceRefCount() != 0 {
  244. c.c = &dummyChannel{}
  245. return false
  246. }
  247. return true
  248. }
  249. // deleteSelfIfReady tries to delete the channel itself from the channelz database.
  250. // The delete process includes two steps:
  251. // 1. delete the channel from the entry relation tree, i.e. delete the channel reference from its
  252. // parent's child list.
  253. // 2. delete the channel from the map, i.e. delete the channel entirely from channelz. Lookup by id
  254. // will return entry not found error.
  255. func (c *channel) deleteSelfIfReady() {
  256. if !c.deleteSelfFromTree() {
  257. return
  258. }
  259. if !c.deleteSelfFromMap() {
  260. return
  261. }
  262. c.cm.deleteEntry(c.id)
  263. c.trace.clear()
  264. }
  265. func (c *channel) getChannelTrace() *channelTrace {
  266. return c.trace
  267. }
  268. func (c *channel) incrTraceRefCount() {
  269. atomic.AddInt32(&c.traceRefCount, 1)
  270. }
  271. func (c *channel) decrTraceRefCount() {
  272. atomic.AddInt32(&c.traceRefCount, -1)
  273. }
  274. func (c *channel) getTraceRefCount() int {
  275. i := atomic.LoadInt32(&c.traceRefCount)
  276. return int(i)
  277. }
  278. func (c *channel) getRefName() string {
  279. return c.refName
  280. }
  281. type subChannel struct {
  282. refName string
  283. c Channel
  284. closeCalled bool
  285. sockets map[int64]string
  286. id int64
  287. pid int64
  288. cm *channelMap
  289. trace *channelTrace
  290. traceRefCount int32
  291. }
  292. func (sc *subChannel) addChild(id int64, e entry) {
  293. if v, ok := e.(*normalSocket); ok {
  294. sc.sockets[id] = v.refName
  295. } else {
  296. grpclog.Errorf("cannot add a child (id = %d) of type %T to a subChannel", id, e)
  297. }
  298. }
  299. func (sc *subChannel) deleteChild(id int64) {
  300. delete(sc.sockets, id)
  301. sc.deleteSelfIfReady()
  302. }
  303. func (sc *subChannel) triggerDelete() {
  304. sc.closeCalled = true
  305. sc.deleteSelfIfReady()
  306. }
  307. func (sc *subChannel) getParentID() int64 {
  308. return sc.pid
  309. }
  310. // deleteSelfFromTree tries to delete the subchannel from the channelz entry relation tree, which
  311. // means deleting the subchannel reference from its parent's child list.
  312. //
  313. // In order for a subchannel to be deleted from the tree, it must meet the criteria that, removal of
  314. // the corresponding grpc object has been invoked, and the subchannel does not have any children left.
  315. //
  316. // The returned boolean value indicates whether the channel has been successfully deleted from tree.
  317. func (sc *subChannel) deleteSelfFromTree() (deleted bool) {
  318. if !sc.closeCalled || len(sc.sockets) != 0 {
  319. return false
  320. }
  321. sc.cm.findEntry(sc.pid).deleteChild(sc.id)
  322. return true
  323. }
  324. // deleteSelfFromMap checks whether it is valid to delete the subchannel from the map, which means
  325. // deleting the subchannel from channelz's tracking entirely. Users can no longer use id to query
  326. // the subchannel, and its memory will be garbage collected.
  327. //
  328. // The trace reference count of the subchannel must be 0 in order to be deleted from the map. This is
  329. // specified in the channel tracing gRFC that as long as some other trace has reference to an entity,
  330. // the trace of the referenced entity must not be deleted. In order to release the resource allocated
  331. // by grpc, the reference to the grpc object is reset to a dummy object.
  332. //
  333. // deleteSelfFromMap must be called after deleteSelfFromTree returns true.
  334. //
  335. // It returns a bool to indicate whether the channel can be safely deleted from map.
  336. func (sc *subChannel) deleteSelfFromMap() (delete bool) {
  337. if sc.getTraceRefCount() != 0 {
  338. // free the grpc struct (i.e. addrConn)
  339. sc.c = &dummyChannel{}
  340. return false
  341. }
  342. return true
  343. }
  344. // deleteSelfIfReady tries to delete the subchannel itself from the channelz database.
  345. // The delete process includes two steps:
  346. // 1. delete the subchannel from the entry relation tree, i.e. delete the subchannel reference from
  347. // its parent's child list.
  348. // 2. delete the subchannel from the map, i.e. delete the subchannel entirely from channelz. Lookup
  349. // by id will return entry not found error.
  350. func (sc *subChannel) deleteSelfIfReady() {
  351. if !sc.deleteSelfFromTree() {
  352. return
  353. }
  354. if !sc.deleteSelfFromMap() {
  355. return
  356. }
  357. sc.cm.deleteEntry(sc.id)
  358. sc.trace.clear()
  359. }
  360. func (sc *subChannel) getChannelTrace() *channelTrace {
  361. return sc.trace
  362. }
  363. func (sc *subChannel) incrTraceRefCount() {
  364. atomic.AddInt32(&sc.traceRefCount, 1)
  365. }
  366. func (sc *subChannel) decrTraceRefCount() {
  367. atomic.AddInt32(&sc.traceRefCount, -1)
  368. }
  369. func (sc *subChannel) getTraceRefCount() int {
  370. i := atomic.LoadInt32(&sc.traceRefCount)
  371. return int(i)
  372. }
  373. func (sc *subChannel) getRefName() string {
  374. return sc.refName
  375. }
  376. // SocketMetric defines the info channelz provides for a specific Socket, which
  377. // includes SocketInternalMetric and channelz-specific data, such as channelz id, etc.
  378. type SocketMetric struct {
  379. // ID is the channelz id of this socket.
  380. ID int64
  381. // RefName is the human readable reference string of this socket.
  382. RefName string
  383. // SocketData contains socket internal metric reported by the socket through
  384. // ChannelzMetric().
  385. SocketData *SocketInternalMetric
  386. }
  387. // SocketInternalMetric defines the struct that the implementor of Socket interface
  388. // should return from ChannelzMetric().
  389. type SocketInternalMetric struct {
  390. // The number of streams that have been started.
  391. StreamsStarted int64
  392. // The number of streams that have ended successfully:
  393. // On client side, receiving frame with eos bit set.
  394. // On server side, sending frame with eos bit set.
  395. StreamsSucceeded int64
  396. // The number of streams that have ended unsuccessfully:
  397. // On client side, termination without receiving frame with eos bit set.
  398. // On server side, termination without sending frame with eos bit set.
  399. StreamsFailed int64
  400. // The number of messages successfully sent on this socket.
  401. MessagesSent int64
  402. MessagesReceived int64
  403. // The number of keep alives sent. This is typically implemented with HTTP/2
  404. // ping messages.
  405. KeepAlivesSent int64
  406. // The last time a stream was created by this endpoint. Usually unset for
  407. // servers.
  408. LastLocalStreamCreatedTimestamp time.Time
  409. // The last time a stream was created by the remote endpoint. Usually unset
  410. // for clients.
  411. LastRemoteStreamCreatedTimestamp time.Time
  412. // The last time a message was sent by this endpoint.
  413. LastMessageSentTimestamp time.Time
  414. // The last time a message was received by this endpoint.
  415. LastMessageReceivedTimestamp time.Time
  416. // The amount of window, granted to the local endpoint by the remote endpoint.
  417. // This may be slightly out of date due to network latency. This does NOT
  418. // include stream level or TCP level flow control info.
  419. LocalFlowControlWindow int64
  420. // The amount of window, granted to the remote endpoint by the local endpoint.
  421. // This may be slightly out of date due to network latency. This does NOT
  422. // include stream level or TCP level flow control info.
  423. RemoteFlowControlWindow int64
  424. // The locally bound address.
  425. LocalAddr net.Addr
  426. // The remote bound address. May be absent.
  427. RemoteAddr net.Addr
  428. // Optional, represents the name of the remote endpoint, if different than
  429. // the original target name.
  430. RemoteName string
  431. SocketOptions *SocketOptionData
  432. Security credentials.ChannelzSecurityValue
  433. }
  434. // Socket is the interface that should be satisfied in order to be tracked by
  435. // channelz as Socket.
  436. type Socket interface {
  437. ChannelzMetric() *SocketInternalMetric
  438. }
  439. type listenSocket struct {
  440. refName string
  441. s Socket
  442. id int64
  443. pid int64
  444. cm *channelMap
  445. }
  446. func (ls *listenSocket) addChild(id int64, e entry) {
  447. grpclog.Errorf("cannot add a child (id = %d) of type %T to a listen socket", id, e)
  448. }
  449. func (ls *listenSocket) deleteChild(id int64) {
  450. grpclog.Errorf("cannot delete a child (id = %d) from a listen socket", id)
  451. }
  452. func (ls *listenSocket) triggerDelete() {
  453. ls.cm.deleteEntry(ls.id)
  454. ls.cm.findEntry(ls.pid).deleteChild(ls.id)
  455. }
  456. func (ls *listenSocket) deleteSelfIfReady() {
  457. grpclog.Errorf("cannot call deleteSelfIfReady on a listen socket")
  458. }
  459. func (ls *listenSocket) getParentID() int64 {
  460. return ls.pid
  461. }
  462. type normalSocket struct {
  463. refName string
  464. s Socket
  465. id int64
  466. pid int64
  467. cm *channelMap
  468. }
  469. func (ns *normalSocket) addChild(id int64, e entry) {
  470. grpclog.Errorf("cannot add a child (id = %d) of type %T to a normal socket", id, e)
  471. }
  472. func (ns *normalSocket) deleteChild(id int64) {
  473. grpclog.Errorf("cannot delete a child (id = %d) from a normal socket", id)
  474. }
  475. func (ns *normalSocket) triggerDelete() {
  476. ns.cm.deleteEntry(ns.id)
  477. ns.cm.findEntry(ns.pid).deleteChild(ns.id)
  478. }
  479. func (ns *normalSocket) deleteSelfIfReady() {
  480. grpclog.Errorf("cannot call deleteSelfIfReady on a normal socket")
  481. }
  482. func (ns *normalSocket) getParentID() int64 {
  483. return ns.pid
  484. }
  485. // ServerMetric defines the info channelz provides for a specific Server, which
  486. // includes ServerInternalMetric and channelz-specific data, such as channelz id,
  487. // child list, etc.
  488. type ServerMetric struct {
  489. // ID is the channelz id of this server.
  490. ID int64
  491. // RefName is the human readable reference string of this server.
  492. RefName string
  493. // ServerData contains server internal metric reported by the server through
  494. // ChannelzMetric().
  495. ServerData *ServerInternalMetric
  496. // ListenSockets tracks the listener socket type children of this server in the
  497. // format of a map from socket channelz id to corresponding reference string.
  498. ListenSockets map[int64]string
  499. }
  500. // ServerInternalMetric defines the struct that the implementor of Server interface
  501. // should return from ChannelzMetric().
  502. type ServerInternalMetric struct {
  503. // The number of incoming calls started on the server.
  504. CallsStarted int64
  505. // The number of incoming calls that have completed with an OK status.
  506. CallsSucceeded int64
  507. // The number of incoming calls that have a completed with a non-OK status.
  508. CallsFailed int64
  509. // The last time a call was started on the server.
  510. LastCallStartedTimestamp time.Time
  511. }
  512. // Server is the interface to be satisfied in order to be tracked by channelz as
  513. // Server.
  514. type Server interface {
  515. ChannelzMetric() *ServerInternalMetric
  516. }
  517. type server struct {
  518. refName string
  519. s Server
  520. closeCalled bool
  521. sockets map[int64]string
  522. listenSockets map[int64]string
  523. id int64
  524. cm *channelMap
  525. }
  526. func (s *server) addChild(id int64, e entry) {
  527. switch v := e.(type) {
  528. case *normalSocket:
  529. s.sockets[id] = v.refName
  530. case *listenSocket:
  531. s.listenSockets[id] = v.refName
  532. default:
  533. grpclog.Errorf("cannot add a child (id = %d) of type %T to a server", id, e)
  534. }
  535. }
  536. func (s *server) deleteChild(id int64) {
  537. delete(s.sockets, id)
  538. delete(s.listenSockets, id)
  539. s.deleteSelfIfReady()
  540. }
  541. func (s *server) triggerDelete() {
  542. s.closeCalled = true
  543. s.deleteSelfIfReady()
  544. }
  545. func (s *server) deleteSelfIfReady() {
  546. if !s.closeCalled || len(s.sockets)+len(s.listenSockets) != 0 {
  547. return
  548. }
  549. s.cm.deleteEntry(s.id)
  550. }
  551. func (s *server) getParentID() int64 {
  552. return 0
  553. }
  554. type tracedChannel interface {
  555. getChannelTrace() *channelTrace
  556. incrTraceRefCount()
  557. decrTraceRefCount()
  558. getRefName() string
  559. }
  560. type channelTrace struct {
  561. cm *channelMap
  562. createdTime time.Time
  563. eventCount int64
  564. mu sync.Mutex
  565. events []*TraceEvent
  566. }
  567. func (c *channelTrace) append(e *TraceEvent) {
  568. c.mu.Lock()
  569. if len(c.events) == getMaxTraceEntry() {
  570. del := c.events[0]
  571. c.events = c.events[1:]
  572. if del.RefID != 0 {
  573. // start recursive cleanup in a goroutine to not block the call originated from grpc.
  574. go func() {
  575. // need to acquire c.cm.mu lock to call the unlocked attemptCleanup func.
  576. c.cm.mu.Lock()
  577. c.cm.decrTraceRefCount(del.RefID)
  578. c.cm.mu.Unlock()
  579. }()
  580. }
  581. }
  582. e.Timestamp = time.Now()
  583. c.events = append(c.events, e)
  584. c.eventCount++
  585. c.mu.Unlock()
  586. }
  587. func (c *channelTrace) clear() {
  588. c.mu.Lock()
  589. for _, e := range c.events {
  590. if e.RefID != 0 {
  591. // caller should have already held the c.cm.mu lock.
  592. c.cm.decrTraceRefCount(e.RefID)
  593. }
  594. }
  595. c.mu.Unlock()
  596. }
  597. // Severity is the severity level of a trace event.
  598. // The canonical enumeration of all valid values is here:
  599. // https://github.com/grpc/grpc-proto/blob/9b13d199cc0d4703c7ea26c9c330ba695866eb23/grpc/channelz/v1/channelz.proto#L126.
  600. type Severity int
  601. const (
  602. // CtUNKNOWN indicates unknown severity of a trace event.
  603. CtUNKNOWN Severity = iota
  604. // CtINFO indicates info level severity of a trace event.
  605. CtINFO
  606. // CtWarning indicates warning level severity of a trace event.
  607. CtWarning
  608. // CtError indicates error level severity of a trace event.
  609. CtError
  610. )
  611. // RefChannelType is the type of the entity being referenced in a trace event.
  612. type RefChannelType int
  613. const (
  614. // RefChannel indicates the referenced entity is a Channel.
  615. RefChannel RefChannelType = iota
  616. // RefSubChannel indicates the referenced entity is a SubChannel.
  617. RefSubChannel
  618. )
  619. func (c *channelTrace) dumpData() *ChannelTrace {
  620. c.mu.Lock()
  621. ct := &ChannelTrace{EventNum: c.eventCount, CreationTime: c.createdTime}
  622. ct.Events = c.events[:len(c.events)]
  623. c.mu.Unlock()
  624. return ct
  625. }