Skip to content

Commit

Permalink
Merge branch 'main' into kratos-ui
Browse files Browse the repository at this point in the history
  • Loading branch information
TimVosch committed Jan 15, 2024
2 parents 0001fe0 + 10ec546 commit 536e78a
Show file tree
Hide file tree
Showing 36 changed files with 2,374 additions and 228 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
# Created by https://www.toptal.com/developers/gitignore/api/windows,macos,linux,go,visualstudiocode
# Edit at https://www.toptal.com/developers/gitignore?templates=windows,macos,linux,go,visualstudiocode

coverage.html

### Go ###
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
Expand Down
1 change: 1 addition & 0 deletions docs/development/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The Core service performs multiple core functions in SensorBucket:
| DB_DSN | The PostgreSQL connection string | yes | |
| AMQP_HOST | The RabbitMQ host | yes | |
| AMQP_QUEUE_MEASUREMENTS | Queue from which to read measurements that need to be stored | no | measurements |
| AMQP_XCHG_MEASUREMENTS_TOPIC| The RabbitMQ exchange topic for incoming measurement storage | no | storage |
| AMQP_QUEUE_INGRESS | Queue from which to read new incoming raw data | no | core-ingress |
| AMQP_XCHG_INGRESS | The RabbitMQ exchange for incoming raw data | no | ingress |
| AMQP_XCHG_INGRESS_TOPIC | The RabbitMQ exchange topic for incoming raw data | no | ingress.* |
Expand Down
5 changes: 3 additions & 2 deletions docs/development/tracing.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ The tracing service requires the following environment variables to be set in or
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -------- | --------------- |
| DB_DSN | The connection string for the PostgreSQL database | Yes | |
| AMQP_HOST | The RabbitMQ host | Yes | |
| AMQP_QUEUE_PIPELINEMESSAGES | The queue on which pipeline messages appear | Yes | |
| AMQP_QUEUE_ERRORS | The queue on which any errors produced by workers appear | Yes | |
| AMQP_QUEUE_PIPELINEMESSAGES | The queue on which pipeline messages appear | Yes | tracing_pipeline_messages |
| AMQP_QUEUE_INGRESS | The topic on which new datapoints will appear | No | archive-ingress |
| AMQP_XCHG_INGRESS | The exchange on which ingress messages will appear. The tracing service will declare the exchange if it doesn't exist yet | No | ingress |
| AMQP_XCHG_INGRESS_TOPIC | The topic on the exhange where ingress messages will be read from | No | ingress.* |
| AMQP_XCHG_PIPELINEMESSAGES| The exchange on which all pipeline messages are published | Yes | pipeline.messages |
| AMQP_XCHG_PIPELINEMESSAGES_TOPIC | The binding between the pipeline messages exchange and the queue | Yes | # |

## Domain

Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,6 @@ github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/
github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/ory/client-go v1.4.6 h1:tW9najNBiWwC3KgU2tq2kCZ1zRCDCNao60a9M1/V71k=
github.com/ory/client-go v1.4.6/go.mod h1:DfrTIlME7tgrdgpn4UN07s4OJ1SwzHfrkz+C6C0Lbm0=
github.com/ory/client-go v1.4.7 h1:uWPGGM5zVwpSBfcDIhvA6D+bu2YB7zF4STtpAvzkOco=
github.com/ory/client-go v1.4.7/go.mod h1:DfrTIlME7tgrdgpn4UN07s4OJ1SwzHfrkz+C6C0Lbm0=
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
Expand Down
122 changes: 122 additions & 0 deletions pkg/health/health.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package health

import (
"context"
"errors"
"fmt"
"log"
"net/http"
"time"

"github.com/go-chi/chi/v5"

"sensorbucket.nl/sensorbucket/internal/web"
)

type Check func() bool

type checks map[string]Check

func (checks checks) Perform() checksResult {
if len(checks) == 0 {
return checksResult{Success: false}
}

success := []string{}
failed := []string{}
for name, check := range checks {
if check() {
success = append(success, name)
continue
}
failed = append(failed, name)
}
return checksResult{
Success: len(failed) == 0,
ChecksSucess: success,
ChecksFailed: failed,
}
}

type HealthChecker struct {
livelinessChecks checks
readinessChecks checks
router chi.Router
}

func NewHealthEndpoint() *HealthChecker {
hc := HealthChecker{
router: chi.NewRouter(),
livelinessChecks: checks{},
readinessChecks: checks{},
}
hc.setupRoutes(hc.router)
return &hc
}

func (hc *HealthChecker) WithLiveChecks(checks checks) *HealthChecker {
for name, c := range checks {
hc.livelinessChecks[name] = c
}
return hc
}

func (hc *HealthChecker) WithReadyChecks(checks checks) *HealthChecker {
for name, c := range checks {
hc.readinessChecks[name] = c
}
return hc
}

func (hc *HealthChecker) setupRoutes(r chi.Router) {
r.Get("/livez", hc.httpLivelinessCheck)
r.Get("/readyz", hc.httpReadinessCheck)
}

func (hc HealthChecker) ServeHTTP(w http.ResponseWriter, r *http.Request) {
hc.router.ServeHTTP(w, r)
}

func (hc *HealthChecker) httpReadinessCheck(w http.ResponseWriter, r *http.Request) {
checksResponse(w, hc.readinessChecks)
}

func (hc *HealthChecker) httpLivelinessCheck(w http.ResponseWriter, r *http.Request) {
checksResponse(w, hc.livelinessChecks)
}

func (hc *HealthChecker) RunAsServer(address string) func(context.Context) error {
srv := &http.Server{
Addr: address,
WriteTimeout: 5 * time.Second,
ReadTimeout: 5 * time.Second,
Handler: hc,
}
go func() {
log.Printf("HealthChecker endpoint available at: %s\n", srv.Addr)
if err := srv.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) && err != nil {
log.Printf("HealthChecker server closed unexpectedly: %s\n", err.Error())
}
}()
return func(ctx context.Context) error {
return srv.Shutdown(ctx)
}
}

func checksResponse(w http.ResponseWriter, checks checks) {
results := checks.Perform()
statusCode := http.StatusOK
if !results.Success {
statusCode = http.StatusServiceUnavailable
}
web.HTTPResponse(w, statusCode, web.APIResponse[checksResult]{
Message: fmt.Sprintf("%d/%d checks passed", len(results.ChecksSucess), len(checks)),
Data: results,
})
}

type checksResult struct {
Success bool `json:"success"`
ChecksSucess []string `json:"checks_success"`
ChecksFailed []string `json:"checks_failed"`
}
Loading

0 comments on commit 536e78a

Please sign in to comment.