2626from google .cloud .bigtable .data ._metrics .data_model import CompletedAttemptMetric
2727from google .cloud .bigtable .data ._metrics .data_model import CompletedOperationMetric
2828
29+ # conversion factor for converting from nanoseconds to milliseconds
30+ NS_TO_MS = 1e6
2931
3032class _OpenTelemetryInstruments :
3133 """
@@ -124,14 +126,15 @@ def __init__(
124126 table_id : str ,
125127 app_profile_id : str | None = None ,
126128 client_uid : str | None = None ,
129+ client_version : str | None = None ,
127130 instruments : _OpenTelemetryInstruments = _OpenTelemetryInstruments (),
128- ** kwargs ,
129131 ):
130132 super ().__init__ ()
131133 self .otel = instruments
134+ client_version = client_version or bigtable_version
132135 # fixed labels sent with each metric update
133136 self .shared_labels = {
134- "client_name" : f"python-bigtable/{ bigtable_version } " ,
137+ "client_name" : f"python-bigtable/{ client_version } " ,
135138 "client_uid" : client_uid or self ._generate_client_uid (),
136139 "resource_instance" : instance_id ,
137140 "resource_table" : table_id ,
@@ -162,6 +165,7 @@ def on_operation_complete(self, op: CompletedOperationMetric) -> None:
162165 Update the metrics associated with a completed operation:
163166 - operation_latencies
164167 - retry_count
168+ - first_response_latencies
165169 """
166170 labels = {
167171 "method" : op .op_type .value ,
@@ -173,14 +177,14 @@ def on_operation_complete(self, op: CompletedOperationMetric) -> None:
173177 is_streaming = str (op .is_streaming )
174178
175179 self .otel .operation_latencies .record (
176- op .duration_ns / 1e6 , {"streaming" : is_streaming , ** labels }
180+ op .duration_ns / NS_TO_MS , {"streaming" : is_streaming , ** labels }
177181 )
178182 if (
179183 op .op_type == OperationType .READ_ROWS
180184 and op .first_response_latency_ns is not None
181185 ):
182186 self .otel .first_response_latencies .record (
183- op .first_response_latency_ns / 1e6 , labels
187+ op .first_response_latency_ns / NS_TO_MS , labels
184188 )
185189 # only record completed attempts if there were retries
186190 if op .completed_attempts :
@@ -192,7 +196,6 @@ def on_attempt_complete(
192196 """
193197 Update the metrics associated with a completed attempt:
194198 - attempt_latencies
195- - first_response_latencies
196199 - server_latencies
197200 - connectivity_error_count
198201 - application_latencies
@@ -208,19 +211,19 @@ def on_attempt_complete(
208211 is_streaming = str (op .is_streaming )
209212
210213 self .otel .attempt_latencies .record (
211- attempt .duration_ns / 1e6 , {"streaming" : is_streaming , "status" : status , ** labels }
214+ attempt .duration_ns / NS_TO_MS , {"streaming" : is_streaming , "status" : status , ** labels }
212215 )
213- combined_throttling = attempt .grpc_throttling_time_ns / 1e6
216+ combined_throttling = attempt .grpc_throttling_time_ns / NS_TO_MS
214217 if not op .completed_attempts :
215218 # add flow control latency to first attempt's throttling latency
216- combined_throttling += (op .flow_throttling_time_ns / 1e6 if op .flow_throttling_time_ns else 0 )
219+ combined_throttling += (op .flow_throttling_time_ns / NS_TO_MS if op .flow_throttling_time_ns else 0 )
217220 self .otel .throttling_latencies .record (combined_throttling , labels )
218221 self .otel .application_latencies .record (
219- (attempt .application_blocking_time_ns + attempt .backoff_before_attempt_ns ) / 1e6 , labels
222+ (attempt .application_blocking_time_ns + attempt .backoff_before_attempt_ns ) / NS_TO_MS , labels
220223 )
221224 if attempt .gfe_latency_ns is not None :
222225 self .otel .server_latencies .record (
223- attempt .gfe_latency_ns / 1e6 ,
226+ attempt .gfe_latency_ns / NS_TO_MS ,
224227 {"streaming" : is_streaming , "status" : status , ** labels },
225228 )
226229 else :
0 commit comments