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 ;
@@ -59,17 +60,25 @@ public class MetricsTracer implements ApiTracer {
5960 private static final String OPERATION_FINISHED_STATUS_MESSAGE =
6061 "Operation has already been completed" ;
6162 private Stopwatch attemptTimer ;
62- private final Stopwatch operationTimer = Stopwatch .createStarted ();
63+ private final Ticker ticker ;
64+ private final Stopwatch operationTimer ;
6365 // These are RPC specific attributes and pertain to a specific API Trace
6466 private final Map <String , String > attributes = new HashMap <>();
6567 private final MetricsRecorder metricsRecorder ;
6668 private final AtomicBoolean operationFinished ;
6769
6870 public MetricsTracer (MethodName methodName , MetricsRecorder metricsRecorder ) {
71+ this (methodName , metricsRecorder , Ticker .systemTicker ());
72+ }
73+
74+ @ VisibleForTesting
75+ MetricsTracer (MethodName methodName , MetricsRecorder metricsRecorder , Ticker ticker ) {
6976 this .attributes .put (METHOD_ATTRIBUTE , methodName .toString ());
7077 this .attributes .put (LANGUAGE_ATTRIBUTE , DEFAULT_LANGUAGE );
7178 this .metricsRecorder = metricsRecorder ;
7279 this .operationFinished = new AtomicBoolean ();
80+ this .ticker = ticker ;
81+ this .operationTimer = Stopwatch .createStarted (ticker );
7382 }
7483
7584 /**
@@ -85,8 +94,7 @@ public void operationSucceeded() {
8594 throw new IllegalStateException (OPERATION_FINISHED_STATUS_MESSAGE );
8695 }
8796 attributes .put (STATUS_ATTRIBUTE , StatusCode .Code .OK .toString ());
88- metricsRecorder .recordOperationLatency (
89- operationTimer .elapsed (TimeUnit .MILLISECONDS ), attributes );
97+ metricsRecorder .recordOperationLatency (elapsedMillis (operationTimer ), attributes );
9098 metricsRecorder .recordOperationCount (1 , attributes );
9199 }
92100
@@ -103,8 +111,7 @@ public void operationCancelled() {
103111 throw new IllegalStateException (OPERATION_FINISHED_STATUS_MESSAGE );
104112 }
105113 attributes .put (STATUS_ATTRIBUTE , StatusCode .Code .CANCELLED .toString ());
106- metricsRecorder .recordOperationLatency (
107- operationTimer .elapsed (TimeUnit .MILLISECONDS ), attributes );
114+ metricsRecorder .recordOperationLatency (elapsedMillis (operationTimer ), attributes );
108115 metricsRecorder .recordOperationCount (1 , attributes );
109116 }
110117
@@ -122,8 +129,7 @@ public void operationFailed(Throwable error) {
122129 }
123130 // Uses the GRPC status code representation.
124131 attributes .put (STATUS_ATTRIBUTE , ObservabilityUtils .extractStatus (error ).toString ());
125- metricsRecorder .recordOperationLatency (
126- operationTimer .elapsed (TimeUnit .MILLISECONDS ), attributes );
132+ metricsRecorder .recordOperationLatency (elapsedMillis (operationTimer ), attributes );
127133 metricsRecorder .recordOperationCount (1 , attributes );
128134 }
129135
@@ -138,7 +144,7 @@ public void operationFailed(Throwable error) {
138144 */
139145 @ Override
140146 public void attemptStarted (Object request , int attemptNumber ) {
141- attemptTimer = Stopwatch .createStarted ();
147+ attemptTimer = Stopwatch .createStarted (ticker );
142148 }
143149
144150 /**
@@ -148,7 +154,7 @@ public void attemptStarted(Object request, int attemptNumber) {
148154 @ Override
149155 public void attemptSucceeded () {
150156 attributes .put (STATUS_ATTRIBUTE , StatusCode .Code .OK .toString ());
151- metricsRecorder .recordAttemptLatency (attemptTimer . elapsed ( TimeUnit . MILLISECONDS ), attributes );
157+ metricsRecorder .recordAttemptLatency (elapsedMillis ( attemptTimer ), attributes );
152158 metricsRecorder .recordAttemptCount (1 , attributes );
153159 }
154160
@@ -159,7 +165,7 @@ public void attemptSucceeded() {
159165 @ Override
160166 public void attemptCancelled () {
161167 attributes .put (STATUS_ATTRIBUTE , StatusCode .Code .CANCELLED .toString ());
162- metricsRecorder .recordAttemptLatency (attemptTimer . elapsed ( TimeUnit . MILLISECONDS ), attributes );
168+ metricsRecorder .recordAttemptLatency (elapsedMillis ( attemptTimer ), attributes );
163169 metricsRecorder .recordAttemptCount (1 , attributes );
164170 }
165171
@@ -174,7 +180,7 @@ public void attemptCancelled() {
174180 @ Override
175181 public void attemptFailedDuration (Throwable error , java .time .Duration delay ) {
176182 attributes .put (STATUS_ATTRIBUTE , ObservabilityUtils .extractStatus (error ).toString ());
177- metricsRecorder .recordAttemptLatency (attemptTimer . elapsed ( TimeUnit . MILLISECONDS ), attributes );
183+ metricsRecorder .recordAttemptLatency (elapsedMillis ( attemptTimer ), attributes );
178184 metricsRecorder .recordAttemptCount (1 , attributes );
179185 }
180186
@@ -198,7 +204,7 @@ public void attemptFailed(Throwable error, org.threeten.bp.Duration delay) {
198204 @ Override
199205 public void attemptFailedRetriesExhausted (Throwable error ) {
200206 attributes .put (STATUS_ATTRIBUTE , ObservabilityUtils .extractStatus (error ).toString ());
201- metricsRecorder .recordAttemptLatency (attemptTimer . elapsed ( TimeUnit . MILLISECONDS ), attributes );
207+ metricsRecorder .recordAttemptLatency (elapsedMillis ( attemptTimer ), attributes );
202208 metricsRecorder .recordAttemptCount (1 , attributes );
203209 }
204210
@@ -212,7 +218,7 @@ public void attemptFailedRetriesExhausted(Throwable error) {
212218 @ Override
213219 public void attemptPermanentFailure (Throwable error ) {
214220 attributes .put (STATUS_ATTRIBUTE , ObservabilityUtils .extractStatus (error ).toString ());
215- metricsRecorder .recordAttemptLatency (attemptTimer . elapsed ( TimeUnit . MILLISECONDS ), attributes );
221+ metricsRecorder .recordAttemptLatency (elapsedMillis ( attemptTimer ), attributes );
216222 metricsRecorder .recordAttemptCount (1 , attributes );
217223 }
218224
@@ -236,6 +242,10 @@ public void addAttributes(Map<String, String> attributes) {
236242 }
237243 ;
238244
245+ private static double elapsedMillis (Stopwatch stopwatch ) {
246+ return stopwatch .elapsed (TimeUnit .NANOSECONDS ) / 1_000_000.0 ;
247+ }
248+
239249 @ VisibleForTesting
240250 Map <String , String > getAttributes () {
241251 return attributes ;
0 commit comments