实现基础的统计指标

This commit is contained in:
GoEdgeLab
2021-06-30 20:01:00 +08:00
parent 82d21cee0d
commit 7ca9c3a22c
15 changed files with 948 additions and 3 deletions

View File

@@ -7,6 +7,7 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
"github.com/TeaOSLab/EdgeNode/internal/metrics"
"github.com/TeaOSLab/EdgeNode/internal/stats"
"github.com/TeaOSLab/EdgeNode/internal/utils"
"github.com/iwind/TeaGo/types"
@@ -247,6 +248,11 @@ func (this *HTTPRequest) doEnd() {
stats.SharedTrafficStatManager.Add(this.Server.Id, this.writer.sentBodyBytes, 0, 1, 0)
}
}
// 指标
if metrics.SharedManager.HasHTTPMetrics() {
this.doMetricsResponse()
}
}
// RawURI 原始的请求URI

View File

@@ -0,0 +1,58 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package nodes
import (
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeNode/internal/metrics"
)
// 指标统计 - 响应
// 只需要在结束时调用指标进行统计
func (this *HTTPRequest) doMetricsResponse() {
metrics.SharedManager.Add(this)
}
func (this *HTTPRequest) MetricKey(key string) string {
return this.Format(key)
}
func (this *HTTPRequest) MetricValue(value string) (result int64, ok bool) {
// TODO 需要忽略健康检查的请求,但是同时也要防止攻击者模拟健康检查
switch value {
case "${countRequest}":
return 1, true
case "${countTrafficOut}":
// 这里不包括Header长度
return this.writer.SentBodyBytes(), true
case "${countTrafficIn}":
var hl int64 = 0 // header length
for k, values := range this.RawReq.Header {
for _, v := range values {
hl += int64(len(k) + len(v) + 2 /** k: v **/)
}
}
return this.RawReq.ContentLength + hl, true
case "${countConnection}":
metricNewConnMapLocker.Lock()
_, ok := metricNewConnMap[this.RawReq.RemoteAddr]
if ok {
delete(metricNewConnMap, this.RawReq.RemoteAddr)
}
metricNewConnMapLocker.Unlock()
if ok {
return 1, true
} else {
return 0, false
}
}
return 0, false
}
func (this *HTTPRequest) MetricServerId() int64 {
return this.Server.Id
}
func (this *HTTPRequest) MetricCategory() string {
return serverconfigs.MetricItemCategoryHTTP
}

View File

@@ -7,6 +7,8 @@ func (this *HTTPRequest) doStat() {
if this.Server == nil {
return
}
// 内置的统计
stats.SharedHTTPRequestStatManager.AddRemoteAddr(this.Server.Id, this.requestRemoteAddr())
stats.SharedHTTPRequestStatManager.AddUserAgent(this.Server.Id, this.requestHeader("User-Agent"))
}

View File

@@ -9,11 +9,14 @@ import (
"net"
"net/http"
"strings"
"sync"
"sync/atomic"
"time"
)
var httpErrorLogger = log.New(io.Discard, "", 0)
var metricNewConnMap = map[string]bool{} // remoteAddr => bool
var metricNewConnMapLocker = &sync.Mutex{}
type HTTPListener struct {
BaseListener
@@ -39,15 +42,27 @@ func (this *HTTPListener) Serve() error {
this.httpServer = &http.Server{
Addr: this.addr,
Handler: handler,
ReadHeaderTimeout: 3 * time.Second, // TODO 改成可以配置
ReadHeaderTimeout: 2 * time.Second, // TODO 改成可以配置
IdleTimeout: 2 * time.Minute, // TODO 改成可以配置
ErrorLog: httpErrorLogger,
ConnState: func(conn net.Conn, state http.ConnState) {
switch state {
case http.StateNew:
atomic.AddInt64(&this.countActiveConnections, 1)
// 为指标存储连接信息
if sharedNodeConfig.HasHTTPConnectionMetrics() {
metricNewConnMapLocker.Lock()
metricNewConnMap[conn.RemoteAddr().String()] = true
metricNewConnMapLocker.Unlock()
}
case http.StateClosed:
atomic.AddInt64(&this.countActiveConnections, -1)
// 移除指标存储连接信息
metricNewConnMapLocker.Lock()
delete(metricNewConnMap, conn.RemoteAddr().String())
metricNewConnMapLocker.Unlock()
}
},
}

View File

@@ -12,6 +12,7 @@ import (
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
"github.com/TeaOSLab/EdgeNode/internal/events"
"github.com/TeaOSLab/EdgeNode/internal/iplibrary"
"github.com/TeaOSLab/EdgeNode/internal/metrics"
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
"github.com/TeaOSLab/EdgeNode/internal/rpc"
"github.com/TeaOSLab/EdgeNode/internal/stats"
@@ -396,6 +397,8 @@ func (this *Node) syncConfig() error {
iplibrary.SharedActionManager.UpdateActions(nodeConfig.FirewallActions)
sharedNodeConfig = nodeConfig
metrics.SharedManager.Update(nodeConfig.MetricItems)
// 发送事件
events.Notify(events.EventReload)