Skip to content

Commit 693fc15

Browse files
tsushanthromtsn
andauthored
fix: use System.nanoTime() for cron check-in duration measurement (#5611)
* fix: use System.nanoTime() for cron check-in duration measurement System.currentTimeMillis() is a wall-clock value and is subject to NTP adjustments and DST transitions. For long-running cron jobs this can produce incorrect or even negative durations in the check-in payload. Switch the start/end capture in CheckInUtils.withCheckIn() and the three SentryCheckInAdvice implementations (sentry-spring, sentry-spring-jakarta, sentry-spring-7) to System.nanoTime(), which is guaranteed monotonic. Use DateUtils.nanosToSeconds() (already present) to convert the delta. Fixes #5579 * changelog --------- Co-authored-by: Roman Zavarnitsyn <rom4ek93@gmail.com>
1 parent 477b848 commit 693fc15

5 files changed

Lines changed: 9 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
### Fixes
66

7+
- Use `System.nanoTime()` for cron check-in duration measurement to avoid incorrect durations from wall-clock adjustments ([#5611](https://github.com/getsentry/sentry-java/pull/5611))
78
- Fix crash when `getHistoricalProcessStartReasons` is called from an isolated or wrong-userId process ([#5597](https://github.com/getsentry/sentry-java/pull/5597))
89
- Release `MediaMuxer` when a replay segment has no encodable frames to avoid a resource leak ([#5583](https://github.com/getsentry/sentry-java/pull/5583))
910

sentry-spring-7/src/main/java/io/sentry/spring7/checkin/SentryCheckInAdvice.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl
9191
TracingUtils.startNewTrace(scopes);
9292

9393
@Nullable SentryId checkInId = null;
94-
final long startTime = System.currentTimeMillis();
94+
final long startTime = System.nanoTime();
9595
boolean didError = false;
9696

9797
try {
@@ -105,7 +105,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl
105105
} finally {
106106
final @NotNull CheckInStatus status = didError ? CheckInStatus.ERROR : CheckInStatus.OK;
107107
CheckIn checkIn = new CheckIn(checkInId, monitorSlug, status);
108-
checkIn.setDuration(DateUtils.millisToSeconds(System.currentTimeMillis() - startTime));
108+
checkIn.setDuration(DateUtils.nanosToSeconds(System.nanoTime() - startTime));
109109
scopes.captureCheckIn(checkIn);
110110
}
111111
}

sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/checkin/SentryCheckInAdvice.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl
9191
TracingUtils.startNewTrace(scopes);
9292

9393
@Nullable SentryId checkInId = null;
94-
final long startTime = System.currentTimeMillis();
94+
final long startTime = System.nanoTime();
9595
boolean didError = false;
9696

9797
try {
@@ -105,7 +105,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl
105105
} finally {
106106
final @NotNull CheckInStatus status = didError ? CheckInStatus.ERROR : CheckInStatus.OK;
107107
CheckIn checkIn = new CheckIn(checkInId, monitorSlug, status);
108-
checkIn.setDuration(DateUtils.millisToSeconds(System.currentTimeMillis() - startTime));
108+
checkIn.setDuration(DateUtils.nanosToSeconds(System.nanoTime() - startTime));
109109
scopes.captureCheckIn(checkIn);
110110
}
111111
}

sentry-spring/src/main/java/io/sentry/spring/checkin/SentryCheckInAdvice.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl
9494
TracingUtils.startNewTrace(scopes);
9595

9696
@Nullable SentryId checkInId = null;
97-
final long startTime = System.currentTimeMillis();
97+
final long startTime = System.nanoTime();
9898
boolean didError = false;
9999

100100
try {
@@ -108,7 +108,7 @@ public Object invoke(final @NotNull MethodInvocation invocation) throws Throwabl
108108
} finally {
109109
final @NotNull CheckInStatus status = didError ? CheckInStatus.ERROR : CheckInStatus.OK;
110110
CheckIn checkIn = new CheckIn(checkInId, monitorSlug, status);
111-
checkIn.setDuration(DateUtils.millisToSeconds(System.currentTimeMillis() - startTime));
111+
checkIn.setDuration(DateUtils.nanosToSeconds(System.nanoTime() - startTime));
112112
scopes.captureCheckIn(checkIn);
113113
}
114114
}

sentry/src/main/java/io/sentry/util/CheckInUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public static <U> U withCheckIn(
3737
try (final @NotNull ISentryLifecycleToken ignored =
3838
Sentry.forkedScopes("CheckInUtils").makeCurrent()) {
3939
final @NotNull IScopes scopes = Sentry.getCurrentScopes();
40-
final long startTime = System.currentTimeMillis();
40+
final long startTime = System.nanoTime();
4141
boolean didError = false;
4242

4343
TracingUtils.startNewTrace(scopes);
@@ -61,7 +61,7 @@ public static <U> U withCheckIn(
6161
if (environment != null) {
6262
checkIn.setEnvironment(environment);
6363
}
64-
checkIn.setDuration(DateUtils.millisToSeconds(System.currentTimeMillis() - startTime));
64+
checkIn.setDuration(DateUtils.nanosToSeconds(System.nanoTime() - startTime));
6565
scopes.captureCheckIn(checkIn);
6666
}
6767
}

0 commit comments

Comments
 (0)