Skip to content

Commit 0168ef4

Browse files
committed
all: remove 7 day offset for new uploads
With opt-in telemetry we don't need to insert an arbitrary delay before the first upload. Remove special handling for this delay, as well as the mention of it in the prompt. Updates golang/go#63218 Change-Id: I7bd1477bfa3d6639dbc84464235be75b6cde974f Reviewed-on: https://go-review.googlesource.com/c/telemetry/+/532175 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Hyang-Ah Hana Kim <[email protected]>
1 parent 0ca973e commit 0168ef4

File tree

7 files changed

+71
-102
lines changed

7 files changed

+71
-102
lines changed

cmd/gotelemetry/main.go

+2-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"os"
1515
"path/filepath"
1616
"strings"
17-
"time"
1817

1918
"golang.org/x/telemetry/cmd/gotelemetry/internal/csv"
2019
"golang.org/x/telemetry/cmd/gotelemetry/internal/view"
@@ -189,13 +188,12 @@ func runOn(_ []string) {
189188
}
190189

191190
func telemetryOnMessage() string {
192-
reportDate := time.Now().AddDate(0, 0, 7).Format("2006-01-02")
193-
return fmt.Sprintf(`Telemetry uploading is now enabled and may be sent to https://telemetry.go.dev/ starting %s. Uploaded data is used to help improve the Go toolchain and related tools, and it will be published as part of a public dataset.
191+
return fmt.Sprintf(`Telemetry uploading is now enabled and data will be periodically sent to https://telemetry.go.dev/. Uploaded data is used to help improve the Go toolchain and related tools, and it will be published as part of a public dataset.
194192
195193
For more details, see https://telemetry.go.dev/privacy.
196194
This data is collected in accordance with the Google Privacy Policy (https://policies.google.com/privacy).
197195
198-
To disable telemetry uploading, run “gotelemetry off”`, reportDate)
196+
To disable telemetry uploading, run “gotelemetry off”.`)
199197
}
200198

201199
func runOff(_ []string) {

internal/counter/counter_test.go

+2-18
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ func TestNewFile(t *testing.T) {
294294
t.Fatal(err)
295295
}
296296
days := (timeEnd.Sub(testStartTime)) / (24 * time.Hour)
297-
if days <= 7 || days > 14 {
297+
if days <= 0 || days > 7 {
298298
timeBegin, _ := time.Parse(time.RFC3339, cf.Meta["TimeBegin"])
299299
t.Logf("testStartTime: %v file: %v TimeBegin: %v TimeEnd: %v", testStartTime, fi[0].Name(), timeBegin, timeEnd)
300300
t.Errorf("%d: days = %d, want 7 < days <= 14", i, days)
@@ -306,27 +306,14 @@ func TestNewFile(t *testing.T) {
306306
}
307307
}
308308

309-
func TestWeekendsNewUser(t *testing.T) {
309+
func TestWeekends(t *testing.T) {
310310
testenv.SkipIfUnsupportedPlatform(t)
311-
commonWeekends(t, false)
312-
}
313-
314-
func TestWeekendsOldUser(t *testing.T) {
315-
testenv.SkipIfUnsupportedPlatform(t)
316-
commonWeekends(t, true)
317-
}
318311

319-
func commonWeekends(t *testing.T, old bool) {
320-
t.Helper()
321312
setup(t)
322313
// get all the 49 combinations of today and when the week ends
323314
for i := 0; i < 7; i++ {
324315
counterTime = future(i)
325316
for index := range "0123456" {
326-
if old {
327-
// make it look like a report has been generated
328-
os.WriteFile(filepath.Join(telemetry.LocalDir, "2000-00-00.json"), []byte("{}\n"), 0666)
329-
}
330317
os.WriteFile(filepath.Join(telemetry.LocalDir, "weekends"), []byte{byte(index + '0')}, 0666)
331318
var f file
332319
c := f.New("gophers")
@@ -361,9 +348,6 @@ func commonWeekends(t *testing.T, old bool) {
361348
// if we're an old user, we should have a <=7 day report
362349
// if we're a new user, we should have a <=7+7 day report
363350
more := 0
364-
if !old {
365-
more = 7
366-
}
367351
if delta <= 0+more || delta > 7+more {
368352
t.Errorf("delta %d, expected %d<delta<=%d",
369353
delta, more, more+7)

internal/counter/file.go

+1-14
Original file line numberDiff line numberDiff line change
@@ -227,20 +227,7 @@ func fileValidity(now time.Time) (int, error) {
227227
if incr <= 0 {
228228
incr += 7
229229
}
230-
// as long as there are no reports this is a new user
231-
fi, err := os.ReadDir(telemetry.LocalDir)
232-
if err != nil {
233-
return 0, err
234-
}
235-
// TODO(rfindley): once we can rely on telemetry users setting a mode date,
236-
// we don't need to implement this heuristic about the existing of json
237-
// files.
238-
for _, f := range fi {
239-
if strings.HasSuffix(f.Name(), ".json") {
240-
return int(incr), nil
241-
}
242-
}
243-
return int(incr) + 7, nil
230+
return int(incr), nil
244231
}
245232

246233
// rotate checks to see whether the file f needs to be rotated,

internal/upload/date.go

+18-21
Original file line numberDiff line numberDiff line change
@@ -35,40 +35,37 @@ func tooOld(date string) bool {
3535
return age > distantPast
3636
}
3737

38-
// return the expiry date of a countfile in YYYY-MM-DD format
39-
func expiryDate(fname string) string {
40-
t := expiry(fname)
41-
if t.IsZero() {
42-
return ""
43-
}
44-
// PJW: is this sometimes off by a day?
45-
year, month, day := t.Date()
46-
return fmt.Sprintf("%04d-%02d-%02d", year, month, day)
47-
}
48-
4938
// a time in the far future for the expiry time with errors
5039
var farFuture = time.UnixMilli(1 << 62)
5140

52-
// expiry returns the expiry time of a countfile. For errors
53-
// it returns a time far in the future, so that erroneous files
54-
// don't look like they should be used.
55-
func expiry(fname string) time.Time {
41+
// counterDateSpan parses the counter file named fname and returns the (begin, end) span
42+
// recorded in its metadata.
43+
// On any error, it returns (0, farFuture), so that invalid files don't look
44+
// like they can be used.
45+
//
46+
// TODO(rfindley): just return an error to make this explicit.
47+
func counterDateSpan(fname string) (begin, end time.Time) {
5648
parsed, err := parse(fname)
5749
if err != nil {
5850
logger.Printf("expiry Parse: %v for %s", err, fname)
59-
return farFuture // don't process it, whatever it is
51+
return time.Time{}, farFuture
52+
}
53+
begin, err = time.Parse(time.RFC3339, parsed.Meta["TimeBegin"])
54+
if err != nil {
55+
logger.Printf("time.Parse(%s[TimeBegin]) failed: %v", fname, err)
56+
return time.Time{}, farFuture
6057
}
61-
expiry, err := time.Parse(time.RFC3339, parsed.Meta["TimeEnd"])
58+
end, err = time.Parse(time.RFC3339, parsed.Meta["TimeEnd"])
6259
if err != nil {
63-
logger.Printf("time.Parse: %v for %s", err, fname)
64-
return farFuture // don't process it, whatever it is
60+
logger.Printf("time.Parse(%s[TimeEnd]) failed: %v", fname, err)
61+
return time.Time{}, farFuture
6562
}
66-
return expiry
63+
return begin, end
6764
}
6865

6966
// stillOpen returns true if the counter file might still be active
7067
func stillOpen(fname string) bool {
71-
expiry := expiry(fname)
68+
_, expiry := counterDateSpan(fname)
7269
return expiry.After(thisInstant)
7370
}
7471

internal/upload/dates_test.go

+18-20
Original file line numberDiff line numberDiff line change
@@ -48,36 +48,34 @@ func TestDates(t *testing.T) {
4848
const today = "2020-01-24"
4949
const yesterday = "2020-01-23"
5050
tests := []Test{ // each date must be different to subvert the parse cache
51-
{ // test that existing counters and ready files are not uploaded if telemetry was recently enabled.
52-
name: "beforefirstupload",
53-
today: "2019-12-04",
54-
date: "2019-12-03",
55-
begins: "2019-12-01",
56-
ends: "2019-12-03",
57-
readys: []string{"2019-12-02"},
51+
{ // test that existing counters and ready files are not uploaded if they span data before telemetry was enabled
52+
name: "beforefirstupload",
53+
today: "2019-12-04",
54+
date: "2019-12-03",
55+
begins: "2019-12-01",
56+
ends: "2019-12-03",
57+
readys: []string{"2019-12-01", "2019-12-02"},
58+
// We get one local report: the newly created report.
59+
// It is not ready as it begins on the same day that telemetry was
60+
// enabled, and we err on the side of assuming it holds data from before
61+
// the user turned on uploading.
5862
wantLocal: 1,
63+
// The report for 2019-12-01 is still ready, because it was not uploaded.
64+
// This could happen in practice if the user disabled and then reenabled
65+
// telmetry.
5966
wantReady: 1,
67+
// The report for 2019-12-02 was uploaded.
68+
wantUploadeds: 1,
6069
},
61-
{ // test that existing counters and ready files are not uploaded if telemetry was recently enabled.
70+
{ // test that existing counters and ready files are uploaded they only contain data after telemetry was enabled
6271
name: "oktoupload",
6372
today: "2019-12-10",
6473
date: "2019-12-09",
6574
begins: "2019-12-02",
6675
ends: "2019-12-09",
6776
readys: []string{"2019-12-07"},
6877
wantLocal: 1,
69-
wantReady: 1, // ready report is before the first upload time
70-
wantUploadeds: 1, // ...but the new report is uploaded
71-
},
72-
{ // test that existing counters and ready files are not uploaded if telemetry was recently enabled.
73-
name: "uploadnewreport",
74-
today: "2019-12-14",
75-
date: "2019-12-12",
76-
begins: "2019-12-04",
77-
ends: "2019-12-12",
78-
readys: []string{"2019-12-13"},
79-
wantLocal: 1,
80-
wantUploadeds: 2, // ready report was uploaded
78+
wantUploadeds: 2, // Both new report and existing report are uploaded.
8179
},
8280
{ // test that an old countfile is removed and no reports generated
8381
name: "oldcountfile",

internal/upload/findwork.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,14 @@ func findWork(localdir, uploaddir string) work {
5454
// right thing...
5555
//
5656
// (see https://github.com/golang/go/issues/63142#issuecomment-1734025130)
57-
if asof.AddDate(0, 0, 7).Before(reportDate) {
57+
if asof.Before(reportDate) {
58+
// Note: since this report was created after telemetry was enabled,
59+
// we can only assume that the process that created it checked that
60+
// the counter data contained therein was all from after the asof
61+
// date.
62+
//
63+
// TODO(rfindley): store the begin date in reports, so that we can
64+
// verify this assumption.
5865
ans.readyfiles = append(ans.readyfiles, filepath.Join(localdir, fi.Name()))
5966
}
6067
} else {

internal/upload/reports.go

+22-24
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,27 @@ func reports(todo *work) ([]string, error) {
3333
if lastWeek >= today { //should never happen
3434
lastWeek = ""
3535
}
36-
countFiles := make(map[string][]string) // date->filename
36+
countFiles := make(map[string][]string) // expiry date string->filenames
37+
earliest := make(map[string]time.Time) // earliest begin time for any counter
3738
for _, f := range todo.countfiles {
38-
exp := expiryDate(f)
39-
if exp < today {
40-
countFiles[exp] = append(countFiles[exp], f)
39+
begin, end := counterDateSpan(f)
40+
41+
if end.Before(thisInstant) {
42+
expiry := end.Format(dateFormat)
43+
countFiles[expiry] = append(countFiles[expiry], f)
44+
if earliest[expiry].IsZero() || earliest[expiry].After(begin) {
45+
earliest[expiry] = begin
46+
}
4147
}
4248
}
43-
for k, v := range countFiles {
44-
if notNeeded(k, *todo) {
49+
for expiry, files := range countFiles {
50+
if notNeeded(expiry, *todo) {
4551
// The report already exists.
4652
// There's another check in createReport.
47-
deleteFiles(v)
53+
deleteFiles(files)
4854
continue
4955
}
50-
fname, err := createReport(k, v, lastWeek)
56+
fname, err := createReport(earliest[expiry], expiry, files, lastWeek)
5157
if err != nil {
5258
return nil, err
5359
}
@@ -101,7 +107,7 @@ func deleteFiles(files []string) {
101107

102108
// createReports for all the count files for the same date.
103109
// returns the absolute path name of the file containing the report
104-
func createReport(date string, files []string, lastWeek string) (string, error) {
110+
func createReport(start time.Time, expiryDate string, files []string, lastWeek string) (string, error) {
105111
if uploadConfig == nil {
106112
a, v, err := configstore.Download("latest", nil)
107113
if err != nil {
@@ -115,27 +121,19 @@ func createReport(date string, files []string, lastWeek string) (string, error)
115121
if uploadConfig == nil || mode != "on" {
116122
uploadOK = false // no config, nothing to upload
117123
}
118-
if tooOld(date) {
124+
if tooOld(expiryDate) {
119125
uploadOK = false
120126
}
121-
if uploadOK && !asof.IsZero() {
122-
// If the mode is recorded with an asof date, don't upload if the asof date
123-
// is too recent.
127+
// If the mode is recorded with an asof date, don't upload if the report
128+
// includes any data on or before the asof date.
129+
if !asof.IsZero() && !asof.Before(start) {
124130
uploadOK = false
125-
t, err := time.Parse("2006-01-02", date)
126-
if err == nil {
127-
if asof.AddDate(0, 0, 7).Before(t) {
128-
uploadOK = true
129-
}
130-
} else {
131-
logger.Printf("parsing report date: %v", err)
132-
}
133131
}
134132
// should we check that all the x.Meta are consistent for GOOS, GOARCH, etc?
135133
report := &telemetry.Report{
136134
Config: configVersion,
137135
X: computeRandom(), // json encodes all the bits
138-
Week: date,
136+
Week: expiryDate,
139137
LastWeek: lastWeek,
140138
}
141139
// X is not being used as a probability to decide which counters to upload,
@@ -217,8 +215,8 @@ func createReport(date string, files []string, lastWeek string) (string, error)
217215
if err != nil {
218216
return "", fmt.Errorf("failed to marshal upload report (%v)", err)
219217
}
220-
localFileName := filepath.Join(it.LocalDir, "local."+date+".json")
221-
uploadFileName := filepath.Join(it.LocalDir, date+".json")
218+
localFileName := filepath.Join(it.LocalDir, "local."+expiryDate+".json")
219+
uploadFileName := filepath.Join(it.LocalDir, expiryDate+".json")
222220
// if either file exists, someone has been here ahead of us
223221
// (there is still a race, but this check shortens the open window)
224222
if _, err := os.Stat(localFileName); err == nil {

0 commit comments

Comments
 (0)