ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

使用 OpenTelemetry 完整接入 Python 可观测性:highlight.io 全栈监控实战指南

使用 OpenTelemetry 完整接入 Python 可观测性:highlight.io 全栈监控实战指南 可观测性后端【免费下载链接】highlighthighlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.项目地址https://gitcode.com/gh_mirrors/hi/highlight点击查看免费下载本指南以开源全栈监控平台 highlight.io 为落地场景系统讲解如何在 Python 应用中基于 OpenTelemetry 规范采集 traces、metrics、logs 三类信号并从 Provider、Processor、Exporter 三个核心组件出发给出可直接复制运行的日志、链路追踪、指标接入代码以及自动埋点、中间件和统一配置模块o11y.py的完整实战方案。读完本文你将掌握一套与后端无关、可迁移到任意 OpenTelemetry 兼容后端的 Python 观测性接入能力。OpenTelemetry 埋点组件Provider → Processor → Exporter在应用内的工作流数据最终发往 Highlight 或自建的 Collector 集群OpenTelemetry 中的三类信号SignalsOpenTelemetry 是一套定义如何把遥测数据发送到可观测性后端的重要规范。Highlight.io、Grafana 等后端均支持这一规范它的核心优势在于与厂商无关你可以用同一套代码把数据发给多个观测平台。在 OpenTelemetry 中信号signal是指被采集并发送到观测后端的一类遥测数据主要包括以下三种Traces链路追踪表示一个请求在分布式系统中穿越各个服务与组件时的端到端旅程由若干span链路中的单个工作单元组成。Traces 帮助你理解请求流向定位性能瓶颈或系统中的错误。Metrics指标对系统性能与健康状况的数值化度量例如请求计数、错误率、延迟等。指标通常按时间聚合用于监控趋势和配置告警。Logs日志带时间戳的应用事件记录包含可用于监控、调试与排查应用行为的详细信息并带有 info、warning、error 等严重级别。除了这三类信号还有可以从信号中派生出来的其他构造。例如错误error可以以 traces 作为底层数据类型来表示从而提供错误发生位置与原因的背景信息会话session则可以由 traces、metrics、logs 多种信号组合构建给出一名用户与系统交互的整体视图。在 OpenTelemetry 的语境下信号是通过对系统容器、应用或服务进行埋点instrumentation而产生的。埋点的三大核心组件在应用代码中接入 OpenTelemetry 时几个关键组件共同构成了 OpenTelemetry API。这些组件被设计为灵活通用、可复用于所有信号。信号离开应用后会进入一个或多个OpenTelemetry Collector——Highlight 托管了一组可直接投递数据的 Collector 集群你也可以选择自建。下面逐一说明对应上文架构图中的流水线。Provider一切配置的入口Provider 是保存遥测数据配置的 API 入口点。链路追踪场景下对应TracerProvider日志场景下对应LoggerProvider。Provider 负责搭建环境并确保所有必要配置就位包括配置厂商专属的 API Key或简单到设置 service name 与环境名。例如TracerProvider可以设置 service name、environment 等 Resource 属性并设置 Highlight 项目 ID让 trace 关联到你的 Highlight 项目。示例代码如下from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.resources import Resource provider TracerProvider(resourceResource.create( { service.name: my-service, highlight.project_id: YOUR_PROJECT_ID, environment: production, } )) trace.set_tracer_provider(provider) tracer trace.get_tracer(my-service)其中highlight.project_id是 Highlight 特有的 SpanAttribute用于把遥测数据归属到指定项目在 Highlight 的 Native OpenTelemetry 文档 中highlight.project_id、highlight.session_id、highlight.trace_id三个附加属性共同承载 Highlight 上下文此外还有可选的highlight.sourcefrontend/backend、highlight.type如http.request、highlight.key等属性用于附加上下文。Processor发送前的加工处理Processor 定义了对已创建信号的前置处理逻辑例如批量batching、采样sampling、过滤filtering甚至数据富化enriching。这一点很重要因为从不同机器发送数据时你可能会有定制化需求。最简单的例子是BatchSpanProcessor它把 span 收集成批再交给 exporter比逐条发送高效得多。from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter processor BatchSpanProcessor( exporterOTLPSpanExporter(endpointhttps://otel.highlight.io:4317), max_queue_size1000, max_export_batch_size100, schedule_delay_millis1000, )这里使用BatchSpanProcessor搭配OTLPSpanExporter把 span 发往 Highlight Collector同时配置了批处理参数队列容量 1000、每批最多 100 条、每 1 秒1000 毫秒导出一次。在 Python SDK 的实际实现中Highlight 默认的 OTLP 上报端点正是https://otel.highlight.io:4317见 sdk.py 中OTLP_HTTP常量。Exporter把数据送到后端最后Exporter 负责把遥测数据发送到后端在这里配置端点以及与目标后端相关的其他设置。例如OTLPSpanExporter配置端点和必要的请求头而ConsoleSpanExporter只是把 span 打印到控制台。from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter exporter OTLPSpanExporter(endpointhttps://otel.highlight.io:4317, insecureTrue, headers{ foo: bar })如上所示Exporter 指向 Highlight Collector并设置了foo: bar请求头。insecureTrue表示使用不加密的 gRPC 通道通常用于本地调试或已加密代理后端。实战一采集并上报日志熟悉了高层概念后下面把应用接入 OpenTelemetry 后端。示例以 Highlight.io 为目标后端但同样的原理适用于任何支持 OpenTelemetry 的后端。首先安装必要依赖pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp然后依次配置 Provider、Processor 和 Exporterservice_name my-service environment production otel_endpoint https://otel.highlight.io:4317 # Set up the logger provider with the resource logger_provider LoggerProvider(resourceResource.create( { service.name: service_name, highlight.project_id: YOUR_PROJECT_ID, environment: environment, } )) set_logger_provider(logger_provider) # Configure the OTLP log exporter exporter OTLPLogExporter(endpointotel_endpoint, insecureTrue) logger_provider.add_log_record_processor(BatchLogRecordProcessor(exporter)) # Set up the logger logger logging.getLogger(service_name) logger.setLevel(logging.DEBUG) # Add the OpenTelemetry logging handler handler LoggingHandler(levellogging.DEBUG, logger_providerlogger_provider) logger.addHandler(handler)要点说明LoggerProvider携带 Resourceservice.name、highlight.project_id、environment通过set_logger_provider注册为全局默认BatchLogRecordProcessor对日志记录做批量导出避免每条日志一次网络请求LoggingHandler是 OpenTelemetry SDK 提供的标准logging.Handler适配器把它挂到 Python 标准logginglogger 上应用里所有logger.info(...)调用都会自动转成 OTLP 日志记录。关于日志如何进入后端Highlight 在 Native OpenTelemetry 文档 中给出了两种路径优先使用 SDK 的原生日志接入端点v1/logs若某语言 SDK 不支持原生日志上报则把消息作为 trace 上的 Event 发送Event 名为log属性为log.severity与log.message。异常则遵循异常语义约定exception.type、exception.message、exception.stacktrace以 Trace Event 形式上报。从 Highlight 的 Python SDK 源码看LogHandler.emit实现 正是把标准 logging 记录桥接到当前 span 的log_hook中从而让日志天然携带 trace 上下文。实战二采集并上报链路追踪与日志类似可以埋点让应用发送 trace 到 OpenTelemetry 后端。先安装依赖pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp再配置 Provider、Processor 与 Exporterimport logging from opentelemetry import trace from opentelemetry._logs import set_logger_provider from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler from opentelemetry.sdk._logs.export import BatchLogRecordProcessor from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.sdk.trace.export import ConsoleSpanExporter from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter import sys # Define the service name and environment service_name my-service environment production otel_endpoint https://otel.highlight.io:4317 # Create a resource with service name and highlight project ID provider TracerProvider(resourceResource.create( { service.name: service_name, highlight.project_id: YOUR_PROJECT_ID, environment: environment, } )) processor BatchSpanProcessor(OTLPSpanExporter(endpointotel_endpoint, insecureTrue)) provider.add_span_processor(processor) trace.set_tracer_provider(provider) tracer trace.get_tracer(service_name)完成日志与 trace 的埋点后就可以用tracer与logger对象开始向后端发送数据了with tracer.start_as_current_span(example-span) as span: logger.info(hello, world!) span.set_attributes( { category: special, rows_affected: 123 } ) logger.warning(whoa there, {key: value})这段代码演示了 trace 与日志的关联用法在 span 上下文内记录的日志会自动关联到当前 spanspan.set_attributes可以把业务字段如category、rows_affected附加到 span 上供后续在 Highlight 中按这些属性搜索过滤。Highlight 在区分不同服务的数据时正是依靠 OpenTelemetry 语义约定中的service.name与service.version通常取 git commit hash属性见 Native OpenTelemetry 文档。实战三采集并上报指标最后接入指标。下面发送一个简单的计数指标你也可以发送直方图、仪表盘gauge等其他类型。先安装依赖pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp再配置 Provider、Processor 与 Exporterfrom opentelemetry import metrics from opentelemetry.sdk.metrics import MeterProvider, set_meter_provider from opentelemetry.sdk.metrics.export import ConsoleMetricsExporter from opentelemetry.sdk.resources import Resource # Set up the meter provider with the resource meter_provider MeterProvider(resourceResource.create( { service.name: service_name, highlight.project_id: YOUR_PROJECT_ID, environment: environment, } )) set_meter_provider(meter_provider) meter metrics.get_meter(my-service) counter meter.create_counter(my-counter)然后用 meter 创建 counter 并累加数值counter.add(1)注意这是最简单的示例。你还可以创建直方图histogram、仪表盘gauge等其他类型的指标或者使用Observable Metric Objects可观测指标对象实现更复杂的指标采集如收集 CPU 使用率、内存使用率等。在 Highlight 的 Python 示例代码 中SDK 内部维护了_counters、_histograms、_gauges、_up_down_counters等指标注册表并统一支持 Counter、Histogram、UpDownCounter 三类聚合时态AggregationTemporality供上层 API 直接使用。自动埋点与中间件除手动埋点外OpenTelemetry 还支持对主流库与框架的自动埋点auto-instrumentation无需修改应用代码即可自动采集遥测数据。在 Python 中可以使用 OpenTelemetry Distro SDK 或 Zero Code Python 方案自动完成埋点这些方案的代价是需要改变应用的启动运行方式可能影响你的部署策略。更好的替代方案是使用中间件middleware它是一层位于应用与 OpenTelemetry 后端之间的代码可以自动采集遥测数据。例如在 FastAPI 应用中可以写一个简单中间件包裹整个应用为每个请求自动创建 tracefrom fastapi import Request, FastAPI app FastAPI() app.middleware(http) async def trace_middleware(request, call_next): with tracer.start_as_current_span(f{request.method} {request.url.path}): response await call_next(request) return response app.get(/) def read_root(): return {message: Hello, World!}中间件的优势在于无需改变应用的运行方式只要在每个端点内写入信号该请求相关的 trace 与日志就会被自动关联起来。从 Highlight Python SDK 的 integrations 目录 看官方已经为 FastAPI、Flask、Django、Celery、SQLAlchemy、OpenAI、LangChain 等数十种常用框架与库提供了现成的集成封装可作为自建中间件的参考实现。整合落地一份可复用的 o11y.py 配置模块把上述各部分 OpenTelemetry 配置整合进一个文件应用只需导入即可使用。创建o11y.pyimport logging import os from dotenv import load_dotenv from typing import Optional from opentelemetry import metrics, trace from opentelemetry.sdk.metrics.export import AggregationTemporality from opentelemetry.sdk.metrics import Counter, Histogram, UpDownCounter from opentelemetry._logs import set_logger_provider from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler from opentelemetry.sdk._logs.export import BatchLogRecordProcessor, ConsoleLogExporter from opentelemetry.sdk.metrics import MeterProvider from opentelemetry.sdk.metrics.export import ConsoleMetricExporter, PeriodicExportingMetricReader from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter EXPORTER_OTLP_ENDPOINT os.getenv(OTEL_ENDPOINT,https://otel.highlight.io:4317) # read from .env load_dotenv() print(OTEL Endpoint is: , EXPORTER_OTLP_ENDPOINT) HIGHLIGHT_PROJECT_ID os.getenv(HIGHLIGHT_PROJECT_ID, EMPTY) print(HIGHLIGHT_PROJECT_ID is: , HIGHLIGHT_PROJECT_ID) import sys def create_logger(service_name: str, environment: Optional[str] production, local_debug: bool False) - logging.Logger: if environment is None: environment production commit os.getenv(RENDER_GIT_COMMIT, unknown) resource Resource.create( { service.name: service_name, highlight.project_id: HIGHLIGHT_PROJECT_ID, environment: environment, commit: commit } ) logger_provider LoggerProvider(resourceresource) set_logger_provider(logger_provider) exporter OTLPLogExporter(endpointEXPORTER_OTLP_ENDPOINT, insecureTrue) if not local_debug else ConsoleLogExporter() logger_provider.add_log_record_processor(BatchLogRecordProcessor(exporter)) logger logging.getLogger(service_name) logger.setLevel(logging.DEBUG) handler LoggingHandler(levellogging.DEBUG, logger_providerlogger_provider) logger.addHandler(handler) # Add console handler for stdout console_handler logging.StreamHandler(sys.stdout) console_handler.setLevel(logging.DEBUG) if commit: formatter logging.Formatter(commit: commit - %(asctime)s - %(name)s - %(levelname)s - %(message)s) else: formatter logging.Formatter(%(asctime)s - %(name)s - %(levelname)s - %(message)s) console_handler.setFormatter(formatter) logger.addHandler(console_handler) return logger def create_tracer( service_name: str, environment: Optional[str] production, local_debug: bool False ) - trace.Tracer: if environment is None: environment production commit os.getenv(RENDER_GIT_COMMIT, unknown) provider TracerProvider(resourceResource.create( { service.name: service_name, highlight.project_id: HIGHLIGHT_PROJECT_ID, environment: environment, commit: commit } )) processor BatchSpanProcessor(OTLPSpanExporter(endpointEXPORTER_OTLP_ENDPOINT, insecureTrue)) if not local_debug else BatchSpanProcessor(ConsoleSpanExporter()) provider.add_span_processor(processor) trace.set_tracer_provider(provider) tracer trace.get_tracer(service_name) return tracer def get_meter(service_name: str, environment: Optional[str] production, local_debug: bool False) - metrics.Meter: if environment is None: environment production commit os.getenv(RENDER_GIT_COMMIT, unknown) preferred_temporality: dict[type, AggregationTemporality] { Counter: AggregationTemporality.DELTA, UpDownCounter: AggregationTemporality.DELTA, Histogram: AggregationTemporality.DELTA, } readers [PeriodicExportingMetricReader(exporterOTLPMetricExporter(endpointEXPORTER_OTLP_ENDPOINT, insecureTrue, preferred_temporalitypreferred_temporality))] if local_debug: readers.append(PeriodicExportingMetricReader(exporterConsoleMetricExporter( preferred_temporalitypreferred_temporality ), export_interval_millis1000)) provider MeterProvider(resourceResource.create( { service.name: service_name, highlight.project_id: HIGHLIGHT_PROJECT_ID, environment: environment, commit: commit } ), metric_readersreaders) metrics.set_meter_provider(provider) meter metrics.get_meter(service_name) return meter这个模块的设计要点端点与项目 ID 全部通过环境变量注入OTEL_ENDPOINT默认https://otel.highlight.io:4317与HIGHLIGHT_PROJECT_ID配合.env文件load_dotenv()部署时无需改代码统一 Resource每次创建 Provider 都会带上service.name、highlight.project_id、environment、commit来自RENDER_GIT_COMMIT环境变量用于区分版本四个属性本地调试开关local_debug为 True 时自动切换到 Console 系列的 ExporterConsoleLogExporter、ConsoleSpanExporter、ConsoleMetricExporter把数据打印到终端而不外发指标聚合时态Counter、UpDownCounter、Histogram 统一配置为AggregationTemporality.DELTA通过PeriodicExportingMetricReader周期性导出本地调试模式下额外追加每 1000ms 导出一次的 Console 读取器。接下来在 Flask 应用的入口main.py中使用它只需初始化 OpenTelemetry 资源import os from o11y import create_logger, create_tracer, get_meter # Initialize observability tools service_name flask-backend logger create_logger(service_name, os.getenv(ENVIRONMENT)) tracer create_tracer(service_name, os.getenv(ENVIRONMENT)) meter get_meter(service_name, os.getenv(ENVIRONMENT)) histogram meter.create_histogram(request_duration_histogram) gauge meter.create_gauge(request_duration_gauge) counter meter.create_counter(request_count) logger.info(Starting the application)随后在任意路由/业务代码里 importlogger、tracer、meter或这里的counter、histogram、gauge即可开始上报数据。完整的 Flask 端到端示例可直接参考仓库中的 e2e/python/highlight_flask 目录以及 Highlight Python SDK 的 README 中给出的本地运行方式如poetry run flask run。进阶多后端并行投递与上下文约定当你需要把同一份遥测数据同时发往多个观测后端时可以使用 OpenTelemetry Collector 做扇出fan-out应用 SDK 只把数据发给 Collector再由 Collector 分发给多个后端。Highlight 的 Native OpenTelemetry 文档 给出了一个可用的 Collector 配置示例receivers: # listening to the OpenTelemetry SDK from your application otlp: protocols: grpc: endpoint: 0.0.0.0:4317 http: endpoint: 0.0.0.0:4318 processors: batch: exporters: otlphttp/highlight: endpoint: https://otel.highlight.io compression: gzip otlphttp/example: endpoint: https://example.com/otel service: pipelines: traces: receivers: [otlp] processors: [batch] exporters: [otlphttp/highlight, otlphttp/example] metrics: receivers: [otlp] processors: [batch] exporters: [otlphttp/highlight, otlphttp/example] logs: receivers: [otlp] processors: [batch] exporters: [otlphttp/highlight, otlphttp/example]应用 SDK 通过 gRPC4317或 HTTP4318把 traces、metrics、logs 三条管线送到 CollectorCollector 经batch处理器聚合后同时转发到 Highlight 与任意其他后端。此外Highlight 约定通过X-Highlight-Request请求头格式sessionId/requestId传递会话与请求上下文对应的highlight.session_id、highlight.trace_id属性会附加到 trace 上用于把前后端遥测数据关联成完整的用户会话视图。小结本文从 OpenTelemetry 的三类信号讲起梳理了 Provider、Processor、Exporter 三大埋点组件的职责并给出了日志、链路追踪、指标三类信号的完整接入代码最后用一个可复用的o11y.py模块把三者统一起来配合 Flask 入口在几分钟内完成应用的全栈观测性接入。这套方案完全基于厂商无关的 OpenTelemetry 规范同样的代码稍作端点调整即可迁移到任何兼容后端而结合 Highlight 的 Collector 集群与highlight.*上下文属性你还能获得前后端关联、会话回放、错误监控等全栈能力。若要深入了解 Highlight 的遥测数据属性约定与多后端配置可继续阅读 Native OpenTelemetry 文档 和 Python SDK 源码。赞分享可观测性后端【免费下载链接】highlighthighlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.项目地址https://gitcode.com/gh_mirrors/hi/highlight点击查看免费下载相关推荐Feast Feature Server Kubernetes 可观测性实战OpenTelemetry Prometheus 监控接入指南Feast Feature Server Kubernetes 可观测性实战OpenTelemetry Prometheus 监控接入指南 本文基于 FeMLOps后端数据工程OneUptime VMware 监控实战指南基于 OpenTelemetry vcenter 接收器的 vSphere 全栈可观测性OneUptime VMware 监控实战指南基于 OpenTelemetry vcenter 接收器的 vSphere 全栈可观测性 本指南以 OneUpt可观测性后端运维前端云原生微服务AI Agenthighlight.io 集成 Angular从 SDK 初始化到全栈可观测性的完整接入指南highlight.io 集成 Angular从 SDK 初始化到全栈可观测性的完整接入指南 本文基于 highlight.io 官方文档 Angular 接可观测性后端上一篇clangd完整指南如何快速配置C语言服务器提升开发效率下一篇Dioxus移动应用发布指南App Store与Google Play上架完整教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表