optimal storge choice

This commit is contained in:
lzh
2025-07-09 14:51:22 +08:00
parent b4ad29e9cf
commit 9823ca0cef
7 changed files with 109 additions and 95 deletions

View File

@@ -1,8 +1,6 @@
package api package api
import ( import (
"errors"
"github.com/lzh-1625/go_process_manager/internal/app/logic" "github.com/lzh-1625/go_process_manager/internal/app/logic"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@@ -27,9 +25,6 @@ func (c *configApi) SetSystemConfiguration(ctx *gin.Context, _ any) (err error)
return return
} }
func (c *configApi) EsConfigReload(ctx *gin.Context, _ any) (err error) { func (c *configApi) LogConfigReload(ctx *gin.Context, _ any) (err error) {
if !logic.EsLogic.InitEs() { return logic.LogLogicImpl.Init()
err = errors.New("es init fail")
}
return
} }

View File

@@ -1,72 +1,17 @@
package logic package logic
import ( import (
"strings"
"github.com/lzh-1625/go_process_manager/config" "github.com/lzh-1625/go_process_manager/config"
"github.com/lzh-1625/go_process_manager/internal/app/model" "github.com/lzh-1625/go_process_manager/internal/app/search"
"github.com/lzh-1625/go_process_manager/internal/app/repository"
"github.com/lzh-1625/go_process_manager/log" _ "github.com/lzh-1625/go_process_manager/internal/app/search/bleve"
_ "github.com/lzh-1625/go_process_manager/internal/app/search/es"
_ "github.com/lzh-1625/go_process_manager/internal/app/search/sqlite"
) )
type LogLogic interface { var LogLogicImpl search.LogLogic
Search(req model.GetLogReq, filterProcessName ...string) model.LogResp
Insert(log string, processName string, using string, ts int64)
}
var LogLogicImpl LogLogic
func InitLog() { func InitLog() {
switch config.CF.StorgeType { LogLogicImpl = search.GetSearchImpl(config.CF.StorgeType)
case "es": LogLogicImpl.Init()
LogLogicImpl = LogEs
EsLogic.InitEs()
log.Logger.Infow("使用es作为日志存储")
case "bleve":
LogLogicImpl = BleveLogic
BleveLogic.InitBleve()
log.Logger.Infow("使用bleve作为日志存储")
default:
LogLogicImpl = LogSqlite
log.Logger.Infow("使用sqlite作为日志存储")
}
}
type logSqlite struct{}
var LogSqlite = new(logSqlite)
func (l *logSqlite) Search(req model.GetLogReq, filterProcessName ...string) model.LogResp {
req.FilterName = filterProcessName
data, total := repository.LogRepository.SearchLog(req)
if req.Match.Log != "" {
for i := range data {
data[i].Log = strings.ReplaceAll(data[i].Log, req.Match.Log, "\033[43m"+req.Match.Log+"\033[0m")
}
}
return model.LogResp{
Data: data,
Total: total,
}
}
func (l *logSqlite) Insert(log string, processName string, using string, ts int64) {
repository.LogRepository.InsertLog(model.ProcessLog{
Log: log,
Name: processName,
Using: using,
Time: ts,
})
}
type logEs struct{}
var LogEs = new(logEs)
func (l *logEs) Search(req model.GetLogReq, filterProcessName ...string) model.LogResp {
return EsLogic.Search(req, filterProcessName...)
}
func (l *logEs) Insert(log string, processName string, using string, ts int64) {
EsLogic.Insert(log, processName, using, ts)
} }

View File

@@ -138,7 +138,7 @@ func routePathInit(r *gin.Engine) {
{ {
configGroup.GET("", bind(api.ConfigApi.GetSystemConfiguration, None)) configGroup.GET("", bind(api.ConfigApi.GetSystemConfiguration, None))
configGroup.PUT("", bind(api.ConfigApi.SetSystemConfiguration, None)) configGroup.PUT("", bind(api.ConfigApi.SetSystemConfiguration, None))
configGroup.PUT("/es", bind(api.ConfigApi.EsConfigReload, None)) configGroup.PUT("/log", bind(api.ConfigApi.LogConfigReload, None))
} }
} }
} }

View File

@@ -1,4 +1,4 @@
package logic package bleve
import ( import (
"time" "time"
@@ -9,17 +9,20 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/lzh-1625/go_process_manager/internal/app/model" "github.com/lzh-1625/go_process_manager/internal/app/model"
sr "github.com/lzh-1625/go_process_manager/internal/app/search"
logger "github.com/lzh-1625/go_process_manager/log" logger "github.com/lzh-1625/go_process_manager/log"
gse "github.com/vcaesar/gse-bleve" gse "github.com/vcaesar/gse-bleve"
) )
type bleveLogic struct { func init() {
sr.Register("bleve", new(bleveSearch))
}
type bleveSearch struct {
index bleve.Index index bleve.Index
} }
var BleveLogic = new(bleveLogic) func (b *bleveSearch) Init() error {
func (b *bleveLogic) InitBleve() {
opt := gse.Option{ opt := gse.Option{
Dicts: "embed, zh", Dicts: "embed, zh",
Stop: "", Stop: "",
@@ -29,7 +32,7 @@ func (b *bleveLogic) InitBleve() {
indexMapping, err := gse.NewMapping(opt) indexMapping, err := gse.NewMapping(opt)
if err != nil { if err != nil {
logger.Logger.Errorw("bleve init fail", "err", err) logger.Logger.Errorw("bleve init fail", "err", err)
return return err
} }
mapping := bleve.NewDocumentMapping() mapping := bleve.NewDocumentMapping()
log := bleve.NewTextFieldMapping() log := bleve.NewTextFieldMapping()
@@ -50,13 +53,14 @@ func (b *bleveLogic) InitBleve() {
index, err = bleve.New("log.bleve", indexMapping) index, err = bleve.New("log.bleve", indexMapping)
if err != nil { if err != nil {
logger.Logger.Errorw("bleve init error", "err", err) logger.Logger.Errorw("bleve init error", "err", err)
return return err
} }
} }
b.index = index b.index = index
return nil
} }
func (b *bleveLogic) Insert(logContent string, processName string, using string, ts int64) { func (b *bleveSearch) Insert(logContent string, processName string, using string, ts int64) {
if err := b.index.Index(uuid.NewString(), model.ProcessLog{ if err := b.index.Index(uuid.NewString(), model.ProcessLog{
Log: logContent, Log: logContent,
Name: processName, Name: processName,
@@ -67,7 +71,7 @@ func (b *bleveLogic) Insert(logContent string, processName string, using string,
} }
} }
func (b *bleveLogic) Search(req model.GetLogReq, filterProcessName ...string) (result model.LogResp) { func (b *bleveSearch) Search(req model.GetLogReq, filterProcessName ...string) (result model.LogResp) {
buildQuery := bleve.NewBooleanQuery() buildQuery := bleve.NewBooleanQuery()
if req.Match.Log != "" { if req.Match.Log != "" {
logQuery := bleve.NewMatchQuery(req.Match.Log) logQuery := bleve.NewMatchQuery(req.Match.Log)

View File

@@ -1,4 +1,4 @@
package logic package es
import ( import (
"context" "context"
@@ -10,22 +10,23 @@ import (
"github.com/lzh-1625/go_process_manager/config" "github.com/lzh-1625/go_process_manager/config"
"github.com/lzh-1625/go_process_manager/internal/app/model" "github.com/lzh-1625/go_process_manager/internal/app/model"
"github.com/lzh-1625/go_process_manager/internal/app/search"
"github.com/lzh-1625/go_process_manager/log" "github.com/lzh-1625/go_process_manager/log"
"github.com/olivere/elastic/v7" "github.com/olivere/elastic/v7"
) )
type esLogic struct { func init() {
search.Register("es", new(esSearch))
}
type esSearch struct {
esClient *elastic.Client esClient *elastic.Client
} }
var ( func (e *esSearch) Init() error {
EsLogic = new(esLogic)
)
func (e *esLogic) InitEs() bool {
var err error var err error
EsLogic.esClient, err = elastic.NewClient( e.esClient, err = elastic.NewClient(
elastic.SetURL(config.CF.EsUrl), elastic.SetURL(config.CF.EsUrl),
elastic.SetBasicAuth(config.CF.EsUsername, config.CF.EsPassword), elastic.SetBasicAuth(config.CF.EsUsername, config.CF.EsPassword),
elastic.SetSniff(false), elastic.SetSniff(false),
@@ -38,13 +39,13 @@ func (e *esLogic) InitEs() bool {
) )
if err != nil { if err != nil {
log.Logger.Warnw("Failed to connect to es", "err", err) log.Logger.Warnw("Failed to connect to es", "err", err)
return false return err
} }
EsLogic.CreateIndexIfNotExists(config.CF.EsIndex) e.CreateIndexIfNotExists(config.CF.EsIndex)
return true return nil
} }
func (e *esLogic) Insert(logContent string, processName string, using string, ts int64) { func (e *esSearch) Insert(logContent string, processName string, using string, ts int64) {
data := model.ProcessLog{ data := model.ProcessLog{
Log: logContent, Log: logContent,
Name: processName, Name: processName,
@@ -57,7 +58,7 @@ func (e *esLogic) Insert(logContent string, processName string, using string, ts
} }
} }
func (e *esLogic) CreateIndexIfNotExists(index string) error { func (e *esSearch) CreateIndexIfNotExists(index string) error {
ctx := context.Background() ctx := context.Background()
exists, err := e.esClient.IndexExists(index).Do(ctx) exists, err := e.esClient.IndexExists(index).Do(ctx)
@@ -78,7 +79,7 @@ func (e *esLogic) CreateIndexIfNotExists(index string) error {
return nil return nil
} }
func (e *esLogic) Search(req model.GetLogReq, filterProcessName ...string) model.LogResp { func (e *esSearch) Search(req model.GetLogReq, filterProcessName ...string) model.LogResp {
// 检查 req 是否为 nil // 检查 req 是否为 nil
if req.Page.From < 0 || req.Page.Size <= 0 { if req.Page.From < 0 || req.Page.Size <= 0 {
log.Logger.Error("无效的分页请求参数") log.Logger.Error("无效的分页请求参数")
@@ -148,7 +149,7 @@ func (e *esLogic) Search(req model.GetLogReq, filterProcessName ...string) model
} }
// 通过反射得到mapping // 通过反射得到mapping
func (e *esLogic) structToJSON() string { func (e *esSearch) structToJSON() string {
typ := reflect.TypeOf(model.ProcessLog{}) typ := reflect.TypeOf(model.ProcessLog{})
properties := make(map[string]map[string]string) properties := make(map[string]map[string]string)
for i := 0; i < typ.NumField(); i++ { for i := 0; i < typ.NumField(); i++ {

View File

@@ -0,0 +1,27 @@
package search
import (
"github.com/lzh-1625/go_process_manager/internal/app/model"
"github.com/lzh-1625/go_process_manager/log"
)
type LogLogic interface {
Search(req model.GetLogReq, filterProcessName ...string) model.LogResp
Insert(log string, processName string, using string, ts int64)
Init() error
}
var searchImplMap map[string]LogLogic = map[string]LogLogic{}
func Register(name string, impl LogLogic) {
searchImplMap[name] = impl
}
func GetSearchImpl(name string) LogLogic {
v, ok := searchImplMap[name]
if ok {
return v
}
log.Logger.Warnw("未找到对应的存储引擎,使用默认[sqlite]", "name", name)
return searchImplMap["sqlite"]
}

View File

@@ -0,0 +1,42 @@
package sqlite
import (
"strings"
"github.com/lzh-1625/go_process_manager/internal/app/model"
"github.com/lzh-1625/go_process_manager/internal/app/repository"
"github.com/lzh-1625/go_process_manager/internal/app/search"
)
func init() {
search.Register("sqlite", new(sqliteSearch))
}
type sqliteSearch struct{}
func (l *sqliteSearch) Search(req model.GetLogReq, filterProcessName ...string) model.LogResp {
req.FilterName = filterProcessName
data, total := repository.LogRepository.SearchLog(req)
if req.Match.Log != "" {
for i := range data {
data[i].Log = strings.ReplaceAll(data[i].Log, req.Match.Log, "\033[43m"+req.Match.Log+"\033[0m")
}
}
return model.LogResp{
Data: data,
Total: total,
}
}
func (l *sqliteSearch) Insert(log string, processName string, using string, ts int64) {
repository.LogRepository.InsertLog(model.ProcessLog{
Log: log,
Name: processName,
Using: using,
Time: ts,
})
}
func (l *sqliteSearch) Init() error {
return nil
}