Skip to content

Commit 0f460f3

Browse files
committed
Metrics: add daily top 10
Add export of current daily download stats for all files that have been downloaded in the current day. With this is also added a retention period for these stats as they can be heavy for the database and should be removed after use.
1 parent bcdb746 commit 0f460f3

4 files changed

Lines changed: 69 additions & 6 deletions

File tree

config/config.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,12 @@ func defaultConfig() Configuration {
5454
SHA256: true,
5555
MD5: false,
5656
},
57-
DisallowRedirects: false,
58-
WeightDistributionRange: 1.5,
59-
DisableOnMissingFile: false,
60-
RPCListenAddress: "localhost:3390",
61-
RPCPassword: "",
57+
DisallowRedirects: false,
58+
WeightDistributionRange: 1.5,
59+
DisableOnMissingFile: false,
60+
RPCListenAddress: "localhost:3390",
61+
RPCPassword: "",
62+
MetricsTopFilesRetention: 1,
6263
}
6364
}
6465

@@ -93,6 +94,8 @@ type Configuration struct {
9394

9495
RPCListenAddress string `yaml:"RPCListenAddress"`
9596
RPCPassword string `yaml:"RPCPassword"`
97+
98+
MetricsTopFilesRetention int `yaml:"MetricsTopFilesRetention"`
9699
}
97100

98101
type fallback struct {
@@ -165,6 +168,9 @@ func ReloadConfig() error {
165168
if c.RepositoryScanInterval < 0 {
166169
c.RepositoryScanInterval = 0
167170
}
171+
if c.MetricsTopFilesRetention < 1 {
172+
return fmt.Errorf("Invalid retention duration in days")
173+
}
168174

169175
if config != nil &&
170176
(c.RedisAddress != config.RedisAddress ||

http/metrics.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strings"
99
"time"
1010

11+
"github.com/etix/mirrorbits/config"
1112
"github.com/gomodule/redigo/redis"
1213
)
1314

@@ -233,6 +234,42 @@ func (h *HTTP) metricsHandler(w http.ResponseWriter, r *http.Request) {
233234
output += "\n"
234235
}
235236

237+
// Get daily stats for top 10
238+
retention := config.GetConfig().MetricsTopFilesRetention
239+
for nbDays := 0; nbDays < retention; nbDays++ {
240+
day := today.AddDate(0, 0, nbDays*-1)
241+
rconn.Send("MULTI")
242+
for _, file := range fileList {
243+
mkey := fmt.Sprintf("STATS_TOP_%s_%s", file,
244+
day.Format("2006_01_02"))
245+
rconn.Send("HGETALL", mkey)
246+
}
247+
stats, err = redis.Values(rconn.Do("EXEC"))
248+
if err != nil {
249+
log.Error("Cannot fetch file per country stats: " + err.Error())
250+
return
251+
}
252+
for index, stat := range stats {
253+
hashSlice, _ := redis.ByteSlices(stat, err)
254+
for i := 0; i < len(hashSlice); i += 2 {
255+
field, _ := redis.String(hashSlice[i], err)
256+
value, _ := redis.Int(hashSlice[i+1], err)
257+
sep := strings.Index(field, "_")
258+
country := field[:sep]
259+
mirrorID, err := strconv.Atoi(field[sep+1:])
260+
if err != nil {
261+
log.Error("Failed to convert mirror ID: ", err)
262+
return
263+
}
264+
mirror := mirrorsMap[mirrorID]
265+
output += fmt.Sprintf("stats_top"+
266+
"{file=\"%s\",country=\"%s\",mirror=\"%s\"} %d\n",
267+
fileList[index], country, mirror, value,
268+
)
269+
}
270+
}
271+
}
272+
236273
w.Write([]byte(output))
237274
}
238275

http/stats.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"sync"
1212
"time"
1313

14+
"github.com/etix/mirrorbits/config"
1415
"github.com/etix/mirrorbits/database"
1516
"github.com/etix/mirrorbits/filesystem"
1617
"github.com/etix/mirrorbits/mirrors"
@@ -140,8 +141,8 @@ func (s *Stats) pushStats() {
140141
return
141142
}
142143

144+
topFileRetention := config.GetConfig().MetricsTopFilesRetention
143145
rconn.Send("MULTI")
144-
145146
for k, v := range s.mapStats {
146147
if v == 0 {
147148
continue
@@ -216,6 +217,16 @@ func (s *Stats) pushStats() {
216217
rconn.Send("HINCRBY", mkey, key, v)
217218
mkey = mkey[:strings.LastIndex(mkey, "_")]
218219
}
220+
mkey = fmt.Sprintf("STATS_TOP_%s_%s", file, date)
221+
rconn.Send("HINCRBY", mkey, key, v)
222+
t, err := time.Parse("2006_01_02", date)
223+
if err != nil {
224+
log.Error("Failed to parse date: ", err.Error())
225+
return
226+
}
227+
t = t.AddDate(0, 0, topFileRetention)
228+
topExpireDate := t.Format("2006_01_02")
229+
rconn.Send("EXPIREAT", mkey, topExpireDate)
219230
} else {
220231
log.Warning("Stats: unknown type", typ)
221232
}

mirrorbits.conf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,12 @@
128128
# - URL: http://fallback2.mirror/repo/
129129
# CountryCode: us
130130
# ContinentCode: na
131+
132+
###################
133+
##### METRICS #####
134+
###################
135+
136+
## Number of days to keep the daily top 10 metrics in database
137+
## Keep in mind that this will have an impact on the database's RAM usage
138+
## It is not recommended to keep more than a few days of retention.
139+
## MetricsTopFilesRetention: 1

0 commit comments

Comments
 (0)