1
0

statistics.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright 2014 beego Author. All Rights Reserved.
  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 toolbox
  15. import (
  16. "fmt"
  17. "sync"
  18. "time"
  19. )
  20. // Statistics struct
  21. type Statistics struct {
  22. RequestURL string
  23. RequestController string
  24. RequestNum int64
  25. MinTime time.Duration
  26. MaxTime time.Duration
  27. TotalTime time.Duration
  28. }
  29. // URLMap contains several statistics struct to log different data
  30. type URLMap struct {
  31. lock sync.RWMutex
  32. LengthLimit int //limit the urlmap's length if it's equal to 0 there's no limit
  33. urlmap map[string]map[string]*Statistics
  34. }
  35. // AddStatistics add statistics task.
  36. // it needs request method, request url, request controller and statistics time duration
  37. func (m *URLMap) AddStatistics(requestMethod, requestURL, requestController string, requesttime time.Duration) {
  38. m.lock.Lock()
  39. defer m.lock.Unlock()
  40. if method, ok := m.urlmap[requestURL]; ok {
  41. if s, ok := method[requestMethod]; ok {
  42. s.RequestNum++
  43. if s.MaxTime < requesttime {
  44. s.MaxTime = requesttime
  45. }
  46. if s.MinTime > requesttime {
  47. s.MinTime = requesttime
  48. }
  49. s.TotalTime += requesttime
  50. } else {
  51. nb := &Statistics{
  52. RequestURL: requestURL,
  53. RequestController: requestController,
  54. RequestNum: 1,
  55. MinTime: requesttime,
  56. MaxTime: requesttime,
  57. TotalTime: requesttime,
  58. }
  59. m.urlmap[requestURL][requestMethod] = nb
  60. }
  61. } else {
  62. if m.LengthLimit > 0 && m.LengthLimit <= len(m.urlmap) {
  63. return
  64. }
  65. methodmap := make(map[string]*Statistics)
  66. nb := &Statistics{
  67. RequestURL: requestURL,
  68. RequestController: requestController,
  69. RequestNum: 1,
  70. MinTime: requesttime,
  71. MaxTime: requesttime,
  72. TotalTime: requesttime,
  73. }
  74. methodmap[requestMethod] = nb
  75. m.urlmap[requestURL] = methodmap
  76. }
  77. }
  78. // GetMap put url statistics result in io.Writer
  79. func (m *URLMap) GetMap() map[string]interface{} {
  80. m.lock.RLock()
  81. defer m.lock.RUnlock()
  82. var fields = []string{"requestUrl", "method", "times", "used", "max used", "min used", "avg used"}
  83. var resultLists [][]string
  84. content := make(map[string]interface{})
  85. content["Fields"] = fields
  86. for k, v := range m.urlmap {
  87. for kk, vv := range v {
  88. result := []string{
  89. fmt.Sprintf("% -50s", k),
  90. fmt.Sprintf("% -10s", kk),
  91. fmt.Sprintf("% -16d", vv.RequestNum),
  92. fmt.Sprintf("%d", vv.TotalTime),
  93. fmt.Sprintf("% -16s", toS(vv.TotalTime)),
  94. fmt.Sprintf("%d", vv.MaxTime),
  95. fmt.Sprintf("% -16s", toS(vv.MaxTime)),
  96. fmt.Sprintf("%d", vv.MinTime),
  97. fmt.Sprintf("% -16s", toS(vv.MinTime)),
  98. fmt.Sprintf("%d", time.Duration(int64(vv.TotalTime)/vv.RequestNum)),
  99. fmt.Sprintf("% -16s", toS(time.Duration(int64(vv.TotalTime)/vv.RequestNum))),
  100. }
  101. resultLists = append(resultLists, result)
  102. }
  103. }
  104. content["Data"] = resultLists
  105. return content
  106. }
  107. // GetMapData return all mapdata
  108. func (m *URLMap) GetMapData() []map[string]interface{} {
  109. m.lock.Lock()
  110. defer m.lock.Unlock()
  111. var resultLists []map[string]interface{}
  112. for k, v := range m.urlmap {
  113. for kk, vv := range v {
  114. result := map[string]interface{}{
  115. "request_url": k,
  116. "method": kk,
  117. "times": vv.RequestNum,
  118. "total_time": toS(vv.TotalTime),
  119. "max_time": toS(vv.MaxTime),
  120. "min_time": toS(vv.MinTime),
  121. "avg_time": toS(time.Duration(int64(vv.TotalTime) / vv.RequestNum)),
  122. }
  123. resultLists = append(resultLists, result)
  124. }
  125. }
  126. return resultLists
  127. }
  128. // StatisticsMap hosld global statistics data map
  129. var StatisticsMap *URLMap
  130. func init() {
  131. StatisticsMap = &URLMap{
  132. urlmap: make(map[string]map[string]*Statistics),
  133. }
  134. }