mirror of
https://github.com/TeaOSLab/EdgeAPI.git
synced 2025-11-10 20:40:56 +08:00
自动检测本地数据库磁盘是否已满,如果已满,则不再写入访问日志
This commit is contained in:
@@ -2,6 +2,7 @@ package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
@@ -29,8 +30,9 @@ var httpAccessLogDAOMapping = map[int64]*HTTPAccessLogDAOWrapper{} // dbNodeId =
|
||||
|
||||
// HTTPAccessLogDAOWrapper HTTP访问日志DAO
|
||||
type HTTPAccessLogDAOWrapper struct {
|
||||
DAO *HTTPAccessLogDAO
|
||||
NodeId int64
|
||||
DAO *HTTPAccessLogDAO
|
||||
NodeId int64
|
||||
IsLocal bool
|
||||
}
|
||||
|
||||
func init() {
|
||||
@@ -195,7 +197,7 @@ func (this *DBNodeInitializer) loop() error {
|
||||
continue
|
||||
}
|
||||
|
||||
daoObject := dbs.DAOObject{
|
||||
var daoObject = dbs.DAOObject{
|
||||
Instance: db,
|
||||
DB: node.Name + "(id:" + strconv.Itoa(int(node.Id)) + ")",
|
||||
Table: tableDef.Name,
|
||||
@@ -210,12 +212,13 @@ func (this *DBNodeInitializer) loop() error {
|
||||
|
||||
accessLogLocker.Lock()
|
||||
accessLogDBMapping[nodeId] = db
|
||||
dao := &HTTPAccessLogDAO{
|
||||
var dao = &HTTPAccessLogDAO{
|
||||
DAOObject: daoObject,
|
||||
}
|
||||
httpAccessLogDAOMapping[nodeId] = &HTTPAccessLogDAOWrapper{
|
||||
DAO: dao,
|
||||
NodeId: nodeId,
|
||||
DAO: dao,
|
||||
NodeId: nodeId,
|
||||
IsLocal: dbutils.IsLocalAddr(node.Host),
|
||||
}
|
||||
accessLogLocker.Unlock()
|
||||
}
|
||||
|
||||
@@ -161,16 +161,27 @@ func (this *HTTPAccessLogDAO) DumpAccessLogsFromQueue(size int) (hasMore bool, e
|
||||
size = 100
|
||||
}
|
||||
|
||||
if len(oldAccessLogQueue) == 0 && len(accessLogQueue) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
var dao = randomHTTPAccessLogDAO()
|
||||
if dao == nil {
|
||||
dao = &HTTPAccessLogDAOWrapper{
|
||||
DAO: SharedHTTPAccessLogDAO,
|
||||
NodeId: 0,
|
||||
}
|
||||
}
|
||||
|
||||
if len(oldAccessLogQueue) == 0 && len(accessLogQueue) == 0 {
|
||||
return false, nil
|
||||
// 检查本地数据库空间
|
||||
if dbutils.IsLocalDatabase && !dbutils.HasFreeSpace {
|
||||
return false, errors.New("dump accesslog failed: there is no enough space left for database (" + dbutils.LocalDatabaseDataDir + ")")
|
||||
}
|
||||
} else if dao.IsLocal {
|
||||
// 检查本地数据库空间
|
||||
// 我们假定本地只能安装一个数据库,访问日志中的数据库和当前API连接的数据库一致
|
||||
if !dbutils.HasFreeSpace {
|
||||
return true, errors.New("dump accesslog failed: there is no enough space left for database (" + dbutils.LocalDatabaseDataDir + ")")
|
||||
}
|
||||
}
|
||||
|
||||
// 开始事务
|
||||
|
||||
73
internal/db/utils/disk.go
Normal file
73
internal/db/utils/disk.go
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package dbutils
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"golang.org/x/sys/unix"
|
||||
"time"
|
||||
)
|
||||
|
||||
const minFreeSpaceGB = 3
|
||||
|
||||
var HasFreeSpace = true
|
||||
var IsLocalDatabase = false
|
||||
var LocalDatabaseDataDir = ""
|
||||
|
||||
func init() {
|
||||
var ticker = time.NewTicker(5 * time.Minute)
|
||||
|
||||
dbs.OnReadyDone(func() {
|
||||
goman.New(func() {
|
||||
for range ticker.C {
|
||||
HasFreeSpace = CheckHasFreeSpace()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// CheckHasFreeSpace 检查当前数据库是否有剩余空间
|
||||
func CheckHasFreeSpace() bool {
|
||||
db, _ := dbs.Default()
|
||||
if db == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
config, _ := db.Config()
|
||||
if config == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
dsnConfig, _ := mysql.ParseDSN(config.Dsn)
|
||||
if dsnConfig == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if IsLocalAddr(dsnConfig.Addr) {
|
||||
IsLocalDatabase = true
|
||||
|
||||
// only for local database
|
||||
one, err := db.FindOne("SHOW VARIABLES WHERE variable_name='datadir'")
|
||||
if err != nil || len(one) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
var dir = one.GetString("Value")
|
||||
if len(dir) == 0 {
|
||||
return true
|
||||
}
|
||||
LocalDatabaseDataDir = dir
|
||||
|
||||
var stat unix.Statfs_t
|
||||
err = unix.Statfs(dir, &stat)
|
||||
if err != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
var availableSpace = (stat.Bavail * uint64(stat.Bsize)) / (1 << 30) // GB
|
||||
return availableSpace > minFreeSpaceGB
|
||||
}
|
||||
return true
|
||||
}
|
||||
14
internal/db/utils/disk_test.go
Normal file
14
internal/db/utils/disk_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package dbutils_test
|
||||
|
||||
import (
|
||||
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHasFreeSpace(t *testing.T) {
|
||||
t.Log(dbutils.CheckHasFreeSpace())
|
||||
t.Log(dbutils.LocalDatabaseDataDir)
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package dbutils
|
||||
|
||||
import (
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -69,3 +70,26 @@ func SetGlobalVarMax(db *dbs.DB, variableName string, maxValue int) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsLocalAddr 是否为本地数据库
|
||||
func IsLocalAddr(addr string) bool {
|
||||
var host = addr
|
||||
if strings.Contains(addr, ":") {
|
||||
host, _, _ = net.SplitHostPort(addr)
|
||||
if len(host) == 0 {
|
||||
host = addr
|
||||
}
|
||||
}
|
||||
|
||||
if host == "127.0.0.1" || host == "::1" || host == "localhost" {
|
||||
return true
|
||||
}
|
||||
|
||||
interfaceAddrs, _ := net.InterfaceAddrs()
|
||||
for _, interfaceAddr := range interfaceAddrs {
|
||||
if strings.HasPrefix(interfaceAddr.String(), host+"/") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ package dbutils_test
|
||||
|
||||
import (
|
||||
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
||||
"github.com/iwind/TeaGo/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -12,3 +13,13 @@ func TestQuoteLike(t *testing.T) {
|
||||
t.Log(s + " => " + dbutils.QuoteLike(s))
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsLocalAddr(t *testing.T) {
|
||||
var a = assert.NewAssertion(t)
|
||||
a.IsTrue(dbutils.IsLocalAddr("127.0.0.1"))
|
||||
a.IsTrue(dbutils.IsLocalAddr("localhost"))
|
||||
a.IsTrue(dbutils.IsLocalAddr("::1"))
|
||||
a.IsTrue(dbutils.IsLocalAddr("127.0.0.1:3306"))
|
||||
a.IsFalse(dbutils.IsLocalAddr("192.168.2.200"))
|
||||
a.IsFalse(dbutils.IsLocalAddr("192.168.2.200:3306"))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user