1
2
3
4
5 package upload
6
7 import (
8 "bytes"
9 "net/http"
10 "os"
11 "path/filepath"
12 "regexp"
13 "strings"
14 "time"
15
16 "golang.org/x/telemetry/internal/telemetry"
17 )
18
19 var (
20 dateRE = regexp.MustCompile(`(\d\d\d\d-\d\d-\d\d)[.]json$`)
21 dateFormat = telemetry.DateOnly
22
23 )
24
25
26
27 func (u *uploader) uploadReportDate(fname string) time.Time {
28 match := dateRE.FindStringSubmatch(fname)
29 if match == nil || len(match) < 2 {
30 u.logger.Printf("malformed report name: missing date: %q", filepath.Base(fname))
31 return time.Time{}
32 }
33 d, err := time.Parse(dateFormat, match[1])
34 if err != nil {
35 u.logger.Printf("malformed report name: bad date: %q", filepath.Base(fname))
36 return time.Time{}
37 }
38 return d
39 }
40
41 func (u *uploader) uploadReport(fname string) {
42 thisInstant := u.startTime
43
44
45
46 today := thisInstant.Format(telemetry.DateOnly)
47 match := dateRE.FindStringSubmatch(fname)
48 if match == nil || len(match) < 2 {
49 u.logger.Printf("Report name %q missing date", filepath.Base(fname))
50 } else if match[1] > today {
51 u.logger.Printf("Report date for %q is later than today (%s)", filepath.Base(fname), today)
52 return
53 }
54 buf, err := os.ReadFile(fname)
55 if err != nil {
56 u.logger.Printf("%v reading %s", err, fname)
57 return
58 }
59 if u.uploadReportContents(fname, buf) {
60
61 }
62 }
63
64
65 func (u *uploader) uploadReportContents(fname string, buf []byte) bool {
66 fdate := strings.TrimSuffix(filepath.Base(fname), ".json")
67 fdate = fdate[len(fdate)-len(telemetry.DateOnly):]
68
69 newname := filepath.Join(u.dir.UploadDir(), fdate+".json")
70
71
72 {
73 lockname := newname + ".lock"
74 lockfile, err := os.OpenFile(lockname, os.O_CREATE|os.O_EXCL, 0666)
75 if err != nil {
76 u.logger.Printf("Failed to acquire lock %s: %v", lockname, err)
77 return false
78 }
79 _ = lockfile.Close()
80 defer os.Remove(lockname)
81 }
82
83 if _, err := os.Stat(newname); err == nil {
84
85
86 u.logger.Printf("After acquire: report already uploaded")
87 _ = os.Remove(fname)
88 return false
89 }
90
91 endpoint := u.uploadServerURL + "/" + fdate
92 b := bytes.NewReader(buf)
93 resp, err := http.Post(endpoint, "application/json", b)
94 if err != nil {
95 u.logger.Printf("Error upload %s to %s: %v", filepath.Base(fname), endpoint, err)
96 return false
97 }
98
99 if resp.StatusCode != 200 {
100 u.logger.Printf("Failed to upload %s to %s: %s", filepath.Base(fname), endpoint, resp.Status)
101 if resp.StatusCode >= 400 && resp.StatusCode < 500 {
102 err := os.Remove(fname)
103 if err == nil {
104 u.logger.Printf("Removed local/%s", filepath.Base(fname))
105 } else {
106 u.logger.Printf("Error removing local/%s: %v", filepath.Base(fname), err)
107 }
108 }
109 return false
110 }
111
112 if err := os.WriteFile(newname, buf, 0644); err == nil {
113 os.Remove(fname)
114 }
115 u.logger.Printf("Uploaded %s to %q", fdate+".json", endpoint)
116 return true
117 }
118
View as plain text