Go web services are known for their performance and reliability, but even the most well-written Go code can fail - from misconfigurations to database outages to infrastructure issues. This guide shows you how to set up external uptime monitoring for Go web services using Vigilmon.
What to Monitor in a Go Web Service
Vigilmon checks your Go service from the outside, the same way your users or clients do. The key things to monitor:
- HTTP health endpoint - a dedicated route that confirms your server is running
- Key API endpoints - your most critical business routes
- TCP port - if you expose raw TCP (gRPC, database)
- SSL certificate - expiry monitoring for HTTPS services
Adding a Health Endpoint
For the standard library
et/http:
`go
package main
import (
"encoding/json"
"net/http"
"time"
)
type HealthResponse struct {
Status string json:"status"
Timestamp time.Time json:"timestamp"
Version string json:"version"
}
func healthHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(HealthResponse{
Status: "ok",
Timestamp: time.Now(),
Version: "1.0.0",
})
}
func main() {
http.HandleFunc("/health", healthHandler)
http.ListenAndServe(":8080", nil)
}
`
Health Check with Database Connectivity
For services that depend on a database:
`go
import (
"database/sql"
"net/http"
"encoding/json"
_ "github.com/lib/pq"
)
var db *sql.DB
func healthHandler(w http.ResponseWriter, r *http.Request) {
response := map[string]interface{}{
"status": "ok",
}
// Check database
if err := db.PingContext(r.Context()); err != nil {
response["status"] = "degraded"
response["database"] = "unreachable"
w.WriteHeader(http.StatusServiceUnavailable)
} else {
response["database"] = "ok"
w.WriteHeader(http.StatusOK)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
`
Vigilmon detects the 503 status and sends an alert.
With Gin Framework
`go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/health", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
"service": "my-go-api",
})
})
r.Run(":8080")
}
`
With Echo Framework
`go
package main
import (
"net/http"
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
e.GET("/health", func(c echo.Context) error {
return c.JSON(http.StatusOK, map[string]string{
"status": "ok",
})
})
e.Start(":8080")
}
`
With Chi Router
`go
package main
import (
"encoding/json"
"net/http"
"github.com/go-chi/chi/v5"
)
func main() {
r := chi.NewRouter()
r.Get("/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", r)
}
`
Monitoring gRPC Services
For gRPC services, add a separate HTTP health endpoint alongside your gRPC server:
`go
// Run HTTP health server on a different port
go func() {
mux := http.NewServeMux()
mux.HandleFunc("/health", healthHandler)
http.ListenAndServe(":8081", mux)
}()
// Run gRPC server on main port
grpcServer.Serve(lis)
`
Monitor the HTTP health endpoint at port 8081, and add a TCP monitor for port 8080 (gRPC).
Setting Up Vigilmon Monitoring
- Log in to vigilmon.online
- Click New Monitor
- Configure:
- URL: https://your-go-service.com/health
- Method: GET
- Expected status: 200
- Interval: 1 minute
- Regions: 2+ regions for consensus alerting
- Set up alerts (Slack, email, or webhook)
Recommended Monitor Set for Go Services
| Monitor | URL | Interval |
|---|---|---|
| App health | /health | 1 min |
| Critical API | /api/v1/status | 1 min |
| gRPC port (TCP) | :50051 | 1 min |
| SSL expiry | your-domain.com | daily |
Graceful Shutdown Awareness
Go's graceful shutdown means your health endpoint may return 503 during a deploy. Configure Vigilmon to require 2 consecutive failures before alerting - this prevents false alerts during rolling restarts.
Conclusion
Go services are fast and efficient, but they still need external uptime monitoring. Vigilmon gives you:
- External checks from multiple global regions
- 1-minute check intervals - know within 60 seconds when something goes wrong
- Multi-region consensus - no false alerts from transient network issues
- Free tier to get started
Top comments (0)