dns clickhouse改造

This commit is contained in:
robin
2026-02-10 19:30:44 +08:00
parent 4812ad5aaf
commit 1bb8140a41
47 changed files with 2815 additions and 174 deletions

View File

@@ -80,7 +80,7 @@ func (this *StorageManager) Loop() error {
if int64(policy.Id) == publicPolicyId {
this.disableDefaultDB = policy.DisableDefaultDB
this.writeTargets = serverconfigs.ParseWriteTargetsFromPolicy(policy.WriteTargets, policy.Type, policy.DisableDefaultDB)
this.writeTargets = serverconfigs.ResolveWriteTargetsByType(policy.Type, policy.DisableDefaultDB)
foundPolicy = true
}
}
@@ -185,6 +185,9 @@ func (this *StorageManager) WriteTargets() *serverconfigs.AccessLogWriteTargets
}
func (this *StorageManager) createStorage(storageType string, optionsJSON []byte) (StorageInterface, error) {
if serverconfigs.IsFileBasedStorageType(storageType) {
storageType = serverconfigs.AccessLogStorageTypeFile
}
switch storageType {
case serverconfigs.AccessLogStorageTypeFile:
var config = &serverconfigs.AccessLogFileStorageConfig{}

View File

@@ -85,6 +85,10 @@ func (s *LogsIngestStore) List(ctx context.Context, f ListFilter) (rows []*LogsI
if f.Day == "" {
return nil, "", fmt.Errorf("clickhouse: day required")
}
dayNumber, err := normalizeDayNumber(f.Day)
if err != nil {
return nil, "", err
}
table := "logs_ingest"
if s.client.cfg.Database != "" && s.client.cfg.Database != "default" {
table = quoteIdent(s.client.cfg.Database) + "." + quoteIdent("logs_ingest")
@@ -92,7 +96,7 @@ func (s *LogsIngestStore) List(ctx context.Context, f ListFilter) (rows []*LogsI
table = quoteIdent(table)
}
conditions := []string{"toDate(timestamp) = '" + escapeString(f.Day) + "'"}
conditions := []string{"toYYYYMMDD(timestamp) = " + strconv.Itoa(dayNumber)}
if f.HourFrom != "" {
if _, err := strconv.Atoi(f.HourFrom); err == nil {
conditions = append(conditions, "toHour(timestamp) >= "+f.HourFrom)
@@ -240,6 +244,22 @@ func escapeString(s string) string {
return strings.ReplaceAll(s, "'", "''")
}
func normalizeDayNumber(day string) (int, error) {
normalized := strings.TrimSpace(day)
if normalized == "" {
return 0, fmt.Errorf("clickhouse: day required")
}
normalized = strings.ReplaceAll(normalized, "-", "")
if len(normalized) != 8 {
return 0, fmt.Errorf("clickhouse: invalid day '%s'", day)
}
dayNumber, err := strconv.Atoi(normalized)
if err != nil {
return 0, fmt.Errorf("clickhouse: invalid day '%s'", day)
}
return dayNumber, nil
}
func mapToLogsIngestRow(m map[string]interface{}) *LogsIngestRow {
r := &LogsIngestRow{}
u64 := func(key string) uint64 {

View File

@@ -0,0 +1,375 @@
package clickhouse
import (
"context"
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
// NSLogsIngestRow 对应 dns_logs_ingest 表一行.
type NSLogsIngestRow struct {
Timestamp time.Time
RequestId string
NodeId uint64
ClusterId uint64
DomainId uint64
RecordId uint64
RemoteAddr string
QuestionName string
QuestionType string
RecordName string
RecordType string
RecordValue string
Networking string
IsRecursive bool
Error string
NSRouteCodes []string
ContentJSON string
}
// NSListFilter DNS 日志查询过滤条件.
type NSListFilter struct {
Day string
Size int64
Reverse bool
LastRequestId string
NSClusterId int64
NSNodeId int64
NSDomainId int64
NSRecordId int64
RecordType string
Keyword string
}
// NSLogsIngestStore DNS ClickHouse 查询封装.
type NSLogsIngestStore struct {
client *Client
}
// NewNSLogsIngestStore 创建 NSLogsIngestStore.
func NewNSLogsIngestStore() *NSLogsIngestStore {
return &NSLogsIngestStore{client: NewClient()}
}
// Client 返回底层 client.
func (s *NSLogsIngestStore) Client() *Client {
return s.client
}
// List 列出 DNS 访问日志,返回列表、下一游标与是否有更多.
func (s *NSLogsIngestStore) List(ctx context.Context, f NSListFilter) (rows []*NSLogsIngestRow, nextCursor string, hasMore bool, err error) {
if !s.client.IsConfigured() {
return nil, "", false, fmt.Errorf("clickhouse: not configured")
}
if f.Day == "" {
return nil, "", false, fmt.Errorf("clickhouse: day required")
}
dayNumber, err := normalizeDayNumber(f.Day)
if err != nil {
return nil, "", false, err
}
table := quoteIdent("dns_logs_ingest")
if s.client.cfg.Database != "" && s.client.cfg.Database != "default" {
table = quoteIdent(s.client.cfg.Database) + "." + quoteIdent("dns_logs_ingest")
}
conditions := []string{"toYYYYMMDD(timestamp) = " + strconv.Itoa(dayNumber)}
if f.NSClusterId > 0 {
conditions = append(conditions, "cluster_id = "+strconv.FormatInt(f.NSClusterId, 10))
}
if f.NSNodeId > 0 {
conditions = append(conditions, "node_id = "+strconv.FormatInt(f.NSNodeId, 10))
}
if f.NSDomainId > 0 {
conditions = append(conditions, "domain_id = "+strconv.FormatInt(f.NSDomainId, 10))
}
if f.NSRecordId > 0 {
conditions = append(conditions, "record_id = "+strconv.FormatInt(f.NSRecordId, 10))
}
if f.RecordType != "" {
conditions = append(conditions, "question_type = '"+escapeString(f.RecordType)+"'")
}
if f.Keyword != "" {
keyword := escapeString(f.Keyword)
conditions = append(conditions, fmt.Sprintf("(remote_addr LIKE '%%%s%%' OR question_name LIKE '%%%s%%' OR record_value LIKE '%%%s%%' OR error LIKE '%%%s%%')", keyword, keyword, keyword, keyword))
}
// 游标分页reverse=false 查更旧reverse=true 查更新。
if f.LastRequestId != "" {
if f.Reverse {
conditions = append(conditions, "request_id > '"+escapeString(f.LastRequestId)+"'")
} else {
conditions = append(conditions, "request_id < '"+escapeString(f.LastRequestId)+"'")
}
}
orderDir := "DESC"
if f.Reverse {
orderDir = "ASC"
}
limit := f.Size
if limit <= 0 {
limit = 20
}
if limit > 1000 {
limit = 1000
}
query := fmt.Sprintf(
"SELECT timestamp, request_id, node_id, cluster_id, domain_id, record_id, remote_addr, question_name, question_type, record_name, record_type, record_value, networking, is_recursive, error, ns_route_codes, content_json FROM %s WHERE %s ORDER BY timestamp %s, request_id %s LIMIT %d",
table,
strings.Join(conditions, " AND "),
orderDir,
orderDir,
limit+1,
)
var rawRows []map[string]interface{}
if err = s.client.Query(ctx, query, &rawRows); err != nil {
return nil, "", false, err
}
rows = make([]*NSLogsIngestRow, 0, len(rawRows))
for _, rawRow := range rawRows {
row := mapToNSLogsIngestRow(rawRow)
if row != nil {
rows = append(rows, row)
}
}
hasMore = len(rows) > int(limit)
if hasMore {
nextCursor = rows[limit].RequestId
rows = rows[:limit]
} else if len(rows) > 0 {
nextCursor = rows[len(rows)-1].RequestId
}
if f.Reverse {
for left, right := 0, len(rows)-1; left < right; left, right = left+1, right-1 {
rows[left], rows[right] = rows[right], rows[left]
}
if len(rows) > 0 {
nextCursor = rows[0].RequestId
}
}
return rows, nextCursor, hasMore, nil
}
// FindByRequestId 按 request_id 查单条 DNS 日志.
func (s *NSLogsIngestStore) FindByRequestId(ctx context.Context, requestId string) (*NSLogsIngestRow, error) {
if !s.client.IsConfigured() {
return nil, fmt.Errorf("clickhouse: not configured")
}
if requestId == "" {
return nil, nil
}
table := quoteIdent("dns_logs_ingest")
if s.client.cfg.Database != "" && s.client.cfg.Database != "default" {
table = quoteIdent(s.client.cfg.Database) + "." + quoteIdent("dns_logs_ingest")
}
query := fmt.Sprintf(
"SELECT timestamp, request_id, node_id, cluster_id, domain_id, record_id, remote_addr, question_name, question_type, record_name, record_type, record_value, networking, is_recursive, error, ns_route_codes, content_json FROM %s WHERE request_id = '%s' LIMIT 1",
table,
escapeString(requestId),
)
var rawRows []map[string]interface{}
if err := s.client.Query(ctx, query, &rawRows); err != nil {
return nil, err
}
if len(rawRows) == 0 {
return nil, nil
}
return mapToNSLogsIngestRow(rawRows[0]), nil
}
func mapToNSLogsIngestRow(row map[string]interface{}) *NSLogsIngestRow {
result := &NSLogsIngestRow{}
u64 := func(key string) uint64 {
value, ok := row[key]
if !ok || value == nil {
return 0
}
switch typed := value.(type) {
case float64:
return uint64(typed)
case string:
number, _ := strconv.ParseUint(typed, 10, 64)
return number
case json.Number:
number, _ := typed.Int64()
return uint64(number)
case int64:
return uint64(typed)
case uint64:
return typed
}
return 0
}
str := func(key string) string {
value, ok := row[key]
if !ok || value == nil {
return ""
}
switch typed := value.(type) {
case string:
return typed
case json.Number:
return typed.String()
default:
return fmt.Sprintf("%v", typed)
}
}
ts := func(key string) time.Time {
value, ok := row[key]
if !ok || value == nil {
return time.Time{}
}
switch typed := value.(type) {
case string:
if typed == "" {
return time.Time{}
}
layouts := []string{
"2006-01-02 15:04:05",
time.RFC3339,
"2006-01-02T15:04:05",
}
for _, layout := range layouts {
if parsed, err := time.Parse(layout, typed); err == nil {
return parsed
}
}
case float64:
return time.Unix(int64(typed), 0)
case json.Number:
number, _ := typed.Int64()
return time.Unix(number, 0)
}
return time.Time{}
}
boolValue := func(key string) bool {
value, ok := row[key]
if !ok || value == nil {
return false
}
switch typed := value.(type) {
case bool:
return typed
case float64:
return typed > 0
case int64:
return typed > 0
case uint64:
return typed > 0
case string:
switch strings.ToLower(strings.TrimSpace(typed)) {
case "1", "true", "yes":
return true
}
}
return false
}
parseStringArray := func(key string) []string {
value, ok := row[key]
if !ok || value == nil {
return nil
}
switch typed := value.(type) {
case []string:
return typed
case []interface{}:
result := make([]string, 0, len(typed))
for _, one := range typed {
if one == nil {
continue
}
result = append(result, fmt.Sprintf("%v", one))
}
return result
case string:
if typed == "" {
return nil
}
var result []string
if json.Unmarshal([]byte(typed), &result) == nil {
return result
}
return []string{typed}
}
return nil
}
result.Timestamp = ts("timestamp")
result.RequestId = str("request_id")
result.NodeId = u64("node_id")
result.ClusterId = u64("cluster_id")
result.DomainId = u64("domain_id")
result.RecordId = u64("record_id")
result.RemoteAddr = str("remote_addr")
result.QuestionName = str("question_name")
result.QuestionType = str("question_type")
result.RecordName = str("record_name")
result.RecordType = str("record_type")
result.RecordValue = str("record_value")
result.Networking = str("networking")
result.IsRecursive = boolValue("is_recursive")
result.Error = str("error")
result.NSRouteCodes = parseStringArray("ns_route_codes")
result.ContentJSON = str("content_json")
return result
}
// NSRowToPB 将 ClickHouse 行转换为 pb.NSAccessLog.
func NSRowToPB(row *NSLogsIngestRow) *pb.NSAccessLog {
if row == nil {
return nil
}
log := &pb.NSAccessLog{
NsNodeId: int64(row.NodeId),
NsDomainId: int64(row.DomainId),
NsRecordId: int64(row.RecordId),
NsRouteCodes: row.NSRouteCodes,
RemoteAddr: row.RemoteAddr,
QuestionName: row.QuestionName,
QuestionType: row.QuestionType,
RecordName: row.RecordName,
RecordType: row.RecordType,
RecordValue: row.RecordValue,
Networking: row.Networking,
Timestamp: row.Timestamp.Unix(),
RequestId: row.RequestId,
Error: row.Error,
IsRecursive: row.IsRecursive,
}
if !row.Timestamp.IsZero() {
log.TimeLocal = row.Timestamp.Format("2/Jan/2006:15:04:05 -0700")
}
if row.ContentJSON != "" {
contentLog := &pb.NSAccessLog{}
if json.Unmarshal([]byte(row.ContentJSON), contentLog) == nil {
contentLog.RequestId = row.RequestId
return contentLog
}
}
return log
}

View File

@@ -108,6 +108,7 @@ func (this *HTTPAccessLogPolicyDAO) FindAllEnabledAndOnPolicies(tx *dbs.Tx) (res
// CreatePolicy 创建策略
func (this *HTTPAccessLogPolicyDAO) CreatePolicy(tx *dbs.Tx, name string, policyType string, optionsJSON []byte, condsJSON []byte, isPublic bool, firewallOnly bool, disableDefaultDB bool, writeTargetsJSON []byte) (policyId int64, err error) {
_ = writeTargetsJSON
var op = NewHTTPAccessLogPolicyOperator()
op.Name = name
op.Type = policyType
@@ -121,15 +122,14 @@ func (this *HTTPAccessLogPolicyDAO) CreatePolicy(tx *dbs.Tx, name string, policy
op.IsOn = true
op.FirewallOnly = firewallOnly
op.DisableDefaultDB = disableDefaultDB
if len(writeTargetsJSON) > 0 {
op.WriteTargets = writeTargetsJSON
}
op.WriteTargets = dbs.SQL("NULL")
op.State = HTTPAccessLogPolicyStateEnabled
return this.SaveInt64(tx, op)
}
// UpdatePolicy 修改策略
func (this *HTTPAccessLogPolicyDAO) UpdatePolicy(tx *dbs.Tx, policyId int64, name string, policyType string, optionsJSON []byte, condsJSON []byte, isPublic bool, firewallOnly bool, disableDefaultDB bool, writeTargetsJSON []byte, isOn bool) error {
_ = writeTargetsJSON
if policyId <= 0 {
return errors.New("invalid policyId")
}
@@ -167,9 +167,7 @@ func (this *HTTPAccessLogPolicyDAO) UpdatePolicy(tx *dbs.Tx, policyId int64, nam
op.IsPublic = isPublic
op.FirewallOnly = firewallOnly
op.DisableDefaultDB = disableDefaultDB
if len(writeTargetsJSON) > 0 {
op.WriteTargets = writeTargetsJSON
}
op.WriteTargets = dbs.SQL("NULL")
op.IsOn = isOn
return this.Save(tx, op)
}

View File

@@ -0,0 +1,22 @@
package models
import (
"encoding/json"
"strings"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
)
// ParseHTTPAccessLogPolicyFilePath 提取访问日志策略中的文件路径(所有 file* 类型有效)。
func ParseHTTPAccessLogPolicyFilePath(policy *HTTPAccessLogPolicy) string {
if policy == nil || !serverconfigs.IsFileBasedStorageType(policy.Type) || len(policy.Options) == 0 {
return ""
}
config := &serverconfigs.AccessLogFileStorageConfig{}
if err := json.Unmarshal(policy.Options, config); err != nil {
return ""
}
return strings.TrimSpace(config.Path)
}

View File

@@ -1174,7 +1174,8 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared
if publicPolicyId > 0 {
publicPolicy, _ := SharedHTTPAccessLogPolicyDAO.FindEnabledHTTPAccessLogPolicy(tx, publicPolicyId)
if publicPolicy != nil {
config.GlobalServerConfig.HTTPAccessLog.WriteTargets = serverconfigs.ParseWriteTargetsFromPolicy(publicPolicy.WriteTargets, publicPolicy.Type, publicPolicy.DisableDefaultDB)
config.GlobalServerConfig.HTTPAccessLog.WriteTargets = serverconfigs.ResolveWriteTargetsByType(publicPolicy.Type, publicPolicy.DisableDefaultDB)
config.GlobalServerConfig.HTTPAccessLog.FilePath = ParseHTTPAccessLogPolicyFilePath(publicPolicy)
}
}
}

View File

@@ -472,6 +472,16 @@ func (this *NSNodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64) (*dnsconfigs.
}
}
}
{
publicPolicyId, _ := SharedHTTPAccessLogPolicyDAO.FindCurrentPublicPolicyId(tx)
if publicPolicyId > 0 {
publicPolicy, _ := SharedHTTPAccessLogPolicyDAO.FindEnabledHTTPAccessLogPolicy(tx, publicPolicyId)
if publicPolicy != nil {
config.AccessLogWriteTargets = serverconfigs.ResolveWriteTargetsByType(publicPolicy.Type, publicPolicy.DisableDefaultDB)
config.AccessLogFilePath = ParseHTTPAccessLogPolicyFilePath(publicPolicy)
}
}
}
// 递归DNS配置
if IsNotNull(cluster.Recursion) {

View File

@@ -4,6 +4,7 @@ package nameservers
import (
"context"
"github.com/TeaOSLab/EdgeAPI/internal/clickhouse"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/db/models/nameservers"
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
@@ -29,11 +30,13 @@ func (this *NSAccessLogService) CreateNSAccessLogs(ctx context.Context, req *pb.
return &pb.CreateNSAccessLogsResponse{}, nil
}
var tx = this.NullTx()
if this.canWriteNSAccessLogsToDB() {
var tx = this.NullTx()
err = models.SharedNSAccessLogDAO.CreateNSAccessLogs(tx, req.NsAccessLogs)
if err != nil {
return nil, err
err = models.SharedNSAccessLogDAO.CreateNSAccessLogs(tx, req.NsAccessLogs)
if err != nil {
return nil, err
}
}
return &pb.CreateNSAccessLogsResponse{}, nil
@@ -54,6 +57,34 @@ func (this *NSAccessLogService) ListNSAccessLogs(ctx context.Context, req *pb.Li
// TODO 检查权限
}
store := clickhouse.NewNSLogsIngestStore()
canReadFromClickHouse := this.shouldReadNSAccessLogsFromClickHouse() && store.Client().IsConfigured() && req.Day != ""
canReadFromMySQL := this.shouldReadNSAccessLogsFromMySQL()
if canReadFromClickHouse {
resp, listErr := this.listNSAccessLogsFromClickHouse(ctx, store, req)
if listErr == nil && resp != nil {
return resp, nil
}
if !canReadFromMySQL {
if listErr != nil {
return nil, listErr
}
return &pb.ListNSAccessLogsResponse{
NsAccessLogs: []*pb.NSAccessLog{},
HasMore: false,
RequestId: "",
}, nil
}
}
if !canReadFromMySQL {
return &pb.ListNSAccessLogsResponse{
NsAccessLogs: []*pb.NSAccessLog{},
HasMore: false,
RequestId: "",
}, nil
}
accessLogs, requestId, hasMore, err := models.SharedNSAccessLogDAO.ListAccessLogs(tx, req.RequestId, req.Size, req.Day, req.NsClusterId, req.NsNodeId, req.NsDomainId, req.NsRecordId, req.RecordType, req.Keyword, req.Reverse)
if err != nil {
return nil, err
@@ -67,23 +98,9 @@ func (this *NSAccessLogService) ListNSAccessLogs(ctx context.Context, req *pb.Li
}
// 线路
if len(a.NsRouteCodes) > 0 {
for _, routeCode := range a.NsRouteCodes {
route, err := nameservers.SharedNSRouteDAO.FindEnabledRouteWithCode(nil, routeCode)
if err != nil {
return nil, err
}
if route != nil {
a.NsRoutes = append(a.NsRoutes, &pb.NSRoute{
Id: types.Int64(route.Id),
IsOn: route.IsOn,
Name: route.Name,
Code: routeCode,
NsCluster: nil,
NsDomain: nil,
})
}
}
err = this.fillNSRoutes(a)
if err != nil {
return nil, err
}
result = append(result, a)
@@ -104,6 +121,31 @@ func (this *NSAccessLogService) FindNSAccessLog(ctx context.Context, req *pb.Fin
return nil, err
}
store := clickhouse.NewNSLogsIngestStore()
canReadFromClickHouse := this.shouldReadNSAccessLogsFromClickHouse() && store.Client().IsConfigured()
canReadFromMySQL := this.shouldReadNSAccessLogsFromMySQL()
if canReadFromClickHouse {
row, findErr := store.FindByRequestId(ctx, req.RequestId)
if findErr != nil {
if !canReadFromMySQL {
return nil, findErr
}
} else if row != nil {
a := clickhouse.NSRowToPB(row)
if a != nil {
err = this.fillNSRoutes(a)
if err != nil {
return nil, err
}
}
return &pb.FindNSAccessLogResponse{NsAccessLog: a}, nil
}
}
if !canReadFromMySQL {
return &pb.FindNSAccessLogResponse{NsAccessLog: nil}, nil
}
var tx = this.NullTx()
accessLog, err := models.SharedNSAccessLogDAO.FindAccessLogWithRequestId(tx, req.RequestId)
@@ -123,5 +165,70 @@ func (this *NSAccessLogService) FindNSAccessLog(ctx context.Context, req *pb.Fin
if err != nil {
return nil, err
}
err = this.fillNSRoutes(a)
if err != nil {
return nil, err
}
return &pb.FindNSAccessLogResponse{NsAccessLog: a}, nil
}
func (this *NSAccessLogService) listNSAccessLogsFromClickHouse(ctx context.Context, store *clickhouse.NSLogsIngestStore, req *pb.ListNSAccessLogsRequest) (*pb.ListNSAccessLogsResponse, error) {
rows, nextCursor, hasMore, err := store.List(ctx, clickhouse.NSListFilter{
Day: req.Day,
Size: req.Size,
Reverse: req.Reverse,
LastRequestId: req.RequestId,
NSClusterId: req.NsClusterId,
NSNodeId: req.NsNodeId,
NSDomainId: req.NsDomainId,
NSRecordId: req.NsRecordId,
RecordType: req.RecordType,
Keyword: req.Keyword,
})
if err != nil {
return nil, err
}
result := make([]*pb.NSAccessLog, 0, len(rows))
for _, row := range rows {
a := clickhouse.NSRowToPB(row)
if a == nil {
continue
}
err = this.fillNSRoutes(a)
if err != nil {
return nil, err
}
result = append(result, a)
}
return &pb.ListNSAccessLogsResponse{
NsAccessLogs: result,
HasMore: hasMore,
RequestId: nextCursor,
}, nil
}
func (this *NSAccessLogService) fillNSRoutes(accessLog *pb.NSAccessLog) error {
if accessLog == nil || len(accessLog.NsRouteCodes) == 0 {
return nil
}
for _, routeCode := range accessLog.NsRouteCodes {
route, err := nameservers.SharedNSRouteDAO.FindEnabledRouteWithCode(nil, routeCode)
if err != nil {
return err
}
if route != nil {
accessLog.NsRoutes = append(accessLog.NsRoutes, &pb.NSRoute{
Id: types.Int64(route.Id),
IsOn: route.IsOn,
Name: route.Name,
Code: routeCode,
NsCluster: nil,
NsDomain: nil,
})
}
}
return nil
}

View File

@@ -0,0 +1,17 @@
//go:build plus
package nameservers
import "github.com/TeaOSLab/EdgeAPI/internal/accesslogs"
func (this *NSAccessLogService) canWriteNSAccessLogsToDB() bool {
return accesslogs.SharedStorageManager.WriteMySQL()
}
func (this *NSAccessLogService) shouldReadNSAccessLogsFromClickHouse() bool {
return accesslogs.SharedStorageManager.WriteClickHouse()
}
func (this *NSAccessLogService) shouldReadNSAccessLogsFromMySQL() bool {
return accesslogs.SharedStorageManager.WriteMySQL()
}

View File

@@ -8,12 +8,27 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/accesslogs"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
)
type HTTPAccessLogPolicyService struct {
BaseService
}
func (this *HTTPAccessLogPolicyService) normalizeStorageTypeAndTargets(policyType string, writeTargetsJSON []byte, disableDefaultDB bool) (string, []byte) {
_ = writeTargetsJSON
_ = disableDefaultDB
// 兼容旧前端/缓存可能传来的历史类型编码
switch policyType {
case "clickhouse":
policyType = serverconfigs.AccessLogStorageTypeFileClickhouse
case "mysql_clickhouse":
policyType = serverconfigs.AccessLogStorageTypeFileMySQLClickhouse
}
return policyType, nil
}
// CountAllHTTPAccessLogPolicies 计算访问日志策略数量
func (this *HTTPAccessLogPolicyService) CountAllHTTPAccessLogPolicies(ctx context.Context, req *pb.CountAllHTTPAccessLogPoliciesRequest) (*pb.RPCCountResponse, error) {
_, err := this.ValidateAdmin(ctx)
@@ -53,7 +68,7 @@ func (this *HTTPAccessLogPolicyService) ListHTTPAccessLogPolicies(ctx context.Co
IsPublic: policy.IsPublic,
FirewallOnly: policy.FirewallOnly == 1,
DisableDefaultDB: policy.DisableDefaultDB,
WriteTargetsJSON: policy.WriteTargets,
WriteTargetsJSON: nil,
})
}
return &pb.ListHTTPAccessLogPoliciesResponse{HttpAccessLogPolicies: pbPolicies}, nil
@@ -76,8 +91,10 @@ func (this *HTTPAccessLogPolicyService) CreateHTTPAccessLogPolicy(ctx context.Co
}
}
policyType, writeTargetsJSON := this.normalizeStorageTypeAndTargets(req.Type, req.WriteTargetsJSON, req.DisableDefaultDB)
// 创建
policyId, err := models.SharedHTTPAccessLogPolicyDAO.CreatePolicy(tx, req.Name, req.Type, req.OptionsJSON, req.CondsJSON, req.IsPublic, req.FirewallOnly, req.DisableDefaultDB, req.WriteTargetsJSON)
policyId, err := models.SharedHTTPAccessLogPolicyDAO.CreatePolicy(tx, req.Name, policyType, req.OptionsJSON, req.CondsJSON, req.IsPublic, req.FirewallOnly, req.DisableDefaultDB, writeTargetsJSON)
if err != nil {
return nil, err
}
@@ -101,8 +118,10 @@ func (this *HTTPAccessLogPolicyService) UpdateHTTPAccessLogPolicy(ctx context.Co
}
}
policyType, writeTargetsJSON := this.normalizeStorageTypeAndTargets(req.Type, req.WriteTargetsJSON, req.DisableDefaultDB)
// 保存修改
err = models.SharedHTTPAccessLogPolicyDAO.UpdatePolicy(tx, req.HttpAccessLogPolicyId, req.Name, req.Type, req.OptionsJSON, req.CondsJSON, req.IsPublic, req.FirewallOnly, req.DisableDefaultDB, req.WriteTargetsJSON, req.IsOn)
err = models.SharedHTTPAccessLogPolicyDAO.UpdatePolicy(tx, req.HttpAccessLogPolicyId, req.Name, policyType, req.OptionsJSON, req.CondsJSON, req.IsPublic, req.FirewallOnly, req.DisableDefaultDB, writeTargetsJSON, req.IsOn)
if err != nil {
return nil, err
}
@@ -134,7 +153,7 @@ func (this *HTTPAccessLogPolicyService) FindHTTPAccessLogPolicy(ctx context.Cont
IsPublic: policy.IsPublic,
FirewallOnly: policy.FirewallOnly == 1,
DisableDefaultDB: policy.DisableDefaultDB,
WriteTargetsJSON: policy.WriteTargets,
WriteTargetsJSON: nil,
}}, nil
}