Azure Monitor Logs 工具手册
先把五个标识分开
Azure Monitor Logs 以 Log Analytics workspace 和 table 承载日志查询,Data Collection Rule(DCR)描述输入 stream、变换和目标。程序通过 Logs Ingestion API 直写时,URL 需要 DCR 的 logs ingestion endpoint、DCR immutable ID 和 stream name;查询又使用 workspace GUID。ARM resource ID 则用于资源管理与 RBAC。
这些值外观相近,职责完全不同。把 workspace GUID 填进 ARM scope、把 resource ID 放进摄取 URL,或者给 workspace Reader 却没给 DCR 发送权限,都会产生看似相同的 401/403/空查询。官方 Logs Ingestion API 概览 应作为端点与对象语义基线。
创建隔离的 workspace 与 table
下面使用当前 Azure CLI 登录用户做一次独立实验。执行者除了创建资源,还需要写 role assignment;普通 Contributor 不具备这一动作。生产发送端应使用 managed identity 或 federated credential,不应下载长期 client secret。
az login
az account show --query '{subscription:id,tenant:tenantId,user:user.name}' -o json
LAB_ID="$(date -u +%Y%m%d%H%M%S)-$RANDOM"
RG="rg-log-lab-$LAB_ID"
LOCATION=eastus
WORKSPACE="law-log-lab-$LAB_ID"
AZ_TMP=$(mktemp -d "${TMPDIR:-/tmp}/azure-log-lab.XXXXXXXX")
az group create --name "$RG" --location "$LOCATION" \
--tags log-lab-owner="$LAB_ID" purpose=tool-efficiency-lab
az monitor log-analytics workspace create \
--resource-group "$RG" --workspace-name "$WORKSPACE" \
--location "$LOCATION" --retention-time 30
WORKSPACE_ID=$(az monitor log-analytics workspace show \
--resource-group "$RG" --workspace-name "$WORKSPACE" \
--query customerId -o tsv)
SUBSCRIPTION_ID=$(az account show --query id -o tsv)
WORKSPACE_RESOURCE_ID=$(az monitor log-analytics workspace show \
--resource-group "$RG" --workspace-name "$WORKSPACE" \
--query id -o tsv)WORKSPACE_ID 是查询 API 使用的 GUID,WORKSPACE_RESOURCE_ID 是 Azure Resource Manager 路径。自定义 table 必须先存在,名称带 _CL 后缀:
az rest --method put \
--url "https://management.azure.com${WORKSPACE_RESOURCE_ID}/tables/Checkout_CL?api-version=2022-10-01" \
--body '{
"properties": {
"schema": {
"name": "Checkout_CL",
"columns": [
{"name":"TimeGenerated","type":"datetime"},
{"name":"Service","type":"string"},
{"name":"TraceId","type":"string"},
{"name":"Message","type":"string"}
]
},
"retentionInDays": 30,
"totalRetentionInDays": 30
}
}'DCR 既是 schema 契约,也是静默丢数点
下面的 DCR 声明输入 stream,把它送到 workspace 中的自定义 table。transformKql: source 不改动事件;真正部署时可以删字段、改类型、计算列或过滤,但每一条 transform 都要有“应通过”和“应过滤”的合成样本。
{
"location": "eastus",
"kind": "Direct",
"properties": {
"streamDeclarations": {
"Custom-CheckoutRaw": {
"columns": [
{"name":"TimeGenerated","type":"datetime"},
{"name":"Service","type":"string"},
{"name":"TraceId","type":"string"},
{"name":"Message","type":"string"}
]
}
},
"destinations": {
"logAnalytics": [
{
"workspaceResourceId": "WORKSPACE_RESOURCE_ID",
"name": "checkoutWorkspace"
}
]
},
"dataFlows": [
{
"streams": ["Custom-CheckoutRaw"],
"destinations": ["checkoutWorkspace"],
"transformKql": "source",
"outputStream": "Custom-Checkout_CL"
}
]
}
}保存为 $AZ_TMP/dcr.json,替换 workspace resource ID 后创建 DCR:
DCR="dcr-checkout-$LAB_ID"
DCR_RESOURCE_ID="/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RG/providers/Microsoft.Insights/dataCollectionRules/$DCR"
sed -i "s|WORKSPACE_RESOURCE_ID|$WORKSPACE_RESOURCE_ID|" "$AZ_TMP/dcr.json"
az rest --method put \
--url "https://management.azure.com${DCR_RESOURCE_ID}?api-version=2023-03-11" \
--body "@$AZ_TMP/dcr.json"
DCR_IMMUTABLE_ID=$(az rest \
--url "https://management.azure.com${DCR_RESOURCE_ID}?api-version=2023-03-11" \
--query properties.immutableId -o tsv)
DCR_ENDPOINT=$(az rest \
--url "https://management.azure.com${DCR_RESOURCE_ID}?api-version=2023-03-11" \
--query properties.endpoints.logsIngestion -o tsv)kind: Direct 让新 DCR 获得直接摄取 endpoint。使用 Private Link,或 DCR 没有该 endpoint 时,才需要独立 Data Collection Endpoint(DCE)。旧 DCR 不能原地补出 endpoint,需要创建替代 DCR;这个差异在迁移时必须显式记录。
发送权限和查询权限是两条链
发送者在 DCR scope 上需要 Monitoring Metrics Publisher,查询者在 workspace 或更细范围上获得只读角色。下面用当前登录用户验证实验,生产应用不应照搬用户身份:
PRINCIPAL_ID=$(az ad signed-in-user show --query id -o tsv)
az role assignment create \
--assignee-object-id "$PRINCIPAL_ID" --assignee-principal-type User \
--role "Monitoring Metrics Publisher" --scope "$DCR_RESOURCE_ID"
az role assignment create \
--assignee-object-id "$PRINCIPAL_ID" --assignee-principal-type User \
--role "Log Analytics Reader" --scope "$WORKSPACE_RESOURCE_ID"生成当前 UTC 时间的 JSON 数组。Logs Ingestion API 的 body 必须是数组,即使只有一条记录:
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
cat > "$AZ_TMP/payload.json" <<EOF
[
{
"TimeGenerated": "$NOW",
"Service": "checkout",
"TraceId": "TE-AZ-001",
"Message": "payment timeout"
}
]
EOF
TOKEN=$(az account get-access-token \
--scope https://monitor.azure.com/.default --query accessToken -o tsv)
curl -i -X POST \
"${DCR_ENDPOINT}/dataCollectionRules/${DCR_IMMUTABLE_ID}/streams/Custom-CheckoutRaw?api-version=2023-01-01" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
--data-binary "@$AZ_TMP/payload.json"HTTP 204 表示摄取 API 接纳了请求,不代表查询立即可见。等待处理后再按 workspace GUID 查询:
az monitor log-analytics query \
--workspace "$WORKSPACE_ID" \
--analytics-query 'Checkout_CL | where TraceId == "TE-AZ-001" | project TimeGenerated, Service, Message' \
--timespan PT1H -o table401 先查 token audience 与过期时间;403 查发送身份是否能访问 DCR;400 查 stream name、数组形状、字段类型和 transform。204 后长期无数据,要查 DCR 目标 table、transformKql、workspace region、table 摄取状态与 DCR 自身错误日志。查询 403 属于另一条读权限链,不能反推摄取失败。
table plan 会改变能力,不只是单价
Analytics、Basic、Auxiliary 等 table plan 会改变查询、保留与交互能力。为了降低摄取单价切换 plan,却继续假设所有 KQL、告警和查询延迟保持不变,是一种常见的迁移失误。变更前要用真实查询集验证扫描量、延迟和缺失操作。
成本通常包括摄取与保留,还可能叠加查询、search job、restore、export、Sentinel、dedicated cluster、跨区域 DCR、Event Hub、Storage 与 Private Link。配额和 API 限制随订阅、region、table plan 与合同变化,容量评审应读取目标订阅的 Usage and estimated costs、服务限制和 DCR 指标。
Azure Monitor Agent 与 Logs Ingestion API 都可能经过 DCR。平台应监控 DCR 的接收量、处理错误和 transformation 结果;只看 workspace 里偶尔出现数据,无法证明日志链完整。
实验清理与生产退出不是同一动作
清理前先从内存移除访问令牌,再核对订阅、资源组前缀和 owner tag。三项任一不匹配就停止:
unset TOKEN
test "$(az account show --query id -o tsv)" = "$SUBSCRIPTION_ID"
case "$RG" in rg-log-lab-*) ;; *) echo "refuse unexpected RG: $RG" >&2; exit 1;; esac
test "$(az group show --name "$RG" --query 'tags."log-lab-owner"' -o tsv)" = "$LAB_ID"
az group delete --name "$RG" --yes --no-wait
rm -r -- "$AZ_TMP"这段删除只适用于本次独立实验资源组。生产回滚 DCR 时应恢复旧 association 或旧摄取 endpoint,保留新旧 table 的核对窗口;删除 workspace 会同时影响查询、告警、Sentinel、导出和审计引用,不能作为普通配置回滚。能清楚回答谁能发送、谁能查询、哪条 transform 改过数据、哪个 ID 属于哪个控制面,Azure Monitor Logs 才真正可维护。
