Skip to content

Commit

Permalink
Merge pull request #41 from gowizzard/development
Browse files Browse the repository at this point in the history
Add new metric for health status of docker containers.
  • Loading branch information
gowizzard authored Jan 5, 2025
2 parents 5f5cdfa + 1dceac4 commit 0711405
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 49 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

[![Go Test](https://github.com/gowizzard/mobyspulse/actions/workflows/go-test.yml/badge.svg)](https://github.com/gowizzard/mobyspulse/actions/workflows/go-test.yml) [![Docker Test](https://github.com/gowizzard/mobyspulse/actions/workflows/docker-test.yml/badge.svg)](https://github.com/gowizzard/mobyspulse/actions/workflows/docker-test.yml) [![Docker Build](https://github.com/gowizzard/mobyspulse/actions/workflows/docker-build.yml/badge.svg)](https://github.com/gowizzard/mobyspulse/actions/workflows/docker-build.yml) [![Pull Request Labels](https://github.com/gowizzard/mobyspulse/actions/workflows/pull-request-labels.yml/badge.svg)](https://github.com/gowizzard/mobyspulse/actions/workflows/pull-request-labels.yml)

A little prometheus exporter to get the restarts of containers, with multiple attributes to get specific container information.
A little prometheus exporter to get the restarts and health status of containers, with multiple attributes to get specific container information.

</div>

Expand Down Expand Up @@ -45,6 +45,7 @@ The exporter provides the following metrics:
```text
# Moby's Pulse - Docker metrics exporter for Prometheus.
# This is a custom exporter for Docker metrics. Your system running Docker version "26.0.1" and API version "1.45" is being monitored.
container_restart_count{id="2c35a3500c6384cd88b1cb30182ba39e54c74e4047515d2e6db662aaa7116bb2",name="mobyspulse",image="mobyspulse-mobyspulse:latest",created="1713079803",started_at="1713079803"} 0
# This is a custom exporter for Docker metrics. Your system running Docker version "27.4.0" and API version "1.47" is being monitored.
container_restart_count{id="e76457b7744717e700db61fae0a0145290a35d1e9850ba135548c1f5ef8ed736",name="mobyspulse",image="mobyspulse-mobyspulse:latest",status="running",created="1735905255",started_at="1735905255"} 0
container_state_health_status{id="e76457b7744717e700db61fae0a0145290a35d1e9850ba135548c1f5ef8ed736",name="mobyspulse",image="mobyspulse-mobyspulse:latest",status="running",created="1735905255",started_at="1735905255"} healthy
```
104 changes: 59 additions & 45 deletions internal/handler/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
type Metric struct {
Name string
Labels []Labels
Value int
Value interface{}
}

// Labels is to define the labels' struct. It has the key and value fields.
Expand Down Expand Up @@ -65,61 +65,75 @@ func Metrics(w http.ResponseWriter, _ *http.Request) {
tag = image.RepoTags[0]
}

metric := Metric{
Name: "container_restart_count",
Labels: []Labels{
{
Key: "id",
Value: container.Id,
},
{
Key: "name",
Value: strings.Replace(container.Name, "/", "", 1),
},
{
Key: "image",
Value: tag,
},
{
Key: "status",
Value: container.State.Status,
},
{
Key: "created",
Value: strconv.FormatInt(container.Created.Unix(), 10),
},
{
Key: "started_at",
Value: strconv.FormatInt(container.State.StartedAt.Unix(), 10),
},
labels := []Labels{
{
Key: "id",
Value: container.Id,
},
{
Key: "name",
Value: strings.Replace(container.Name, "/", "", 1),
},
{
Key: "image",
Value: tag,
},
{
Key: "status",
Value: container.State.Status,
},
{
Key: "created",
Value: strconv.FormatInt(container.Created.Unix(), 10),
},
{
Key: "started_at",
Value: strconv.FormatInt(container.State.StartedAt.Unix(), 10),
},
Value: container.RestartCount,
}

var b strings.Builder
metrics := []Metric{
{
Name: "container_restart_count",
Labels: labels,
Value: container.RestartCount,
},
{
Name: "container_state_health_status",
Labels: labels,
Value: container.State.Health.Status,
},
}

b.WriteString(metric.Name)
b.WriteString("{")
for _, value := range metrics {

for index, value := range metric.Labels {
var b strings.Builder

_, err = fmt.Fprintf(&b, `%s="%s"`, value.Key, value.Value)
if err != nil {
write.Logger.Error("Write the container restart count metric.", "err", err)
}
b.WriteString(value.Name)
b.WriteString("{")

label := len(value.Labels) - 1
for index, value := range value.Labels {

_, err = fmt.Fprintf(&b, `%s="%s"`, value.Key, value.Value)
if err != nil {
write.Logger.Error("Write the container restart count metric.", "err", err)
}

if index < label {
b.WriteString(",")
}

if index < len(metric.Labels)-1 {
b.WriteString(",")
}

}
b.WriteString("}")
b.WriteString(fmt.Sprintf(" %v\n", value.Value))

b.WriteString("}")
b.WriteString(fmt.Sprintf(" %v\n", metric.Value))
_, err = fmt.Fprintf(w, b.String())
if err != nil {
write.Logger.Error("Write the container restart count metric.", "err", err)
}

_, err = fmt.Fprintf(w, b.String())
if err != nil {
write.Logger.Error("Write the container restart count metric.", "err", err)
}

}
Expand Down
5 changes: 4 additions & 1 deletion internal/request/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ type ContainerResponse struct {
Name string `json:"Name"`
RestartCount int `json:"RestartCount"`
State struct {
StartedAt time.Time `json:"StartedAt"`
Status string `json:"Status"`
StartedAt time.Time `json:"StartedAt"`
Health struct {
Status string `json:"Status"`
}
} `json:"State"`
}

Expand Down

0 comments on commit 0711405

Please sign in to comment.