Removed alpha prototype source

This commit is contained in:
Toby Chui
2023-05-04 20:42:35 +08:00
parent 2c586aee32
commit a1d779a0ce
275 changed files with 0 additions and 150920 deletions

View File

@@ -1,67 +0,0 @@
package statistic
import (
"encoding/json"
"net/http"
"imuslab.com/zoraxy/mod/utils"
)
/*
Handler.go
This script handles incoming request for loading the statistic of the day
*/
func (c *Collector) HandleTodayStatLoad(w http.ResponseWriter, r *http.Request) {
fast, err := utils.GetPara(r, "fast")
if err != nil {
fast = "false"
}
d := c.DailySummary
if fast == "true" {
//Only return the counter
exported := DailySummaryExport{
TotalRequest: d.TotalRequest,
ErrorRequest: d.ErrorRequest,
ValidRequest: d.ValidRequest,
}
js, _ := json.Marshal(exported)
utils.SendJSONResponse(w, string(js))
} else {
//Return everything
exported := DailySummaryExport{
TotalRequest: d.TotalRequest,
ErrorRequest: d.ErrorRequest,
ValidRequest: d.ValidRequest,
ForwardTypes: make(map[string]int),
RequestOrigin: make(map[string]int),
RequestClientIp: make(map[string]int),
}
// Export ForwardTypes sync.Map
d.ForwardTypes.Range(func(key, value interface{}) bool {
exported.ForwardTypes[key.(string)] = value.(int)
return true
})
// Export RequestOrigin sync.Map
d.RequestOrigin.Range(func(key, value interface{}) bool {
exported.RequestOrigin[key.(string)] = value.(int)
return true
})
// Export RequestClientIp sync.Map
d.RequestClientIp.Range(func(key, value interface{}) bool {
exported.RequestClientIp[key.(string)] = value.(int)
return true
})
js, _ := json.Marshal(exported)
utils.SendJSONResponse(w, string(js))
}
}

View File

@@ -1,186 +0,0 @@
package statistic
import (
"strings"
"sync"
"time"
"imuslab.com/zoraxy/mod/database"
)
/*
Statistic Package
This packet is designed to collection information
and store them for future analysis
*/
//Faststat, a interval summary for all collected data and avoid
//looping through every data everytime a overview is needed
type DailySummary struct {
TotalRequest int64 //Total request of the day
ErrorRequest int64 //Invalid request of the day, including error or not found
ValidRequest int64 //Valid request of the day
//Type counters
ForwardTypes *sync.Map //Map that hold the forward types
RequestOrigin *sync.Map //Map that hold [country ISO code]: visitor counter
RequestClientIp *sync.Map //Map that hold all unique request IPs
}
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")
//Create the collector object
thisCollector := Collector{
DailySummary: newDailySummary(),
Option: &option,
}
//Load the stat if exists for today
//This will exists if the program was forcefully restarted
year, month, day := time.Now().Date()
summary := thisCollector.LoadSummaryOfDay(year, month, day)
if summary != nil {
thisCollector.DailySummary = summary
}
//Schedule the realtime statistic clearing at midnight everyday
rtstatStopChan := thisCollector.ScheduleResetRealtimeStats()
thisCollector.rtdataStopChan = rtstatStopChan
return &thisCollector, nil
}
//Write the current in-memory summary to database file
func (c *Collector) SaveSummaryOfDay() {
//When it is called in 0:00am, make sure it is stored as yesterday key
t := time.Now().Add(-30 * time.Second)
summaryKey := t.Format("02_01_2006")
saveData := DailySummaryToExport(*c.DailySummary)
c.Option.Database.Write("stats", summaryKey, saveData)
}
//Load the summary of a day given
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")
targetSummaryExport := DailySummaryExport{}
c.Option.Database.Read("stats", summaryKey, &targetSummaryExport)
targetSummary := DailySummaryExportToSummary(targetSummaryExport)
return &targetSummary
}
//This function gives the current slot in the 288- 5 minutes interval of the day
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() {
//Stop the ticker
c.rtdataStopChan <- true
//Write the buffered data into database
c.SaveSummaryOfDay()
}
//Main function to record all the inbound traffics
//Note that this function run in go routine and might have concurrent R/W issue
//Please make sure there is no racing paramters in this function
func (c *Collector) RecordRequest(ri RequestInfo) {
go func() {
c.DailySummary.TotalRequest++
if ri.Succ {
c.DailySummary.ValidRequest++
} else {
c.DailySummary.ErrorRequest++
}
//Store the request info into correct types of maps
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)
}
}()
}
//nightly task
func (c *Collector) ScheduleResetRealtimeStats() chan bool {
doneCh := make(chan bool)
go func() {
defer close(doneCh)
for {
// calculate duration until next midnight
now := time.Now()
// Get midnight of the next day in the local time zone
midnight := time.Date(now.Year(), now.Month(), now.Day()+1, 0, 0, 0, 0, now.Location())
// Calculate the duration until midnight
duration := midnight.Sub(now)
select {
case <-time.After(duration):
// store daily summary to database and reset summary
c.SaveSummaryOfDay()
c.DailySummary = newDailySummary()
case <-doneCh:
// stop the routine
return
}
}
}()
return doneCh
}
func newDailySummary() *DailySummary {
return &DailySummary{
TotalRequest: 0,
ErrorRequest: 0,
ValidRequest: 0,
ForwardTypes: &sync.Map{},
RequestOrigin: &sync.Map{},
RequestClientIp: &sync.Map{},
}
}

View File

@@ -1,66 +0,0 @@
package statistic
import "sync"
type DailySummaryExport struct {
TotalRequest int64 //Total request of the day
ErrorRequest int64 //Invalid request of the day, including error or not found
ValidRequest int64 //Valid request of the day
ForwardTypes map[string]int
RequestOrigin map[string]int
RequestClientIp map[string]int
}
func DailySummaryToExport(summary DailySummary) DailySummaryExport {
export := DailySummaryExport{
TotalRequest: summary.TotalRequest,
ErrorRequest: summary.ErrorRequest,
ValidRequest: summary.ValidRequest,
ForwardTypes: make(map[string]int),
RequestOrigin: make(map[string]int),
RequestClientIp: make(map[string]int),
}
summary.ForwardTypes.Range(func(key, value interface{}) bool {
export.ForwardTypes[key.(string)] = value.(int)
return true
})
summary.RequestOrigin.Range(func(key, value interface{}) bool {
export.RequestOrigin[key.(string)] = value.(int)
return true
})
summary.RequestClientIp.Range(func(key, value interface{}) bool {
export.RequestClientIp[key.(string)] = value.(int)
return true
})
return export
}
func DailySummaryExportToSummary(export DailySummaryExport) DailySummary {
summary := DailySummary{
TotalRequest: export.TotalRequest,
ErrorRequest: export.ErrorRequest,
ValidRequest: export.ValidRequest,
ForwardTypes: &sync.Map{},
RequestOrigin: &sync.Map{},
RequestClientIp: &sync.Map{},
}
for k, v := range export.ForwardTypes {
summary.ForwardTypes.Store(k, v)
}
for k, v := range export.RequestOrigin {
summary.RequestOrigin.Store(k, v)
}
for k, v := range export.RequestClientIp {
summary.RequestClientIp.Store(k, v)
}
return summary
}