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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Cosmos.OpenTelemetry.Functions" Version="0.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Cosmos.OpenTelemetry.Functions" Version="0.1.1" />
                    
Directory.Packages.props
<PackageReference Include="Cosmos.OpenTelemetry.Functions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Cosmos.OpenTelemetry.Functions --version 0.1.1
                    
#r "nuget: Cosmos.OpenTelemetry.Functions, 0.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Cosmos.OpenTelemetry.Functions@0.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Cosmos.OpenTelemetry.Functions&version=0.1.1
                    
Install as a Cake Addin
#tool nuget:?package=Cosmos.OpenTelemetry.Functions&version=0.1.1
                    
Install as a Cake Tool

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.1 101 10/20/2026
0.1.0 95 10/20/2026