如何使用Azure Log Analytics .NET SDK执行跨工作区查询?
Alright, let's get your cross-workspace query up and running with the Microsoft.Azure.OperationalInsights SDK—you’re already on the right track by noticing the AdditionalWorkspaces property, that’s exactly the tool we need here.
First, Let’s Break Down the AdditionalWorkspaces Property
This is an IList<string> where you can add the IDs of all extra workspaces you want to query, alongside your main workspace set via WorkspaceId. A quick heads-up: the service principal you’re using for authentication needs query permissions (like the Log Analytics Reader role) on every single workspace in this list—don’t skip setting that up in Azure IAM!
Step 1: Dynamically Fetch Workspace IDs
First, add a method to pull your target workspace IDs from wherever you store them (config, database, etc.). Here’s an example using your existing SettingsHelpers:
private List<string> GetTargetWorkspaceIds() { // Example: Pull a comma-separated list of workspace IDs from your settings var workspaceIdsConfig = SettingsHelpers.PullSettingsByKey("additionalWorkspaceIds"); return workspaceIdsConfig.Split(',') .Select(id => id.Trim()) .ToList(); }
Step 2: Updated Query Method for Cross-Workspace Scenarios
Now, let’s adjust your query method to configure the AdditionalWorkspaces and write a cross-workspace Kusto query. There are two common ways to structure this:
Option 1: Explicitly Reference Specific Workspaces
If you need to target specific tables in specific workspaces, use this approach:
public async Task<string> CrossWorkspaceLogAnalyticsQuery() { // Grab main workspace ID and additional workspace IDs var mainWorkspaceId = SettingsHelpers.PullSettingsByKey("workspaceId"); var additionalWorkspaces = GetTargetWorkspaceIds(); // Configure the client _operationalInsightsDataClient.WorkspaceId = mainWorkspaceId; _operationalInsightsDataClient.AdditionalWorkspaces.Clear(); // Reset to avoid duplicates additionalWorkspaces.ForEach(id => _operationalInsightsDataClient.AdditionalWorkspaces.Add(id)); // Build the cross-workspace query var query = @" union withsource=SourceWorkspace (workspace('" + mainWorkspaceId + @"').Usage), " + string.Join(",\n", additionalWorkspaces.Select(id => $"(workspace('{id}').Usage)")) + @" | where TimeGenerated > ago(3h) | where DataType == 'Perf' | where QuantityUnit == 'MBytes' | summarize avg(Quantity) by SourceWorkspace, Computer | sort by avg_Quantity desc nulls last"; var jsonResult = await _operationalInsightsDataClient.QueryAsync(query); return JsonConvert.SerializeObject(jsonResult.Results); }
Option 2: Simplified Union Across All Configured Workspaces
If you want to union the same table across your main workspace + all additional workspaces, use this shorthand (the * automatically includes all workspaces set in the client):
public async Task<string> SimplifiedCrossWorkspaceQuery() { var mainWorkspaceId = SettingsHelpers.PullSettingsByKey("workspaceId"); var additionalWorkspaces = GetTargetWorkspaceIds(); // Configure client _operationalInsightsDataClient.WorkspaceId = mainWorkspaceId; _operationalInsightsDataClient.AdditionalWorkspaces.Clear(); additionalWorkspaces.ForEach(id => _operationalInsightsDataClient.AdditionalWorkspaces.Add(id)); // Shorthand query: union all 'Usage' tables from main + additional workspaces var query = @" union withsource=SourceWorkspace * | where TimeGenerated > ago(3h) | where DataType == 'Perf' | where QuantityUnit == 'MBytes' | summarize avg(Quantity) by SourceWorkspace, Computer | sort by avg_Quantity desc nulls last"; var jsonResult = await _operationalInsightsDataClient.QueryAsync(query); return JsonConvert.SerializeObject(jsonResult.Results); }
Quick Key Notes
- Permissions Check: Double-check that your service principal has access to every workspace you’re querying—missing permissions will throw errors.
- Test First: Validate your Kusto query in the Azure Portal’s Log Analytics workspace before coding it, to make sure it returns the data you expect.
- Cleanup: Always clear the
AdditionalWorkspaceslist before adding new IDs to avoid accidental duplicates from previous method calls.
内容的提问来源于stack exchange,提问作者Zack ISSOIR

