server.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. // Copyright 2016 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 metric
  15. /*
  16. var (
  17. DailyDataKeepDays int = 7
  18. ServerMetricInfoMap map[string]*ServerMetric
  19. smMutex sync.RWMutex
  20. )
  21. type ServerMetric struct {
  22. Name string `json:"name"`
  23. Type string `json:"type"`
  24. BindAddr string `json:"bind_addr"`
  25. ListenPort int64 `json:"listen_port"`
  26. CustomDomains []string `json:"custom_domains"`
  27. Locations []string `json:"locations"`
  28. Status string `json:"status"`
  29. UseEncryption bool `json:"use_encryption"`
  30. UseGzip bool `json:"use_gzip"`
  31. PrivilegeMode bool `json:"privilege_mode"`
  32. // statistics
  33. CurrentConns int64 `json:"current_conns"`
  34. Daily []*DailyServerStats `json:"daily"`
  35. mutex sync.RWMutex
  36. }
  37. type DailyServerStats struct {
  38. Time string `json:"time"`
  39. FlowIn int64 `json:"flow_in"`
  40. FlowOut int64 `json:"flow_out"`
  41. TotalAcceptConns int64 `json:"total_accept_conns"`
  42. }
  43. // for sort
  44. type ServerMetricList []*ServerMetric
  45. func (l ServerMetricList) Len() int { return len(l) }
  46. func (l ServerMetricList) Less(i, j int) bool { return l[i].Name < l[j].Name }
  47. func (l ServerMetricList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
  48. func init() {
  49. ServerMetricInfoMap = make(map[string]*ServerMetric)
  50. }
  51. func (s *ServerMetric) clone() *ServerMetric {
  52. copy := *s
  53. copy.CustomDomains = make([]string, len(s.CustomDomains))
  54. var i int
  55. for i = range copy.CustomDomains {
  56. copy.CustomDomains[i] = s.CustomDomains[i]
  57. }
  58. copy.Daily = make([]*DailyServerStats, len(s.Daily))
  59. for i = range copy.Daily {
  60. tmpDaily := *s.Daily[i]
  61. copy.Daily[i] = &tmpDaily
  62. }
  63. return &copy
  64. }
  65. func GetAllProxyMetrics() []*ServerMetric {
  66. result := make(ServerMetricList, 0)
  67. smMutex.RLock()
  68. for _, metric := range ServerMetricInfoMap {
  69. metric.mutex.RLock()
  70. tmpMetric := metric.clone()
  71. metric.mutex.RUnlock()
  72. result = append(result, tmpMetric)
  73. }
  74. smMutex.RUnlock()
  75. // sort for result by proxy name
  76. sort.Sort(result)
  77. return result
  78. }
  79. // if proxyName isn't exist, return nil
  80. func GetProxyMetrics(proxyName string) *ServerMetric {
  81. smMutex.RLock()
  82. defer smMutex.RUnlock()
  83. metric, ok := ServerMetricInfoMap[proxyName]
  84. if ok {
  85. metric.mutex.RLock()
  86. tmpMetric := metric.clone()
  87. metric.mutex.RUnlock()
  88. return tmpMetric
  89. } else {
  90. return nil
  91. }
  92. }
  93. func SetProxyInfo(proxyName string, proxyType, bindAddr string,
  94. useEncryption, useGzip, privilegeMode bool, customDomains []string,
  95. locations []string, listenPort int64) {
  96. smMutex.Lock()
  97. info, ok := ServerMetricInfoMap[proxyName]
  98. if !ok {
  99. info = &ServerMetric{}
  100. info.Daily = make([]*DailyServerStats, 0)
  101. }
  102. info.Name = proxyName
  103. info.Type = proxyType
  104. info.UseEncryption = useEncryption
  105. info.UseGzip = useGzip
  106. info.PrivilegeMode = privilegeMode
  107. info.BindAddr = bindAddr
  108. info.ListenPort = listenPort
  109. info.CustomDomains = customDomains
  110. info.Locations = locations
  111. ServerMetricInfoMap[proxyName] = info
  112. smMutex.Unlock()
  113. }
  114. func SetStatus(proxyName string, status int64) {
  115. smMutex.RLock()
  116. metric, ok := ServerMetricInfoMap[proxyName]
  117. smMutex.RUnlock()
  118. if ok {
  119. metric.mutex.Lock()
  120. metric.Status = consts.StatusStr[status]
  121. metric.mutex.Unlock()
  122. }
  123. }
  124. type DealFuncType func(*DailyServerStats)
  125. func DealDailyData(dailyData []*DailyServerStats, fn DealFuncType) (newDailyData []*DailyServerStats) {
  126. now := time.Now().Format("20060102")
  127. dailyLen := len(dailyData)
  128. if dailyLen == 0 {
  129. daily := &DailyServerStats{}
  130. daily.Time = now
  131. fn(daily)
  132. dailyData = append(dailyData, daily)
  133. } else {
  134. daily := dailyData[dailyLen-1]
  135. if daily.Time == now {
  136. fn(daily)
  137. } else {
  138. newDaily := &DailyServerStats{}
  139. newDaily.Time = now
  140. fn(newDaily)
  141. if dailyLen == DailyDataKeepDays {
  142. for i := 0; i < dailyLen-1; i++ {
  143. dailyData[i] = dailyData[i+1]
  144. }
  145. dailyData[dailyLen-1] = newDaily
  146. } else {
  147. dailyData = append(dailyData, newDaily)
  148. }
  149. }
  150. }
  151. return dailyData
  152. }
  153. func OpenConnection(proxyName string) {
  154. smMutex.RLock()
  155. metric, ok := ServerMetricInfoMap[proxyName]
  156. smMutex.RUnlock()
  157. if ok {
  158. metric.mutex.Lock()
  159. metric.CurrentConns++
  160. metric.Daily = DealDailyData(metric.Daily, func(stats *DailyServerStats) {
  161. stats.TotalAcceptConns++
  162. })
  163. metric.mutex.Unlock()
  164. }
  165. }
  166. func CloseConnection(proxyName string) {
  167. smMutex.RLock()
  168. metric, ok := ServerMetricInfoMap[proxyName]
  169. smMutex.RUnlock()
  170. if ok {
  171. metric.mutex.Lock()
  172. metric.CurrentConns--
  173. metric.mutex.Unlock()
  174. }
  175. }
  176. func AddFlowIn(proxyName string, value int64) {
  177. smMutex.RLock()
  178. metric, ok := ServerMetricInfoMap[proxyName]
  179. smMutex.RUnlock()
  180. if ok {
  181. metric.mutex.Lock()
  182. metric.Daily = DealDailyData(metric.Daily, func(stats *DailyServerStats) {
  183. stats.FlowIn += value
  184. })
  185. metric.mutex.Unlock()
  186. }
  187. }
  188. func AddFlowOut(proxyName string, value int64) {
  189. smMutex.RLock()
  190. metric, ok := ServerMetricInfoMap[proxyName]
  191. smMutex.RUnlock()
  192. if ok {
  193. metric.mutex.Lock()
  194. metric.Daily = DealDailyData(metric.Daily, func(stats *DailyServerStats) {
  195. stats.FlowOut += value
  196. })
  197. metric.mutex.Unlock()
  198. }
  199. }
  200. */