sockstats.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Package sockstats collects statistics about network sockets used by
  4. // the Tailscale client. The context where sockets are used must be
  5. // instrumented with the WithSockStats() function.
  6. //
  7. // Only available on POSIX platforms when built with Tailscale's fork of Go.
  8. package sockstats
  9. import (
  10. "context"
  11. "tailscale.com/net/netmon"
  12. "tailscale.com/types/logger"
  13. )
  14. // SockStats contains statistics for sockets instrumented with the
  15. // WithSockStats() function
  16. type SockStats struct {
  17. Stats map[Label]SockStat
  18. CurrentInterfaceCellular bool
  19. }
  20. // SockStat contains the sent and received bytes for a socket instrumented with
  21. // the WithSockStats() function.
  22. type SockStat struct {
  23. TxBytes uint64
  24. RxBytes uint64
  25. }
  26. // Label is an identifier for a socket that stats are collected for. A finite
  27. // set of values that may be used to label a socket to encourage grouping and
  28. // to make storage more efficient.
  29. type Label uint8
  30. //go:generate go run golang.org/x/tools/cmd/stringer -type Label -trimprefix Label
  31. // Labels are named after the package and function/struct that uses the socket.
  32. // Values may be persisted and thus existing entries should not be re-numbered.
  33. const (
  34. LabelControlClientAuto Label = 0 // control/controlclient/auto.go
  35. LabelControlClientDialer Label = 1 // control/controlhttp/client.go
  36. LabelDERPHTTPClient Label = 2 // derp/derphttp/derphttp_client.go
  37. LabelLogtailLogger Label = 3 // logtail/logtail.go
  38. LabelDNSForwarderDoH Label = 4 // net/dns/resolver/forwarder.go
  39. LabelDNSForwarderUDP Label = 5 // net/dns/resolver/forwarder.go
  40. LabelNetcheckClient Label = 6 // net/netcheck/netcheck.go
  41. LabelPortmapperClient Label = 7 // net/portmapper/portmapper.go
  42. LabelMagicsockConnUDP4 Label = 8 // wgengine/magicsock/magicsock.go
  43. LabelMagicsockConnUDP6 Label = 9 // wgengine/magicsock/magicsock.go
  44. LabelNetlogLogger Label = 10 // wgengine/netlog/logger.go
  45. LabelSockstatlogLogger Label = 11 // log/sockstatlog/logger.go
  46. LabelDNSForwarderTCP Label = 12 // net/dns/resolver/forwarder.go
  47. )
  48. // WithSockStats instruments a context so that sockets created with it will
  49. // have their statistics collected.
  50. func WithSockStats(ctx context.Context, label Label, logf logger.Logf) context.Context {
  51. return withSockStats(ctx, label, logf)
  52. }
  53. // Get returns the current socket statistics.
  54. func Get() *SockStats {
  55. return get()
  56. }
  57. // InterfaceSockStats contains statistics for sockets instrumented with the
  58. // WithSockStats() function, broken down by interface. The statistics may be a
  59. // subset of the total if interfaces were added after the instrumented socket
  60. // was created.
  61. type InterfaceSockStats struct {
  62. Stats map[Label]InterfaceSockStat
  63. Interfaces []string
  64. }
  65. // InterfaceSockStat contains the per-interface sent and received bytes for a
  66. // socket instrumented with the WithSockStats() function.
  67. type InterfaceSockStat struct {
  68. TxBytesByInterface map[string]uint64
  69. RxBytesByInterface map[string]uint64
  70. }
  71. // GetWithInterfaces is a variant of Get that returns the current socket
  72. // statistics broken down by interface. It is slightly more expensive than Get.
  73. func GetInterfaces() *InterfaceSockStats {
  74. return getInterfaces()
  75. }
  76. // ValidationSockStats contains external validation numbers for sockets
  77. // instrumented with WithSockStats. It may be a subset of the all sockets,
  78. // depending on what externa measurement mechanisms the platform supports.
  79. type ValidationSockStats struct {
  80. Stats map[Label]ValidationSockStat
  81. }
  82. // ValidationSockStat contains the validation bytes for a socket instrumented
  83. // with WithSockStats.
  84. type ValidationSockStat struct {
  85. TxBytes uint64
  86. RxBytes uint64
  87. }
  88. // GetValidation is a variant of Get that returns external validation numbers
  89. // for stats. It is more expensive than Get and should be used in debug
  90. // interfaces only.
  91. func GetValidation() *ValidationSockStats {
  92. return getValidation()
  93. }
  94. // SetNetMon configures the sockstats package to monitor the active
  95. // interface, so that per-interface stats can be collected.
  96. func SetNetMon(netMon *netmon.Monitor) {
  97. setNetMon(netMon)
  98. }
  99. // DebugInfo returns a string containing debug information about the tracked
  100. // statistics.
  101. func DebugInfo() string {
  102. return debugInfo()
  103. }