// 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(time.DateOnly, 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 }