1# Copyright 2024 gRPC authors. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""gRPC Python helloworld.Greeter client with observability enabled.""" 15 16from collections import defaultdict 17import logging 18import time 19 20import grpc 21import grpc_observability 22import helloworld_pb2 23import helloworld_pb2_grpc 24import open_telemetry_exporter 25from opentelemetry.sdk.metrics import MeterProvider 26from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader 27 28OTEL_EXPORT_INTERVAL_S = 0.5 29 30 31def run(): 32 all_metrics = defaultdict(list) 33 otel_exporter = open_telemetry_exporter.OTelMetricExporter(all_metrics) 34 reader = PeriodicExportingMetricReader( 35 exporter=otel_exporter, 36 export_interval_millis=OTEL_EXPORT_INTERVAL_S * 1000, 37 ) 38 provider = MeterProvider(metric_readers=[reader]) 39 40 otel_plugin = grpc_observability.OpenTelemetryPlugin( 41 meter_provider=provider 42 ) 43 otel_plugin.register_global() 44 45 with grpc.insecure_channel(target="localhost:50051") as channel: 46 stub = helloworld_pb2_grpc.GreeterStub(channel) 47 try: 48 response = stub.SayHello(helloworld_pb2.HelloRequest(name="You")) 49 print(f"Greeter client received: {response.message}") 50 except grpc.RpcError as rpc_error: 51 print("Call failed with code: ", rpc_error.code()) 52 otel_plugin.deregister_global() 53 54 # Sleep to make sure all metrics are exported. 55 time.sleep(5) 56 57 print("Metrics exported on client side:") 58 for metric in all_metrics: 59 print(metric) 60 61 62if __name__ == "__main__": 63 logging.basicConfig() 64 run() 65