Miclitcom.Telemetry.SDK
1.0.0
dotnet add package Miclitcom.Telemetry.SDK --version 1.0.0
NuGet\Install-Package Miclitcom.Telemetry.SDK -Version 1.0.0
<PackageReference Include="Miclitcom.Telemetry.SDK" Version="1.0.0" />
<PackageVersion Include="Miclitcom.Telemetry.SDK" Version="1.0.0" />
<PackageReference Include="Miclitcom.Telemetry.SDK" />
paket add Miclitcom.Telemetry.SDK --version 1.0.0
#r "nuget: Miclitcom.Telemetry.SDK, 1.0.0"
#:package Miclitcom.Telemetry.SDK@1.0.0
#addin nuget:?package=Miclitcom.Telemetry.SDK&version=1.0.0
#tool nuget:?package=Miclitcom.Telemetry.SDK&version=1.0.0
Miclitcom.Telemetry.SDK
A library that provides a generic and transparent interface for working with application telemetry, logs, metrics, and observability. This library abstracts Azure Application Insights implementation details so that consumers only need to work with a simple set of interfaces.
Features
- Abstract telemetry interfaces that hide implementation details.
- Comprehensive observability support:
- Logging with multiple severity levels.
- Metrics tracking with statistical aggregation.
- Dependency tracking for external calls.
- Request tracking for incoming requests.
- Custom event tracking.
- Automatic inclusion of foundational telemetry keys for consistency and traceability (see "Foundational Telemetry Keys" section).
- Operation correlation for distributed tracing (leveraging
System.Diagnostics.Activity
). - Global properties that can be configured to apply to all telemetry items.
- Fluent API for tracking operations (dependencies, requests).
- Easy integration with .NET Dependency Injection.
- Simple configuration.
Getting Started
Installation
dotnet add package Miclitcom.Telemetry.SDK
Configuration
Configure the telemetry provider in your Program.cs
(for .NET 6+) or Startup.cs
.
1. Basic Configuration:
// In Program.cs or Startup.cs
builder.Services.AddMiclitcomTelemetry(options =>
{
options.ConnectionString = builder.Configuration["ApplicationInsights:ConnectionString"]; // Required
options.ApplicationName = "MyAwesomeService"; // Recommended: service_name / cloud_role
// Optional: Service Context
options.ApplicationVersion = "1.0.2"; // service_version
// Optional: Environment Context
options.Environment = "Production"; // environment
options.Region = "East US"; // region
// Optional: User/Session Context Defaults (can be overridden per request)
// options.UserId = "default-user";
// options.SessionId = "default-session";
// Optional: Custom/Extensible Defaults
// options.DefaultFeatureArea = "General";
// options.DefaultOperationType = "api-call";
// options.DefaultTenantId = "default-tenant";
// options.CustomCorrelationId = "your-custom-correlation-id"; // If not using W3C standard
// Optional: Sampling and Disabling Telemetry
options.SamplingPercentage = 100.0; // Defaults to 100% (no sampling)
options.DisableTelemetry = false; // Defaults to false
});
// Alternative simplified configuration (less control over foundational keys)
// builder.Services.AddMiclitcomTelemetry(
// builder.Configuration["ApplicationInsights:ConnectionString"],
// "MyAwesomeService");
2. AppSettings.json Example:
{
"ApplicationInsights": {
"ConnectionString": "YOUR_APPLICATION_INSIGHTS_CONNECTION_STRING"
}
// You can also store other Miclitcom.Telemetry.SDK options here and bind them
}
Foundational Telemetry Keys
The SDK automatically includes or helps you configure the following foundational keys for better traceability and correlation. Many are set based on the TelemetryConfiguration
options or are automatically collected by Application Insights.
Category | Property Name | How it's Handled by SDK / AppInsights |
---|---|---|
Tracing | operation_Id |
Auto-collected by AppInsights (from Activity.TraceId & Activity.SpanId ). |
parent_Id |
Auto-collected by AppInsights (from Activity.ParentSpanId ). |
|
trace_Id |
Auto-collected by AppInsights (W3C traceparent header, from Activity.TraceId ). |
|
Service Context | service_name |
Set from TelemetryConfiguration.ApplicationName (maps to AI's cloud_RoleName ). |
service_version |
Set from TelemetryConfiguration.ApplicationVersion (maps to AI's component_Version ). Falls back to assembly version. |
|
sdk_version |
Automatically added as a custom property (sdk_version ) by this SDK. |
|
Environment | environment |
Set as a custom property from TelemetryConfiguration.Environment . |
region |
Set as a custom property from TelemetryConfiguration.Region . |
|
machine_name |
Auto-collected by AppInsights (as device_Id or cloud_RoleInstance ). |
|
cloud_role |
Set from TelemetryConfiguration.ApplicationName (maps to AI's cloud_RoleName ). |
|
cloud_role_instance |
Auto-collected by AppInsights (e.g., container ID, pod name). | |
Request Context | user_Id |
Set from TelemetryConfiguration.UserId as default; can be overridden. Mapped to AI's user_Id . |
session_Id |
Set from TelemetryConfiguration.SessionId as default; can be overridden. Mapped to AI's session_Id . |
|
client_ip |
Auto-collected by AppInsights for requests (AI redacts by default). | |
request_path |
Auto-collected by AppInsights for requests. | |
http_method |
Auto-collected by AppInsights for requests. | |
status_code |
Auto-collected by AppInsights for requests and dependencies. | |
Dependency Context | dependency_type |
Auto-collected by AppInsights for dependencies. |
dependency_name |
Auto-collected by AppInsights for dependencies. | |
dependency_target |
Auto-collected by AppInsights for dependencies. | |
Custom/Extensible | feature_area |
Set as a default custom property from TelemetryConfiguration.DefaultFeatureArea . |
operation_type |
Set as a default custom property from TelemetryConfiguration.DefaultOperationType . |
|
tenant_id |
Set as a default custom property from TelemetryConfiguration.DefaultTenantId . |
|
correlation_id |
Set as a default custom property from TelemetryConfiguration.CustomCorrelationId . |
Usage Examples
1. Inject ITelemetryClientFactory
to create named clients:
public class MyService
{
private readonly ITelemetryClient _telemetryClient;
public MyService(ITelemetryClientFactory telemetryFactory)
{
// You can create a named client. The name often corresponds to the component or service name.
_telemetryClient = telemetryFactory.CreateClient("MySpecificComponent");
}
public void DoWork()
{
_telemetryClient.Logger.TraceInformation("Work is being done in MySpecificComponent.");
// ... other telemetry operations
}
}
2. Basic Logging (ILogger
):
// Inject ILogger (often via ITelemetryClient.Logger)
public class WeatherService
{
private readonly ILogger _logger;
public WeatherService(ITelemetryClientFactory telemetryFactory)
{
_logger = telemetryFactory.CreateClient("WeatherService").Logger;
}
public async Task<string> GetWeatherAsync(string location)
{
_logger.TraceInformation($"Getting weather for {location}",
new Dictionary<string, string> { { "location_param", location } });
try
{
// ... Get weather data ...
_logger.TraceVerbose("Successfully retrieved weather data.");
return "Sunny";
}
catch (Exception ex)
{
_logger.TraceError($"Failed to get weather for {location}", ex,
new Dictionary<string, string> { { "error_type", ex.GetType().Name } });
throw;
}
}
}
3. Tracking Metrics (IMetricsTracker
):
// Inject IMetricsTracker (often via ITelemetryClient.Metrics)
public class OrderService
{
private readonly IMetricsTracker _metrics;
public OrderService(ITelemetryClientFactory telemetryFactory)
{
_metrics = telemetryFactory.CreateClient("OrderService").Metrics;
}
public async Task CreateOrderAsync(decimal orderAmount, bool isExpress)
{
_metrics.TrackMetric("OrderAmount", (double)orderAmount,
new Dictionary<string, string> { { "currency", "USD" } });
_metrics.IncrementCounter("OrdersCreated");
if (isExpress)
{
_metrics.IncrementCounter("ExpressShippingOrders",
new Dictionary<string, string> { { "shipping_tier", "express" } });
}
// ... save order ...
}
}
4. Tracking Dependencies (IDependencyTracker
):
Dependencies are often tracked automatically by Application Insights (e.g., HttpClient, SQL calls) if the appropriate agent or listeners are active. Manual tracking is useful for custom dependencies or when auto-collection isn't available.
// Inject IDependencyTracker (often via ITelemetryClient.Dependencies)
public class PaymentService
{
private readonly IDependencyTracker _dependencies;
private readonly HttpClient _httpClient;
public PaymentService(ITelemetryClientFactory telemetryFactory, HttpClient httpClient)
{
_dependencies = telemetryFactory.CreateClient("PaymentService").Dependencies;
_httpClient = httpClient; // Assuming HttpClient is configured for DI
}
public async Task<bool> ProcessPaymentAsync(decimal amount)
{
// StartDependencyScope returns an IDisposable TelemetryOperationScope
using var dependencyScope = _dependencies.StartDependencyScope(
dependencyTypeName: "HTTP",
target: "payment-gateway.example.com",
dependencyName: "ProcessExternalPayment",
data: $"POST /api/charge?amount={amount}" // Can be URL or command
);
try
{
// Simulate HTTP call
// var response = await _httpClient.PostAsync(...);
await Task.Delay(150); // Simulate network latency
bool paymentSucceeded = amount < 1000; // Simulate success/failure
dependencyScope.Success = paymentSucceeded;
dependencyScope.ResultCode = paymentSucceeded ? "200" : "400";
dependencyScope.Properties["payment_processor_id"] = "processor-xyz";
return paymentSucceeded;
}
catch (Exception ex)
{
dependencyScope.Success = false;
dependencyScope.ResultCode = "500"; // Or a more specific error code
dependencyScope.SetException(ex);
throw;
}
// Scope is automatically completed (and duration measured) when disposed
}
}
5. Tracking Requests (IRequestTracker
):
Incoming requests (e.g., to an API endpoint) are typically tracked automatically by Application Insights in ASP.NET Core applications. Manual tracking is less common but can be used for non-standard request processing, like background jobs acting like requests.
// Inject IRequestTracker (often via ITelemetryClient.Requests)
public class MessageHandler
{
private readonly IRequestTracker _requests;
public MessageHandler(ITelemetryClientFactory telemetryFactory)
{
_requests = telemetryFactory.CreateClient("MessageHandler").Requests;
}
public async Task HandleMessageAsync(string messageContent, string messageId)
{
using var requestScope = _requests.StartRequestScope(
name: "ProcessQueueMessage",
source: $"queue://my-input-queue/{messageId}" // Optional: source of the request
);
requestScope.Properties["message_length"] = messageContent.Length.ToString();
try
{
// ... process message ...
await Task.Delay(100);
requestScope.Success = true;
requestScope.ResponseCode = "Completed"; // Or a relevant status
}
catch (Exception ex)
{
requestScope.Success = false;
requestScope.ResponseCode = "Failed";
requestScope.SetException(ex);
throw;
}
}
}
6. Tracking Custom Events (IEventTracker
):
// Inject IEventTracker (often via ITelemetryClient.Events)
public class UserActivityService
{
private readonly IEventTracker _events;
public UserActivityService(ITelemetryClientFactory telemetryFactory)
{
_events = telemetryFactory.CreateClient("UserActivityService").Events;
}
public void UserLoggedIn(string userId, string authMethod)
{
_events.TrackEvent("UserLoggedIn",
properties: new Dictionary<string, string>
{
{ "authentication_method", authMethod },
{ "login_time_utc", DateTime.UtcNow.ToString("o") }
},
metrics: new Dictionary<string, double>
{
{ "login_count_for_user_today", 1 } // Example metric with event
}
);
}
}
7. Using ITelemetryContext
for Operation Correlation (Advanced):
While StartDependencyScope
and StartRequestScope
handle operation correlation for their specific types, you can use ITelemetryContext.StartOperation
for more generic operation grouping. This leverages System.Diagnostics.Activity
for distributed tracing.
public class ComplexWorkflowService
{
private readonly ITelemetryClient _telemetryClient;
public ComplexWorkflowService(ITelemetryClientFactory telemetryFactory)
{
_telemetryClient = telemetryFactory.CreateClient("ComplexWorkflow");
}
public async Task ExecuteWorkflowAsync(string workflowId)
{
// This starts a new System.Diagnostics.Activity, which Application Insights uses for correlation.
// The operation_Id, parent_Id, and trace_Id will be set based on this Activity.
using var operation = _telemetryClient.Context.StartOperation(
operationName: "ExecuteComplexWorkflow",
operationId: null, // Let Activity generate if null
parentId: null // Let Activity determine parent if null
);
// Add custom properties to the current Activity's tags, which can be picked up by telemetry initializers.
_telemetryClient.Context.SetProperty("workflow_id", workflowId);
_telemetryClient.Context.SetProperty("custom_tag_for_activity", "my_value");
_telemetryClient.Logger.TraceInformation("Starting complex workflow.");
try
{
// ... call other services, perform steps ...
// Any telemetry sent within this 'using' block will be correlated to this operation.
await StepOneAsync();
await StepTwoAsync();
_telemetryClient.Events.TrackEvent("WorkflowCompleted");
_telemetryClient.Logger.TraceInformation("Complex workflow finished successfully.");
}
catch (Exception ex)
{
_telemetryClient.Logger.TraceError("Complex workflow failed.", ex);
// Optionally, set exception on the operation if your TelemetryContext implementation supports it.
// ((dynamic)operation).SetException(ex); // This depends on the concrete type of 'operation'
throw;
}
}
private async Task StepOneAsync()
{
using var stepOneOp = _telemetryClient.Dependencies.StartDependencyScope("InternalProcess", "WorkflowSteps", "StepOne");
await Task.Delay(50);
_telemetryClient.Logger.TraceVerbose("Step one completed.");
stepOneOp.Success = true;
}
private async Task StepTwoAsync()
{
using var stepTwoOp = _telemetryClient.Dependencies.StartDependencyScope("InternalProcess", "WorkflowSteps", "StepTwo");
await Task.Delay(70);
_telemetryClient.Logger.TraceVerbose("Step two completed.");
stepTwoOp.Success = true;
}
}
Interfaces Overview
ITelemetryClientFactory
: Creates instances ofITelemetryClient
.ITelemetryClient
: Provides access to all specific trackers (ILogger
,IMetricsTracker
, etc.) and theITelemetryContext
.ILogger
: For logging messages at various severity levels (Verbose, Debug, Information, Warning, Error, Critical).IMetricsTracker
: For tracking numerical values, counters, and aggregated metrics.IDependencyTracker
: For tracking outgoing calls to external services or components.IRequestTracker
: For tracking incoming requests or operations that act like requests.IEventTracker
: For tracking custom named events with associated properties and metrics.ITelemetryContext
: For managing operation context (like operation IDs, parent IDs for correlation) and setting global or operation-specific properties.
Benefits
- Abstraction: Your application code is decoupled from the specific telemetry backend (e.g., Azure Application Insights).
- Comprehensive: A single, consistent API for various observability needs.
- Testability: Interfaces can be easily mocked for unit testing your application logic.
- Flexibility: The underlying telemetry implementation can be evolved or even swapped without major changes to consuming code.
- Standardization: Promotes consistent telemetry practices across your services by incorporating foundational keys.
- Simplicity: Provides a clean, straightforward API for common telemetry operations.
License
This project is licensed under the MIT License - see the LICENSE
file for details (if one exists in your project, otherwise assume standard MIT or your organization's default).
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
-
net9.0
- Microsoft.ApplicationInsights (>= 2.23.0)
- Microsoft.ApplicationInsights.AspNetCore (>= 2.23.0)
- Microsoft.Extensions.DependencyInjection (>= 9.0.5)
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 |
---|