Skip to content

Commit df0020c

Browse files
committed
Healthcheck
1 parent be50510 commit df0020c

File tree

4 files changed

+100
-1
lines changed

4 files changed

+100
-1
lines changed

go.mod

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,9 @@ module github.com/nextmn/json-api
22

33
go 1.22
44

5-
require github.com/gofrs/uuid v4.4.0+incompatible
5+
require (
6+
github.com/gofrs/uuid v4.4.0+incompatible
7+
github.com/sirupsen/logrus v1.9.3
8+
)
9+
10+
require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect

go.sum

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,17 @@
1+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
3+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
14
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
25
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
6+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
7+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
8+
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
9+
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
10+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
11+
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
12+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
13+
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
14+
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
15+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
16+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
17+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

healthcheck/doc.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright 2024 Louis Royer and the NextMN contributors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style license that can be
3+
// found in the LICENSE file.
4+
// SPDX-License-Identifier: MIT
5+
6+
// Package healthcheck allow to check current status of a node.
7+
package healthcheck

healthcheck/healthcheck.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright 2024 Louis Royer and the NextMN contributors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style license that can be
3+
// found in the LICENSE file.
4+
// SPDX-License-Identifier: MIT
5+
6+
package healthcheck
7+
8+
import (
9+
"context"
10+
"encoding/json"
11+
"fmt"
12+
"net/http"
13+
"time"
14+
15+
"github.com/sirupsen/logrus"
16+
)
17+
18+
// Healthcheck allows to check status of the node
19+
type Healthcheck struct {
20+
uri string
21+
userAgent string
22+
}
23+
24+
// Status of the node
25+
type Status struct {
26+
Ready bool `json:"ready"`
27+
}
28+
29+
// Create a new Healthcheck
30+
func NewHealthcheck(uri string, userAgent string) *Healthcheck {
31+
return &Healthcheck{
32+
uri: uri,
33+
userAgent: userAgent,
34+
}
35+
}
36+
37+
// Run returns an error if the node status is not `ready`
38+
func (h *Healthcheck) Run(ctx context.Context) error {
39+
client := http.Client{
40+
Timeout: 100 * time.Millisecond,
41+
}
42+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, h.uri+"/status", nil)
43+
if err != nil {
44+
logrus.WithError(err).Error("Error while creating http get request")
45+
return err
46+
}
47+
req.Header.Add("User-Agent", h.userAgent)
48+
req.Header.Set("Accept", "application/json")
49+
req.Header.Set("Accept-Charset", "utf-8")
50+
resp, err := client.Do(req)
51+
if err != nil {
52+
logrus.WithFields(logrus.Fields{"remote-server": h.uri}).WithError(err).Info("No http response")
53+
return err
54+
}
55+
defer resp.Body.Close()
56+
if resp.StatusCode != 200 {
57+
logrus.WithFields(logrus.Fields{"remote-server": h.uri}).WithError(err).Info("Http response is not 200 OK")
58+
return err
59+
}
60+
decoder := json.NewDecoder(resp.Body)
61+
var status Status
62+
if err := decoder.Decode(&status); err != nil {
63+
logrus.WithFields(logrus.Fields{"remote-server": h.uri}).WithError(err).Info("Could not decode json response")
64+
return err
65+
}
66+
if !status.Ready {
67+
err := fmt.Errorf("Server is not ready")
68+
logrus.WithFields(logrus.Fields{"remote-server": h.uri}).WithError(err).Info("Server is not ready")
69+
return err
70+
}
71+
return nil
72+
}

0 commit comments

Comments
 (0)