日常查询由mysql改为clickhouse
This commit is contained in:
16
EdgeNode/.gitignore
vendored
16
EdgeNode/.gitignore
vendored
@@ -0,0 +1,16 @@
|
||||
# Windows local development
|
||||
*_windows.go
|
||||
configs/api_node.yaml
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
# Build binaries
|
||||
bin/
|
||||
|
||||
# Runtime Data
|
||||
data/
|
||||
configs/node.json
|
||||
logs/
|
||||
opt/
|
||||
|
||||
@@ -102,7 +102,7 @@ func FromHTTPAccessLog(l *pb.HTTPAccessLog, clusterId int64) (ingest IngestLog,
|
||||
Host: l.GetHost(),
|
||||
IP: l.GetRawRemoteAddr(),
|
||||
Method: l.GetRequestMethod(),
|
||||
Path: l.GetRequestPath(),
|
||||
Path: l.GetRequestURI(), // 使用 RequestURI 以包含查询参数
|
||||
Status: l.GetStatus(),
|
||||
BytesIn: l.GetRequestLength(),
|
||||
BytesOut: l.GetBytesSent(),
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -197,10 +196,7 @@ func (this *AppCmd) runStart() {
|
||||
_ = os.Setenv("EdgeBackground", "on")
|
||||
|
||||
var cmd = exec.Command(this.exe())
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
Foreground: false,
|
||||
Setsid: true,
|
||||
}
|
||||
configureSysProcAttr(cmd)
|
||||
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
|
||||
15
EdgeNode/internal/apps/app_utils_unix.go
Normal file
15
EdgeNode/internal/apps/app_utils_unix.go
Normal file
@@ -0,0 +1,15 @@
|
||||
//go:build !windows
|
||||
|
||||
package apps
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func configureSysProcAttr(cmd *exec.Cmd) {
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
Foreground: false,
|
||||
Setsid: true,
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package caches
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
|
||||
@@ -10,7 +9,6 @@ import (
|
||||
memutils "github.com/TeaOSLab/EdgeNode/internal/utils/mem"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"golang.org/x/sys/unix"
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
@@ -191,44 +189,6 @@ func (this *Manager) StorageMap() map[int64]StorageInterface {
|
||||
return this.storageMap
|
||||
}
|
||||
|
||||
// TotalDiskSize 消耗的磁盘尺寸
|
||||
func (this *Manager) TotalDiskSize() int64 {
|
||||
this.locker.RLock()
|
||||
defer this.locker.RUnlock()
|
||||
|
||||
var total = int64(0)
|
||||
var sidMap = map[string]bool{} // partition sid => bool
|
||||
for _, storage := range this.storageMap {
|
||||
// 这里不能直接用 storage.TotalDiskSize() 相加,因为多个缓存策略缓存目录可能处在同一个分区目录下
|
||||
fileStorage, ok := storage.(*FileStorage)
|
||||
if ok {
|
||||
var options = fileStorage.options // copy
|
||||
if options != nil {
|
||||
var dir = options.Dir // copy
|
||||
if len(dir) == 0 {
|
||||
continue
|
||||
}
|
||||
var stat = &unix.Statfs_t{}
|
||||
err := unix.Statfs(dir, stat)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
var sid = fmt.Sprintf("%d_%d", stat.Fsid.Val[0], stat.Fsid.Val[1])
|
||||
if sidMap[sid] {
|
||||
continue
|
||||
}
|
||||
sidMap[sid] = true
|
||||
total += int64(stat.Blocks-stat.Bfree) * int64(stat.Bsize) // we add extra int64() for darwin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if total < 0 {
|
||||
total = 0
|
||||
}
|
||||
|
||||
return total
|
||||
}
|
||||
|
||||
// TotalMemorySize 消耗的内存尺寸
|
||||
func (this *Manager) TotalMemorySize() int64 {
|
||||
|
||||
48
EdgeNode/internal/caches/manager_unix.go
Normal file
48
EdgeNode/internal/caches/manager_unix.go
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !windows
|
||||
|
||||
package caches
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// TotalDiskSize 消耗的磁盘尺寸
|
||||
func (this *Manager) TotalDiskSize() int64 {
|
||||
this.locker.RLock()
|
||||
defer this.locker.RUnlock()
|
||||
|
||||
var total = int64(0)
|
||||
var sidMap = map[string]bool{} // partition sid => bool
|
||||
for _, storage := range this.storageMap {
|
||||
// 这里不能直接用 storage.TotalDiskSize() 相加,因为多个缓存策略缓存目录可能处在同一个分区目录下
|
||||
fileStorage, ok := storage.(*FileStorage)
|
||||
if ok {
|
||||
var options = fileStorage.options // copy
|
||||
if options != nil {
|
||||
var dir = options.Dir // copy
|
||||
if len(dir) == 0 {
|
||||
continue
|
||||
}
|
||||
var stat = &unix.Statfs_t{}
|
||||
err := unix.Statfs(dir, stat)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
var sid = fmt.Sprintf("%d_%d", stat.Fsid.Val[0], stat.Fsid.Val[1])
|
||||
if sidMap[sid] {
|
||||
continue
|
||||
}
|
||||
sidMap[sid] = true
|
||||
total += int64(stat.Blocks-stat.Bfree) * int64(stat.Bsize) // we add extra int64() for darwin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if total < 0 {
|
||||
total = 0
|
||||
}
|
||||
|
||||
return total
|
||||
}
|
||||
@@ -35,7 +35,6 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -736,7 +735,7 @@ func (this *FileStorage) openWriter(key string, expiredAt int64, status int, hea
|
||||
|
||||
// 尝试锁定,如果锁定失败,则直接返回
|
||||
fsutils.WriterLimiter.Ack()
|
||||
err = syscall.Flock(int(writer.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
|
||||
err = tryLockFile(int(writer.Fd()))
|
||||
fsutils.WriterLimiter.Release()
|
||||
if err != nil {
|
||||
removeOnFailure = false
|
||||
|
||||
9
EdgeNode/internal/caches/storage_utils_unix.go
Normal file
9
EdgeNode/internal/caches/storage_utils_unix.go
Normal file
@@ -0,0 +1,9 @@
|
||||
//go:build !windows
|
||||
|
||||
package caches
|
||||
|
||||
import "syscall"
|
||||
|
||||
func tryLockFile(fd int) error {
|
||||
return syscall.Flock(fd, syscall.LOCK_EX|syscall.LOCK_NB)
|
||||
}
|
||||
@@ -19,11 +19,8 @@ import (
|
||||
"github.com/TeaOSLab/EdgeNode/internal/utils/writers"
|
||||
_ "github.com/biessek/golang-ico"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"github.com/iwind/gowebp"
|
||||
_ "golang.org/x/image/bmp"
|
||||
_ "golang.org/x/image/webp"
|
||||
"image"
|
||||
"image/gif"
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
"io"
|
||||
@@ -1045,169 +1042,6 @@ func (this *HTTPWriter) calculateStaleLife() int {
|
||||
return staleLife
|
||||
}
|
||||
|
||||
// 结束WebP
|
||||
func (this *HTTPWriter) finishWebP() {
|
||||
// 处理WebP
|
||||
if this.webpIsEncoding {
|
||||
atomic.AddInt32(&webPThreads, 1)
|
||||
defer func() {
|
||||
atomic.AddInt32(&webPThreads, -1)
|
||||
}()
|
||||
|
||||
var webpCacheWriter caches.Writer
|
||||
|
||||
// 准备WebP Cache
|
||||
if this.cacheReader != nil || this.cacheWriter != nil {
|
||||
var cacheKey = ""
|
||||
var expiredAt int64 = 0
|
||||
|
||||
if this.cacheReader != nil {
|
||||
cacheKey = this.req.cacheKey + caches.SuffixWebP
|
||||
expiredAt = this.cacheReader.ExpiresAt()
|
||||
} else if this.cacheWriter != nil {
|
||||
cacheKey = this.cacheWriter.Key() + caches.SuffixWebP
|
||||
expiredAt = this.cacheWriter.ExpiredAt()
|
||||
}
|
||||
|
||||
webpCacheWriter, _ = this.cacheStorage.OpenWriter(cacheKey, expiredAt, this.StatusCode(), -1, -1, -1, false)
|
||||
if webpCacheWriter != nil {
|
||||
// 写入Header
|
||||
for k, v := range this.Header() {
|
||||
if this.shouldIgnoreHeader(k) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 这里是原始的数据,不需要内容编码
|
||||
if k == "Content-Encoding" || k == "Transfer-Encoding" {
|
||||
continue
|
||||
}
|
||||
for _, v1 := range v {
|
||||
_, err := webpCacheWriter.WriteHeader([]byte(k + ":" + v1 + "\n"))
|
||||
if err != nil {
|
||||
remotelogs.Error("HTTP_WRITER", "write webp cache failed: "+err.Error())
|
||||
_ = webpCacheWriter.Discard()
|
||||
webpCacheWriter = nil
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if webpCacheWriter != nil {
|
||||
var teeWriter = writers.NewTeeWriterCloser(this.writer, webpCacheWriter)
|
||||
teeWriter.OnFail(func(err error) {
|
||||
if webpCacheWriter != nil {
|
||||
_ = webpCacheWriter.Discard()
|
||||
}
|
||||
webpCacheWriter = nil
|
||||
})
|
||||
this.writer = teeWriter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var reader = readers.NewBytesCounterReader(this.rawReader)
|
||||
|
||||
var imageData image.Image
|
||||
var gifImage *gif.GIF
|
||||
var isGif = strings.Contains(this.webpOriginContentType, "image/gif")
|
||||
var err error
|
||||
if isGif {
|
||||
gifImage, err = gif.DecodeAll(reader)
|
||||
if gifImage != nil && (gifImage.Config.Width > gowebp.WebPMaxDimension || gifImage.Config.Height > gowebp.WebPMaxDimension) {
|
||||
webPIgnoreURLSet.Push(this.req.URL())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
imageData, _, err = image.Decode(reader)
|
||||
if imageData != nil {
|
||||
var bound = imageData.Bounds()
|
||||
if bound.Max.X > gowebp.WebPMaxDimension || bound.Max.Y > gowebp.WebPMaxDimension {
|
||||
webPIgnoreURLSet.Push(this.req.URL())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// 发生了错误终止处理
|
||||
webPIgnoreURLSet.Push(this.req.URL())
|
||||
return
|
||||
}
|
||||
|
||||
var f = types.Float32(this.webpQuality)
|
||||
if f <= 0 || f > 100 {
|
||||
if this.size > (8<<20) || this.size <= 0 {
|
||||
f = 30
|
||||
} else if this.size > (1 << 20) {
|
||||
f = 50
|
||||
} else if this.size > (128 << 10) {
|
||||
f = 60
|
||||
} else {
|
||||
f = 75
|
||||
}
|
||||
}
|
||||
|
||||
if imageData != nil {
|
||||
err = gowebp.Encode(this.writer, imageData, &gowebp.Options{
|
||||
Lossless: false,
|
||||
Quality: f,
|
||||
Exact: true,
|
||||
})
|
||||
} else if gifImage != nil {
|
||||
var anim = gowebp.NewWebpAnimation(gifImage.Config.Width, gifImage.Config.Height, gifImage.LoopCount)
|
||||
|
||||
anim.WebPAnimEncoderOptions.SetKmin(9)
|
||||
anim.WebPAnimEncoderOptions.SetKmax(17)
|
||||
var webpConfig = gowebp.NewWebpConfig()
|
||||
//webpConfig.SetLossless(1)
|
||||
webpConfig.SetQuality(f)
|
||||
|
||||
var timeline = 0
|
||||
var lastErr error
|
||||
for i, img := range gifImage.Image {
|
||||
err = anim.AddFrame(img, timeline, webpConfig)
|
||||
if err != nil {
|
||||
// 有错误直接跳过
|
||||
lastErr = err
|
||||
err = nil
|
||||
}
|
||||
timeline += gifImage.Delay[i] * 10
|
||||
}
|
||||
if lastErr != nil {
|
||||
remotelogs.Error("HTTP_WRITER", "'"+this.req.URL()+"' encode webp failed: "+lastErr.Error())
|
||||
}
|
||||
err = anim.AddFrame(nil, timeline, webpConfig)
|
||||
|
||||
if err == nil {
|
||||
err = anim.Encode(this.writer)
|
||||
}
|
||||
|
||||
anim.ReleaseMemory()
|
||||
}
|
||||
|
||||
if err != nil && !this.req.canIgnore(err) {
|
||||
remotelogs.Error("HTTP_WRITER", "'"+this.req.URL()+"' encode webp failed: "+err.Error())
|
||||
}
|
||||
|
||||
if err == nil && webpCacheWriter != nil {
|
||||
err = webpCacheWriter.Close()
|
||||
if err != nil {
|
||||
_ = webpCacheWriter.Discard()
|
||||
} else {
|
||||
this.cacheStorage.AddToList(&caches.Item{
|
||||
Type: webpCacheWriter.ItemType(),
|
||||
Key: webpCacheWriter.Key(),
|
||||
ExpiresAt: webpCacheWriter.ExpiredAt(),
|
||||
StaleAt: webpCacheWriter.ExpiredAt() + int64(this.calculateStaleLife()),
|
||||
HeaderSize: webpCacheWriter.HeaderSize(),
|
||||
BodySize: webpCacheWriter.BodySize(),
|
||||
Host: this.req.ReqHost,
|
||||
ServerId: this.req.ReqServer.Id,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 结束缓存相关处理
|
||||
func (this *HTTPWriter) finishCache() {
|
||||
|
||||
181
EdgeNode/internal/nodes/http_writer_ext_unix.go
Normal file
181
EdgeNode/internal/nodes/http_writer_ext_unix.go
Normal file
@@ -0,0 +1,181 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build !windows
|
||||
|
||||
package nodes
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeNode/internal/caches"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/utils/readers"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/utils/writers"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"github.com/iwind/gowebp"
|
||||
"image"
|
||||
"image/gif"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// 结束WebP
|
||||
func (this *HTTPWriter) finishWebP() {
|
||||
// 处理WebP
|
||||
if this.webpIsEncoding {
|
||||
atomic.AddInt32(&webPThreads, 1)
|
||||
defer func() {
|
||||
atomic.AddInt32(&webPThreads, -1)
|
||||
}()
|
||||
|
||||
var webpCacheWriter caches.Writer
|
||||
|
||||
// 准备WebP Cache
|
||||
if this.cacheReader != nil || this.cacheWriter != nil {
|
||||
var cacheKey = ""
|
||||
var expiredAt int64 = 0
|
||||
|
||||
if this.cacheReader != nil {
|
||||
cacheKey = this.req.cacheKey + caches.SuffixWebP
|
||||
expiredAt = this.cacheReader.ExpiresAt()
|
||||
} else if this.cacheWriter != nil {
|
||||
cacheKey = this.cacheWriter.Key() + caches.SuffixWebP
|
||||
expiredAt = this.cacheWriter.ExpiredAt()
|
||||
}
|
||||
|
||||
webpCacheWriter, _ = this.cacheStorage.OpenWriter(cacheKey, expiredAt, this.StatusCode(), -1, -1, -1, false)
|
||||
if webpCacheWriter != nil {
|
||||
// 写入Header
|
||||
for k, v := range this.Header() {
|
||||
if this.shouldIgnoreHeader(k) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 这里是原始的数据,不需要内容编码
|
||||
if k == "Content-Encoding" || k == "Transfer-Encoding" {
|
||||
continue
|
||||
}
|
||||
for _, v1 := range v {
|
||||
_, err := webpCacheWriter.WriteHeader([]byte(k + ":" + v1 + "\n"))
|
||||
if err != nil {
|
||||
remotelogs.Error("HTTP_WRITER", "write webp cache failed: "+err.Error())
|
||||
_ = webpCacheWriter.Discard()
|
||||
webpCacheWriter = nil
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if webpCacheWriter != nil {
|
||||
var teeWriter = writers.NewTeeWriterCloser(this.writer, webpCacheWriter)
|
||||
teeWriter.OnFail(func(err error) {
|
||||
if webpCacheWriter != nil {
|
||||
_ = webpCacheWriter.Discard()
|
||||
}
|
||||
webpCacheWriter = nil
|
||||
})
|
||||
this.writer = teeWriter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var reader = readers.NewBytesCounterReader(this.rawReader)
|
||||
|
||||
var imageData image.Image
|
||||
var gifImage *gif.GIF
|
||||
var isGif = strings.Contains(this.webpOriginContentType, "image/gif")
|
||||
var err error
|
||||
if isGif {
|
||||
gifImage, err = gif.DecodeAll(reader)
|
||||
if gifImage != nil && (gifImage.Config.Width > gowebp.WebPMaxDimension || gifImage.Config.Height > gowebp.WebPMaxDimension) {
|
||||
webPIgnoreURLSet.Push(this.req.URL())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
imageData, _, err = image.Decode(reader)
|
||||
if imageData != nil {
|
||||
var bound = imageData.Bounds()
|
||||
if bound.Max.X > gowebp.WebPMaxDimension || bound.Max.Y > gowebp.WebPMaxDimension {
|
||||
webPIgnoreURLSet.Push(this.req.URL())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// 发生了错误终止处理
|
||||
webPIgnoreURLSet.Push(this.req.URL())
|
||||
return
|
||||
}
|
||||
|
||||
var f = types.Float32(this.webpQuality)
|
||||
if f <= 0 || f > 100 {
|
||||
if this.size > (8<<20) || this.size <= 0 {
|
||||
f = 30
|
||||
} else if this.size > (1 << 20) {
|
||||
f = 50
|
||||
} else if this.size > (128 << 10) {
|
||||
f = 60
|
||||
} else {
|
||||
f = 75
|
||||
}
|
||||
}
|
||||
|
||||
if imageData != nil {
|
||||
err = gowebp.Encode(this.writer, imageData, &gowebp.Options{
|
||||
Lossless: false,
|
||||
Quality: f,
|
||||
Exact: true,
|
||||
})
|
||||
} else if gifImage != nil {
|
||||
var anim = gowebp.NewWebpAnimation(gifImage.Config.Width, gifImage.Config.Height, gifImage.LoopCount)
|
||||
|
||||
anim.WebPAnimEncoderOptions.SetKmin(9)
|
||||
anim.WebPAnimEncoderOptions.SetKmax(17)
|
||||
var webpConfig = gowebp.NewWebpConfig()
|
||||
//webpConfig.SetLossless(1)
|
||||
webpConfig.SetQuality(f)
|
||||
|
||||
var timeline = 0
|
||||
var lastErr error
|
||||
for i, img := range gifImage.Image {
|
||||
err = anim.AddFrame(img, timeline, webpConfig)
|
||||
if err != nil {
|
||||
// 有错误直接跳过
|
||||
lastErr = err
|
||||
err = nil
|
||||
}
|
||||
timeline += gifImage.Delay[i] * 10
|
||||
}
|
||||
if lastErr != nil {
|
||||
remotelogs.Error("HTTP_WRITER", "'"+this.req.URL()+"' encode webp failed: "+lastErr.Error())
|
||||
}
|
||||
err = anim.AddFrame(nil, timeline, webpConfig)
|
||||
|
||||
if err == nil {
|
||||
err = anim.Encode(this.writer)
|
||||
}
|
||||
|
||||
anim.ReleaseMemory()
|
||||
}
|
||||
|
||||
if err != nil && !this.req.canIgnore(err) {
|
||||
remotelogs.Error("HTTP_WRITER", "'"+this.req.URL()+"' encode webp failed: "+err.Error())
|
||||
}
|
||||
|
||||
if err == nil && webpCacheWriter != nil {
|
||||
err = webpCacheWriter.Close()
|
||||
if err != nil {
|
||||
_ = webpCacheWriter.Discard()
|
||||
} else {
|
||||
this.cacheStorage.AddToList(&caches.Item{
|
||||
Type: webpCacheWriter.ItemType(),
|
||||
Key: webpCacheWriter.Key(),
|
||||
ExpiresAt: webpCacheWriter.ExpiredAt(),
|
||||
StaleAt: webpCacheWriter.ExpiredAt() + int64(this.calculateStaleLife()),
|
||||
HeaderSize: webpCacheWriter.HeaderSize(),
|
||||
BodySize: webpCacheWriter.BodySize(),
|
||||
Host: this.req.ReqHost,
|
||||
ServerId: this.req.ReqServer.Id,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build !arm64
|
||||
// +build !arm64
|
||||
//go:build !arm64 && !windows
|
||||
|
||||
package nodes
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
package nodes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/shirou/gopsutil/v3/cpu"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/shirou/gopsutil/v3/mem"
|
||||
"math"
|
||||
"sync"
|
||||
@@ -21,7 +20,7 @@ var windowsLoadValues = []*WindowsLoadValue{}
|
||||
var windowsLoadLocker = &sync.Mutex{}
|
||||
|
||||
// 更新内存
|
||||
func (this *NodeStatusExecutor) updateMem(status *NodeStatus) {
|
||||
func (this *NodeStatusExecutor) updateMem(status *nodeconfigs.NodeStatus) {
|
||||
stat, err := mem.VirtualMemory()
|
||||
if err != nil {
|
||||
status.Error = err.Error()
|
||||
@@ -32,14 +31,16 @@ func (this *NodeStatusExecutor) updateMem(status *NodeStatus) {
|
||||
}
|
||||
|
||||
// 更新负载
|
||||
func (this *NodeStatusExecutor) updateLoad(status *NodeStatus) {
|
||||
func (this *NodeStatusExecutor) updateLoad(status *nodeconfigs.NodeStatus) {
|
||||
timestamp := time.Now().Unix()
|
||||
|
||||
currentLoad := 0
|
||||
info, err := cpu.ProcInfo()
|
||||
if err == nil && len(info) > 0 && info[0].ProcessorQueueLength < 1000 {
|
||||
currentLoad = int(info[0].ProcessorQueueLength)
|
||||
}
|
||||
/*
|
||||
info, err := cpu.ProcInfo()
|
||||
if err == nil && len(info) > 0 && info[0].ProcessorQueueLength < 1000 {
|
||||
currentLoad = int(info[0].ProcessorQueueLength)
|
||||
}
|
||||
*/
|
||||
|
||||
// 删除15分钟之前的数据
|
||||
windowsLoadLocker.Lock()
|
||||
@@ -93,9 +94,11 @@ func (this *NodeStatusExecutor) updateLoad(status *NodeStatus) {
|
||||
windowsLoadLocker.Unlock()
|
||||
|
||||
// 在老Windows上不显示错误
|
||||
if err == context.DeadlineExceeded {
|
||||
err = nil
|
||||
}
|
||||
/*
|
||||
if err == context.DeadlineExceeded {
|
||||
err = nil
|
||||
}
|
||||
*/
|
||||
status.Load1m = load1
|
||||
status.Load5m = load5
|
||||
status.Load15m = load15
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !windows
|
||||
|
||||
package fsutils
|
||||
|
||||
@@ -4,20 +4,9 @@ package fsutils
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeNode/internal/utils/fasttime"
|
||||
"golang.org/x/sys/unix"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// StatDevice device contains the path
|
||||
func StatDevice(path string) (*StatResult, error) {
|
||||
var stat = &unix.Statfs_t{}
|
||||
err := unix.Statfs(path, stat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewStatResult(stat), nil
|
||||
}
|
||||
|
||||
var locker = &sync.RWMutex{}
|
||||
var cacheMap = map[string]*StatResult{} // path => StatResult
|
||||
|
||||
@@ -44,38 +33,3 @@ func StatDeviceCache(path string) (*StatResult, error) {
|
||||
cacheMap[path] = stat
|
||||
return stat, nil
|
||||
}
|
||||
|
||||
type StatResult struct {
|
||||
rawStat *unix.Statfs_t
|
||||
blockSize uint64
|
||||
|
||||
updatedAt int64
|
||||
}
|
||||
|
||||
func NewStatResult(rawStat *unix.Statfs_t) *StatResult {
|
||||
var blockSize = rawStat.Bsize
|
||||
if blockSize < 0 {
|
||||
blockSize = 0
|
||||
}
|
||||
|
||||
return &StatResult{
|
||||
rawStat: rawStat,
|
||||
blockSize: uint64(blockSize),
|
||||
updatedAt: fasttime.Now().Unix(),
|
||||
}
|
||||
}
|
||||
|
||||
func (this *StatResult) FreeSize() uint64 {
|
||||
return this.rawStat.Bfree * this.blockSize
|
||||
}
|
||||
|
||||
func (this *StatResult) TotalSize() uint64 {
|
||||
return this.rawStat.Blocks * this.blockSize
|
||||
}
|
||||
|
||||
func (this *StatResult) UsedSize() uint64 {
|
||||
if this.rawStat.Bfree <= this.rawStat.Blocks {
|
||||
return (this.rawStat.Blocks - this.rawStat.Bfree) * this.blockSize
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
54
EdgeNode/internal/utils/fs/stat_unix.go
Normal file
54
EdgeNode/internal/utils/fs/stat_unix.go
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !windows
|
||||
|
||||
package fsutils
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeNode/internal/utils/fasttime"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// StatDevice device contains the path
|
||||
func StatDevice(path string) (*StatResult, error) {
|
||||
var stat = &unix.Statfs_t{}
|
||||
err := unix.Statfs(path, stat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewStatResult(stat), nil
|
||||
}
|
||||
|
||||
type StatResult struct {
|
||||
rawStat *unix.Statfs_t
|
||||
blockSize uint64
|
||||
|
||||
updatedAt int64
|
||||
}
|
||||
|
||||
func NewStatResult(rawStat *unix.Statfs_t) *StatResult {
|
||||
var blockSize = rawStat.Bsize
|
||||
if blockSize < 0 {
|
||||
blockSize = 0
|
||||
}
|
||||
|
||||
return &StatResult{
|
||||
rawStat: rawStat,
|
||||
blockSize: uint64(blockSize),
|
||||
updatedAt: fasttime.Now().Unix(),
|
||||
}
|
||||
}
|
||||
|
||||
func (this *StatResult) FreeSize() uint64 {
|
||||
return this.rawStat.Bfree * this.blockSize
|
||||
}
|
||||
|
||||
func (this *StatResult) TotalSize() uint64 {
|
||||
return this.rawStat.Blocks * this.blockSize
|
||||
}
|
||||
|
||||
func (this *StatResult) UsedSize() uint64 {
|
||||
if this.rawStat.Bfree <= this.rawStat.Blocks {
|
||||
return (this.rawStat.Blocks - this.rawStat.Bfree) * this.blockSize
|
||||
}
|
||||
return 0
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !linux
|
||||
//go:build !linux && !windows
|
||||
|
||||
package mmap
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build plus
|
||||
//go:build plus && !windows
|
||||
|
||||
package mmap
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build !freebsd
|
||||
// +build !freebsd
|
||||
//go:build !freebsd && !windows
|
||||
// +build !freebsd,!windows
|
||||
|
||||
package utils
|
||||
|
||||
@@ -15,7 +15,7 @@ func ListenReuseAddr(network string, addr string) (net.Listener, error) {
|
||||
config := &net.ListenConfig{
|
||||
Control: func(network, address string, c syscall.RawConn) error {
|
||||
return c.Control(func(fd uintptr) {
|
||||
err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, SO_REUSEPORT, 1)
|
||||
err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1)
|
||||
if err != nil {
|
||||
logs.Println("[LISTEN]" + err.Error())
|
||||
}
|
||||
@@ -8,6 +8,8 @@ package injectionutils
|
||||
#include <libinjection.h>
|
||||
#include <stdlib.h>
|
||||
*/
|
||||
//go:build cgo
|
||||
|
||||
import "C"
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeNode/internal/utils/fasttime"
|
||||
|
||||
18
EdgeNode/internal/waf/injectionutils/utils_sqli_nocgo.go
Normal file
18
EdgeNode/internal/waf/injectionutils/utils_sqli_nocgo.go
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !cgo
|
||||
|
||||
package injectionutils
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeNode/internal/waf/utils"
|
||||
)
|
||||
|
||||
// DetectSQLInjectionCache detect sql injection in string with cache
|
||||
func DetectSQLInjectionCache(input string, isStrict bool, cacheLife utils.CacheLife) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// DetectSQLInjection detect sql injection in string
|
||||
func DetectSQLInjection(input string, isStrict bool) bool {
|
||||
return false
|
||||
}
|
||||
@@ -8,6 +8,8 @@ package injectionutils
|
||||
#include <libinjection.h>
|
||||
#include <stdlib.h>
|
||||
*/
|
||||
//go:build cgo
|
||||
|
||||
import "C"
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeNode/internal/utils/fasttime"
|
||||
|
||||
17
EdgeNode/internal/waf/injectionutils/utils_xss_nocgo.go
Normal file
17
EdgeNode/internal/waf/injectionutils/utils_xss_nocgo.go
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !cgo
|
||||
|
||||
package injectionutils
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeNode/internal/waf/utils"
|
||||
)
|
||||
|
||||
func DetectXSSCache(input string, isStrict bool, cacheLife utils.CacheLife) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// DetectXSS detect XSS in string
|
||||
func DetectXSS(input string, isStrict bool) bool {
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user