Introducing Goctuator: a Go-Based Actuator Module

mikeyglitz

mikeyGlitz

Posted on November 23, 2022

Introducing Goctuator: a Go-Based Actuator Module

As a developer, I'm constantly deploying and updating production-ready web servers. Some of the most important features that I look for in a web server are the metrics and the server's health. Having developed a number of Java web servers, I've come to appreciate the Spring Boot Actuator extensions for Spring Web applications.

In the context of a Spring application, an actuator is a server extension which will provide information about the server. These metrics could be items like the health and stability of connections that the application depends on (i.e. the database), or system resource utilization metrics. When I deploy applications onto a deployment environment such as a Kubernetes cluster or into the Cloud (EKS, ECS, Fargate), actuators are consumed by the cloud services to monitor the service health.

I wasn't able to find much to go on as far as modules to implement this feature in Golang. I decided to roll my own.

What is Goctuator?

Goctuator is short for Go-Actuator. This module provides spring-boot like actuator functionality to Go-based web servers. Goctuator provides the following endpoints

  • /env - Displays the current runtime environment variables
  • /info - Used to convey information about the package being published such as author, version number, go-lang runtime that the project was built with, CPU architecture that the application was built for, Git revision hash, and the repo URL
  • /health - This endpoint displays the overall system health as well as the health of any dependencies (i.e. database connection status)
  • /metrics - This endpoint displays system resource utilization
  • /treaddump - This endpoint displays a snapshot of the current thread and leverages pprof.lookup to gather information about the goroutines in use

Installation

Installing Goctuator is fairly simple. Use go get to retrieve the module and add it to your project

go get gitlab.com/mikeyGlitz/gohealth
Enter fullscreen mode Exit fullscreen mode

After the package is installed you could add it to your project using a HTTP handler

HTTP package

handler := actuator.GetHandler(&actuator.Config{})
http.Handle("/actuator", handler)
Enter fullscreen mode Exit fullscreen mode

Gin handler

handler := actuator.GetHandler(&actuator.Config{})
r := gin.Default()
r.Get("/actuator", func(ctx *gin.Context) {
    handle(ctx.Writer, ctx.Request)
}
Enter fullscreen mode Exit fullscreen mode

Customization

The Goctuator module may be customized in one of two ways:

  • You can disable an endpoint
  • You can add custom health checkers
  • You can tailor the /info endpoint

Customizing available endpoints

The actuator.Configuration structure supports a slice Endpoints which is used to configure which endpoints are enabled as actuators:

config := &actuator.Configuration {
  Endpoints: []actuator.Endpoint {
    actuator.ENV,
    actuator.INFO,
  }
}
Enter fullscreen mode Exit fullscreen mode

With this configuration, only the /info and /env endpoints would be enabled

Customizing Health Checkers

The health checkers may also be customized. By default the module provides endpoints which simulate a generic ping response as well as an endpoint which provides disk usage statistics for the application. These health checkers are located in health.PingChecker and health.DiskStatusChecker.

You may also write your own Health Checker by implementing the HealthChecker interface:

type ComponentDetails struct {
  Status HealthStatus `json:status` // Can either be UP or DOWN
  // Details - a struct which can be converted into a JSON
  // object which will provide additional details about the
  // service which health is being checked
  Details interface{} `json:details`
}

type HealthCheckResult struct {
  ComponentDetails
  Service string
}

type HealthChecker interface {
  CheckHealth() HealthCheckResult
}
Enter fullscreen mode Exit fullscreen mode

When the /health endpoint is requested, the response will resemble the following JSON object:

{
  "status": "UP",
  "components": {
    "diskspace": {
      "status": "UP",
      "details": {
        "all": "",
        "used": "",
        "free": "",
        "available": ""
      }
    },
    "ping": {
      "status": "UP"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Customizing information returned by /info

The information returned by the /info endpoint is set at compile-time using ldflags

go build -ldflags="-X gitlab.com/mikeyGlitz/gohealth/pkg/info.AppName=${appName} <other flags>"
Enter fullscreen mode Exit fullscreen mode

The /info endpoint utilizes the following variables:

Variable Description
AppName The name of your application
AppDescription A brief description of what your application does
AppVersion An application version i.e. v1.0.0
Git Variables
CommitID The SHA1 of the commit
CommitTime A timestamp of when the commit took place
BuildTime A timestamp of when the application build took place
RepositoryUrl A URL of where the Git repository is located
Branch The branch name the build was executed on
Application Environment
OS Operating system the application runs - darwin, linux
RuntimeVersion The version of go the application was built for
Arch The CPU architecture the application was built for - arm64

For more information about Goctuator and how to use it, please consult the Readme.

💖 💪 🙅 🚩
mikeyglitz
mikeyGlitz

Posted on November 23, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related