gRCP Health Check with Powershell

FJS 21 Reputation points
2022-05-08T16:38:07.973+00:00

Hello.
I am checking periodically gRPC health of several microservices, every two seconds, it is working since I got the response they are serving, the output is { "status": "SERVING" }

 while ($true) {grpcurl -d '{ \"service1\": \"name1\" }' -H "authorization: key key"  host1:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service2\": \"name2\" }' -H "authorization: key key"  host2:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service3\": \"name3\" }' -H "authorization: key key"  host3:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service4\": \"name4\" }' -H "authorization: key key"  host4:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service5\": \"name5\" }' -H "authorization: key key"  host5:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service6\": \"name6\" }' -H "authorization: key key" host6:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service7\": \"name7\" }' -H "authorization: key key" host7:port grpc.health.v1.Health/Check;start-sleep 2}

Now I need a notification if the output is not "SERVING" while the code keeps running in a loop, how can I achieve this?

Please note, one or more service can fail but other can be ok so notification should only about the ones are not answering "SERVING", thanks,

Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,381 questions
{count} votes

Accepted answer
  1. Rich Matheisen 45,091 Reputation points
    2022-05-10T14:49:34.68+00:00

    There are ways to make this more efficient, and to also handle those times when grpcurl doesn't return anything in STDOUT (e.g. the host cannot be contacted, authentication fails, etc.) but writes an error message to STDERR, but I'll leave that part up to you,

    Give this one a try:

    function Serving{
        param(
            $val
        )
        if ($val -isnot [array]){
            return $false
        }
        if ($val.count -ne 3){
            return $false
        }
        Try{
            $p = $val -join "" | ConvertFrom-Json -ErrorAction STOP
            if ($p.status -eq 'serving'){
                $true
            }
            else{
                $false
            }
        }
        Catch{
            Write-Host "'$p' is not JSON"
            $false
        }
    }
    while ($true) {
        $beep = $false
        [array]$response = grpcurl -d '{ \"service1\": \"name1\" }' -H "authorization: key key"  host1:port grpc.health.v1.Health/Check
        if (-Not (Serving $response)){
            Write-Host "Service1 isn't serving" -ForegroundColor Yellow
            $beep = $true
        }
        [array]$response = grpcurl -d '{ \"service2\": \"name2\" }' -H "authorization: key key"  host2:port grpc.health.v1.Health/Check
        if (-Not (Serving $response)){
            Write-Host "Service2 isn't serving" -ForegroundColor Yellow
            $beep = $true
        }
        [array]$response = grpcurl -d '{ \"service3\": \"name3\" }' -H "authorization: key key"  host3:port grpc.health.v1.Health/Check
        if (-Not (Serving $response)){
            Write-Host "Service3 isn't serving" -ForegroundColor Yellow
            $beep = $true
        }
        [array]$response = grpcurl -d '{ \"service4\": \"name4\" }' -H "authorization: key key"  host4:port grpc.health.v1.Health/Check 
        if (-Not (Serving $response)){
            Write-Host "Service4 isn't serving" -ForegroundColor Yellow
            $beep = $true
        }
        [array]$response = grpcurl -d '{ \"service5\": \"name5\" }' -H "authorization: key key"  host5:port grpc.health.v1.Health/Check
        if (-Not (Serving $response)){
            Write-Host "Service5 isn't serving" -ForegroundColor Yellow
            $beep = $true
        }
        [array]$response = grpcurl -d '{ \"service6\": \"name6\" }' -H "authorization: key key"  host6:port grpc.health.v1.Health/Check
        if (-Not (Serving $response)){
            Write-Host "Service6 isn't serving" -ForegroundColor Yellow
            $beep = $true
        }
        [array]$response = grpcurl -d '{ \"service7\": \"name7\" }' -H "authorization: key key"  host7:port grpc.health.v1.Health/Check 
        if (-Not (Serving $response)){
            Write-Host "Service7 isn't serving" -ForegroundColor Yellow
            $beep = $true
        }
        if ($beep){
            [console]::beep(500, 300)
        }
        Start-Sleep 2 
    }
    

14 additional answers

Sort by: Most helpful
  1. Rich Matheisen 45,091 Reputation points
    2022-05-09T19:09:32.68+00:00

    This works when the output from grpcurl is multiple lines (of JSON):

    while ($true) {
        $responses = @()
        $responses += grpcurl -d '{ \"service1\": \"name1\" }' -H "authorization: key key"  host1:port grpc.health.v1.Health/Check
        $responses += grpcurl -d '{ \"service2\": \"name2\" }' -H "authorization: key key"  host2:port grpc.health.v1.Health/Check
        $responses += grpcurl -d '{ \"service3\": \"name3\" }' -H "authorization: key key"  host3:port grpc.health.v1.Health/Check 
        $responses += grpcurl -d '{ \"service4\": \"name4\" }' -H "authorization: key key"  host4:port grpc.health.v1.Health/Check 
        $responses += grpcurl -d '{ \"service5\": \"name5\" }' -H "authorization: key key"  host5:port grpc.health.v1.Health/Check 
        $responses += grpcurl -d '{ \"service6\": \"name6\" }' -H "authorization: key key"  host6:port grpc.health.v1.Health/Check 
        $responses += grpcurl -d '{ \"service7\": \"name7\" }' -H "authorization: key key"  host7:port grpc.health.v1.Health/Check 
        $ctr = 0
        [array]$bad = @()
        ForEach ($response in $responses) {
            $ctr++
            $pp = $response -join "" | ConvertFrom-Json
            if ($pp.status -ne 'SERVING') {
                $bad += $ctr
            }      
        }
        if ($bad.count -gt 0) {
            [console]::beep(500, 300)
            $bad |
                ForEach-Object {
                    Write-Host "host$($_): $($responses[$_ - 1])" -ForegroundColor Yellow
                }
    
        }
        Start-Sleep 2 
    }
    
    0 comments No comments

  2. FJS 21 Reputation points
    2022-05-09T19:55:01.6+00:00

    Is not working for me :(

    ConvertFrom-Json : Primitivo JSON no válido: "SERVING".

    • $pp = $response -join "" | ConvertFrom-Json
    • ~~~~~~~~~~~~~~~~
      • CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
      • FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
    0 comments No comments