123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- package statistic
- import (
- "strings"
- "sync"
- "time"
- "imuslab.com/Zoraxy/mod/database"
- )
- type DailySummary struct {
- TotalRequest int64
- ErrorRequest int64
- ValidRequest int64
-
- ForwardTypes *sync.Map
- RequestOrigin *sync.Map
- RequestClientIp *sync.Map
- }
- type RequestInfo struct {
- IpAddr string
- RequestOriginalCountryISOCode string
- Succ bool
- StatusCode int
- ForwardType string
- }
- type CollectorOption struct {
- Database *database.Database
- }
- type Collector struct {
- rtdataStopChan chan bool
- DailySummary *DailySummary
- Option *CollectorOption
- }
- func NewStatisticCollector(option CollectorOption) (*Collector, error) {
- option.Database.NewTable("stats")
-
- thisCollector := Collector{
- DailySummary: newDailySummary(),
- Option: &option,
- }
-
-
- year, month, day := time.Now().Date()
- summary := thisCollector.LoadSummaryOfDay(year, month, day)
- if summary != nil {
- thisCollector.DailySummary = summary
- }
-
- rtstatStopChan := thisCollector.ScheduleResetRealtimeStats()
- thisCollector.rtdataStopChan = rtstatStopChan
- return &thisCollector, nil
- }
- func (c *Collector) SaveSummaryOfDay() {
-
- t := time.Now().Add(-30 * time.Second)
- summaryKey := t.Format("02_01_2006")
- c.Option.Database.Write("stats", summaryKey, c.DailySummary)
- }
- func (c *Collector) LoadSummaryOfDay(year int, month time.Month, day int) *DailySummary {
- date := time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.Local)
- summaryKey := date.Format("02_01_2006")
- var targetSummary = newDailySummary()
- c.Option.Database.Read("stats", summaryKey, &targetSummary)
- return targetSummary
- }
- func (c *Collector) GetCurrentRealtimeStatIntervalId() int {
- now := time.Now()
- startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local).Unix()
- secondsSinceStartOfDay := now.Unix() - startOfDay
- interval := secondsSinceStartOfDay / (5 * 60)
- return int(interval)
- }
- func (c *Collector) Close() {
-
- c.rtdataStopChan <- true
-
- c.SaveSummaryOfDay()
- }
- func (c *Collector) RecordRequest(ri RequestInfo) {
- go func() {
- c.DailySummary.TotalRequest++
- if ri.Succ {
- c.DailySummary.ValidRequest++
- } else {
- c.DailySummary.ErrorRequest++
- }
-
- ft, ok := c.DailySummary.ForwardTypes.Load(ri.ForwardType)
- if !ok {
- c.DailySummary.ForwardTypes.Store(ri.ForwardType, 1)
- } else {
- c.DailySummary.ForwardTypes.Store(ri.ForwardType, ft.(int)+1)
- }
- originISO := strings.ToLower(ri.RequestOriginalCountryISOCode)
- fo, ok := c.DailySummary.RequestOrigin.Load(originISO)
- if !ok {
- c.DailySummary.RequestOrigin.Store(originISO, 1)
- } else {
- c.DailySummary.RequestOrigin.Store(originISO, fo.(int)+1)
- }
- fi, ok := c.DailySummary.RequestClientIp.Load(ri.IpAddr)
- if !ok {
- c.DailySummary.RequestClientIp.Store(ri.IpAddr, 1)
- } else {
- c.DailySummary.RequestClientIp.Store(ri.IpAddr, fi.(int)+1)
- }
- }()
- }
- func (c *Collector) ScheduleResetRealtimeStats() chan bool {
- doneCh := make(chan bool)
- go func() {
- defer close(doneCh)
- for {
-
- now := time.Now()
-
- midnight := time.Date(now.Year(), now.Month(), now.Day()+1, 0, 0, 0, 0, now.Location())
-
- duration := midnight.Sub(now)
- select {
- case <-time.After(duration):
-
- c.SaveSummaryOfDay()
- c.DailySummary = newDailySummary()
- case <-doneCh:
-
- return
- }
- }
- }()
- return doneCh
- }
- func newDailySummary() *DailySummary {
- return &DailySummary{
- TotalRequest: 0,
- ErrorRequest: 0,
- ValidRequest: 0,
- ForwardTypes: &sync.Map{},
- RequestOrigin: &sync.Map{},
- RequestClientIp: &sync.Map{},
- }
- }
|