3838import com .google .api .gax .rpc .StatusCode ;
3939import com .google .common .annotations .VisibleForTesting ;
4040import com .google .common .base .Stopwatch ;
41+ import com .google .common .base .Ticker ;
4142import java .util .HashMap ;
4243import java .util .Map ;
4344import java .util .concurrent .TimeUnit ;
@@ -58,18 +59,27 @@ public class MetricsTracer implements ApiTracer {
5859 public static final String DEFAULT_LANGUAGE = "Java" ;
5960 private static final String OPERATION_FINISHED_STATUS_MESSAGE =
6061 "Operation has already been completed" ;
62+ private static final double NANOS_PER_MILLISECOND = 1_000_000.0 ;
6163 private Stopwatch attemptTimer ;
62- private final Stopwatch operationTimer = Stopwatch .createStarted ();
64+ private final Ticker ticker ;
65+ private final Stopwatch operationTimer ;
6366 // These are RPC specific attributes and pertain to a specific API Trace
6467 private final Map <String , String > attributes = new HashMap <>();
6568 private final MetricsRecorder metricsRecorder ;
6669 private final AtomicBoolean operationFinished ;
6770
6871 public MetricsTracer (MethodName methodName , MetricsRecorder metricsRecorder ) {
72+ this (methodName , metricsRecorder , Ticker .systemTicker ());
73+ }
74+
75+ @ VisibleForTesting
76+ MetricsTracer (MethodName methodName , MetricsRecorder metricsRecorder , Ticker ticker ) {
6977 this .attributes .put (METHOD_ATTRIBUTE , methodName .toString ());
7078 this .attributes .put (LANGUAGE_ATTRIBUTE , DEFAULT_LANGUAGE );
7179 this .metricsRecorder = metricsRecorder ;
7280 this .operationFinished = new AtomicBoolean ();
81+ this .ticker = ticker ;
82+ this .operationTimer = Stopwatch .createStarted (ticker );
7383 }
7484
7585 /**
@@ -86,7 +96,7 @@ public void operationSucceeded() {
8696 }
8797 attributes .put (STATUS_ATTRIBUTE , StatusCode .Code .OK .toString ());
8898 metricsRecorder .recordOperationLatency (
89- operationTimer .elapsed (TimeUnit .MILLISECONDS ) , attributes );
99+ operationTimer .elapsed (TimeUnit .NANOSECONDS ) / NANOS_PER_MILLISECOND , attributes );
90100 metricsRecorder .recordOperationCount (1 , attributes );
91101 }
92102
@@ -104,7 +114,7 @@ public void operationCancelled() {
104114 }
105115 attributes .put (STATUS_ATTRIBUTE , StatusCode .Code .CANCELLED .toString ());
106116 metricsRecorder .recordOperationLatency (
107- operationTimer .elapsed (TimeUnit .MILLISECONDS ) , attributes );
117+ operationTimer .elapsed (TimeUnit .NANOSECONDS ) / NANOS_PER_MILLISECOND , attributes );
108118 metricsRecorder .recordOperationCount (1 , attributes );
109119 }
110120
@@ -123,7 +133,7 @@ public void operationFailed(Throwable error) {
123133 // Uses the GRPC status code representation.
124134 attributes .put (STATUS_ATTRIBUTE , ObservabilityUtils .extractStatus (error ).toString ());
125135 metricsRecorder .recordOperationLatency (
126- operationTimer .elapsed (TimeUnit .MILLISECONDS ) , attributes );
136+ operationTimer .elapsed (TimeUnit .NANOSECONDS ) / NANOS_PER_MILLISECOND , attributes );
127137 metricsRecorder .recordOperationCount (1 , attributes );
128138 }
129139
@@ -138,7 +148,7 @@ public void operationFailed(Throwable error) {
138148 */
139149 @ Override
140150 public void attemptStarted (Object request , int attemptNumber ) {
141- attemptTimer = Stopwatch .createStarted ();
151+ attemptTimer = Stopwatch .createStarted (ticker );
142152 }
143153
144154 /**
@@ -148,7 +158,8 @@ public void attemptStarted(Object request, int attemptNumber) {
148158 @ Override
149159 public void attemptSucceeded () {
150160 attributes .put (STATUS_ATTRIBUTE , StatusCode .Code .OK .toString ());
151- metricsRecorder .recordAttemptLatency (attemptTimer .elapsed (TimeUnit .MILLISECONDS ), attributes );
161+ metricsRecorder .recordAttemptLatency (
162+ attemptTimer .elapsed (TimeUnit .NANOSECONDS ) / NANOS_PER_MILLISECOND , attributes );
152163 metricsRecorder .recordAttemptCount (1 , attributes );
153164 }
154165
@@ -159,7 +170,8 @@ public void attemptSucceeded() {
159170 @ Override
160171 public void attemptCancelled () {
161172 attributes .put (STATUS_ATTRIBUTE , StatusCode .Code .CANCELLED .toString ());
162- metricsRecorder .recordAttemptLatency (attemptTimer .elapsed (TimeUnit .MILLISECONDS ), attributes );
173+ metricsRecorder .recordAttemptLatency (
174+ attemptTimer .elapsed (TimeUnit .NANOSECONDS ) / NANOS_PER_MILLISECOND , attributes );
163175 metricsRecorder .recordAttemptCount (1 , attributes );
164176 }
165177
@@ -174,7 +186,8 @@ public void attemptCancelled() {
174186 @ Override
175187 public void attemptFailedDuration (Throwable error , java .time .Duration delay ) {
176188 attributes .put (STATUS_ATTRIBUTE , ObservabilityUtils .extractStatus (error ).toString ());
177- metricsRecorder .recordAttemptLatency (attemptTimer .elapsed (TimeUnit .MILLISECONDS ), attributes );
189+ metricsRecorder .recordAttemptLatency (
190+ attemptTimer .elapsed (TimeUnit .NANOSECONDS ) / NANOS_PER_MILLISECOND , attributes );
178191 metricsRecorder .recordAttemptCount (1 , attributes );
179192 }
180193
@@ -198,7 +211,8 @@ public void attemptFailed(Throwable error, org.threeten.bp.Duration delay) {
198211 @ Override
199212 public void attemptFailedRetriesExhausted (Throwable error ) {
200213 attributes .put (STATUS_ATTRIBUTE , ObservabilityUtils .extractStatus (error ).toString ());
201- metricsRecorder .recordAttemptLatency (attemptTimer .elapsed (TimeUnit .MILLISECONDS ), attributes );
214+ metricsRecorder .recordAttemptLatency (
215+ attemptTimer .elapsed (TimeUnit .NANOSECONDS ) / NANOS_PER_MILLISECOND , attributes );
202216 metricsRecorder .recordAttemptCount (1 , attributes );
203217 }
204218
@@ -212,7 +226,8 @@ public void attemptFailedRetriesExhausted(Throwable error) {
212226 @ Override
213227 public void attemptPermanentFailure (Throwable error ) {
214228 attributes .put (STATUS_ATTRIBUTE , ObservabilityUtils .extractStatus (error ).toString ());
215- metricsRecorder .recordAttemptLatency (attemptTimer .elapsed (TimeUnit .MILLISECONDS ), attributes );
229+ metricsRecorder .recordAttemptLatency (
230+ attemptTimer .elapsed (TimeUnit .NANOSECONDS ) / NANOS_PER_MILLISECOND , attributes );
216231 metricsRecorder .recordAttemptCount (1 , attributes );
217232 }
218233
0 commit comments