mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-05 15:26:36 +08:00
416603b616
- Replace db.DB(ctx) with database.DB(ctx) from plugins/infra/database
- Replace db.Redis/db.PrefixedKey/db.GetJSON/db.SetJSON with cachepkg.* from plugins/infra/cache
- Replace pkg/persistence/idgen with pkg/idgen (already exists)
- Replace pkg/persistence/batchwriter with pkg/batchwriter (already exists)
- Replace pkg/persistence/migrator with pkg/migrator (already exists)
- Replace pkg/persistence/logstore with plugins/domain/risk_control/logstore
- Delete defunct pkg/{persistence,cap,message_gateway,push,shared,task}
- Fix vet issues: db alias in domain_test.go, driver_asynq_worker.TaskHandler reference
- Update Makefile architecture guard
- Update docs and skill references
- Update go.mod: gorilla/sessions promotion to direct dependency
141 lines
3.3 KiB
Go
141 lines
3.3 KiB
Go
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package logstore
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sort"
|
|
"time"
|
|
|
|
db "github.com/Rain-kl/Wavelet/plugins/infra/database"
|
|
)
|
|
|
|
const hoursInDay = 24
|
|
|
|
// GetDailyTrend returns per-day access counts for the last days days (inclusive of today).
|
|
func GetDailyTrend(ctx context.Context, days int) ([]DailyTrend, error) {
|
|
if days < 1 {
|
|
days = 7
|
|
}
|
|
|
|
ch := db.ChDB(ctx)
|
|
if ch == nil {
|
|
return nil, fmt.Errorf("clickhouse gorm connection is not initialized")
|
|
}
|
|
|
|
startTime := time.Now().AddDate(0, 0, -(days - 1)).Truncate(hoursInDay * time.Hour)
|
|
tableName := UserAccessLog{}.TableName()
|
|
|
|
query := fmt.Sprintf(`
|
|
SELECT toDate(created_at) AS date, count() AS count
|
|
FROM %s
|
|
WHERE created_at >= ?
|
|
GROUP BY date
|
|
ORDER BY date ASC
|
|
`, tableName)
|
|
|
|
type trendRow struct {
|
|
Date time.Time
|
|
Count uint64
|
|
}
|
|
|
|
var rows []trendRow
|
|
if err := ch.Raw(query, startTime).Scan(&rows).Error; err != nil {
|
|
return nil, fmt.Errorf("get daily trend: %w", err)
|
|
}
|
|
|
|
trendMap := make(map[string]uint64, days)
|
|
for i := 0; i < days; i++ {
|
|
dateStr := time.Now().AddDate(0, 0, -i).Format("2006-01-02")
|
|
trendMap[dateStr] = 0
|
|
}
|
|
for _, row := range rows {
|
|
dateStr := row.Date.Format("2006-01-02")
|
|
trendMap[dateStr] = row.Count
|
|
}
|
|
|
|
result := make([]DailyTrend, 0, days)
|
|
for i := days - 1; i >= 0; i-- {
|
|
dateStr := time.Now().AddDate(0, 0, -i).Format("2006-01-02")
|
|
result = append(result, DailyTrend{
|
|
Date: dateStr,
|
|
Count: trendMap[dateStr],
|
|
})
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// GetBrowserDistribution returns browser-grouped access counts since startTime.
|
|
func GetBrowserDistribution(ctx context.Context, startTime time.Time) ([]BrowserShare, error) {
|
|
ch := db.ChDB(ctx)
|
|
if ch == nil {
|
|
return nil, fmt.Errorf("clickhouse gorm connection is not initialized")
|
|
}
|
|
|
|
tableName := UserAccessLog{}.TableName()
|
|
query := fmt.Sprintf(`
|
|
SELECT user_agent, count() AS count
|
|
FROM %s
|
|
WHERE created_at >= ?
|
|
GROUP BY user_agent
|
|
`, tableName)
|
|
|
|
type uaRow struct {
|
|
UserAgent string
|
|
Count uint64
|
|
}
|
|
|
|
var rows []uaRow
|
|
if err := ch.Raw(query, startTime).Scan(&rows).Error; err != nil {
|
|
return nil, fmt.Errorf("get browser distribution: %w", err)
|
|
}
|
|
|
|
browserCounts := make(map[string]uint64)
|
|
for _, row := range rows {
|
|
browser := ParseBrowserName(row.UserAgent)
|
|
browserCounts[browser] += row.Count
|
|
}
|
|
|
|
result := make([]BrowserShare, 0, len(browserCounts))
|
|
for browser, count := range browserCounts {
|
|
result = append(result, BrowserShare{
|
|
Browser: browser,
|
|
Count: count,
|
|
})
|
|
}
|
|
sort.Slice(result, func(i, j int) bool {
|
|
return result[i].Count > result[j].Count
|
|
})
|
|
return result, nil
|
|
}
|
|
|
|
// GetTopActiveUsers returns the most active users since startTime.
|
|
func GetTopActiveUsers(ctx context.Context, startTime time.Time, limit int) ([]TopUser, error) {
|
|
if limit < 1 {
|
|
limit = 10
|
|
}
|
|
|
|
ch := db.ChDB(ctx)
|
|
if ch == nil {
|
|
return nil, fmt.Errorf("clickhouse gorm connection is not initialized")
|
|
}
|
|
|
|
tableName := UserAccessLog{}.TableName()
|
|
query := fmt.Sprintf(`
|
|
SELECT user_id, count() AS count
|
|
FROM %s
|
|
WHERE created_at >= ? AND user_id > 0
|
|
GROUP BY user_id
|
|
ORDER BY count DESC
|
|
LIMIT ?
|
|
`, tableName)
|
|
|
|
var users []TopUser
|
|
if err := ch.Raw(query, startTime, limit).Scan(&users).Error; err != nil {
|
|
return nil, fmt.Errorf("get top active users: %w", err)
|
|
}
|
|
return users, nil
|
|
}
|