metric.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. // Copyright 2017 fatedier, fatedier@gmail.com
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package server
  15. import (
  16. "sync"
  17. "github.com/fatedier/frp/models/config"
  18. "github.com/fatedier/frp/utils/metric"
  19. )
  20. const (
  21. ReserveDays = 7
  22. )
  23. var globalStats *ServerStatistics
  24. type ServerStatistics struct {
  25. TotalTrafficIn metric.DateCounter
  26. TotalTrafficOut metric.DateCounter
  27. CurConns metric.Counter
  28. ClientCounts metric.Counter
  29. ProxyTypeCounts map[string]metric.Counter
  30. ProxyStatistics map[string]*ProxyStatistics
  31. mu sync.Mutex
  32. }
  33. type ProxyStatistics struct {
  34. ProxyType string
  35. TrafficIn metric.DateCounter
  36. TrafficOut metric.DateCounter
  37. CurConns metric.Counter
  38. }
  39. func init() {
  40. globalStats = &ServerStatistics{
  41. TotalTrafficIn: metric.NewDateCounter(ReserveDays),
  42. TotalTrafficOut: metric.NewDateCounter(ReserveDays),
  43. CurConns: metric.NewCounter(),
  44. ClientCounts: metric.NewCounter(),
  45. ProxyTypeCounts: make(map[string]metric.Counter),
  46. ProxyStatistics: make(map[string]*ProxyStatistics),
  47. }
  48. }
  49. func StatsNewClient() {
  50. if config.ServerCommonCfg.DashboardPort != 0 {
  51. globalStats.ClientCounts.Inc(1)
  52. }
  53. }
  54. func StatsCloseClient() {
  55. if config.ServerCommonCfg.DashboardPort != 0 {
  56. globalStats.ClientCounts.Dec(1)
  57. }
  58. }
  59. func StatsNewProxy(name string, proxyType string) {
  60. if config.ServerCommonCfg.DashboardPort != 0 {
  61. globalStats.mu.Lock()
  62. defer globalStats.mu.Unlock()
  63. counter, ok := globalStats.ProxyTypeCounts[proxyType]
  64. if !ok {
  65. counter = metric.NewCounter()
  66. }
  67. counter.Inc(1)
  68. globalStats.ProxyTypeCounts[proxyType] = counter
  69. proxyStats, ok := globalStats.ProxyStatistics[name]
  70. if !ok {
  71. proxyStats = &ProxyStatistics{
  72. ProxyType: proxyType,
  73. CurConns: metric.NewCounter(),
  74. TrafficIn: metric.NewDateCounter(ReserveDays),
  75. TrafficOut: metric.NewDateCounter(ReserveDays),
  76. }
  77. globalStats.ProxyStatistics[name] = proxyStats
  78. }
  79. }
  80. }
  81. func StatsCloseProxy(proxyType string) {
  82. if config.ServerCommonCfg.DashboardPort != 0 {
  83. globalStats.mu.Lock()
  84. defer globalStats.mu.Unlock()
  85. if counter, ok := globalStats.ProxyTypeCounts[proxyType]; ok {
  86. counter.Dec(1)
  87. }
  88. }
  89. }
  90. func StatsOpenConnection(name string) {
  91. if config.ServerCommonCfg.DashboardPort != 0 {
  92. globalStats.CurConns.Inc(1)
  93. globalStats.mu.Lock()
  94. defer globalStats.mu.Unlock()
  95. proxyStats, ok := globalStats.ProxyStatistics[name]
  96. if ok {
  97. proxyStats.CurConns.Inc(1)
  98. globalStats.ProxyStatistics[name] = proxyStats
  99. }
  100. }
  101. }
  102. func StatsCloseConnection(name string) {
  103. if config.ServerCommonCfg.DashboardPort != 0 {
  104. globalStats.CurConns.Dec(1)
  105. globalStats.mu.Lock()
  106. defer globalStats.mu.Unlock()
  107. proxyStats, ok := globalStats.ProxyStatistics[name]
  108. if ok {
  109. proxyStats.CurConns.Dec(1)
  110. globalStats.ProxyStatistics[name] = proxyStats
  111. }
  112. }
  113. }
  114. func StatsAddTrafficIn(name string, trafficIn int64) {
  115. if config.ServerCommonCfg.DashboardPort != 0 {
  116. globalStats.TotalTrafficIn.Inc(trafficIn)
  117. globalStats.mu.Lock()
  118. defer globalStats.mu.Unlock()
  119. proxyStats, ok := globalStats.ProxyStatistics[name]
  120. if ok {
  121. proxyStats.TrafficIn.Inc(trafficIn)
  122. globalStats.ProxyStatistics[name] = proxyStats
  123. }
  124. }
  125. }
  126. func StatsAddTrafficOut(name string, trafficOut int64) {
  127. if config.ServerCommonCfg.DashboardPort != 0 {
  128. globalStats.TotalTrafficOut.Inc(trafficOut)
  129. globalStats.mu.Lock()
  130. defer globalStats.mu.Unlock()
  131. proxyStats, ok := globalStats.ProxyStatistics[name]
  132. if ok {
  133. proxyStats.TrafficOut.Inc(trafficOut)
  134. globalStats.ProxyStatistics[name] = proxyStats
  135. }
  136. }
  137. }
  138. // Functions for getting server stats.
  139. type ServerStats struct {
  140. TotalTrafficIn int64
  141. TotalTrafficOut int64
  142. CurConns int64
  143. ClientCounts int64
  144. ProxyTypeCounts map[string]int64
  145. }
  146. func StatsGetServer() *ServerStats {
  147. globalStats.mu.Lock()
  148. defer globalStats.mu.Unlock()
  149. s := &ServerStats{
  150. TotalTrafficIn: globalStats.TotalTrafficIn.TodayCount(),
  151. TotalTrafficOut: globalStats.TotalTrafficOut.TodayCount(),
  152. CurConns: globalStats.CurConns.Count(),
  153. ClientCounts: globalStats.ClientCounts.Count(),
  154. ProxyTypeCounts: make(map[string]int64),
  155. }
  156. for k, v := range globalStats.ProxyTypeCounts {
  157. s.ProxyTypeCounts[k] = v.Count()
  158. }
  159. return s
  160. }
  161. type ProxyStats struct {
  162. Name string
  163. Type string
  164. TodayTrafficIn int64
  165. TodayTrafficOut int64
  166. CurConns int64
  167. }
  168. func StatsGetProxiesByType(proxyType string) []*ProxyStats {
  169. res := make([]*ProxyStats, 0)
  170. globalStats.mu.Lock()
  171. defer globalStats.mu.Unlock()
  172. for name, proxyStats := range globalStats.ProxyStatistics {
  173. if proxyStats.ProxyType != proxyType {
  174. continue
  175. }
  176. ps := &ProxyStats{
  177. Name: name,
  178. Type: proxyStats.ProxyType,
  179. TodayTrafficIn: proxyStats.TrafficIn.TodayCount(),
  180. TodayTrafficOut: proxyStats.TrafficOut.TodayCount(),
  181. CurConns: proxyStats.CurConns.Count(),
  182. }
  183. res = append(res, ps)
  184. }
  185. return res
  186. }
  187. type ProxyTrafficInfo struct {
  188. Name string
  189. TrafficIn []int64
  190. TrafficOut []int64
  191. }
  192. func StatsGetProxyTraffic(name string) (res *ProxyTrafficInfo) {
  193. globalStats.mu.Lock()
  194. defer globalStats.mu.Unlock()
  195. proxyStats, ok := globalStats.ProxyStatistics[name]
  196. if ok {
  197. res = &ProxyTrafficInfo{
  198. Name: name,
  199. }
  200. res.TrafficIn = proxyStats.TrafficIn.GetLastDaysCount(ReserveDays)
  201. res.TrafficOut = proxyStats.TrafficOut.GetLastDaysCount(ReserveDays)
  202. }
  203. return
  204. }