github.com/astaxie/beego@v1.12.3/toolbox/statistics.go (about)

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