gRPC services are fast, efficient, and increasingly common in microservice architectures. But they are harder to monitor than REST APIs — HTTP health check tools do not understand the gRPC wire protocol.
This guide explains how to add uptime monitoring to gRPC services and expose them to external monitors like Vigilmon.
The gRPC Monitoring Challenge
Standard HTTP uptime monitors send GET requests and check for a 200 status code. gRPC uses HTTP/2 with Protobuf encoding — a plain GET to a gRPC endpoint returns a 405 or an unreadable response, not a useful health check.
The solution: expose a separate HTTP health endpoint alongside your gRPC service, or implement the standard gRPC health checking protocol.
Option 1: Add an HTTP Health Endpoint
The simplest approach is to run a lightweight HTTP server on a separate port that exposes a health endpoint:
// Go gRPC server with HTTP health endpoint
package main
import (
"encoding/json"
"net"
"net/http"
"log"
"google.golang.org/grpc"
pb "your-service/proto"
)
func main() {
// Start gRPC server on port 50051
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
grpcServer := grpc.NewServer()
pb.RegisterYourServiceServer(grpcServer, &yourServiceImpl{})
// Start HTTP health server on port 8080
go func() {
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
})
http.ListenAndServe(":8080", nil)
}()
log.Printf("gRPC server listening on :50051")
if err := grpcServer.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
Then monitor http://your-service:8080/health in Vigilmon.
Option 2: Use gRPC Health Checking Protocol
The gRPC ecosystem has a standard health checking protocol. Implement it in your service:
import (
"google.golang.org/grpc/health"
"google.golang.org/grpc/health/grpc_health_v1"
)
healthServer := health.NewServer()
grpc_health_v1.RegisterHealthServer(grpcServer, healthServer)
// Set service status
healthServer.SetServingStatus("your.service.YourService", grpc_health_v1.HealthCheckResponse_SERVING)
You can then use grpc-health-probe to check health from your infrastructure, but for external monitoring from Vigilmon, the HTTP endpoint approach is simpler.
Option 3: Envoy Proxy Health Endpoint
If your gRPC services run behind Envoy (common in service meshes), Envoy exposes an admin endpoint you can monitor:
GET http://your-envoy:9901/ready
This confirms Envoy is ready to proxy traffic. Add it to Vigilmon to know when your proxy layer is healthy.
Setting Up Vigilmon for gRPC Services
- Sign up at vigilmon.online — free for 50 monitors
- Add your HTTP health endpoint URL:
https://your-grpc-service.com/health - Set check interval to 1 minute
- Configure Slack or email alerts
Monitoring gRPC Deployments on Kubernetes
In Kubernetes, add both liveness and readiness probes alongside Vigilmon:
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
Kubernetes probes restart unhealthy pods. Vigilmon tells you when the entire service is unreachable from the outside — which can happen even when all pods show healthy internally.
Python gRPC Example
For Python gRPC services, add a Flask health server:
from concurrent import futures
import threading
import grpc
from flask import Flask, jsonify
import your_service_pb2_grpc
app = Flask(__name__)
@app.route('/health')
def health():
return jsonify({"status": "ok"})
def serve_grpc():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
your_service_pb2_grpc.add_YourServiceServicer_to_server(YourServiceServicer(), server)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()
if __name__ == '__main__':
# Start gRPC in background thread
grpc_thread = threading.Thread(target=serve_grpc, daemon=True)
grpc_thread.start()
# Flask HTTP health server on port 8080
app.run(host='0.0.0.0', port=8080)
What External gRPC Monitoring Catches
External uptime monitoring of gRPC services catches:
- Network-level failures (DNS, routing, firewall changes)
- Load balancer misconfiguration
- Service mesh failures (Envoy crashes, Istio policy changes)
- Deployment failures where a new image does not start correctly
- Certificate expiry (if using mTLS on your gRPC connections)
Without external monitoring, gRPC service failures can go undetected until a downstream service starts throwing errors or users notice a degraded feature.
Summary
gRPC services need uptime monitoring as much as REST APIs do — perhaps more, because failures are less visible. Add an HTTP health endpoint to your gRPC services, expose it on a separate port, and add it to Vigilmon for external multi-region monitoring.
Add your gRPC health endpoint to Vigilmon — free, 1-minute check intervals, multi-region.
Top comments (1)
I found the discussion on implementing the standard gRPC health checking protocol particularly interesting, as it highlights the importance of using established protocols for interoperability. The example code for setting up a health server using
health.NewServer()and registering it with the gRPC server is helpful. However, I've found that in some cases, using a separate HTTP health endpoint can be more straightforward, especially when dealing with external monitors like Vigilmon. Have you considered any trade-offs between using the gRPC health checking protocol versus a separate HTTP endpoint in terms of complexity and maintainability?