代码之家  ›  专栏  ›  技术社区  ›  jz22

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

  •  0
  • jz22  · 技术社区  · 4 年前

    我有一片结构。每个结构看起来如下。

    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个柱状图。每小时一次。

    0 回复  |  直到 4 年前
        1
  •  -1
  •   mrosales    4 年前

    为此,您可以执行以下操作:

    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, "Hour\tSuccessful\tTotal\n")
        for _, summary := range summaries {
            fmt.Fprintf(w, "%v\t%d\t%d\n", 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
    }