问题描述
我们有不同的微服务(函数应用、虚拟机服务器等)记录应用洞察。一个简单的 python http 服务器托管在 linux VM 上,我希望此服务器接收 traceparent http 标头(W3C 跟踪),将信息记录到应用程序洞察中。这个 python 服务器应该在应用程序映射中创建一个单独的节点。
我能够从 traceparent http 标头中提取 span 上下文并使用它来记录信息。但我无法在应用程序地图中将其视为单独的节点。
有 middlewares 用于烧瓶,django 用于跟踪请求。但是对于python简单的http服务器没有现成的解决方案。
目标是让 vm 上的这个 python 服务器在应用程序映射中被表示为一个单独的节点。
附上我的python脚本以供参考。 (此代码是使用 flask-middleware 中的代码编写的)
import six
import logging
import sys
from opencensus.ext.azure.log_exporter import AzureLogHandler
from google.rpc import code_pb2
from opencensus.ext.azure.trace_exporter import AzureExporter
from opencensus.common import configuration
from opencensus.trace import (
attributes_helper,execution_context,print_exporter,samplers,)
from opencensus.trace import span as span_module
from opencensus.trace import stack_trace,status
from opencensus.trace import tracer as tracer_module
from opencensus.trace import utils
from opencensus.trace.propagation import trace_context_http_header_format
from opencensus.trace import config_integration
HTTP_HOST = attributes_helper.COMMON_ATTRIBUTES['HTTP_HOST']
HTTP_METHOD = attributes_helper.COMMON_ATTRIBUTES['HTTP_METHOD']
HTTP_PATH = attributes_helper.COMMON_ATTRIBUTES['HTTP_PATH']
HTTP_ROUTE = attributes_helper.COMMON_ATTRIBUTES['HTTP_ROUTE']
HTTP_URL = attributes_helper.COMMON_ATTRIBUTES['HTTP_URL']
HTTP_STATUS_CODE = attributes_helper.COMMON_ATTRIBUTES['HTTP_STATUS_CODE']
EXCLUDELIST_PATHS = 'EXCLUDELIST_PATHS'
EXCLUDELIST_HOSTNAMES = 'EXCLUDELIST_HOSTNAMES'
config_integration.trace_integrations(['logging'])
trace_parent_header= "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
APP_INSIGHTS_KEY = "KEY HERE"
logging.basicConfig(
format='%(asctime)s traceId=%(traceId)s spanId=%(spanId)s %(message)s')
log = logging.getLogger(__name__)
def callback_function(envelope):
envelope.tags['ai.cloud.role'] = 'Pixm Agent'
handler = AzureLogHandler(
connection_string='InstrumentationKey=APP_INSIGHTS_KEY')
handler.setFormatter(logging.Formatter('%(traceId)s %(spanId)s %(message)s'))
handler.add_telemetry_processor(callback_function)
log.addHandler(handler)
propogator = trace_context_http_header_format.TraceContextPropagator()
sampler = samplers.ProbabilitySampler(rate=1.0)
exporter = AzureExporter(
connection_string="InstrumentationKey=APP_INSIGHTS_KEY")
exporter.add_telemetry_processor(callback_function)
try:
span_context = propogator.from_headers(
{"traceparent": trace_parent_header})
log.info("he...")
tracer = tracer_module.Tracer(
span_context=span_context,sampler=sampler,exporter=exporter,propagator=propogator)
span = tracer.start_span()
span.span_kind = span_module.SpanKind.SERVER
# Set the span name as the name of the current module name
span.name = '[{}]{}'.format(
'get','testurl')
tracer.add_attribute_to_current_span(
HTTP_HOST,'testurlhost'
)
tracer.add_attribute_to_current_span(
HTTP_METHOD,'get'
)
tracer.add_attribute_to_current_span(
HTTP_PATH,'testurlpath'
)
tracer.add_attribute_to_current_span(
HTTP_URL,str('testurl')
)
# execution_context.set_opencensus_attr(
# 'excludelist_hostnames',# self.excludelist_hostnames
# )
with tracer.span(name="main-ashish"):
for i in range(0,10):
log.warning("identity logs..."+str(i))
except Exception: # pragma: NO COVER
log.error('Failed to trace request',exc_info=True)
解决方法
应用程序映射通过跟踪安装了 Application Insights SDK 的服务器之间进行的 HTTP 依赖项调用来查找组件。
OpenCensus Python telemetry processors
您可以通过更改 cloud_RoleName
字段中的 ai.cloud.role
属性来修改 tags
。
def callback_function(envelope):
envelope.tags['ai.cloud.role'] = 'new_role_name'
# AzureLogHandler
handler.add_telemetry_processor(callback_function)
# AzureExporter
exporter.add_telemetry_processor(callback_function)
使用 W3C TraceContext 将信息记录到 Application Insights 的相关标头
Application Insights 正在过渡到 W3C Trace-Context,它定义了:
traceparent:携带全局唯一的操作 ID 和调用的唯一标识符。
tracestate:携带系统特定的跟踪上下文。 最新版本的 Application Insights SDK 支持 Trace-Context 协议。
相关 HTTP 协议(也称为 Request-Id)已被弃用。该协议定义了两个标头:
Request-Id:携带呼叫的全球唯一 ID。
Correlation-Context:携带分布式跟踪属性的名称-值对集合。
import logging
from opencensus.trace import config_integration
from opencensus.trace.samplers import AlwaysOnSampler
from opencensus.trace.tracer import Tracer
config_integration.trace_integrations(['logging'])
logging.basicConfig(format='%(asctime)s traceId=%(traceId)s spanId=%(spanId)s %(message)s')
tracer = Tracer(sampler=AlwaysOnSampler())
logger = logging.getLogger(__name__)
logger.warning('Before the span')
with tracer.span(name='hello'):
logger.warning('In the span')
logger.warning('After the span')
您可以参考Application Map: Triage Distributed Applications、Telemetry correlation in Application Insights和Track incoming requests with OpenCensus Python