Tim Addison

Getting a list of all performance counters ingested to Log Analytics

Log Analytics is a great product - easy to get data ingested, and easy to query it. It’s also pretty easy to run up a sizeable bill (with the cost being based on GB ingested). I’ve found it helpful to regularly review what is being ingested to a workspace, which I typically do with the following query:

| where TimeGenerated > ago(30d)
| where IsBillable == true
| summarize TotalVolumeGB = sum(Quantity) / 1024 by Solution, DataType
| order by TotalVolumeGB desc

You’ll get to know which solutions are data heavy pretty fast (I’m looking at you Wire Data and DNS Analytics). Something I’ve recently spent some time on is performance counters - after the Perf data type crept to the top of the list, so I drilled into that with the _BilledSize property:

| where TimeGenerated > ago(30d)
| summarize TotalVolumeGB = sum(_BilledSize) / pow(1024, 3) by ObjectName, CounterName // Computer
| order by TotalVolumeGB desc

A recent review showed a fair amount of performance counter overlap between workspaces - my suspicion was that we were ingesting the same counters in multiple workspaces. The following script dumps all counters ingested to any workspace, along with their target instance and frequency. A reliable way to drive up your ingestion costs are the Process/% Processor Time counter ingested for every instance (*) at a frequency of 10 seconds.

We got rid of that one pretty fast.

Import-Module Az


$allPerfCounters = @()

$subscriptions = Get-AzSubscription
foreach ($subscription in $subscriptions) {
  $subscription | Set-AzContext

  $workspaces = Get-AzOperationalInsightsWorkspace

  foreach ($workspace in $workspaces) {

    $perfCounters = Get-AzOperationalInsightsDataSource -Kind WindowsPerformanceCounter -Workspace $workspace

    foreach ($counter in $perfCounters) {
      $allPerfCounters += [pscustomobject]@{
        Subscription  = $subscription.Name
        ResourceGroup = $counter.ResourceGroupName
        Workspace     = $counter.WorkspaceName
        ObjectName    = $counter.Properties.ObjectName
        InstanceName  = $counter.Properties.InstanceName
        CounterName   = $counter.Properties.CounterName
        Interval      = $counter.Properties.IntervalSeconds
$allPerfCounters | Format-Table

Example Results

Along with a bit of Excel and the results from the earlier queries, it was easy to work through the list and cut down on ingestion costs.

For more information on understanding costs I’ve found the following articles helpful: