实现了 opentelemetry 来进行链路追踪
但是server端有一点不优雅的代码 希望 帮忙解答或解决一哈
先上 Client段代码
import time
import grpc
from proto import helloworld_pb2, helloworld_pb2_grpc
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.instrumentation.grpc import GrpcInstrumentorClient
from opentelemetry.sdk.trace.export import (
ConsoleSpanExporter,
SimpleSpanProcessor,
)
# 1. 这个问题能改吗?
# 2. 其他语言有没有这个问题 其他语言 go语言 python 不服气
if __name__ == '__main__':
resource = Resource(attributes={
SERVICE_NAME: "mxshop-grpc"
})
jaeger_exporter = JaegerExporter(
agent_host_name="192.168.16.196",
agent_port=6831,
)
provider = TracerProvider(resource=resource)
# 这是 导出器 设置为 Jaeger 也可设置为 控制台 zipkin 等 需要看官网给的例子
processor = BatchSpanProcessor(jaeger_exporter)
provider.add_span_processor(processor)
# 这是 设置 grpc 相关代码
proto_simple = SimpleSpanProcessor(ConsoleSpanExporter())
provider.add_span_processor(proto_simple)
# 设置全局默认跟踪程序提供程序
trace.set_tracer_provider(provider)
# 这里的代码封装了 tracer = trace.get_tracer(__name__) 所以不需要我们手动开启链路追踪
instrumentor = GrpcInstrumentorClient().instrument()
with grpc.insecure_channel("localhost:50051") as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
hello_request = helloworld_pb2.HelloRequest()
hello_request.name = "bobby"
hello_request.id.extend([1, 2])
hello_request.id.append(3)
rsp: helloworld_pb2.HelloReply = stub.SayHello(hello_request)
print(rsp.message)
time.sleep(2)
Server端 代码
import time
from concurrent import futures
from random import randint
import grpc
import logging
from proto import helloworld_pb2, helloworld_pb2_grpc
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry import trace
from opentelemetry.instrumentation.grpc import GrpcInstrumentorServer
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.trace.export import (
ConsoleSpanExporter,
SimpleSpanProcessor,
)
resource = Resource(attributes={
SERVICE_NAME: "mxshop-srv"
})
jaeger_exporter = JaegerExporter(
agent_host_name="192.168.16.196",
agent_port=6831,
)
provider = TracerProvider(resource=resource)
# 这是 导出器 设置为 Jaeger 也可设置为 控制台 zipkin 等 需要看官网给的例子
processor = BatchSpanProcessor(jaeger_exporter)
provider.add_span_processor(processor)
# 这是 设置 grpc 相关代码
proto_simple = SimpleSpanProcessor(ConsoleSpanExporter())
provider.add_span_processor(proto_simple)
# 这是另一种注入方式
# trace.get_tracer_provider().add_span_processor(
# SimpleSpanProcessor(ConsoleSpanExporter())
# )
# 设置全局默认跟踪程序提供程序
trace.set_tracer_provider(provider)
# 这里有点问题 但是我不清楚怎么修改 因为需要 深层次 去 调用 tracer 来创建 子链路 所以我这声明了一个 tracer 理论上 他应该是有什么方法可以给我们来调用的
tracer = trace.get_tracer(__name__)
# 这里的代码封装了 tracer = trace.get_tracer(__name__) 所以不需要我们手动开启链路追踪
grpc_server_instrumentor = GrpcInstrumentorServer().instrument()
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
# 如何在这里找到父的span
with tracer.start_span('execute') as execute_span:
time.sleep(randint(1, 9) * 0.1)
return helloworld_pb2.HelloReply(message=f"您好, {request.name}, id {request.id}")
if __name__ == '__main__':
# 1. 实例化server
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
# 2. 注册逻辑到server中
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
# 3. 启动server
server.add_insecure_port("[::]:50051")
server.start()
server.wait_for_termination()
这里的问题在于 从 opentelemetry 的风格来看 他是不希望我们来手动生成 tracer 的
但是 子链路 又需要父链路 才能生成
要不然又是全新的链路
所以我在 server上 自己又去声明了一遍 tracer = trace.get_tracer(name)
这很不优雅 但是不知道调用什么方法 来实现 子链路
请问 这如何解决呢
重新看了一下代码 是我傻了
# 设置全局默认跟踪程序提供程序
trace.set_tracer_provider(provider)
这里将 trace 设置了全局变量
然后 子链路调用 只要如下 调用即可
tracer = trace.get_tracer(__name__)
with tracer.start_span('execute') as execute_span:
# 你的代码逻辑
如果可以的话 bobby老师登个QQ 有些问题问一下?