github.com/grafana/synthetic-monitoring-agent@v0.64.2/internal/scraper/scrape_clock.go (about) 1 package scraper 2 3 import ( 4 "time" 5 6 kitlog "github.com/go-kit/log" 7 ) 8 9 // scrapeClock decides how a single scrape's telemetry is timestamped. The 10 // scheduled scraper and unscheduled collector select different policies at 11 // their entry points, while the scrape pipeline remains caller-agnostic. 12 type scrapeClock interface { 13 // wrapperLogTimestamp is the kitlog Valuer for the wrapper-log `ts` field. 14 // extractLogs turns that field into each Loki entry's timestamp, so it 15 // governs where logs without their own `time` field land. 16 wrapperLogTimestamp() kitlog.Valuer 17 // endLogFields returns any extra fields appended to the terminal 18 // (succeeded/failed) wrapper log, e.g. an event-end `time` that overrides 19 // `ts` for that line. 20 endLogFields(duration float64) []any 21 // fallbackDuration computes the probe duration when the prober reports none. 22 fallbackDuration(wallStart time.Time) time.Duration 23 } 24 25 // wallClock is the scheduled scraper's policy: real-time log timestamps and a 26 // duration fallback measured from the scrape's nominal time. 27 type wallClock struct { 28 scheduledAt time.Time 29 } 30 31 func scheduledScrapeClock(scheduledAt time.Time) scrapeClock { 32 return wallClock{scheduledAt: scheduledAt} 33 } 34 35 func (wallClock) wrapperLogTimestamp() kitlog.Valuer { return kitlog.DefaultTimestampUTC } 36 37 func (wallClock) endLogFields(float64) []any { return nil } 38 39 // fallbackDuration deliberately ignores wallStart: measuring from the scrape's 40 // nominal time is the scheduled path's pre-existing behavior. 41 func (w wallClock) fallbackDuration(time.Time) time.Duration { 42 return time.Since(w.scheduledAt) 43 } 44 45 // logicalClock places a scrape's telemetry at a caller-supplied event time, 46 // which may be arbitrarily far in the past: the wrapper `ts` is pinned to 47 // eventTime and the terminal log is shifted to eventTime+duration, while the 48 // duration fallback still measures real elapsed time. 49 type logicalClock struct { 50 eventTime time.Time 51 } 52 53 func logicalScrapeClock(eventTime time.Time) scrapeClock { 54 return logicalClock{eventTime: eventTime} 55 } 56 57 func (l logicalClock) wrapperLogTimestamp() kitlog.Valuer { 58 return kitlog.TimestampFormat(l.eventTime.UTC, time.RFC3339Nano) 59 } 60 61 func (l logicalClock) endLogFields(duration float64) []any { 62 eventEnd := l.eventTime.Add(time.Duration(duration * float64(time.Second))) 63 return []any{"time", eventEnd.UTC().Format(time.RFC3339Nano)} 64 } 65 66 func (logicalClock) fallbackDuration(wallStart time.Time) time.Duration { 67 return time.Since(wallStart) 68 }