0

I've looked around a while for how to go about to parse a Prometheus promo answer using PowerShell to convert published Windows system performance metrics back to PowerShell objects.

# HELP CPU_Total Total CPU load in percent of all processors combined.
# TYPE CPU_Total gauge
CPU_Total{Instance="_total"} 1.29915
# HELP Disk_Avg_Bytes_Read Average number of bytes transfered from the disk during read operations.
# TYPE Disk_Avg_Bytes_Read gauge
Disk_Avg_Bytes_Read{Instance="harddiskvolume2"} 0
# HELP Disk_Avg_Bytes_Read Average number of bytes transfered from the disk during read operations.
# TYPE Disk_Avg_Bytes_Read gauge
Disk_Avg_Bytes_Read{Instance="c"} 0
# HELP Disk_Avg_Bytes_Read Average number of bytes transfered from the disk during read operations.
# TYPE Disk_Avg_Bytes_Read gauge
Disk_Avg_Bytes_Read{Instance="_total"} 0
# HELP Disk_Avg_Bytes_Write Average number of bytes transfered to the disk during write operations.
# TYPE Disk_Avg_Bytes_Write gauge
Disk_Avg_Bytes_Write{Instance="harddiskvolume2"} 0
# HELP Disk_Avg_Bytes_Write Average number of bytes transfered to the disk during write operations.
# TYPE Disk_Avg_Bytes_Write gauge
Disk_Avg_Bytes_Write{Instance="c"} 8192
# HELP Disk_Avg_Bytes_Write Average number of bytes transfered to the disk during write operations.
# TYPE Disk_Avg_Bytes_Write gauge
Disk_Avg_Bytes_Write{Instance="_total"} 8192
# HELP Disk_sec_per_Read Average time, in seconds, of a read of data from the disk.
# TYPE Disk_sec_per_Read gauge
Disk_sec_per_Read{Instance="harddiskvolume2"} 0

There a plenty of examples in Go (How to parse Prometheus data) and C#, etc. and they all seem to refer back to the Google ProtoBuf library

Even if PowerShell can interpret C#, I haven't a clue about how to write it :)
I assume that the download for Windows is a .Net-library, but exposing the calls is a daunting task when the foundation of knowledge is PowerShell.
And I need to use a DLL-explorer to find the names of the public calls available.

So I tried to start download the .Net version of ProtBuf, with accompanying dependencies, and then install using 'Install-Package' only to end up in the error

Install-Package: Dependency loop detected for package 'protobuf-net'

But using

choco install protoc

works like a charm.

Unfortunatley, Promethues no longer supports the JSON-format, so the proto file that can be found at
https://github.com/prometheus/client_model/blob/master/io/prometheus/client/metrics.proto
is no longer maintained (although it might be in the future again).

So,

  • is there a simple way to construct a parser based on the prom file in PowerShell?

Edit: Using Chocolatey to install the library instead...
Edit II: The ProtoBuf library is actually an protoc.exe file with command switches
Edit III: Found the Prometheus ebnf specification
Edit IV: Added a promo example

Dennis
  • 871
  • 9
  • 29
  • 1
    PowerShell, as of v7.3.4, lacks direct integration with NuGet packages, as evidenced not only by the "dependency loop" error you ran into. Even when installation succeeds, loading the relevant assembly doesn't always load its dependencies, which requires a .NET SDK-based workaround (which also bypasses the "dependency loop" problem. See [this answer](https://stackoverflow.com/a/75537273/45375) for more information. With a properly installed NuGet package you can _almost always_ do everything you can do in C# in PowerShell as well (a notably exception are ByRef-like types such as `System.Span`) – mklement0 May 30 '23 at 16:08
  • @mklement0 I'm restraining myself to 7.2.x LTS :) But I did use Windows PowerShell with Install-Package. – Dennis May 30 '23 at 16:10
  • 1
    Understood - I was merely using the latest stable version as of this writing as a reference point; in _older_ versions you're definitely out of luck. The truth is that proper NuGet package integration has been asked for years ago, but it doesn't look like there's any movement - see [GitHub issue #6724](https://github.com/PowerShell/PowerShell/issues/6724). – mklement0 May 30 '23 at 16:13
  • I think I noticed a Chocolatey installer as well for ProtoBuf. Just didn't want to install Chocolatey if not needed. – Dennis May 30 '23 at 16:15

2 Answers2

0

As far as I can tell, the protoc.exe is an actual compiler to supply different languages with the necessary binary code to do de/serialisation in accordance with a proto-file describing the data format.

So since PowerShell only provides a JIT-compiler for C#, I don't see how protoc.exe can be used with PowerShell.

Dennis
  • 871
  • 9
  • 29
0

I did find prom2json, but not as a binary for Windows or easaly transferable to PowerShell.
And that would have resulted in a cmd tool anyway.

So I resorted to plain text parsing for now...

$RestCall = Invoke-RestMethod -Uri http://localhost:9700/metrics

$RestObjects = $RestCall -split "`n# HELP "

[array]$Metrics = $null
foreach ($Object in $RestObjects) {
  $Part = $Object -split "`n"

  $Help = $Part[0]
  $Type = $Part[1] # for now we only have gauge, ignore
  [array]$ValueStruct = ($Part[2] -split '[{}]').Trim(' ')

  if ($ValueStruct.Count -ne 1) {# label
    $ValueName = $ValueStruct[0]
    $Label = $ValueStruct[1] -split "="
    $LabelName = $Label[0]
    $LabelValue = $Label[1] -replace '"',''
    $Value = $ValueStruct[2]
  } else {# no label
    $ValueStruct = $Part[2] -split ' '

    $ValueName = $ValueStruct[0]
    $LabelName = $null
    $LabelValue = $null
    $Value = $ValueStruct[1]
  }
    

  $Metric = [PSCustomObject]@{
    Name    = $ValueName
    Instance = $LabelValue
    Value   = $Value
  }

  $Metrics += $Metric

}

$Metrics

Dennis
  • 871
  • 9
  • 29