Overview
NuGet.Services.Logging is the centralized logging and telemetry infrastructure library shared across NuGet backend services and the gallery web application. It unifies two telemetry pipelines — structured logging via Serilog and metrics/traces via Azure Application Insights — into a single, consistent setup that any NuGet service can adopt with a few method calls. The entry point is LoggingSetup, which builds a pre-configured Serilog LoggerConfiguration and produces an ILoggerFactory wired to both the Serilog pipeline and, when an instrumentation key is provided, the Application Insights sink. System.Diagnostics.Trace listeners are also redirected into Serilog so that legacy trace-based logging in third-party libraries flows through the same pipeline.
The library also provides a complete Application Insights telemetry customization layer. ApplicationInsights.Initialize constructs a TelemetryConfiguration that deliberately avoids the deprecated TelemetryConfiguration.Active singleton and instead returns an ApplicationInsightsConfiguration object — a disposable wrapper holding both the TelemetryConfiguration and a DiagnosticsTelemetryModule — that callers own and manage explicitly. Six telemetry initializers and one Serilog enricher stamp every telemetry item and log event with contextual metadata including machine name, cloud role, deployment ID, deployment label, job name, instance name, and build-time assembly metadata (branch, commit ID, build date). Two telemetry processors — one for requests and one for exceptions — adjust Application Insights behavior to match NuGet’s specific conventions.
The project targets both net472 and netstandard2.0. The ExceptionTelemetryProcessor is excluded from the netstandard2.0 build because it depends on System.Web.HttpException, which is only available on .NET Framework.
Role in System
NuGet.Services.Logging is a leaf dependency consumed by higher-level service projects. It references only NuGet.Services.Contracts (for the ITelemetryClient interface) and third-party packages, so it introduces no circular dependencies.
Unified Logging Bootstrap
LoggingSetup.CreateDefaultLoggerConfiguration and CreateLoggerFactory provide a one-call setup that enables Serilog enrichers (machine name, process ID, log context, assembly metadata), an optional console sink, an optional Application Insights sink, and a SerilogTraceListener that captures System.Diagnostics.Trace output.Application Insights Initialization
ApplicationInsights.Initialize produces a self-contained ApplicationInsightsConfiguration that avoids the deprecated TelemetryConfiguration.Active singleton, wires up TelemetryModules from ApplicationInsights.config if present, and configures a DiagnosticsTelemetryModule with an optional heartbeat interval.Telemetry Enrichers and Initializers
Six
ITelemetryInitializer implementations stamp every Application Insights telemetry item with NuGet-specific context: machine name, cloud role/instance, deployment ID, deployment label, job name and instance name, and build-time assembly metadata (branch, commit, build date).Telemetry Processors
RequestTelemetryProcessor allows specific HTTP response codes to be declared successful regardless of Application Insights defaults. ExceptionTelemetryProcessor (net472 only) converts HttpException items with status codes below 500 into trace telemetry to reduce noise in exception analysis.ITelemetryClient Wrapper
TelemetryClientWrapper implements ITelemetryClient (from NuGet.Services.Contracts) by delegating to the Application Insights TelemetryClient. All calls are wrapped in try/catch so that telemetry failures never propagate to the caller.Duration Metrics
DurationMetric and DurationMetric<TProperties> are IDisposable types that start a Stopwatch on construction and emit an elapsed-seconds metric via ITelemetryClient on disposal, enabling using-block timing of any operation. The extension method TrackDuration on ITelemetryClient provides a fluent API for creating them.Key Files and Classes
Dependencies
NuGet Package References
Internal Project References
Notable Patterns and Implementation Details
ApplicationInsights.Initialize uses TelemetryConfiguration.CreateDefault() rather than new TelemetryConfiguration() or TelemetryConfiguration.Active. CreateDefault() reads the ApplicationInsights.config file if one is present, preserving any module or channel configuration defined there, while still returning a fresh instance that the caller owns. TelemetryConfiguration.Active is deprecated and is never set.All six telemetry initializers that extend
SupportPropertiesTelemetryInitializer or implement ITelemetryInitializer directly use ISupportProperties instead of the deprecated telemetry.Context.Properties API. This is required because the context-level properties bag is marked obsolete in newer Application Insights SDK versions, and some telemetry types (such as MetricTelemetry) do not populate it at all.The assembly metadata stamped by
NuGetAssemblyMetadataEnricher and NuGetAssemblyMetadataTelemetryInitializer (Branch, CommitId, BuildDateUtc) is injected into the entry assembly at build time by a PowerShell script in the NuGetGallery build pipeline via AssemblyMetadataAttribute. When running locally without a CI build, these attributes will typically be absent and the enrichers will silently skip stamping.