-
Notifications
You must be signed in to change notification settings - Fork 325
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use java.time.Instant to get micros accurate timestamps (#261)
fall back to System.currentTimeMillis() for Java 7
- Loading branch information
1 parent
5a76939
commit c6b43e1
Showing
4 changed files
with
109 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
apm-agent-core/src/main/java/co/elastic/apm/impl/transaction/SystemClock.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/*- | ||
* #%L | ||
* Elastic APM Java agent | ||
* %% | ||
* Copyright (C) 2018 Elastic and contributors | ||
* %% | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* #L% | ||
*/ | ||
package co.elastic.apm.impl.transaction; | ||
|
||
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; | ||
|
||
import java.time.Clock; | ||
import java.time.Instant; | ||
|
||
public interface SystemClock { | ||
|
||
long getEpochMicros(); | ||
|
||
enum ForCurrentVM implements SystemClock { | ||
INSTANCE; | ||
private final SystemClock dispatcher; | ||
|
||
ForCurrentVM() { | ||
SystemClock localDispatcher; | ||
try { | ||
// being cautious to not cause linking of ForJava8CapableVM in case we are not running on Java 8+ | ||
Class.forName("java.time.Clock"); | ||
localDispatcher = (SystemClock) Class.forName(SystemClock.class.getName() + "$ForJava8CapableVM").getEnumConstants()[0]; | ||
} catch (Exception e) { | ||
localDispatcher = ForLegacyVM.INSTANCE; | ||
} | ||
dispatcher = localDispatcher; | ||
} | ||
|
||
@Override | ||
public long getEpochMicros() { | ||
return dispatcher.getEpochMicros(); | ||
} | ||
} | ||
|
||
@IgnoreJRERequirement | ||
enum ForJava8CapableVM implements SystemClock { | ||
INSTANCE; | ||
|
||
private static final Clock clock = Clock.systemUTC(); | ||
|
||
@Override | ||
public long getEpochMicros() { | ||
// escape analysis, plz kick in and allocate the Instant on the stack | ||
final Instant now = clock.instant(); | ||
return now.getEpochSecond() * 1_000_000 + now.getNano() / 1_000; | ||
} | ||
} | ||
|
||
enum ForLegacyVM implements SystemClock { | ||
INSTANCE; | ||
|
||
@Override | ||
public long getEpochMicros() { | ||
return System.currentTimeMillis() * 1_000; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
apm-agent-core/src/test/java/co/elastic/apm/impl/transaction/SystemClockTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package co.elastic.apm.impl.transaction; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.data.Offset.offset; | ||
|
||
class SystemClockTest { | ||
|
||
@Test | ||
void testClocks() { | ||
final long currentVmEpochMicros = SystemClock.ForCurrentVM.INSTANCE.getEpochMicros(); | ||
final long java8EpochMicros = SystemClock.ForJava8CapableVM.INSTANCE.getEpochMicros(); | ||
final long java7EpochMicros = SystemClock.ForLegacyVM.INSTANCE.getEpochMicros(); | ||
assertThat(java8EpochMicros).isCloseTo(java7EpochMicros, offset(TimeUnit.SECONDS.toMicros(10))); | ||
assertThat(java8EpochMicros).isCloseTo(currentVmEpochMicros, offset(TimeUnit.SECONDS.toMicros(10))); | ||
assertThat(java7EpochMicros % 1000).isEqualTo(0); | ||
} | ||
} |