Atc.LogAnalytics
1.1.2
dotnet add package Atc.LogAnalytics --version 1.1.2
NuGet\Install-Package Atc.LogAnalytics -Version 1.1.2
<PackageReference Include="Atc.LogAnalytics" Version="1.1.2" />
<PackageVersion Include="Atc.LogAnalytics" Version="1.1.2" />
<PackageReference Include="Atc.LogAnalytics" />
paket add Atc.LogAnalytics --version 1.1.2
#r "nuget: Atc.LogAnalytics, 1.1.2"
#:package Atc.LogAnalytics@1.1.2
#addin nuget:?package=Atc.LogAnalytics&version=1.1.2
#tool nuget:?package=Atc.LogAnalytics&version=1.1.2
Introduction
Atc.LogAnalytics is a .NET library that wraps the Azure.Monitor.Query.Logs SDK, providing a structured and type-safe approach to querying Azure Log Analytics workspaces.
Table of Contents
- Introduction
- Requirements
- How to contribute
Features
- ✅ Type-safe queries: Define strongly-typed query results with C# records
- ✅ Script abstraction: Store KQL queries in embedded
.kqlfiles - ✅ Workspace and Resource queries: Support for both workspace-centric and resource-centric query patterns
- ✅ Dependency injection: First-class support for Microsoft.Extensions.DependencyInjection
- ✅ Named configurations: Support multiple Log Analytics workspaces with named configurations
- ✅ Parameter binding: Automatic mapping from C# record properties to KQL variables
Getting Started
Installation
Install the NuGet package:
dotnet add package Atc.LogAnalytics
Basic Usage
Define a query record, a result record, and a KQL file:
using Atc.LogAnalytics;
// Query parameters are defined as record properties
public record HeartbeatQuery(string? ComputerName = null, int TopCount = 100)
: LogAnalyticsQuery<HeartbeatRecord>;
// Result type matches the columns projected in KQL
public record HeartbeatRecord(
DateTimeOffset TimeGenerated,
string Computer,
string OSType,
string Version);
Create a file named HeartbeatQuery.kql in the same folder as your query class. Mark it as an embedded resource in your .csproj:
<ItemGroup>
<EmbeddedResource Include="Queries\**\*.kql" />
</ItemGroup>
// Parameters from the C# record are available as KQL variables (camelCase)
let computerFilter = iif(isempty(computerName), true, Computer == computerName);
Heartbeat
| where computerFilter
| project TimeGenerated, Computer, OSType, Version
| top topCount by TimeGenerated desc
Configuring with ServiceCollection Extensions
Register Log Analytics services and inject ILogAnalyticsProcessorFactory to execute queries:
using Atc.LogAnalytics.Extensions;
using Azure.Identity;
builder.Services.ConfigureLogAnalytics(options =>
{
options.WorkspaceId = builder.Configuration["LogAnalytics:WorkspaceId"]!;
options.Credential = new DefaultAzureCredential();
});
public class HeartbeatService
{
private readonly ILogAnalyticsProcessorFactory processorFactory;
public HeartbeatService(ILogAnalyticsProcessorFactory processorFactory)
{
this.processorFactory = processorFactory;
}
public async Task<HeartbeatRecord[]?> GetRecentHeartbeatsAsync(
string? computerName = null,
CancellationToken ct = default)
{
var processor = processorFactory.Create();
var query = new HeartbeatQuery(ComputerName: computerName, TopCount: 50);
return await processor.ExecuteWorkspaceQuery(query, ct);
}
}
Script Pattern
Queries are defined as C# records with embedded KQL files:
ILogAnalyticsScript
├── LogAnalyticsScript (abstract record, loads .kql files)
└── LogAnalyticsQuery<T> (returns T[])
KQL File Convention
- File name must match the query class name:
MyQuery.kql - File must be an embedded resource
- File must be in the same namespace/folder as the query class
- Parameters are referenced in KQL using camelCase naming
Parameter Mapping
| C# Type | KQL Type | Example |
|---|---|---|
string |
string |
"value" |
null |
dynamic |
dynamic(null) |
int, long |
int, long |
100 |
bool |
bool |
true, false |
DateTime, DateTimeOffset |
datetime |
datetime(2024-01-01) |
TimeSpan |
timespan |
1h, 30m |
Guid |
guid |
guid(...) |
Enum |
string |
"Warning" |
IEnumerable, arrays |
dynamic |
dynamic(["a","b"]) |
Result Mapping
Column names in your KQL project statement should match the property names in your result record (case-insensitive):
| project TimeGenerated, Computer, OSType, Version
public record HeartbeatRecord(
DateTimeOffset TimeGenerated,
string Computer,
string OSType,
string Version);
Workspace vs Resource Queries
Azure Log Analytics supports two query patterns:
Workspace Query — Targets a Log Analytics Workspace by its ID (GUID). All resources that send logs to the workspace are queryable. Best for cross-resource analysis, dashboards, and aggregated reporting.
var result = await processor.ExecuteWorkspaceQuery(
new HeartbeatQuery(),
cancellationToken);
Resource Query — Targets a specific Azure resource by its ARM resource ID. Only logs from that specific resource are returned. Best for resource-specific troubleshooting and isolated analysis.
var resourceId = new ResourceIdentifier(
"/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Compute/virtualMachines/{vm}");
var result = await processor.ExecuteResourceQuery(
new HeartbeatQuery(),
resourceId,
cancellationToken);
| Scenario | Recommended Pattern |
|---|---|
| Dashboard showing all VM health | Workspace query |
| Troubleshooting a specific VM issue | Resource query |
| Aggregating logs across multiple apps | Workspace query |
| Analyzing one App Service's exceptions | Resource query |
| Cross-workspace queries | Workspace query with AdditionalWorkspaces query option |
Configuration Options
AtcLogAnalyticsOptions
| Property | Type | Description |
|---|---|---|
WorkspaceId |
string |
The Log Analytics workspace ID (GUID). Required for workspace queries. |
Credential |
TokenCredential |
Azure credential for authentication. Required. |
Endpoint |
Uri? |
Custom endpoint URI. Defaults to Azure public cloud. |
AtcLogAnalyticsQueryOptions
Per-query options that can be passed when executing a query.
| Property | Type | Default | Description |
|---|---|---|---|
TimeRange |
LogsQueryTimeRange? |
null |
Time range for the query. If null, query must specify time filter. |
ServerTimeout |
TimeSpan? |
null |
Server-side query timeout. |
AdditionalWorkspaces |
IList<string>? |
null |
Additional workspaces for this specific query. |
var options = new AtcLogAnalyticsQueryOptions
{
TimeRange = new LogsQueryTimeRange(TimeSpan.FromDays(7)),
ServerTimeout = TimeSpan.FromMinutes(5),
};
var result = await processor.ExecuteWorkspaceQuery(query, options, ct);
Named Configurations
Register multiple workspaces with named configurations:
// Production workspace
services.ConfigureLogAnalytics(options =>
{
options.WorkspaceId = "prod-workspace-guid";
options.Credential = new DefaultAzureCredential();
}, configurationName: "Production");
// Development workspace
services.ConfigureLogAnalytics(options =>
{
options.WorkspaceId = "dev-workspace-guid";
options.Credential = new DefaultAzureCredential();
}, configurationName: "Development");
// Use a named configuration
var processor = processorFactory.Create("Production");
Cross-Workspace Queries
Cross-workspace queries are configured per-query via AtcLogAnalyticsQueryOptions:
var queryOptions = new AtcLogAnalyticsQueryOptions
{
AdditionalWorkspaces = new List<string> { "secondary-workspace" }
};
var result = await processor.ExecuteWorkspaceQuery(query, queryOptions, ct);
Custom Endpoints
For Azure Government, China, or private link scenarios:
services.ConfigureLogAnalytics(options =>
{
options.WorkspaceId = "your-workspace-guid";
options.Credential = new DefaultAzureCredential();
// Azure Government
options.Endpoint = new Uri("https://api.loganalytics.us/v1");
});
Authentication
The library uses Azure.Identity for authentication. The recommended approach is DefaultAzureCredential, which automatically tries multiple authentication methods.
For local development, sign in with Azure CLI:
az login
az account set --subscription "your-subscription-id"
For production, use Managed Identity:
// System-assigned managed identity
options.Credential = new ManagedIdentityCredential();
// User-assigned managed identity
options.Credential = new ManagedIdentityCredential("client-id");
Requirements
How to contribute
| 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
- Atc (>= 3.0.18)
- Azure.Identity (>= 1.18.0)
- Azure.Monitor.Query.Logs (>= 1.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Logging (>= 10.0.3)
- Microsoft.Extensions.Options (>= 10.0.3)
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 |
|---|---|---|
| 1.1.2 | 29 | 3/5/2026 |