mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-28 05:46:36 +08:00
feat(access-logs): 概览支持 Zone/域名多选筛选
概览可按 Zone→Domain 层级多选域名并折叠展开;明细列表 IP 旁展示地区。 后端 overview 支持 hosts 多域名精确匹配。
This commit is contained in:
@@ -216,9 +216,10 @@ type AccessLogIPAnalysisView struct {
|
||||
|
||||
// AccessLogOverviewQuery filters access log overview queries.
|
||||
type AccessLogOverviewQuery struct {
|
||||
NodeID string `json:"node_id"`
|
||||
Host string `json:"host"`
|
||||
Hours int `json:"hours"`
|
||||
NodeID string `json:"node_id"`
|
||||
Host string `json:"host"`
|
||||
Hosts []string `json:"hosts"`
|
||||
Hours int `json:"hours"`
|
||||
}
|
||||
|
||||
// AccessLogOverviewMetricPoint is a single overview trend bucket.
|
||||
@@ -284,6 +285,7 @@ func GetAccessLogOverview(ctx context.Context, input AccessLogOverviewQuery) (*A
|
||||
query := model.OpenFlareAccessLogQuery{
|
||||
NodeID: normalized.NodeID,
|
||||
Host: normalized.Host,
|
||||
Hosts: normalized.Hosts,
|
||||
Since: since,
|
||||
Until: now,
|
||||
}
|
||||
@@ -330,13 +332,45 @@ func normalizeAccessLogOverviewQuery(input AccessLogOverviewQuery) AccessLogOver
|
||||
if hours > maxAccessLogOverviewHours {
|
||||
hours = maxAccessLogOverviewHours
|
||||
}
|
||||
hosts := normalizeAccessLogOverviewHosts(input.Hosts)
|
||||
host := strings.TrimSpace(input.Host)
|
||||
if len(hosts) == 0 && host != "" {
|
||||
// Single host query uses Hosts exact-match for consistency with multi-select.
|
||||
hosts = []string{host}
|
||||
host = ""
|
||||
}
|
||||
if len(hosts) > 0 {
|
||||
host = ""
|
||||
}
|
||||
return AccessLogOverviewQuery{
|
||||
NodeID: strings.TrimSpace(input.NodeID),
|
||||
Host: strings.TrimSpace(input.Host),
|
||||
Host: host,
|
||||
Hosts: hosts,
|
||||
Hours: hours,
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeAccessLogOverviewHosts(hosts []string) []string {
|
||||
if len(hosts) == 0 {
|
||||
return nil
|
||||
}
|
||||
seen := make(map[string]struct{}, len(hosts))
|
||||
result := make([]string, 0, len(hosts))
|
||||
for _, host := range hosts {
|
||||
trimmed := strings.TrimSpace(host)
|
||||
if trimmed == "" {
|
||||
continue
|
||||
}
|
||||
key := strings.ToLower(trimmed)
|
||||
if _, exists := seen[key]; exists {
|
||||
continue
|
||||
}
|
||||
seen[key] = struct{}{}
|
||||
result = append(result, trimmed)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func valueCountDistribution(
|
||||
ctx context.Context,
|
||||
query model.OpenFlareAccessLogQuery,
|
||||
@@ -427,6 +461,7 @@ func buildAccessLogOverviewTrends(
|
||||
buckets, err := model.ListOpenFlareAccessLogBuckets(ctx, model.OpenFlareAccessLogBucketQuery{
|
||||
NodeID: query.NodeID,
|
||||
Host: query.Host,
|
||||
Hosts: query.Hosts,
|
||||
Since: query.Since,
|
||||
Until: query.Until,
|
||||
FoldMinutes: 60,
|
||||
|
||||
@@ -19,7 +19,8 @@ import (
|
||||
// @Produce json
|
||||
// @Security SessionCookie
|
||||
// @Param node_id query string false "节点 ID"
|
||||
// @Param host query string false "请求 Host"
|
||||
// @Param host query string false "请求 Host(单域名)"
|
||||
// @Param hosts query []string false "请求 Host 列表(多域名精确匹配)"
|
||||
// @Param hours query int false "统计时间范围(小时)"
|
||||
// @Success 200 {object} response.Any{data=observability.AccessLogOverview} "访问日志概览"
|
||||
// @Failure 400 {object} response.Any "参数错误"
|
||||
@@ -31,6 +32,7 @@ func GetAccessLogOverviewHandler(c *gin.Context) {
|
||||
result, err := GetAccessLogOverview(c.Request.Context(), AccessLogOverviewQuery{
|
||||
NodeID: c.Query("node_id"),
|
||||
Host: c.Query("host"),
|
||||
Hosts: c.QueryArray("hosts"),
|
||||
Hours: readQueryInt(c, "hours"),
|
||||
})
|
||||
if apiutil.AbortBadRequestOnError(c, err) {
|
||||
|
||||
Reference in New Issue
Block a user