你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

适用于 .NET 的 Azure Monitor 查询客户端库 - 版本 1.2.0

Azure Monitor 查询客户端库用于对 Azure Monitor 的两个数据平台执行只读查询:

  • 日志 - 从受监视的资源收集和组织日志和性能数据。 来自不同源的数据(例如来自 Azure 服务的平台日志、来自虚拟机代理的日志和性能数据,以及应用的使用情况和性能数据)可以合并到单个 Azure Log Analytics 工作区中。 可以使用 Kusto 查询语言一起分析各种数据类型。
  • 指标 - 将受监视资源中的数字数据收集到时序数据库中。 指标是定期收集的数值,用于描述系统在某一特定时间的某些情况。 指标是轻量级的,能够支持准实时方案,因此可用于发出警报和快速检测问题。

资源:

入门

先决条件

安装包

使用 NuGet 安装适用于 .NET 的 Azure Monitor 查询客户端库:

dotnet add package Azure.Monitor.Query

验证客户端

查询日志或指标需要经过身份验证的客户端。 若要进行身份验证,请创建 类的 TokenCredential 实例。 将其传递给 或 MetricsQueryClient 类的LogsQueryClient构造函数。

若要进行身份验证,以下示例使用 DefaultAzureCredential 包中的 Azure.Identity

var client = new LogsQueryClient(new DefaultAzureCredential());
var client = new MetricsQueryClient(new DefaultAzureCredential());

执行查询

有关日志和指标查询的示例,请参阅 示例 部分。

关键概念

日志查询速率限制和限制

当请求速率过高时,Log Analytics 服务会应用限制。 限制(如返回的最大行数)也应用于 Kusto 查询。 有关详细信息,请参阅 查询 API

指标数据结构

每组指标值都是具有以下特征的时序:

  • 值的收集时间
  • 与值关联的资源
  • 充当指标类别的命名空间
  • 指标名称
  • 值本身
  • 某些指标可能具有多个维度,如多维指标中所述。 自定义指标最多可以包含 10 个维度。

线程安全

所有客户端实例方法都是线程安全的, (准则) 相互独立。 此设计可确保重用客户端实例的建议始终是安全的,即使在线程之间也是如此。

其他概念

客户端选项 | 访问响应 | 长时间运行的操作 | 处理失败 | 诊断 | 嘲笑 | 客户端生存期

示例

日志查询

可以按工作区 ID 或资源 ID 查询日志。 结果以包含行集合的表的形式返回。

以工作区为中心的日志查询

若要按工作区 ID 进行查询,请使用 LogsQueryClient.QueryWorkspaceAsync 方法:

string workspaceId = "<workspace_id>";
var client = new LogsQueryClient(new DefaultAzureCredential());

Response<LogsQueryResult> result = await client.QueryWorkspaceAsync(
    workspaceId,
    "AzureActivity | top 10 by TimeGenerated",
    new QueryTimeRange(TimeSpan.FromDays(1)));

LogsTable table = result.Value.Table;

foreach (var row in table.Rows)
{
    Console.WriteLine($"{row["OperationName"]} {row["ResourceGroup"]}");
}

以资源为中心的日志查询

若要按资源 ID 进行查询,请使用 LogsQueryClient.QueryResourceAsync 方法。

查找资源 ID:

  1. 导航到Azure 门户中的资源页。
  2. “概述 ”边栏选项卡中,选择“ JSON 视图” 链接。
  3. 在生成的 JSON 中,复制 属性的值 id
var client = new LogsQueryClient(new DefaultAzureCredential());

string resourceId = "/subscriptions/<subscription_id>/resourceGroups/<resource_group_name>/providers/<resource_provider>/<resource>";
string tableName = "<table_name>";
Response<LogsQueryResult> results = await client.QueryResourceAsync(
    new ResourceIdentifier(resourceId),
    $"{tableName} | distinct * | project TimeGenerated",
    new QueryTimeRange(TimeSpan.FromDays(7)));

LogsTable resultTable = results.Value.Table;
foreach (LogsTableRow row in resultTable.Rows)
{
    Console.WriteLine($"{row["OperationName"]} {row["ResourceGroup"]}");
}

foreach (LogsTableColumn columns in resultTable.Columns)
{
    Console.WriteLine("Name: " + columns.Name + " Type: " + columns.Type);
}

处理日志查询响应

方法 QueryWorkspace 返回 , LogsQueryResultQueryBatch 方法返回 LogsBatchQueryResult。 下面是响应的层次结构:

LogsQueryResult
|---Error
|---Status
|---Table
    |---Name
    |---Columns (list of `LogsTableColumn` objects)
        |---Name
        |---Type
    |---Rows (list of `LogsTableRows` objects)
        |---Count
|---AllTables (list of `LogsTable` objects)

将日志查询结果映射到模型

可以使用 方法将日志查询结果映射到模型 LogsQueryClient.QueryWorkspaceAsync<T>

public class MyLogEntryModel
{
    public string ResourceGroup { get; set; }
    public int Count { get; set; }
}
var client = new LogsQueryClient(new DefaultAzureCredential());
string workspaceId = "<workspace_id>";

// Query TOP 10 resource groups by event count
Response<IReadOnlyList<MyLogEntryModel>> response = await client.QueryWorkspaceAsync<MyLogEntryModel>(
    workspaceId,
    "AzureActivity | summarize Count = count() by ResourceGroup | top 10 by Count",
    new QueryTimeRange(TimeSpan.FromDays(1)));

foreach (var logEntryModel in response.Value)
{
    Console.WriteLine($"{logEntryModel.ResourceGroup} had {logEntryModel.Count} events");
}

将日志查询结果映射到基元

如果查询返回基元类型的单个列 (或单个值) ,请使用 LogsQueryClient.QueryWorkspaceAsync<T> 重载对其进行反序列化:

string workspaceId = "<workspace_id>";

var client = new LogsQueryClient(new DefaultAzureCredential());

// Query TOP 10 resource groups by event count
Response<IReadOnlyList<string>> response = await client.QueryWorkspaceAsync<string>(
    workspaceId,
    "AzureActivity | summarize Count = count() by ResourceGroup | top 10 by Count | project ResourceGroup",
    new QueryTimeRange(TimeSpan.FromDays(1)));

foreach (var resourceGroup in response.Value)
{
    Console.WriteLine(resourceGroup);
}

还可以动态检查列的列表。 以下示例将查询结果打印为表:

string workspaceId = "<workspace_id>";

var client = new LogsQueryClient(new DefaultAzureCredential());
Response<LogsQueryResult> response = await client.QueryWorkspaceAsync(
    workspaceId,
    "AzureActivity | top 10 by TimeGenerated",
    new QueryTimeRange(TimeSpan.FromDays(1)));

LogsTable table = response.Value.Table;

foreach (var column in table.Columns)
{
    Console.Write(column.Name + ";");
}

Console.WriteLine();

var columnCount = table.Columns.Count;
foreach (var row in table.Rows)
{
    for (int i = 0; i < columnCount; i++)
    {
        Console.Write(row[i] + ";");
    }

    Console.WriteLine();
}

批处理日志查询

可以使用 方法在单个请求 LogsQueryClient.QueryBatchAsync 中执行多个日志查询:

string workspaceId = "<workspace_id>";

var client = new LogsQueryClient(new DefaultAzureCredential());

// Query TOP 10 resource groups by event count
// And total event count
var batch = new LogsBatchQuery();

string countQueryId = batch.AddWorkspaceQuery(
    workspaceId,
    "AzureActivity | count",
    new QueryTimeRange(TimeSpan.FromDays(1)));
string topQueryId = batch.AddWorkspaceQuery(
    workspaceId,
    "AzureActivity | summarize Count = count() by ResourceGroup | top 10 by Count",
    new QueryTimeRange(TimeSpan.FromDays(1)));

Response<LogsBatchQueryResultCollection> response = await client.QueryBatchAsync(batch);

var count = response.Value.GetResult<int>(countQueryId).Single();
var topEntries = response.Value.GetResult<MyLogEntryModel>(topQueryId);

Console.WriteLine($"AzureActivity has total {count} events");
foreach (var logEntryModel in topEntries)
{
    Console.WriteLine($"{logEntryModel.ResourceGroup} had {logEntryModel.Count} events");
}

高级日志查询方案

设置日志查询超时

某些日志查询的执行时间超过 3 分钟。 默认服务器超时为 3 分钟。 可以将服务器超时增加到最多 10 分钟。 在以下示例中 LogsQueryOptions , 对象的 ServerTimeout 属性用于将服务器超时设置为 10 分钟:

string workspaceId = "<workspace_id>";

var client = new LogsQueryClient(new DefaultAzureCredential());

// Query TOP 10 resource groups by event count
Response<IReadOnlyList<string>> response = await client.QueryWorkspaceAsync<string>(
    workspaceId,
    @"AzureActivity
        | summarize Count = count() by ResourceGroup
        | top 10 by Count
        | project ResourceGroup",
    new QueryTimeRange(TimeSpan.FromDays(1)),
    new LogsQueryOptions
    {
        ServerTimeout = TimeSpan.FromMinutes(10)
    });

foreach (var resourceGroup in response.Value)
{
    Console.WriteLine(resourceGroup);
}

查询多个工作区

若要对多个工作区运行相同的日志查询,请使用 LogsQueryOptions.AdditionalWorkspaces 属性:

string workspaceId = "<workspace_id>";
string additionalWorkspaceId = "<additional_workspace_id>";

var client = new LogsQueryClient(new DefaultAzureCredential());

// Query TOP 10 resource groups by event count
Response<IReadOnlyList<string>> response = await client.QueryWorkspaceAsync<string>(
    workspaceId,
    @"AzureActivity
        | summarize Count = count() by ResourceGroup
        | top 10 by Count
        | project ResourceGroup",
    new QueryTimeRange(TimeSpan.FromDays(1)),
    new LogsQueryOptions
    {
        AdditionalWorkspaces = { additionalWorkspaceId }
    });

foreach (var resourceGroup in response.Value)
{
    Console.WriteLine(resourceGroup);
}

包括统计信息

若要获取日志查询执行统计信息,例如 CPU 和内存消耗:

  1. LogsQueryOptions.IncludeStatistics 属性设置为 true
  2. GetStatistics对 对象调用 方法LogsQueryResult

以下示例输出查询执行时间:

string workspaceId = "<workspace_id>";
var client = new LogsQueryClient(new DefaultAzureCredential());

Response<LogsQueryResult> response = await client.QueryWorkspaceAsync(
    workspaceId,
    "AzureActivity | top 10 by TimeGenerated",
    new QueryTimeRange(TimeSpan.FromDays(1)),
    new LogsQueryOptions
    {
        IncludeStatistics = true,
    });

BinaryData stats = response.Value.GetStatistics();
using var statsDoc = JsonDocument.Parse(stats);
var queryStats = statsDoc.RootElement.GetProperty("query");
Console.WriteLine(queryStats.GetProperty("executionTime").GetDouble());

由于统计信息有效负载的结构因查询而异,因此 BinaryData 使用返回类型。 它包含原始 JSON 响应。 统计信息位于 JSON 的 属性中 query 。 例如:

{
  "query": {
    "executionTime": 0.0156478,
    "resourceUsage": {...},
    "inputDatasetStatistics": {...},
    "datasetStatistics": [{...}]
  }
}

包括可视化效果

若要使用 render 运算符获取日志查询的可视化数据,请执行以下操作:

  1. LogsQueryOptions.IncludeVisualization 属性设置为 true
  2. GetVisualization对 对象调用 方法LogsQueryResult

例如:

string workspaceId = "<workspace_id>";
var client = new LogsQueryClient(new DefaultAzureCredential());

Response<LogsQueryResult> response = await client.QueryWorkspaceAsync(
    workspaceId,
    @"StormEvents
        | summarize event_count = count() by State
        | where event_count > 10
        | project State, event_count
        | render columnchart",
    new QueryTimeRange(TimeSpan.FromDays(1)),
    new LogsQueryOptions
    {
        IncludeVisualization = true,
    });

BinaryData viz = response.Value.GetVisualization();
using var vizDoc = JsonDocument.Parse(viz);
var queryViz = vizDoc.RootElement.GetProperty("visualization");
Console.WriteLine(queryViz.GetString());

由于可视化有效负载的结构因查询而异,因此 BinaryData 使用返回类型。 它包含原始 JSON 响应。 例如:

{
  "visualization": "columnchart",
  "title": null,
  "accumulate": false,
  "isQuerySorted": false,
  "kind": null,
  "legend": null,
  "series": null,
  "yMin": "",
  "yMax": "",
  "xAxis": null,
  "xColumn": null,
  "xTitle": null,
  "yAxis": null,
  "yColumns": null,
  "ySplit": null,
  "yTitle": null,
  "anomalyColumns": null
}

指标查询

可以使用 方法查询 Azure 资源 MetricsQueryClient.QueryResourceAsync 上的指标。 对于每个请求的指标,集合中 TimeSeries 会返回一组聚合值。

查询指标需要资源 ID。 查找资源 ID:

  1. 导航到Azure 门户中的资源页。
  2. “概述 ”边栏选项卡中,选择“ JSON 视图” 链接。
  3. 在生成的 JSON 中,复制 属性的值 id
string resourceId =
    "/subscriptions/<subscription_id>/resourceGroups/<resource_group_name>/providers/<resource_provider>/<resource>";
var client = new MetricsQueryClient(new DefaultAzureCredential());

Response<MetricsQueryResult> results = await client.QueryResourceAsync(
    resourceId,
    new[] { "Query Success Rate", "Query Count" }
);

foreach (MetricResult metric in results.Value.Metrics)
{
    Console.WriteLine(metric.Name);
    foreach (MetricTimeSeriesElement element in metric.TimeSeries)
    {
        Console.WriteLine("Dimensions: " + string.Join(",", element.Metadata));

        foreach (MetricValue value in element.Values)
        {
            Console.WriteLine(value);
        }
    }
}

处理指标查询响应

指标查询 API 返回 对象 MetricsQueryResult 。 对象MetricsQueryResult包含一些属性,例如类型化对象、、、CostResourceRegionNamespaceTimeSpanInterval的列表。MetricResult MetricResult可以使用 参数访问metrics对象列表。 此列表中的每个对象都包含 MetricResult 一个 MetricTimeSeriesElement 对象列表。 每个 MetricTimeSeriesElement 对象都包含 MetadataValues 属性。

下面是响应的层次结构:

MetricsQueryResult
|---Cost
|---Granularity
|---Namespace
|---ResourceRegion
|---TimeSpan
|---Metrics (list of `MetricResult` objects)
    |---Id
    |---ResourceType
    |---Name
    |---Description
    |---Error
    |---Unit
    |---TimeSeries (list of `MetricTimeSeriesElement` objects)
        |---Metadata
        |---Values

使用选项查询指标

MetricsQueryOptions对象可用于支持更精细的指标查询。 请考虑以下示例,该示例查询名为 TestVault 的 Azure 密钥保管库资源。 请求资源的“保管库请求可用性”指标,如指标 ID“可用性”所示。 此外,还包括“Avg”聚合类型。

string resourceId =
    "/subscriptions/<subscription_id>/resourceGroups/<resource_group_name>/providers/Microsoft.KeyVault/vaults/TestVault";
string[] metricNames = new[] { "Availability" };
var client = new MetricsQueryClient(new DefaultAzureCredential());

Response<MetricsQueryResult> result = await client.QueryResourceAsync(
    resourceId,
    metricNames,
    new MetricsQueryOptions
    {
        Aggregations =
        {
            MetricAggregationType.Average,
        }
    });

MetricResult metric = result.Value.Metrics[0];

foreach (MetricTimeSeriesElement element in metric.TimeSeries)
{
    foreach (MetricValue value in element.Values)
    {
        // Prints a line that looks like the following:
        // 6/21/2022 12:29:00 AM +00:00 : 100
        Console.WriteLine($"{value.TimeStamp} : {value.Average}");
    }
}

按维度拆分指标

MetricsQueryOptions.Filter 属性可用于在筛选器值设置为星号时按维度拆分指标。 对于名为 TestWebApp 的App 服务资源,请考虑以下示例。 代码查询资源的 Http2xx 指标,并按 Instance 维度拆分该指标。

string resourceId =
    "/subscriptions/<subscription_id>/resourceGroups/<resource_group_name>/providers/Microsoft.Web/sites/TestWebApp";
string[] metricNames = new[] { "Http2xx" };
// Use of asterisk in filter value enables splitting on Instance dimension.
string filter = "Instance eq '*'";
var client = new MetricsQueryClient(new DefaultAzureCredential());
var options = new MetricsQueryOptions
{
    Aggregations =
    {
        MetricAggregationType.Average,
    },
    Filter = filter,
    TimeRange = TimeSpan.FromDays(2),
};
Response<MetricsQueryResult> result = await client.QueryResourceAsync(
    resourceId,
    metricNames,
    options);

foreach (MetricResult metric in result.Value.Metrics)
{
    foreach (MetricTimeSeriesElement element in metric.TimeSeries)
    {
        foreach (MetricValue value in element.Values)
        {
            // Prints a line that looks like the following:
            // Thursday, May 4, 2023 9:42:00 PM, webwk000002, Http2xx, 1
            Console.WriteLine(
                $"{value.TimeStamp:F}, {element.Metadata["Instance"]}, {metric.Name}, {value.Average}");
        }
    }
}

有关可用于每种 Azure 资源类型的指标和维度的清单,请参阅 Azure Monitor 支持的指标

使用依赖项注入注册客户端

若要向 DI) 容器 (依赖关系注入注册 LogsQueryClient ,请 AddLogsQueryClient 调用 方法。 若要向 DI) 容器 (依赖关系注入注册 MetricsQueryClient ,请 AddMetricsQueryClient 调用 方法。 有关详细信息,请参阅 注册客户端

故障排除

若要诊断各种故障情况,请参阅 故障排除指南

后续步骤

若要了解有关 Azure Monitor 的详细信息,请参阅 Azure Monitor 服务文档

贡献

本项目欢迎贡献和建议。 大多数贡献要求你同意贡献者许可协议 (CLA),并声明你有权(并且确实有权)授予我们使用你的贡献的权利。 有关详细信息,请访问 cla.microsoft.com

提交拉取请求时,CLA 机器人会自动确定是否需要提供 CLA,并使用标签和注释适当地修饰 PR。 按照机器人提供的说明操作。 你只需在所有 Microsoft 存储库中对 CLA 进行一次签名。

此项目采用了 Microsoft 开放源代码行为准则。 有关详细信息,请参阅 行为准则常见问题解答 或如有任何问题或意见,请联系 opencode@microsoft.com

曝光数