2021-01-25 16:40:31 +08:00
|
|
|
|
package stats
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2022-08-21 20:37:49 +08:00
|
|
|
|
iplib "github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
2021-07-06 20:06:57 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
2021-01-25 16:40:31 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
2021-01-26 18:42:46 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/events"
|
2021-12-08 15:17:45 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/goman"
|
2021-07-06 20:06:57 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/monitor"
|
2021-01-25 16:40:31 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
|
|
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/rpc"
|
2021-11-14 10:55:09 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/trackers"
|
2022-01-05 16:05:58 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
2022-12-22 11:38:59 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/utils/agents"
|
2021-07-18 15:51:49 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/waf"
|
2021-01-25 16:40:31 +08:00
|
|
|
|
"github.com/iwind/TeaGo/Tea"
|
2021-07-06 20:06:57 +08:00
|
|
|
|
"github.com/iwind/TeaGo/maps"
|
2021-01-25 16:40:31 +08:00
|
|
|
|
"github.com/iwind/TeaGo/types"
|
|
|
|
|
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
2023-03-11 11:21:03 +08:00
|
|
|
|
"sort"
|
2021-01-25 16:40:31 +08:00
|
|
|
|
"strconv"
|
|
|
|
|
|
"strings"
|
2023-03-12 12:19:25 +08:00
|
|
|
|
"sync"
|
2021-01-25 16:40:31 +08:00
|
|
|
|
"time"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2021-12-05 18:57:30 +08:00
|
|
|
|
type StatItem struct {
|
|
|
|
|
|
Bytes int64
|
|
|
|
|
|
CountRequests int64
|
|
|
|
|
|
CountAttackRequests int64
|
|
|
|
|
|
AttackBytes int64
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-01-25 16:40:31 +08:00
|
|
|
|
var SharedHTTPRequestStatManager = NewHTTPRequestStatManager()
|
|
|
|
|
|
|
2021-06-23 13:14:37 +08:00
|
|
|
|
// HTTPRequestStatManager HTTP请求相关的统计
|
2021-01-25 16:40:31 +08:00
|
|
|
|
// 这里的统计是一个辅助统计,注意不要因为统计而影响服务工作性能
|
|
|
|
|
|
type HTTPRequestStatManager struct {
|
2021-01-26 18:42:46 +08:00
|
|
|
|
ipChan chan string
|
|
|
|
|
|
userAgentChan chan string
|
|
|
|
|
|
firewallRuleGroupChan chan string
|
2021-01-25 16:40:31 +08:00
|
|
|
|
|
2021-12-05 18:57:30 +08:00
|
|
|
|
cityMap map[string]*StatItem // serverId@country@province@city => *StatItem ,不需要加锁,因为我们是使用channel依次执行的
|
|
|
|
|
|
providerMap map[string]int64 // serverId@provider => count
|
|
|
|
|
|
systemMap map[string]int64 // serverId@system@version => count
|
|
|
|
|
|
browserMap map[string]int64 // serverId@browser@version => count
|
2021-01-26 18:42:46 +08:00
|
|
|
|
|
|
|
|
|
|
dailyFirewallRuleGroupMap map[string]int64 // serverId@firewallRuleGroupId@action => count
|
2021-07-06 20:06:57 +08:00
|
|
|
|
|
2023-03-12 12:19:25 +08:00
|
|
|
|
serverCityCountMap map[string]int16 // serverIdString => count cities
|
|
|
|
|
|
serverSystemCountMap map[string]int16 // serverIdString => count systems
|
|
|
|
|
|
serverBrowserCountMap map[string]int16 // serverIdString => count browsers
|
|
|
|
|
|
|
2021-07-06 20:06:57 +08:00
|
|
|
|
totalAttackRequests int64
|
2023-03-12 12:19:25 +08:00
|
|
|
|
|
|
|
|
|
|
locker sync.Mutex
|
2021-01-25 16:40:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-23 13:14:37 +08:00
|
|
|
|
// NewHTTPRequestStatManager 获取新对象
|
2021-01-25 16:40:31 +08:00
|
|
|
|
func NewHTTPRequestStatManager() *HTTPRequestStatManager {
|
|
|
|
|
|
return &HTTPRequestStatManager{
|
2021-01-26 18:42:46 +08:00
|
|
|
|
ipChan: make(chan string, 10_000), // TODO 将来可以配置容量
|
|
|
|
|
|
userAgentChan: make(chan string, 10_000), // TODO 将来可以配置容量
|
|
|
|
|
|
firewallRuleGroupChan: make(chan string, 10_000), // TODO 将来可以配置容量
|
2021-12-05 18:57:30 +08:00
|
|
|
|
cityMap: map[string]*StatItem{},
|
2021-07-05 11:36:50 +08:00
|
|
|
|
providerMap: map[string]int64{},
|
|
|
|
|
|
systemMap: map[string]int64{},
|
|
|
|
|
|
browserMap: map[string]int64{},
|
2021-01-26 18:42:46 +08:00
|
|
|
|
dailyFirewallRuleGroupMap: map[string]int64{},
|
2023-03-12 12:19:25 +08:00
|
|
|
|
|
|
|
|
|
|
serverCityCountMap: map[string]int16{},
|
|
|
|
|
|
serverSystemCountMap: map[string]int16{},
|
|
|
|
|
|
serverBrowserCountMap: map[string]int16{},
|
2021-01-25 16:40:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-23 13:14:37 +08:00
|
|
|
|
// Start 启动
|
2021-01-25 16:40:31 +08:00
|
|
|
|
func (this *HTTPRequestStatManager) Start() {
|
2021-07-06 20:06:57 +08:00
|
|
|
|
// 上传请求总数
|
2022-01-12 20:31:04 +08:00
|
|
|
|
var monitorTicker = time.NewTicker(1 * time.Minute)
|
|
|
|
|
|
events.OnKey(events.EventQuit, this, func() {
|
|
|
|
|
|
monitorTicker.Stop()
|
|
|
|
|
|
})
|
2021-12-08 15:17:45 +08:00
|
|
|
|
goman.New(func() {
|
2022-01-12 20:31:04 +08:00
|
|
|
|
for range monitorTicker.C {
|
|
|
|
|
|
if this.totalAttackRequests > 0 {
|
|
|
|
|
|
monitor.SharedValueQueue.Add(nodeconfigs.NodeValueItemAttackRequests, maps.Map{"total": this.totalAttackRequests})
|
|
|
|
|
|
this.totalAttackRequests = 0
|
2021-07-06 20:06:57 +08:00
|
|
|
|
}
|
2022-01-12 20:31:04 +08:00
|
|
|
|
}
|
2021-12-08 15:17:45 +08:00
|
|
|
|
})
|
2021-07-06 20:06:57 +08:00
|
|
|
|
|
2022-01-12 20:31:04 +08:00
|
|
|
|
var uploadTicker = time.NewTicker(30 * time.Minute)
|
2021-01-25 16:40:31 +08:00
|
|
|
|
if Tea.IsTesting() {
|
2021-01-26 18:42:46 +08:00
|
|
|
|
uploadTicker = time.NewTicker(10 * time.Second) // 在测试环境下缩短Ticker时间,以方便我们调试
|
2021-01-25 16:40:31 +08:00
|
|
|
|
}
|
2021-01-26 18:42:46 +08:00
|
|
|
|
remotelogs.Println("HTTP_REQUEST_STAT_MANAGER", "start ...")
|
2022-01-12 20:31:04 +08:00
|
|
|
|
events.OnKey(events.EventQuit, this, func() {
|
2021-01-26 18:42:46 +08:00
|
|
|
|
remotelogs.Println("HTTP_REQUEST_STAT_MANAGER", "quit")
|
|
|
|
|
|
uploadTicker.Stop()
|
|
|
|
|
|
})
|
2023-03-12 12:19:25 +08:00
|
|
|
|
|
|
|
|
|
|
// 上传Ticker
|
|
|
|
|
|
goman.New(func() {
|
|
|
|
|
|
for range uploadTicker.C {
|
2021-11-14 10:55:09 +08:00
|
|
|
|
var tr = trackers.Begin("UPLOAD_REQUEST_STATS")
|
2021-01-25 16:40:31 +08:00
|
|
|
|
err := this.Upload()
|
2021-11-14 10:55:09 +08:00
|
|
|
|
tr.End()
|
2021-01-25 16:40:31 +08:00
|
|
|
|
if err != nil {
|
2021-11-10 21:51:56 +08:00
|
|
|
|
if !rpc.IsConnError(err) {
|
|
|
|
|
|
remotelogs.Error("HTTP_REQUEST_STAT_MANAGER", "upload failed: "+err.Error())
|
|
|
|
|
|
} else {
|
|
|
|
|
|
remotelogs.Warn("HTTP_REQUEST_STAT_MANAGER", "upload failed: "+err.Error())
|
|
|
|
|
|
}
|
2021-01-25 16:40:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2023-03-12 12:19:25 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 分析Ticker
|
|
|
|
|
|
for {
|
|
|
|
|
|
err := this.Loop()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
if rpc.IsConnError(err) {
|
|
|
|
|
|
remotelogs.Warn("HTTP_REQUEST_STAT_MANAGER", err.Error())
|
|
|
|
|
|
} else {
|
|
|
|
|
|
remotelogs.Error("HTTP_REQUEST_STAT_MANAGER", err.Error())
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2021-01-25 16:40:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-23 13:14:37 +08:00
|
|
|
|
// AddRemoteAddr 添加客户端地址
|
2021-12-05 18:57:30 +08:00
|
|
|
|
func (this *HTTPRequestStatManager) AddRemoteAddr(serverId int64, remoteAddr string, bytes int64, isAttack bool) {
|
2021-01-25 16:40:31 +08:00
|
|
|
|
if len(remoteAddr) == 0 {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
if remoteAddr[0] == '[' { // 排除IPv6
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2022-07-05 20:37:00 +08:00
|
|
|
|
var index = strings.Index(remoteAddr, ":")
|
2021-01-25 16:40:31 +08:00
|
|
|
|
var ip string
|
|
|
|
|
|
if index < 0 {
|
|
|
|
|
|
ip = remoteAddr
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ip = remoteAddr[:index]
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(ip) > 0 {
|
2021-12-05 18:57:30 +08:00
|
|
|
|
var s string
|
|
|
|
|
|
if isAttack {
|
|
|
|
|
|
s = strconv.FormatInt(serverId, 10) + "@" + ip + "@" + types.String(bytes) + "@1"
|
|
|
|
|
|
} else {
|
|
|
|
|
|
s = strconv.FormatInt(serverId, 10) + "@" + ip + "@" + types.String(bytes) + "@0"
|
|
|
|
|
|
}
|
2021-01-25 16:40:31 +08:00
|
|
|
|
select {
|
2021-12-05 18:57:30 +08:00
|
|
|
|
case this.ipChan <- s:
|
2021-01-25 16:40:31 +08:00
|
|
|
|
default:
|
|
|
|
|
|
// 超出容量我们就丢弃
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-23 13:14:37 +08:00
|
|
|
|
// AddUserAgent 添加UserAgent
|
2022-12-22 11:38:59 +08:00
|
|
|
|
func (this *HTTPRequestStatManager) AddUserAgent(serverId int64, userAgent string, ip string) {
|
2023-03-12 12:19:25 +08:00
|
|
|
|
if len(userAgent) == 0 || strings.ContainsRune(userAgent, '@') /** 非常重要,防止后面组合字符串时出现异常 **/ {
|
2021-01-25 16:40:31 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-12-22 11:38:59 +08:00
|
|
|
|
// 是否包含一些知名Agent
|
|
|
|
|
|
if len(userAgent) > 0 && len(ip) > 0 && agents.IsAgentFromUserAgent(userAgent) {
|
|
|
|
|
|
agents.SharedQueue.Push(ip)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-01-25 16:40:31 +08:00
|
|
|
|
select {
|
|
|
|
|
|
case this.userAgentChan <- strconv.FormatInt(serverId, 10) + "@" + userAgent:
|
|
|
|
|
|
default:
|
|
|
|
|
|
// 超出容量我们就丢弃
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-23 13:14:37 +08:00
|
|
|
|
// AddFirewallRuleGroupId 添加防火墙拦截动作
|
2021-07-18 15:51:49 +08:00
|
|
|
|
func (this *HTTPRequestStatManager) AddFirewallRuleGroupId(serverId int64, firewallRuleGroupId int64, actions []*waf.ActionConfig) {
|
2021-01-26 18:42:46 +08:00
|
|
|
|
if firewallRuleGroupId <= 0 {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2021-07-06 20:06:57 +08:00
|
|
|
|
|
2021-07-18 15:51:49 +08:00
|
|
|
|
this.totalAttackRequests++
|
2021-07-06 20:06:57 +08:00
|
|
|
|
|
2021-07-18 15:51:49 +08:00
|
|
|
|
for _, action := range actions {
|
|
|
|
|
|
select {
|
|
|
|
|
|
case this.firewallRuleGroupChan <- strconv.FormatInt(serverId, 10) + "@" + strconv.FormatInt(firewallRuleGroupId, 10) + "@" + action.Code:
|
|
|
|
|
|
default:
|
|
|
|
|
|
// 超出容量我们就丢弃
|
|
|
|
|
|
}
|
2021-01-26 18:42:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-23 13:14:37 +08:00
|
|
|
|
// Loop 单个循环
|
2021-01-25 16:40:31 +08:00
|
|
|
|
func (this *HTTPRequestStatManager) Loop() error {
|
2023-03-12 12:19:25 +08:00
|
|
|
|
select {
|
|
|
|
|
|
case ipString := <-this.ipChan:
|
|
|
|
|
|
// serverId@ip@bytes@isAttack
|
|
|
|
|
|
var pieces = strings.Split(ipString, "@")
|
|
|
|
|
|
if len(pieces) < 4 {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
var serverId = pieces[0]
|
|
|
|
|
|
var ip = pieces[1]
|
|
|
|
|
|
|
|
|
|
|
|
var result = iplib.LookupIP(ip)
|
|
|
|
|
|
if result != nil && result.IsOk() {
|
|
|
|
|
|
var key = serverId + "@" + types.String(result.CountryId()) + "@" + types.String(result.ProvinceId()) + "@" + types.String(result.CityId())
|
|
|
|
|
|
this.locker.Lock()
|
|
|
|
|
|
stat, ok := this.cityMap[key]
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
// 检查数量
|
|
|
|
|
|
if this.serverCityCountMap[key] > 128 { // 限制单个服务的城市数量,防止数量过多
|
|
|
|
|
|
this.locker.Unlock()
|
|
|
|
|
|
return nil
|
2022-08-21 20:37:49 +08:00
|
|
|
|
}
|
2023-03-12 12:19:25 +08:00
|
|
|
|
this.serverCityCountMap[key]++ // 需要放在限制之后,因为使用的是int16
|
2022-08-21 20:37:49 +08:00
|
|
|
|
|
2023-03-12 12:19:25 +08:00
|
|
|
|
stat = &StatItem{}
|
|
|
|
|
|
this.cityMap[key] = stat
|
|
|
|
|
|
}
|
|
|
|
|
|
stat.Bytes += types.Int64(pieces[2])
|
|
|
|
|
|
stat.CountRequests++
|
|
|
|
|
|
if types.Int8(pieces[3]) == 1 {
|
|
|
|
|
|
stat.AttackBytes += types.Int64(pieces[2])
|
|
|
|
|
|
stat.CountAttackRequests++
|
2021-01-25 16:40:31 +08:00
|
|
|
|
}
|
2022-08-21 20:37:49 +08:00
|
|
|
|
|
2023-03-12 12:19:25 +08:00
|
|
|
|
if result.ProviderId() > 0 {
|
|
|
|
|
|
this.providerMap[serverId+"@"+types.String(result.ProviderId())]++
|
2021-01-25 16:40:31 +08:00
|
|
|
|
}
|
2023-03-12 12:19:25 +08:00
|
|
|
|
this.locker.Unlock()
|
|
|
|
|
|
}
|
|
|
|
|
|
case userAgentString := <-this.userAgentChan:
|
|
|
|
|
|
var atIndex = strings.Index(userAgentString, "@")
|
|
|
|
|
|
if atIndex < 0 {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
var serverId = userAgentString[:atIndex]
|
|
|
|
|
|
var userAgent = userAgentString[atIndex+1:]
|
|
|
|
|
|
|
|
|
|
|
|
var result = SharedUserAgentParser.Parse(userAgent)
|
|
|
|
|
|
var osInfo = result.OS
|
|
|
|
|
|
if len(osInfo.Name) > 0 {
|
|
|
|
|
|
dotIndex := strings.Index(osInfo.Version, ".")
|
|
|
|
|
|
if dotIndex > -1 {
|
|
|
|
|
|
osInfo.Version = osInfo.Version[:dotIndex]
|
|
|
|
|
|
}
|
|
|
|
|
|
this.locker.Lock()
|
|
|
|
|
|
|
|
|
|
|
|
var systemKey = serverId + "@" + osInfo.Name + "@" + osInfo.Version
|
|
|
|
|
|
_, ok := this.systemMap[systemKey]
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
if this.serverSystemCountMap[serverId] < 128 { // 限制最大数据,防止攻击
|
|
|
|
|
|
this.serverSystemCountMap[serverId]++
|
|
|
|
|
|
ok = true
|
2023-03-11 11:58:05 +08:00
|
|
|
|
}
|
2021-01-25 16:40:31 +08:00
|
|
|
|
}
|
2023-03-12 12:19:25 +08:00
|
|
|
|
if ok {
|
|
|
|
|
|
this.systemMap[systemKey]++
|
|
|
|
|
|
}
|
|
|
|
|
|
this.locker.Unlock()
|
|
|
|
|
|
}
|
2021-01-25 16:40:31 +08:00
|
|
|
|
|
2023-03-12 12:19:25 +08:00
|
|
|
|
var browser, browserVersion = result.BrowserName, result.BrowserVersion
|
|
|
|
|
|
if len(browser) > 0 {
|
|
|
|
|
|
dotIndex := strings.Index(browserVersion, ".")
|
|
|
|
|
|
if dotIndex > -1 {
|
|
|
|
|
|
browserVersion = browserVersion[:dotIndex]
|
|
|
|
|
|
}
|
|
|
|
|
|
this.locker.Lock()
|
|
|
|
|
|
|
|
|
|
|
|
var browserKey = serverId + "@" + browser + "@" + browserVersion
|
|
|
|
|
|
_, ok := this.browserMap[browserKey]
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
if this.serverBrowserCountMap[serverId] < 256 { // 限制最大数据,防止攻击
|
|
|
|
|
|
this.serverBrowserCountMap[serverId]++
|
|
|
|
|
|
ok = true
|
2023-03-11 11:58:05 +08:00
|
|
|
|
}
|
2021-01-25 16:40:31 +08:00
|
|
|
|
}
|
2023-03-12 12:19:25 +08:00
|
|
|
|
if ok {
|
|
|
|
|
|
this.browserMap[browserKey]++
|
|
|
|
|
|
}
|
|
|
|
|
|
this.locker.Unlock()
|
2021-01-25 16:40:31 +08:00
|
|
|
|
}
|
2023-03-12 12:19:25 +08:00
|
|
|
|
case firewallRuleGroupString := <-this.firewallRuleGroupChan:
|
|
|
|
|
|
this.locker.Lock()
|
|
|
|
|
|
this.dailyFirewallRuleGroupMap[firewallRuleGroupString]++
|
|
|
|
|
|
this.locker.Unlock()
|
2021-01-25 16:40:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-06-23 13:14:37 +08:00
|
|
|
|
// Upload 上传数据
|
2021-01-25 16:40:31 +08:00
|
|
|
|
func (this *HTTPRequestStatManager) Upload() error {
|
|
|
|
|
|
// 上传统计数据
|
|
|
|
|
|
rpcClient, err := rpc.SharedRPC()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-12 12:19:25 +08:00
|
|
|
|
// 拷贝数据
|
|
|
|
|
|
this.locker.Lock()
|
|
|
|
|
|
var cityMap = this.cityMap
|
|
|
|
|
|
var providerMap = this.providerMap
|
|
|
|
|
|
var systemMap = this.systemMap
|
|
|
|
|
|
var browserMap = this.browserMap
|
|
|
|
|
|
var dailyFirewallRuleGroupMap = this.dailyFirewallRuleGroupMap
|
|
|
|
|
|
|
|
|
|
|
|
this.cityMap = map[string]*StatItem{}
|
|
|
|
|
|
this.providerMap = map[string]int64{}
|
|
|
|
|
|
this.systemMap = map[string]int64{}
|
|
|
|
|
|
this.browserMap = map[string]int64{}
|
|
|
|
|
|
this.dailyFirewallRuleGroupMap = map[string]int64{}
|
|
|
|
|
|
|
|
|
|
|
|
this.serverCityCountMap = map[string]int16{}
|
|
|
|
|
|
this.serverSystemCountMap = map[string]int16{}
|
|
|
|
|
|
this.serverBrowserCountMap = map[string]int16{}
|
|
|
|
|
|
|
|
|
|
|
|
this.locker.Unlock()
|
|
|
|
|
|
|
2023-03-11 11:21:03 +08:00
|
|
|
|
// 上传限制
|
2023-03-12 12:19:25 +08:00
|
|
|
|
var maxCities int16 = 32
|
|
|
|
|
|
var maxProviders int16 = 32
|
|
|
|
|
|
var maxSystems int16 = 64
|
|
|
|
|
|
var maxBrowsers int16 = 64
|
2023-03-11 11:21:03 +08:00
|
|
|
|
nodeConfig, _ := nodeconfigs.SharedNodeConfig()
|
|
|
|
|
|
if nodeConfig != nil {
|
|
|
|
|
|
var serverConfig = nodeConfig.GlobalServerConfig // 复制是为了防止在中途修改
|
|
|
|
|
|
if serverConfig != nil {
|
|
|
|
|
|
var uploadConfig = serverConfig.Stat.Upload
|
|
|
|
|
|
if uploadConfig.MaxCities > 0 {
|
|
|
|
|
|
maxCities = uploadConfig.MaxCities
|
|
|
|
|
|
}
|
|
|
|
|
|
if uploadConfig.MaxProviders > 0 {
|
|
|
|
|
|
maxProviders = uploadConfig.MaxProviders
|
|
|
|
|
|
}
|
|
|
|
|
|
if uploadConfig.MaxSystems > 0 {
|
|
|
|
|
|
maxSystems = uploadConfig.MaxSystems
|
|
|
|
|
|
}
|
|
|
|
|
|
if uploadConfig.MaxBrowsers > 0 {
|
|
|
|
|
|
maxBrowsers = uploadConfig.MaxBrowsers
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-05 20:37:00 +08:00
|
|
|
|
var pbCities = []*pb.UploadServerHTTPRequestStatRequest_RegionCity{}
|
|
|
|
|
|
var pbProviders = []*pb.UploadServerHTTPRequestStatRequest_RegionProvider{}
|
|
|
|
|
|
var pbSystems = []*pb.UploadServerHTTPRequestStatRequest_System{}
|
|
|
|
|
|
var pbBrowsers = []*pb.UploadServerHTTPRequestStatRequest_Browser{}
|
2023-03-11 11:21:03 +08:00
|
|
|
|
|
|
|
|
|
|
// 城市
|
2023-03-12 12:19:25 +08:00
|
|
|
|
for k, stat := range cityMap {
|
2022-07-05 20:37:00 +08:00
|
|
|
|
var pieces = strings.SplitN(k, "@", 4)
|
2023-03-11 11:21:03 +08:00
|
|
|
|
var serverId = types.Int64(pieces[0])
|
2021-01-25 16:40:31 +08:00
|
|
|
|
pbCities = append(pbCities, &pb.UploadServerHTTPRequestStatRequest_RegionCity{
|
2023-03-11 11:21:03 +08:00
|
|
|
|
ServerId: serverId,
|
2023-03-12 12:19:25 +08:00
|
|
|
|
CountryId: types.Int64(pieces[1]),
|
|
|
|
|
|
ProvinceId: types.Int64(pieces[2]),
|
|
|
|
|
|
CityId: types.Int64(pieces[3]),
|
2021-12-05 18:57:30 +08:00
|
|
|
|
CountRequests: stat.CountRequests,
|
|
|
|
|
|
CountAttackRequests: stat.CountAttackRequests,
|
|
|
|
|
|
Bytes: stat.Bytes,
|
|
|
|
|
|
AttackBytes: stat.AttackBytes,
|
2021-01-25 16:40:31 +08:00
|
|
|
|
})
|
|
|
|
|
|
}
|
2023-03-12 12:19:25 +08:00
|
|
|
|
if len(cityMap) > int(maxCities) {
|
2023-03-11 11:21:03 +08:00
|
|
|
|
var newPBCities = []*pb.UploadServerHTTPRequestStatRequest_RegionCity{}
|
|
|
|
|
|
sort.Slice(pbCities, func(i, j int) bool {
|
|
|
|
|
|
return pbCities[i].CountRequests > pbCities[j].CountRequests
|
|
|
|
|
|
})
|
|
|
|
|
|
var serverCountMap = map[int64]int16{}
|
|
|
|
|
|
for _, city := range pbCities {
|
|
|
|
|
|
serverCountMap[city.ServerId]++
|
|
|
|
|
|
if serverCountMap[city.ServerId] > maxCities {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
newPBCities = append(newPBCities, city)
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(pbCities) != len(newPBCities) {
|
|
|
|
|
|
pbCities = newPBCities
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 运营商
|
2023-03-12 12:19:25 +08:00
|
|
|
|
for k, count := range providerMap {
|
2022-07-05 20:37:00 +08:00
|
|
|
|
var pieces = strings.SplitN(k, "@", 2)
|
2023-03-11 11:21:03 +08:00
|
|
|
|
var serverId = types.Int64(pieces[0])
|
2021-01-25 16:40:31 +08:00
|
|
|
|
pbProviders = append(pbProviders, &pb.UploadServerHTTPRequestStatRequest_RegionProvider{
|
2023-03-12 12:19:25 +08:00
|
|
|
|
ServerId: serverId,
|
|
|
|
|
|
ProviderId: types.Int64(pieces[1]),
|
|
|
|
|
|
Count: count,
|
2021-01-25 16:40:31 +08:00
|
|
|
|
})
|
|
|
|
|
|
}
|
2023-03-12 12:19:25 +08:00
|
|
|
|
if len(providerMap) > int(maxProviders) {
|
2023-03-11 11:21:03 +08:00
|
|
|
|
var newPBProviders = []*pb.UploadServerHTTPRequestStatRequest_RegionProvider{}
|
|
|
|
|
|
sort.Slice(pbProviders, func(i, j int) bool {
|
|
|
|
|
|
return pbProviders[i].Count > pbProviders[j].Count
|
|
|
|
|
|
})
|
|
|
|
|
|
var serverCountMap = map[int64]int16{}
|
|
|
|
|
|
for _, provider := range pbProviders {
|
|
|
|
|
|
serverCountMap[provider.ServerId]++
|
|
|
|
|
|
if serverCountMap[provider.ServerId] > maxProviders {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
newPBProviders = append(newPBProviders, provider)
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(pbProviders) != len(newPBProviders) {
|
|
|
|
|
|
pbProviders = newPBProviders
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 操作系统
|
2023-03-12 12:19:25 +08:00
|
|
|
|
for k, count := range systemMap {
|
2022-07-05 20:37:00 +08:00
|
|
|
|
var pieces = strings.SplitN(k, "@", 3)
|
2023-03-11 11:21:03 +08:00
|
|
|
|
var serverId = types.Int64(pieces[0])
|
2021-01-25 16:40:31 +08:00
|
|
|
|
pbSystems = append(pbSystems, &pb.UploadServerHTTPRequestStatRequest_System{
|
2023-03-11 11:21:03 +08:00
|
|
|
|
ServerId: serverId,
|
2021-01-25 16:40:31 +08:00
|
|
|
|
Name: pieces[1],
|
|
|
|
|
|
Version: pieces[2],
|
|
|
|
|
|
Count: count,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
2023-03-12 12:19:25 +08:00
|
|
|
|
if len(systemMap) > int(maxSystems) {
|
2023-03-11 11:21:03 +08:00
|
|
|
|
var newPBSystems = []*pb.UploadServerHTTPRequestStatRequest_System{}
|
|
|
|
|
|
sort.Slice(pbSystems, func(i, j int) bool {
|
|
|
|
|
|
return pbSystems[i].Count > pbSystems[j].Count
|
|
|
|
|
|
})
|
|
|
|
|
|
var serverCountMap = map[int64]int16{}
|
|
|
|
|
|
for _, system := range pbSystems {
|
|
|
|
|
|
serverCountMap[system.ServerId]++
|
|
|
|
|
|
if serverCountMap[system.ServerId] > maxSystems {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
newPBSystems = append(newPBSystems, system)
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(pbSystems) != len(newPBSystems) {
|
|
|
|
|
|
pbSystems = newPBSystems
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 浏览器
|
2023-03-12 12:19:25 +08:00
|
|
|
|
for k, count := range browserMap {
|
2022-07-05 20:37:00 +08:00
|
|
|
|
var pieces = strings.SplitN(k, "@", 3)
|
2023-03-11 11:21:03 +08:00
|
|
|
|
var serverId = types.Int64(pieces[0])
|
2021-01-25 16:40:31 +08:00
|
|
|
|
pbBrowsers = append(pbBrowsers, &pb.UploadServerHTTPRequestStatRequest_Browser{
|
2023-03-11 11:21:03 +08:00
|
|
|
|
ServerId: serverId,
|
2021-01-25 16:40:31 +08:00
|
|
|
|
Name: pieces[1],
|
|
|
|
|
|
Version: pieces[2],
|
|
|
|
|
|
Count: count,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
2023-03-12 12:19:25 +08:00
|
|
|
|
if len(browserMap) > int(maxBrowsers) {
|
2023-03-11 11:21:03 +08:00
|
|
|
|
var newPBBrowsers = []*pb.UploadServerHTTPRequestStatRequest_Browser{}
|
|
|
|
|
|
sort.Slice(pbBrowsers, func(i, j int) bool {
|
|
|
|
|
|
return pbBrowsers[i].Count > pbBrowsers[j].Count
|
|
|
|
|
|
})
|
|
|
|
|
|
var serverCountMap = map[int64]int16{}
|
|
|
|
|
|
for _, browser := range pbBrowsers {
|
|
|
|
|
|
serverCountMap[browser.ServerId]++
|
|
|
|
|
|
if serverCountMap[browser.ServerId] > maxBrowsers {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
newPBBrowsers = append(newPBBrowsers, browser)
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(pbBrowsers) != len(newPBBrowsers) {
|
|
|
|
|
|
pbBrowsers = newPBBrowsers
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2021-01-25 16:40:31 +08:00
|
|
|
|
|
2021-01-26 18:42:46 +08:00
|
|
|
|
// 防火墙相关
|
2022-07-05 20:37:00 +08:00
|
|
|
|
var pbFirewallRuleGroups = []*pb.UploadServerHTTPRequestStatRequest_HTTPFirewallRuleGroup{}
|
2023-03-12 12:19:25 +08:00
|
|
|
|
for k, count := range dailyFirewallRuleGroupMap {
|
2022-07-05 20:37:00 +08:00
|
|
|
|
var pieces = strings.SplitN(k, "@", 3)
|
2021-01-26 18:42:46 +08:00
|
|
|
|
pbFirewallRuleGroups = append(pbFirewallRuleGroups, &pb.UploadServerHTTPRequestStatRequest_HTTPFirewallRuleGroup{
|
|
|
|
|
|
ServerId: types.Int64(pieces[0]),
|
|
|
|
|
|
HttpFirewallRuleGroupId: types.Int64(pieces[1]),
|
|
|
|
|
|
Action: pieces[2],
|
|
|
|
|
|
Count: count,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-11 11:21:03 +08:00
|
|
|
|
// 检查是否有数据
|
|
|
|
|
|
if len(pbCities) == 0 &&
|
|
|
|
|
|
len(pbProviders) == 0 &&
|
|
|
|
|
|
len(pbSystems) == 0 &&
|
|
|
|
|
|
len(pbBrowsers) == 0 &&
|
|
|
|
|
|
len(pbFirewallRuleGroups) == 0 {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-01-05 16:05:58 +08:00
|
|
|
|
// 上传数据
|
2022-08-24 20:04:46 +08:00
|
|
|
|
_, err = rpcClient.ServerRPC.UploadServerHTTPRequestStat(rpcClient.Context(), &pb.UploadServerHTTPRequestStatRequest{
|
2021-01-26 18:42:46 +08:00
|
|
|
|
Month: timeutil.Format("Ym"),
|
|
|
|
|
|
Day: timeutil.Format("Ymd"),
|
|
|
|
|
|
RegionCities: pbCities,
|
|
|
|
|
|
RegionProviders: pbProviders,
|
|
|
|
|
|
Systems: pbSystems,
|
|
|
|
|
|
Browsers: pbBrowsers,
|
|
|
|
|
|
HttpFirewallRuleGroups: pbFirewallRuleGroups,
|
2021-01-25 16:40:31 +08:00
|
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
2022-01-05 16:05:58 +08:00
|
|
|
|
// 是否包含了invalid UTF-8
|
|
|
|
|
|
if strings.Contains(err.Error(), "string field contains invalid UTF-8") {
|
|
|
|
|
|
for _, system := range pbSystems {
|
|
|
|
|
|
system.Name = utils.ToValidUTF8string(system.Name)
|
2022-07-20 16:12:46 +08:00
|
|
|
|
system.Version = utils.ToValidUTF8string(system.Version)
|
2022-01-05 16:05:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
for _, browser := range pbBrowsers {
|
|
|
|
|
|
browser.Name = utils.ToValidUTF8string(browser.Name)
|
2022-07-20 16:12:46 +08:00
|
|
|
|
browser.Version = utils.ToValidUTF8string(browser.Version)
|
2022-01-05 16:05:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 再次尝试
|
2022-08-24 20:04:46 +08:00
|
|
|
|
_, err = rpcClient.ServerRPC.UploadServerHTTPRequestStat(rpcClient.Context(), &pb.UploadServerHTTPRequestStatRequest{
|
2022-01-05 16:05:58 +08:00
|
|
|
|
Month: timeutil.Format("Ym"),
|
|
|
|
|
|
Day: timeutil.Format("Ymd"),
|
|
|
|
|
|
RegionCities: pbCities,
|
|
|
|
|
|
RegionProviders: pbProviders,
|
|
|
|
|
|
Systems: pbSystems,
|
|
|
|
|
|
Browsers: pbBrowsers,
|
|
|
|
|
|
HttpFirewallRuleGroups: pbFirewallRuleGroups,
|
|
|
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2021-01-25 16:40:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|