我有一个结构体切片。每个结构体如下所示:
type Log struct {
Success bool `json:"s" bson:"s"`
Latency int `json:"l" bson:"l"`
Timestamp time.Time `json:"t" bson:"t"`
}
前面提到的片最多包含4000条日志。新的日志在片的末尾被推送,这意味着它已经是升序的了。
如何创建切片中所有日志的摘要,按小时对过去24小时进行分组?每小时我需要知道有多少日志是可用的,有多少日志是成功的。可能存在超过24小时的日志
我需要这个来创建过去24小时的图表,其中最多有24条。每小时一个
要做到这一点,您可以这样做:
- 制作几个映射来存储每个小时分区的唯一指标
- 遍历日志,将时间戳截断为一个小时,并增加您感兴趣的指标
- 将指标汇编成列表并按小时排序
这是一个完整的示例https://play.golang.org/p/x25BwNKQ1X6
go run ./main.go
Hour Successful Total
2021-03-04 00:00:00 +0000 UTC 1 1
2021-03-04 01:00:00 +0000 UTC 0 3
2021-03-04 02:00:00 +0000 UTC 0 2
2021-03-04 03:00:00 +0000 UTC 1 5
2021-03-04 04:00:00 +0000 UTC 5 8
2021-03-04 05:00:00 +0000 UTC 1 5
2021-03-04 06:00:00 +0000 UTC 1 3
2021-03-04 07:00:00 +0000 UTC 1 1
2021-03-04 08:00:00 +0000 UTC 2 7
2021-03-04 09:00:00 +0000 UTC 0 1
2021-03-04 10:00:00 +0000 UTC 1 5
2021-03-04 11:00:00 +0000 UTC 0 3
2021-03-04 12:00:00 +0000 UTC 2 4
2021-03-04 14:00:00 +0000 UTC 0 3
2021-03-04 15:00:00 +0000 UTC 3 3
2021-03-04 16:00:00 +0000 UTC 4 6
2021-03-04 17:00:00 +0000 UTC 5 9
2021-03-04 18:00:00 +0000 UTC 3 5
2021-03-04 19:00:00 +0000 UTC 2 6
2021-03-04 20:00:00 +0000 UTC 2 4
2021-03-04 21:00:00 +0000 UTC 5 7
2021-03-04 23:00:00 +0000 UTC 2 6
2021-03-05 00:00:00 +0000 UTC 1 3
// main.go
package main
import (
"fmt"
"math/rand"
"os"
"sort"
"text/tabwriter"
"time"
)
type Log struct {
Success bool `json:"s" bson:"s"`
Latency int `json:"l" bson:"l"`
Timestamp time.Time `json:"t" bson:"t"`
}
func main() {
totalCounts := map[time.Time]int{}
successCounts := map[time.Time]int{}
for _, entry := range sampleLogs(100) {
truncatedTs := entry.Timestamp.Truncate(time.Hour)
totalCounts[truncatedTs] += 1
if entry.Success {
successCounts[truncatedTs] += 1
}
}
var summaries HourSummarySlice
for hour, total := range totalCounts {
summaries = append(summaries, HourSummary{
Timestamp: hour,
TotalCount: total,
SuccessfulCount: successCounts[hour],
})
}
sort.Sort(summaries)
w := tabwriter.NewWriter(os.Stdout, 4, 0, 2, ' ', 0)
fmt.Fprintf(w, "HourtSuccessfultTotaln")
for _, summary := range summaries {
fmt.Fprintf(w, "%vt%dt%dn", summary.Timestamp, summary.SuccessfulCount, summary.TotalCount)
}
w.Flush()
}
type HourSummary struct {
Timestamp time.Time
TotalCount int
SuccessfulCount int
}
// Custom type so we can sort the output.
type HourSummarySlice []HourSummary
func (s HourSummarySlice) Len() int {
return len(s)
}
func (s HourSummarySlice) Less(i, j int) bool {
return s[i].Timestamp.Before(s[j].Timestamp)
}
func (s HourSummarySlice) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func sampleLogs(count int) []Log {
var output []Log
start := time.Now().Add(-24 * time.Hour)
for i := 0; i < count; i++ {
output = append(output, Log{
// flip a coin
Success: rand.Intn(10) > 5,
// random latency between [500, 1000)
Latency: 500 + rand.Intn(500),
// random time offset up to 24hr
Timestamp: start.Add(time.Duration(rand.Int63n(int64(24 * time.Hour)))).UTC(),
})
}
return output
}