blob: 22e4e8aa30c8b2e6d5be401b829241d5679695ab [file] [log] [blame]
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package upload
import (
"fmt"
"os"
"sync"
"time"
"golang.org/x/telemetry/internal/counter"
)
// time and date handling
var distantPast = 21 * 24 * time.Hour
// reports that are too old (21 days) are not uploaded
func (u *uploader) tooOld(date string, uploadStartTime time.Time) bool {
t, err := time.Parse("2006-01-02", date)
if err != nil {
u.logger.Printf("tooOld: %v", err)
return false
}
age := uploadStartTime.Sub(t)
return age > distantPast
}
// counterDateSpan parses the counter file named fname and returns the (begin,
// end) span recorded in its metadata, or an error if this data could not be
// extracted.
func (u *uploader) counterDateSpan(fname string) (begin, end time.Time, _ error) {
parsed, err := u.parseCountFile(fname)
if err != nil {
return time.Time{}, time.Time{}, err
}
timeBegin, ok := parsed.Meta["TimeBegin"]
if !ok {
return time.Time{}, time.Time{}, fmt.Errorf("missing counter metadata for TimeBegin")
}
begin, err = time.Parse(time.RFC3339, timeBegin)
if err != nil {
return time.Time{}, time.Time{}, fmt.Errorf("failed to parse TimeBegin: %v", err)
}
timeEnd, ok := parsed.Meta["TimeEnd"]
if !ok {
return time.Time{}, time.Time{}, fmt.Errorf("missing counter metadata for TimeEnd")
}
end, err = time.Parse(time.RFC3339, timeEnd)
if err != nil {
return time.Time{}, time.Time{}, fmt.Errorf("failed to parse TimeEnd: %v", err)
}
return begin, end, nil
}
// avoid parsing count files multiple times
type parsedCache struct {
mu sync.Mutex
m map[string]*counter.File
}
func (u *uploader) parseCountFile(fname string) (*counter.File, error) {
u.cache.mu.Lock()
defer u.cache.mu.Unlock()
if u.cache.m == nil {
u.cache.m = make(map[string]*counter.File)
}
if f, ok := u.cache.m[fname]; ok {
return f, nil
}
buf, err := os.ReadFile(fname)
if err != nil {
return nil, fmt.Errorf("parse ReadFile: %v for %s", err, fname)
}
f, err := counter.Parse(fname, buf)
if err != nil {
return nil, fmt.Errorf("parse Parse: %v for %s", err, fname)
}
u.cache.m[fname] = f
return f, nil
}