mirror of
https://github.com/TwiN/gatus.git
synced 2024-12-14 11:58:04 +00:00
feat: shields.io endpoint badge (#652)
* feat: shields.io endpoint badge Signed-off-by: Steven Kreitzer <skre@skre.me> * chore: update readme to include new shields.io badge Signed-off-by: Steven Kreitzer <skre@skre.me> --------- Signed-off-by: Steven Kreitzer <skre@skre.me> Co-authored-by: TwiN <twin@linux.com>
This commit is contained in:
parent
1a7aeb5b35
commit
6cbc59b0e8
4 changed files with 87 additions and 0 deletions
20
README.md
20
README.md
|
@ -107,6 +107,7 @@ Have any feedback or questions? [Create a discussion](https://github.com/TwiN/ga
|
|||
- [Badges](#badges)
|
||||
- [Uptime](#uptime)
|
||||
- [Health](#health)
|
||||
- [Health (Shields.io)](#health-shieldsio)
|
||||
- [Response time](#response-time)
|
||||
- [How to change the color thresholds of the response time badge](#how-to-change-the-color-thresholds-of-the-response-time-badge)
|
||||
- [API](#api)
|
||||
|
@ -1958,6 +1959,25 @@ https://example.com/api/v1/endpoints/core_frontend/health/badge.svg
|
|||
```
|
||||
|
||||
|
||||
#### Health (Shields.io)
|
||||
![Health](https://img.shields.io/endpoint?url=https%3A%2F%2Fstatus.twin.sh%2Fapi%2Fv1%2Fendpoints%2Fcore_blog-external%2Fhealth%2Fbadge.shields)
|
||||
|
||||
The path to generate a badge is the following:
|
||||
```
|
||||
/api/v1/endpoints/{key}/health/badge.shields
|
||||
```
|
||||
Where:
|
||||
- `{key}` has the pattern `<GROUP_NAME>_<ENDPOINT_NAME>` in which both variables have ` `, `/`, `_`, `,` and `.` replaced by `-`.
|
||||
|
||||
For instance, if you want the current status of the endpoint `frontend` in the group `core`,
|
||||
the URL would look like this:
|
||||
```
|
||||
https://example.com/api/v1/endpoints/core_frontend/health/badge.shields
|
||||
```
|
||||
|
||||
See more information about the Shields.io badge endpoint [here](https://shields.io/badges/endpoint-badge).
|
||||
|
||||
|
||||
#### Response time
|
||||
![Response time 1h](https://status.twin.sh/api/v1/endpoints/core_blog-external/response-times/1h/badge.svg)
|
||||
![Response time 24h](https://status.twin.sh/api/v1/endpoints/core_blog-external/response-times/24h/badge.svg)
|
||||
|
|
|
@ -66,6 +66,7 @@ func (a *API) createRouter(cfg *config.Config) *fiber.App {
|
|||
unprotectedAPIRouter := apiRouter.Group("/")
|
||||
unprotectedAPIRouter.Get("/v1/config", ConfigHandler{securityConfig: cfg.Security}.GetConfig)
|
||||
unprotectedAPIRouter.Get("/v1/endpoints/:key/health/badge.svg", HealthBadge)
|
||||
unprotectedAPIRouter.Get("/v1/endpoints/:key/health/badge.shields", HealthBadgeShields)
|
||||
unprotectedAPIRouter.Get("/v1/endpoints/:key/uptimes/:duration/badge.svg", UptimeBadge)
|
||||
unprotectedAPIRouter.Get("/v1/endpoints/:key/response-times/:duration/badge.svg", ResponseTimeBadge(cfg))
|
||||
unprotectedAPIRouter.Get("/v1/endpoints/:key/response-times/:duration/chart.svg", ResponseTimeChart)
|
||||
|
|
51
api/badge.go
51
api/badge.go
|
@ -1,6 +1,7 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -125,6 +126,36 @@ func HealthBadge(c *fiber.Ctx) error {
|
|||
return c.Status(200).Send(generateHealthBadgeSVG(healthStatus))
|
||||
}
|
||||
|
||||
func HealthBadgeShields(c *fiber.Ctx) error {
|
||||
key := c.Params("key")
|
||||
pagingConfig := paging.NewEndpointStatusParams()
|
||||
status, err := store.Get().GetEndpointStatusByKey(key, pagingConfig.WithResults(1, 1))
|
||||
if err != nil {
|
||||
if err == common.ErrEndpointNotFound {
|
||||
return c.Status(404).SendString(err.Error())
|
||||
} else if err == common.ErrInvalidTimeRange {
|
||||
return c.Status(400).SendString(err.Error())
|
||||
}
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
healthStatus := HealthStatusUnknown
|
||||
if len(status.Results) > 0 {
|
||||
if status.Results[0].Success {
|
||||
healthStatus = HealthStatusUp
|
||||
} else {
|
||||
healthStatus = HealthStatusDown
|
||||
}
|
||||
}
|
||||
c.Set("Content-Type", "application/json")
|
||||
c.Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||
c.Set("Expires", "0")
|
||||
jsonData, err := generateHealthBadgeShields(healthStatus)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
return c.Status(200).Send(jsonData)
|
||||
}
|
||||
|
||||
func generateUptimeBadgeSVG(duration string, uptime float64) []byte {
|
||||
var labelWidth, valueWidth, valueWidthAdjustment int
|
||||
switch duration {
|
||||
|
@ -299,6 +330,17 @@ func generateHealthBadgeSVG(healthStatus string) []byte {
|
|||
return svg
|
||||
}
|
||||
|
||||
func generateHealthBadgeShields(healthStatus string) ([]byte, error) {
|
||||
color := getBadgeShieldsColorFromHealth(healthStatus)
|
||||
data := map[string]interface{}{
|
||||
"schemaVersion": 1,
|
||||
"label": "gatus",
|
||||
"message": healthStatus,
|
||||
"color": color,
|
||||
}
|
||||
return json.Marshal(data)
|
||||
}
|
||||
|
||||
func getBadgeColorFromHealth(healthStatus string) string {
|
||||
if healthStatus == HealthStatusUp {
|
||||
return badgeColorHexAwesome
|
||||
|
@ -307,3 +349,12 @@ func getBadgeColorFromHealth(healthStatus string) string {
|
|||
}
|
||||
return badgeColorHexPassable
|
||||
}
|
||||
|
||||
func getBadgeShieldsColorFromHealth(healthStatus string) string {
|
||||
if healthStatus == HealthStatusUp {
|
||||
return "brightgreen"
|
||||
} else if healthStatus == HealthStatusDown {
|
||||
return "red"
|
||||
}
|
||||
return "yellow"
|
||||
}
|
||||
|
|
|
@ -110,6 +110,21 @@ func TestBadge(t *testing.T) {
|
|||
Path: "/api/v1/endpoints/invalid_key/health/badge.svg",
|
||||
ExpectedCode: http.StatusNotFound,
|
||||
},
|
||||
{
|
||||
Name: "badge-shields-health-up",
|
||||
Path: "/api/v1/endpoints/core_frontend/health/badge.shields",
|
||||
ExpectedCode: http.StatusOK,
|
||||
},
|
||||
{
|
||||
Name: "badge-shields-health-down",
|
||||
Path: "/api/v1/endpoints/core_backend/health/badge.shields",
|
||||
ExpectedCode: http.StatusOK,
|
||||
},
|
||||
{
|
||||
Name: "badge-shields-health-for-invalid-key",
|
||||
Path: "/api/v1/endpoints/invalid_key/health/badge.shields",
|
||||
ExpectedCode: http.StatusNotFound,
|
||||
},
|
||||
{
|
||||
Name: "chart-response-time-24h",
|
||||
Path: "/api/v1/endpoints/core_backend/response-times/24h/chart.svg",
|
||||
|
|
Loading…
Reference in a new issue