7
7
"sync"
8
8
"time"
9
9
10
+ "golang.org/x/exp/maps"
10
11
"tailscale.com/tstime/rate"
11
12
12
13
"cdr.dev/slog"
@@ -20,7 +21,16 @@ func ReportCLITelemetry(log slog.Logger, rep telemetry.Reporter) func(http.Handl
20
21
21
22
// We send telemetry at most once per minute.
22
23
limiter = rate .NewLimiter (rate .Every (time .Minute ), 1 )
23
- queue []telemetry.CLIInvocation
24
+
25
+ // We map by timestamp to deduplicate invocations, since one invocation
26
+ // will send multiple requests, each with a duplicate header. It's still
27
+ // possible for duplicates to reach the telemetry service since requests
28
+ // can get processed by different coderds, but our analysis tools
29
+ // will deduplicate by timestamp as well.
30
+ //
31
+ // This approach just helps us reduce storage and ingest fees, and doesn't
32
+ // change the correctness.
33
+ queue = make (map [string ]telemetry.CLIInvocation )
24
34
)
25
35
26
36
log = log .Named ("cli-telemetry" )
@@ -62,18 +72,18 @@ func ReportCLITelemetry(log slog.Logger, rep telemetry.Reporter) func(http.Handl
62
72
mu .Lock ()
63
73
defer mu .Unlock ()
64
74
65
- queue = append ( queue , inv )
75
+ queue [ inv . InvokedAt . String ()] = inv
66
76
if ! limiter .Allow () && len (queue ) < 1024 {
67
77
return
68
78
}
69
79
rep .Report (& telemetry.Snapshot {
70
- CLIInvocations : queue ,
80
+ CLIInvocations : maps . Values ( queue ) ,
71
81
})
72
82
log .Debug (
73
83
r .Context (),
74
84
"report sent" , slog .F ("count" , len (queue )),
75
85
)
76
- queue = queue [: 0 ]
86
+ maps . Clear ( queue )
77
87
}()
78
88
})
79
89
}
0 commit comments