@@ -8,9 +8,18 @@ import (
88 "context"
99 "github.com/redis/go-redis/v9"
1010 "strconv"
11+ "strings"
1112 "time"
1213)
1314
15+ const (
16+ kAccessReports_ = "AccessReports:"
17+ kAccessReports_Timestamps = "AccessReports:Timestamps"
18+ kAccessCounts_Targets = "AccessCounts:Targets"
19+ kAccessAddrs_Target_ = "AccessAddrs:Target:"
20+ kAccessUuids_Target_ = "AccessUuids:Target:"
21+ )
22+
1423type Database struct {
1524 Client * redis.Client
1625}
@@ -23,23 +32,85 @@ func (db *Database) AddAccessReport(ctx context.Context, report *AccessReport) e
2332 score , _ = strconv .ParseFloat (now .Format ("20060102150405.99" ), 64 )
2433 )
2534
26- err := db .Client .HSet (ctx , "AccessReports:" + timestamp , * report ).Err ()
35+ err := db .Client .HSet (ctx , kAccessReports_ + timestamp , * report ).Err ()
2736 if err != nil {
2837 return err
2938 }
3039
31- err = db .Client .ZAdd (ctx , "AccessReports:Timestamps" , redis.Z {Score : score , Member : timestamp }).Err ()
40+ err = db .Client .ZAdd (ctx , kAccessReports_Timestamps , redis.Z {Score : score , Member : timestamp }).Err ()
3241 if err != nil {
3342 return err
3443 }
3544
36- return nil
45+ return db .Client .HIncrBy (ctx , kAccessCounts_Targets , report .Target , 1 ).Err ()
46+ }
47+
48+ func (db * Database ) AddAccessAddrOfTarget (ctx context.Context , target , addr string ) error {
49+ return db .Client .SAdd (ctx , kAccessAddrs_Target_ + target , addr ).Err ()
50+ }
51+
52+ func (db * Database ) AddAccessUuidOfTarget (ctx context.Context , target , uuid string ) error {
53+ return db .Client .SAdd (ctx , kAccessUuids_Target_ + target , uuid ).Err ()
3754}
3855
3956func (db * Database ) GetAccessReportsTimestamps (ctx context.Context , start , end string ) ([]string , error ) {
40- return db .Client .ZRangeByScore (ctx , "AccessReports:Timestamps" , & redis.ZRangeBy {Min : start , Max : end }).Result ()
57+ return db .Client .ZRangeByScore (ctx , kAccessReports_Timestamps , & redis.ZRangeBy {Min : start , Max : end }).Result ()
4158}
4259
4360func (db * Database ) GetAccessReportByTimestamp (ctx context.Context , timestamp string ) (report AccessReport , _ error ) {
44- return report , db .Client .HGetAll (ctx , "AccessReports:" + timestamp ).Scan (& report )
61+ return report , db .Client .HGetAll (ctx , kAccessReports_ + timestamp ).Scan (& report )
62+ }
63+
64+ func (db * Database ) GetAccessCountOfTarget (ctx context.Context , target string ) (string , error ) {
65+ return db .Client .HGet (ctx , kAccessCounts_Targets , target ).Result ()
66+ }
67+
68+ func (db * Database ) GetAccessAddrCountOfTarget (ctx context.Context , target string ) (int64 , error ) {
69+ return db .Client .SCard (ctx , kAccessAddrs_Target_ + target ).Result ()
70+ }
71+
72+ func (db * Database ) GetAccessUuidCountOfTarget (ctx context.Context , target string ) (int64 , error ) {
73+ return db .Client .SCard (ctx , kAccessUuids_Target_ + target ).Result ()
74+ }
75+
76+ func (db * Database ) CountAll (ctx context.Context , userAgentFilter []string ) error {
77+ timestamps , err := db .GetAccessReportsTimestamps (ctx , "0" , time .Now ().UTC ().Format ("20060102150405.99" ))
78+ if err != nil {
79+ return err
80+ }
81+
82+ for _ , timestamp := range timestamps {
83+ report , err := db .GetAccessReportByTimestamp (ctx , timestamp )
84+ if err != nil {
85+ return err
86+ }
87+
88+ isFiltered := false
89+ for _ , substr := range userAgentFilter {
90+ if strings .Contains (report .UserAgent , substr ) {
91+ isFiltered = true
92+ break
93+ }
94+ }
95+ if isFiltered {
96+ continue
97+ }
98+
99+ err = db .AddAccessAddrOfTarget (ctx , report .Target , report .SourceIP )
100+ if err != nil {
101+ return err
102+ }
103+
104+ err = db .AddAccessUuidOfTarget (ctx , report .Target , report .UUID )
105+ if err != nil {
106+ return err
107+ }
108+
109+ err = db .Client .HIncrBy (ctx , kAccessCounts_Targets , report .Target , 1 ).Err ()
110+ if err != nil {
111+ return err
112+ }
113+ }
114+
115+ return nil
45116}
0 commit comments