You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对最近24小时的时间戳按小时分组并统计日志总数与成功数?

Solution for Hourly Log Aggregation Over the Last 24 Hours

Got it, let's break down how to solve this efficiently given your sorted log slice. Here's a step-by-step implementation that handles old logs, ensures you get exactly 24 hourly buckets (even with zero logs), and leverages the sorted nature of your slice for performance.

First, let's define a struct to hold our hourly stats (this will make it easy to serialize for your chart later):

// HourlyStats represents the aggregated data for a single hour
type HourlyStats struct {
    Hour        time.Time `json:"hour"`  // The start time of the hour interval
    TotalLogs   int       `json:"total"` // Total logs in the hour
    SuccessLogs int       `json:"success"` // Number of successful logs in the hour
}

Next, the core logic to generate the stats:

func GenerateHourlyStats(logs []Log) []HourlyStats {
    now := time.Now()
    // Calculate the start time of the first hour bucket (24 hours ago, truncated to the hour)
    firstHour := now.Add(-24 * time.Hour).Truncate(time.Hour)

    // Initialize 24 empty stats buckets (one for each hour in the last 24)
    stats := make([]HourlyStats, 24)
    for i := 0; i < 24; i++ {
        stats[i] = HourlyStats{
            Hour: firstHour.Add(time.Duration(i) * time.Hour),
        }
    }

    // Iterate through logs (leverage sorted order to optimize)
    for _, log := range logs {
        // Skip logs older than 24 hours
        if log.Timestamp.Before(firstHour) {
            continue
        }
        // Since logs are sorted ascending, we can break early if we hit future logs
        if log.Timestamp.After(now) {
            break
        }

        // Calculate which hour bucket this log belongs to
        hourOffset := int(log.Timestamp.Sub(firstHour) / time.Hour)
        // Ensure we only count logs within our 24-hour window
        if hourOffset < 24 {
            stats[hourOffset].TotalLogs++
            if log.Success {
                stats[hourOffset].SuccessLogs++
            }
        }
    }

    return stats
}

Key Details & Optimizations:

  • Sorted Slice Advantage: Since your logs are already in ascending order, we can skip old logs quickly and even break early if we encounter logs from the future (though that's unlikely if your logs are generated in real-time).
  • Guaranteed 24 Buckets: We initialize all 24 hour buckets upfront, so even hours with no logs will show TotalLogs: 0 and SuccessLogs: 0—perfect for your chart that needs exactly 24 bars.
  • Efficient Time Grouping: Using Truncate(time.Hour) ensures we align each bucket to the top of the hour, and calculating the hourOffset lets us map each log directly to its bucket with simple arithmetic.
  • Handling Edge Cases: Logs that fall exactly on the hour boundary are correctly grouped, and any logs outside the 24-hour window are ignored completely.

Example Usage:

// Sample logs slice (sorted ascending)
logs := []Log{
    {Success: true, Latency: 100, Timestamp: time.Now().Add(-23*time.Hour - 30*time.Minute)},
    {Success: false, Latency: 200, Timestamp: time.Now().Add(-1*time.Hour - 15*time.Minute)},
    // ... more logs
}

stats := GenerateHourlyStats(logs)
// stats will have 24 entries, each with the hour start time and aggregated counts

This implementation is lightweight (even with 4000 logs, it's a single pass) and aligns perfectly with your use case for generating a 24-hour chart.

内容的提问来源于stack exchange,提问作者jz22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 08:47:29