This commit is contained in:
robin
2026-03-13 14:25:13 +08:00
parent a25a474d6a
commit afbaaa869c
95 changed files with 4591 additions and 2578 deletions

View File

@@ -47,6 +47,33 @@ type HTTPDNSAccessLogListFilter struct {
Size int64
}
type HTTPDNSAccessLogHourlyStat struct {
Hour string
CountRequests int64
}
type HTTPDNSAccessLogDailyStat struct {
Day string
CountRequests int64
}
type HTTPDNSAccessLogTopAppStat struct {
AppId string
AppName string
CountRequests int64
}
type HTTPDNSAccessLogTopDomainStat struct {
Domain string
CountRequests int64
}
type HTTPDNSAccessLogTopNodeStat struct {
ClusterId uint32
NodeId uint32
CountRequests int64
}
type HTTPDNSAccessLogsStore struct {
client *Client
}
@@ -176,6 +203,155 @@ func (s *HTTPDNSAccessLogsStore) List(ctx context.Context, f HTTPDNSAccessLogLis
return result, nil
}
func (s *HTTPDNSAccessLogsStore) FindHourlyStats(ctx context.Context, hourFrom string, hourTo string) ([]*HTTPDNSAccessLogHourlyStat, error) {
if !s.client.IsConfigured() {
return nil, fmt.Errorf("clickhouse: not configured")
}
query := fmt.Sprintf(
"SELECT formatDateTime(toDateTime(created_at), '%%Y%%m%%d%%H') AS hour, count() AS count_requests FROM %s WHERE formatDateTime(toDateTime(created_at), '%%Y%%m%%d%%H') BETWEEN '%s' AND '%s' GROUP BY hour ORDER BY hour ASC",
s.tableName(),
escapeString(hourFrom),
escapeString(hourTo),
)
rows := []map[string]interface{}{}
if err := s.client.Query(ctx, query, &rows); err != nil {
return nil, err
}
result := make([]*HTTPDNSAccessLogHourlyStat, 0, len(rows))
for _, row := range rows {
result = append(result, &HTTPDNSAccessLogHourlyStat{
Hour: toString(row["hour"]),
CountRequests: toInt64(row["count_requests"]),
})
}
return result, nil
}
func (s *HTTPDNSAccessLogsStore) FindDailyStats(ctx context.Context, dayFrom string, dayTo string) ([]*HTTPDNSAccessLogDailyStat, error) {
if !s.client.IsConfigured() {
return nil, fmt.Errorf("clickhouse: not configured")
}
query := fmt.Sprintf(
"SELECT day, count() AS count_requests FROM %s WHERE day BETWEEN '%s' AND '%s' GROUP BY day ORDER BY day ASC",
s.tableName(),
escapeString(dayFrom),
escapeString(dayTo),
)
rows := []map[string]interface{}{}
if err := s.client.Query(ctx, query, &rows); err != nil {
return nil, err
}
result := make([]*HTTPDNSAccessLogDailyStat, 0, len(rows))
for _, row := range rows {
result = append(result, &HTTPDNSAccessLogDailyStat{
Day: toString(row["day"]),
CountRequests: toInt64(row["count_requests"]),
})
}
return result, nil
}
func (s *HTTPDNSAccessLogsStore) ListTopApps(ctx context.Context, dayFrom string, dayTo string, limit int64) ([]*HTTPDNSAccessLogTopAppStat, error) {
if !s.client.IsConfigured() {
return nil, fmt.Errorf("clickhouse: not configured")
}
if limit <= 0 {
limit = 10
}
query := fmt.Sprintf(
"SELECT app_id, max(app_name) AS app_name, count() AS count_requests FROM %s WHERE day BETWEEN '%s' AND '%s' GROUP BY app_id ORDER BY count_requests DESC LIMIT %d",
s.tableName(),
escapeString(dayFrom),
escapeString(dayTo),
limit,
)
rows := []map[string]interface{}{}
if err := s.client.Query(ctx, query, &rows); err != nil {
return nil, err
}
result := make([]*HTTPDNSAccessLogTopAppStat, 0, len(rows))
for _, row := range rows {
result = append(result, &HTTPDNSAccessLogTopAppStat{
AppId: toString(row["app_id"]),
AppName: toString(row["app_name"]),
CountRequests: toInt64(row["count_requests"]),
})
}
return result, nil
}
func (s *HTTPDNSAccessLogsStore) ListTopDomains(ctx context.Context, dayFrom string, dayTo string, limit int64) ([]*HTTPDNSAccessLogTopDomainStat, error) {
if !s.client.IsConfigured() {
return nil, fmt.Errorf("clickhouse: not configured")
}
if limit <= 0 {
limit = 10
}
query := fmt.Sprintf(
"SELECT domain, count() AS count_requests FROM %s WHERE day BETWEEN '%s' AND '%s' AND domain != '' GROUP BY domain ORDER BY count_requests DESC LIMIT %d",
s.tableName(),
escapeString(dayFrom),
escapeString(dayTo),
limit,
)
rows := []map[string]interface{}{}
if err := s.client.Query(ctx, query, &rows); err != nil {
return nil, err
}
result := make([]*HTTPDNSAccessLogTopDomainStat, 0, len(rows))
for _, row := range rows {
result = append(result, &HTTPDNSAccessLogTopDomainStat{
Domain: toString(row["domain"]),
CountRequests: toInt64(row["count_requests"]),
})
}
return result, nil
}
func (s *HTTPDNSAccessLogsStore) ListTopNodes(ctx context.Context, dayFrom string, dayTo string, limit int64) ([]*HTTPDNSAccessLogTopNodeStat, error) {
if !s.client.IsConfigured() {
return nil, fmt.Errorf("clickhouse: not configured")
}
if limit <= 0 {
limit = 10
}
query := fmt.Sprintf(
"SELECT min(cluster_id) AS cluster_id, node_id, count() AS count_requests FROM %s WHERE day BETWEEN '%s' AND '%s' GROUP BY node_id ORDER BY count_requests DESC LIMIT %d",
s.tableName(),
escapeString(dayFrom),
escapeString(dayTo),
limit,
)
rows := []map[string]interface{}{}
if err := s.client.Query(ctx, query, &rows); err != nil {
return nil, err
}
result := make([]*HTTPDNSAccessLogTopNodeStat, 0, len(rows))
for _, row := range rows {
result = append(result, &HTTPDNSAccessLogTopNodeStat{
ClusterId: uint32(toInt64(row["cluster_id"])),
NodeId: uint32(toInt64(row["node_id"])),
CountRequests: toInt64(row["count_requests"]),
})
}
return result, nil
}
func HTTPDNSRowToPB(row *HTTPDNSAccessLogRow) *pb.HTTPDNSAccessLog {
if row == nil {
return nil