Cosmos.OpenTelemetry.Functions
0.1.1
dotnet add package Cosmos.OpenTelemetry.Functions --version 0.1.1
NuGet\Install-Package Cosmos.OpenTelemetry.Functions -Version 0.1.1
<PackageReference Include="Cosmos.OpenTelemetry.Functions" Version="0.1.1" />
<PackageVersion Include="Cosmos.OpenTelemetry.Functions" Version="0.1.1" />
<PackageReference Include="Cosmos.OpenTelemetry.Functions" />
paket add Cosmos.OpenTelemetry.Functions --version 0.1.1
#r "nuget: Cosmos.OpenTelemetry.Functions, 0.1.1"
#:package Cosmos.OpenTelemetry.Functions@0.1.1
#addin nuget:?package=Cosmos.OpenTelemetry.Functions&version=0.1.1
#tool nuget:?package=Cosmos.OpenTelemetry.Functions&version=0.1.1
Cosmos.OpenTelemetry.Functions
Configuración OpenTelemetry del worker aislado de Azure Functions para los bounded contexts de
Cosmos. Reemplaza el bloque AddOpenTelemetry()…UseAzureMonitorExporter() que cada Function App
repetía por una sola línea, y suma la exportación por OTLP al Gateway de observabilidad.
Uso
using Cosmos.OpenTelemetry.Functions;
services.AddCosmosFunctionsTelemetry(
configuration, // en Program.cs: builder.Configuration
"Billing", // dominio → atributo cosmos.dominio
"Wolverine", "Marten", "Cosmos.ControlPlane.Billing.*"); // ActivitySources (admiten comodín)
Se pasa la configuración del host (builder.Configuration en Program.cs, que en Functions
incluye los app settings como variables de entorno). En un test se usa una configuración en memoria
(new ConfigurationBuilder().AddInMemoryCollection(...)), sin tocar las variables del proceso. Es el
mismo patrón de los service defaults de .NET Aspire.
Es la única configuración de telemetría del worker: no combinar con UseAzureMonitorExporter() ni
UseOtlpExporter(), y no usar el Distro UseAzureMonitor() en el worker. Microsoft lo desaconseja:
«avoid using the Azure Monitor distro in the worker process to prevent duplicate telemetry»,
porque trae la instrumentación de ASP.NET Core y el host ya emite la request
(Use OpenTelemetry with Azure Functions — Duplicate request telemetry).
La IConfiguration que se pasa tiene que ser la misma que está registrada en el contenedor: la
condición la lee el paquete, pero el exporter OTLP lee el resto de sus claves de la registrada (y,
si no hay ninguna, del entorno del proceso). En Program.cs eso ya se cumple con
builder.Configuration; en un test con ServiceCollection hay que registrarla
(services.AddSingleton(configuration)).
Qué registra
| Señal | Configuración |
|---|---|
| Base | UseFunctionsWorkerDefaults() (resource de Functions y correlación con el host) |
| Resource | cosmos.proceso=worker y cosmos.dominio=<dominio>. El host de Functions no lleva cosmos.proceso: es lo que distingue los dos procesos, que comparten service.name. Lo que traiga OTEL_RESOURCE_ATTRIBUTES se agrega a las tres señales de los dos exporters; en AI solo llega como se explica en «Los atributos cosmos.* en AI» |
| Trazas | las ActivitySource que se pasan por parámetro. No pasar Microsoft.AspNetCore (ni sumar instrumentación de ASP.NET Core): el host ya emite la request y quedaría duplicada, igual que con el Distro |
| Métricas | meter System.Runtime (GC, memoria, thread pool, excepciones), solo por OTLP: van en un MeterProvider propio con el mismo resource, que existe solo si OTLP está activo, y nunca llegan a AI (unos 20 MB/día por app que acercaban AI a su cap diario). Sin OTLP no se recolectan |
| Logs | IncludeFormattedMessage = true (el cuerpo llega formateado, no la plantilla) e IncludeScopes = true |
Exporters condicionales
Cada exporter se activa solo si su clave existe en la configuración al registrar los servicios. Así el mismo
build se despliega antes que los app settings y no exporta por OTLP hasta que se configure el
endpoint, app por app. Ojo: en una app que ya tiene la connection string de AI, el despliegue
cambia lo que AI recibe (sin muestreo, logs con scopes). Desde 0.1.1 las métricas System.Runtime
del worker ya no llegan a AI (en 0.1.0 sí).
| Variable | Exporter | Notas |
|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT |
OTLP (UseOtlpExporter()), las tres señales |
Solo esta clave lo activa (los endpoints por señal OTEL_EXPORTER_OTLP_{TRACES,METRICS,LOGS}_ENDPOINT se respetan, pero no lo activan). Lee de la configuración del contenedor el resto de la configuración estándar: OTEL_EXPORTER_OTLP_PROTOCOL, _HEADERS, _TIMEOUT, _COMPRESSION. Sin endpoint, o con un valor que no sea una URI absoluta http(s):// (por ejemplo sin esquema), no se registra: el SDK descartaría el valor y apuntaría a localhost:4317 sin avisar. Tampoco se registra si OTEL_EXPORTER_OTLP_HEADERS (o un _{TRACES,METRICS,LOGS}_HEADERS) tiene un valor que el SDK rechaza al arrancar: un elemento sin = (por ejemplo Bearer <token> en vez de Authorization=Bearer <token>), un elemento vacío (coma inicial o doble), una clave repetida (dos Authorization) o User-Agent. Con esos valores el SDK lanzaría una excepción al construir los providers y el worker no arrancaría. Lo mismo con un OTEL_EXPORTER_OTLP_TIMEOUT (o uno por señal) igual a 0: el SDK lo pasa a HttpClient.Timeout y lanzaría al construir el exporter. En todos los casos (endpoint, headers o timeout inválidos) el worker registra al arrancar un warning OTLP export is disabled: <clave> …, con el nombre de la clave y nunca su valor. Una referencia a Key Vault sin resolver sí tiene =: el exporter se registra y no envía nada |
APPLICATIONINSIGHTS_CONNECTION_STRING |
Azure Monitor (UseAzureMonitorExporter()) |
Un valor inválido (por ejemplo una referencia a Key Vault sin resolver) sí impide arrancar al worker, igual que el bloque UseAzureMonitorExporter() que reemplaza. Sin muestreo: SamplingRatio = 1, sin límite de trazas por segundo (el default de 1.8.2 es 5/s) y sin filtrar logs por la decisión de muestreo, para que AI y el Gateway reciban lo mismo durante el dual-export. Live Metrics y las métricas estándar quedan con su default de 1.8.2 (encendidas, como el bloque que reemplaza); el procesador de métricas estándar de AI marca cada span con _MS.ProcessedByMetricExtractors, que puede llegar también por OTLP mientras convivan los dos exporters |
Sin ninguna de las dos, la telemetría se recolecta pero no sale del proceso (desarrollo local).
Ojo con los logs: UseFunctionsWorkerDefaults() le anuncia al host la capacidad
WorkerOpenTelemetryEnabled y el host deja de reenviar los logs del worker. Sin variables, esos
logs no llegan a ningún destino, ni siquiera al AI del host.
El muestreo lo fija el paquete. Mientras AI está activo, su sampler gobierna todas las trazas
(también las que salen por OTLP), y OTEL_TRACES_SAMPLER/OTEL_TRACES_SAMPLER_ARG y la sección
AzureMonitorExporter de la configuración no tienen efecto. Para bajar volumen hay que cambiar el
código o quitar la connection string. Sin AI, el SDK sí respeta OTEL_TRACES_SAMPLER. El sampler de
AI con ratio 1 muestrea siempre y no depende del padre: si el host muestrea sus requests, el worker
emite igual (spans sin padre en el destino).
Los atributos cosmos.* en AI. El exporter de Azure Monitor no copia los atributos del
resource a requests, dependencies ni traces: cosmos.proceso y cosmos.dominio solo
aparecen en la métrica _OTELRESOURCE_ (en customMetrics). Para filtrar por proceso o dominio en
AI se usa cloud_RoleName/cloud_RoleInstance; en el Gateway sí son atributos consultables.
El host de Functions (host.json con "telemetryMode": "OpenTelemetry") exporta por su cuenta con
las mismas variables. Este paquete solo configura el worker.
Nota sobre el namespace
Dentro de un namespace Cosmos.*, un nombre calificado OpenTelemetry.Trace.X escrito en el cuerpo
del código resuelve primero a Cosmos.OpenTelemetry. Usa directivas using OpenTelemetry.Trace;
al inicio del archivo (resuelven desde el namespace global) o global::OpenTelemetry….
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Azure.Monitor.OpenTelemetry.Exporter (>= 1.8.2)
- Microsoft.Azure.Functions.Worker.OpenTelemetry (>= 1.2.0)
- OpenTelemetry.Exporter.OpenTelemetryProtocol (>= 1.16.0)
- OpenTelemetry.Extensions.Hosting (>= 1.16.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.