如何按小时对过去24小时的时间戳进行分组?



我有一个结构体切片。每个结构体如下所示:

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条。每小时一个

要做到这一点,您可以这样做:

  1. 制作几个映射来存储每个小时分区的唯一指标
  2. 遍历日志,将时间戳截断为一个小时,并增加您感兴趣的指标
  3. 将指标汇编成列表并按小时排序

这是一个完整的示例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
}

最新更新