mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-05-06 05:38:50 +00:00
e61772e858
* feat: tsdb * fix(ci): remove --parseGoList=false from swag init to fix dependency resolution * fix(ci): fix swag init directory and temporary remove s390x support due to cgo issues * fix(ci): fix swag init output directory to cmd/dashboard/docs * fix(ci): set GOTOOLCHAIN=auto for gosec * feat: add system storage maintenance for SQLite and TSDB * shit * feat: add s390x support and improve service monitoring * ci: upgrade goreleaser-cross image to v1.25 * ci: add libzstd-dev:s390x for cross-compilation * ci: build libzstd for s390x from source * ci: add libzstd_linux_s390x.go for gozstd linking * ci: use vendor mode for s390x gozstd build * ci: clone zstd source for s390x build * refactor(tsdb): rename MaxDiskUsageGB to MinFreeDiskSpaceGB and optimize queries - Rename config to accurately reflect VictoriaMetrics behavior: minimum free disk space threshold - Add QueryServiceHistoryByServerID for batch query optimization - Fix hasStatus to avoid false status counting when only delay data exists - Fix service aggregation boundary: use successCount*2 >= count - Fix serviceID parsing with strconv.ParseUint error handling - Add TagFiltersCacheSize for better query performance * feat(api): add server metrics endpoint and simplify service history response - Add /server/:id/metrics API for querying TSDB server metrics - Simplify getServiceHistory by removing redundant data conversion - Change AvgDelay type from float32 to float64 - Remove generated swagger docs (to be regenerated) - Update TSDB query, writer and tests * chore: 临时禁用不支持前端 * ci: cache zstd build for s390x to speed up CI * fix(tsdb): fix race conditions, data correctness and optimize performance - Fix TOCTOU race between IsClosed() and write/query by holding RLock - Fix delay=0 excluded from stats by using hasDelay flag instead of value > 0 - Fix fmt.Sscanf -> strconv.ParseUint for server_id parsing with error logging - Fix buffer unbounded growth by flushing inside lock when over maxSize - Split makeMetricRow into makeServerMetricRow/makeServiceMetricRow - Extract InitGlobalSettings() from Open() for VictoriaMetrics globals - Remove redundant instance/GetInstance/SetInstance singleton - Add error logging for silently skipped block decode errors - Optimize WriteBatch* to build all rows in single write call - Optimize downsample to use linear scan instead of map for sorted data - Optimize query slice reuse across block iterations * 服务添加DisplayIndex (#1166) * 服务添加DisplayIndex * 根据ai建议修改 --------- Co-authored-by: huYang <306061454@qq.com> * fix(tsdb): restore SQLite fallback and monthly status reload on restart - Restore ServiceHistory model and SQLite write fallback when TSDB is disabled - Reload monthlyStatus (30-day) and serviceStatusToday from TSDB/SQLite on startup - Add SQLite fallback query for /service/:id/history and /server/:id/service - Remove breaking GET /service/:id endpoint, keep /service/:id/history only - Add QueryServiceDailyStats to TSDB for per-day aggregation - Add tests for monthly status and today stats loading from both TSDB and SQLite - Migrate ServiceHistory table only when TSDB is disabled * ci: exclude false-positive gosec rules G117, G703, G704 * feat(api): expose tsdb_enabled in setting response * ci: restore G115 exclusion accidentally dropped in previous commit * fix: update version numbers for OfficialAdmin and Official templates * chore: upgrade frontend * chore: upgrade frontend --------- Co-authored-by: 胡说丷刂 <34758853+laosan-xx@users.noreply.github.com> Co-authored-by: huYang <306061454@qq.com>
118 lines
2.5 KiB
Go
118 lines
2.5 KiB
Go
package tsdb
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"path/filepath"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/storage"
|
|
)
|
|
|
|
// TSDB 封装 VictoriaMetrics 存储
|
|
type TSDB struct {
|
|
storage *storage.Storage
|
|
config *Config
|
|
mu sync.RWMutex
|
|
closed bool
|
|
|
|
writer *bufferedWriter
|
|
}
|
|
|
|
// InitGlobalSettings 初始化 VictoriaMetrics 包级别的全局设置。
|
|
// 这些设置是进程级别的,应在 Open() 之前调用且只调用一次。
|
|
func InitGlobalSettings(config *Config) {
|
|
memBytes := int(config.MaxMemoryMB * 1024 * 1024)
|
|
storage.SetTSIDCacheSize(memBytes * 35 / 100)
|
|
storage.SetMetricNameCacheSize(memBytes * 10 / 100)
|
|
storage.SetTagFiltersCacheSize(memBytes * 5 / 100)
|
|
storage.SetMetadataStorageSize(memBytes * 1 / 100)
|
|
|
|
storage.SetDedupInterval(config.DedupInterval)
|
|
storage.SetFreeDiskSpaceLimit(config.MinFreeDiskSpaceBytes())
|
|
storage.SetDataFlushInterval(5 * time.Second)
|
|
}
|
|
|
|
// Open 打开或创建 TSDB 存储
|
|
func Open(config *Config) (*TSDB, error) {
|
|
if config == nil {
|
|
config = DefaultConfig()
|
|
}
|
|
|
|
config.Validate()
|
|
|
|
dataPath := config.DataPath
|
|
if !filepath.IsAbs(dataPath) {
|
|
absPath, err := filepath.Abs(dataPath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get absolute path: %w", err)
|
|
}
|
|
dataPath = absPath
|
|
}
|
|
|
|
InitGlobalSettings(config)
|
|
|
|
opts := storage.OpenOptions{
|
|
Retention: time.Duration(config.RetentionDays) * 24 * time.Hour,
|
|
}
|
|
|
|
stor := storage.MustOpenStorage(dataPath, opts)
|
|
|
|
db := &TSDB{
|
|
storage: stor,
|
|
config: config,
|
|
}
|
|
|
|
db.writer = newBufferedWriter(db, config.WriteBufferSize, config.WriteBufferFlushInterval)
|
|
|
|
log.Printf("NEZHA>> TSDB opened at %s, retention: %d days, min free disk: %.1f GB, max memory: %d MB",
|
|
dataPath, config.RetentionDays, config.MinFreeDiskSpaceGB, config.MaxMemoryMB)
|
|
|
|
return db, nil
|
|
}
|
|
|
|
// Close 关闭 TSDB 存储
|
|
func (db *TSDB) Close() error {
|
|
db.mu.Lock()
|
|
defer db.mu.Unlock()
|
|
|
|
if db.closed {
|
|
return nil
|
|
}
|
|
|
|
if db.writer != nil {
|
|
db.writer.stop()
|
|
}
|
|
|
|
db.storage.MustClose()
|
|
db.closed = true
|
|
log.Println("NEZHA>> TSDB closed")
|
|
return nil
|
|
}
|
|
|
|
// Storage 返回底层存储对象(用于高级查询)
|
|
func (db *TSDB) Storage() *storage.Storage {
|
|
return db.storage
|
|
}
|
|
|
|
// Config 返回配置
|
|
func (db *TSDB) Config() *Config {
|
|
return db.config
|
|
}
|
|
|
|
// IsClosed 检查是否已关闭
|
|
func (db *TSDB) IsClosed() bool {
|
|
db.mu.RLock()
|
|
defer db.mu.RUnlock()
|
|
return db.closed
|
|
}
|
|
|
|
// Flush 强制刷盘(主要用于测试)
|
|
func (db *TSDB) Flush() {
|
|
if db.writer != nil {
|
|
db.writer.flush()
|
|
}
|
|
db.storage.DebugFlush()
|
|
}
|