Skip to content

Commit

Permalink
Merge pull request #631 from cj123/healthcheck-endpoint
Browse files Browse the repository at this point in the history
add a health check endpoint
  • Loading branch information
cj123 authored Nov 4, 2019
2 parents f0f8d58 + 4fe66a8 commit 51538e9
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Added:
* You can now filter stock, DLC and mod cars in or out of the car search. Check out the car search help for more details! Please note that you will need to rebuild your search index for this to work. Go to Server Options, scroll down to "Maintenance" and click "Rebuild Search Index"!
* Server Manager will now set up some example Championships and Custom Races if you have not yet created any
* You can now sort the EntryList for a Championship Race Weekend Session by the number of Championship points a driver has. This could be useful for running reverse grid qualifying races!
* Added a health-check endpoint. Hopefully this will help us with debugging issues!

Fixes:

Expand Down
91 changes: 91 additions & 0 deletions healthcheck.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package servermanager

import (
"encoding/json"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"runtime"
"time"

"github.com/cj123/assetto-server-manager/pkg/udp"
)

var LaunchTime = time.Now()

type HealthCheck struct {
raceControl *RaceControl
}

func NewHealthCheck(raceControl *RaceControl) *HealthCheck {
return &HealthCheck{raceControl: raceControl}
}

type HealthCheckResponse struct {
OK bool
Version string
IsPremium bool
IsHosted bool

OS string
NumCPU int
NumGoroutines int
Uptime string
GoVersion string

AssettoIsInstalled bool
StrackerIsInstalled bool

CarDirectoryIsWritable bool
TrackDirectoryIsWritable bool
WeatherDirectoryIsWritable bool
SetupsDirectoryIsWritable bool
ConfigDirectoryIsWritable bool
ResultsDirectoryIsWritable bool

EventInProgress bool
EventIsCritical bool
NumConnectedDrivers int
MaxClientsOverride int
}

func (h *HealthCheck) ServeHTTP(w http.ResponseWriter, r *http.Request) {
event := h.raceControl.process.Event()

_ = json.NewEncoder(w).Encode(HealthCheckResponse{
OK: true,
OS: runtime.GOOS + "/" + runtime.GOARCH,
Version: BuildVersion,
IsPremium: IsPremium == "true",
IsHosted: IsHosted,
MaxClientsOverride: MaxClientsOverride,
NumCPU: runtime.NumCPU(),
NumGoroutines: runtime.NumGoroutine(),
Uptime: time.Since(LaunchTime).String(),
GoVersion: runtime.Version(),

EventInProgress: h.raceControl.process.IsRunning(),
EventIsCritical: !event.IsPractice() && (event.IsChampionship() || event.IsRaceWeekend() || h.raceControl.SessionInfo.Type == udp.SessionTypeRace || h.raceControl.SessionInfo.Type == udp.SessionTypeQualifying),
NumConnectedDrivers: h.raceControl.ConnectedDrivers.Len(),
AssettoIsInstalled: IsAssettoInstalled(),
StrackerIsInstalled: IsStrackerInstalled(),

ConfigDirectoryIsWritable: IsDirWriteable(filepath.Join(ServerInstallPath, "cfg")) == nil,
CarDirectoryIsWritable: IsDirWriteable(filepath.Join(ServerInstallPath, "content", "cars")) == nil,
TrackDirectoryIsWritable: IsDirWriteable(filepath.Join(ServerInstallPath, "content", "tracks")) == nil,
WeatherDirectoryIsWritable: IsDirWriteable(filepath.Join(ServerInstallPath, "content", "weather")) == nil,
SetupsDirectoryIsWritable: IsDirWriteable(filepath.Join(ServerInstallPath, "setups")) == nil,
ResultsDirectoryIsWritable: IsDirWriteable(filepath.Join(ServerInstallPath, "results")) == nil,
})
}

func IsDirWriteable(dir string) error {
file := filepath.Join(dir, ".test-write")

if err := ioutil.WriteFile(file, []byte(""), 0600); err != nil {
return err
}

return os.Remove(file)
}
12 changes: 12 additions & 0 deletions resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type Resolver struct {
serverAdministrationHandler *ServerAdministrationHandler
raceWeekendHandler *RaceWeekendHandler
strackerHandler *StrackerHandler
healthCheck *HealthCheck
}

func NewResolver(templateLoader TemplateLoader, reloadTemplates bool, store Store) (*Resolver, error) {
Expand Down Expand Up @@ -426,6 +427,16 @@ func (r *Resolver) resolveStrackerHandler() *StrackerHandler {
return r.strackerHandler
}

func (r *Resolver) resolveHealthCheck() *HealthCheck {
if r.healthCheck != nil {
return r.healthCheck
}

r.healthCheck = NewHealthCheck(r.resolveRaceControl())

return r.healthCheck
}

func (r *Resolver) ResolveRouter(fs http.FileSystem) http.Handler {
return Router(
fs,
Expand All @@ -445,6 +456,7 @@ func (r *Resolver) ResolveRouter(fs http.FileSystem) http.Handler {
r.resolveScheduledRacesHandler(),
r.resolveRaceWeekendHandler(),
r.resolveStrackerHandler(),
r.resolveHealthCheck(),
)
}

Expand Down
3 changes: 3 additions & 0 deletions router.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func Router(
scheduledRacesHandler *ScheduledRacesHandler,
raceWeekendHandler *RaceWeekendHandler,
strackerHandler *StrackerHandler,
healthCheck *HealthCheck,
) http.Handler {
r := chi.NewRouter()

Expand All @@ -86,6 +87,8 @@ func Router(
r.Get("/", serverAdministrationHandler.home)
r.Get("/changelog", serverAdministrationHandler.changelog)

r.Get("/healthcheck.json", healthCheck.ServeHTTP)

r.Mount("/stracker/", http.HandlerFunc(strackerHandler.proxy))

// content
Expand Down
10 changes: 10 additions & 0 deletions server_install.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ func SetAssettoInstallPath(installPath string) {
}
}

func IsAssettoInstalled() bool {
_, err := os.Stat(filepath.Join(ServerInstallPath, "system"))

if err != nil {
return false
}

return true
}

// InstallAssettoCorsaServer takes a steam login and password and runs steamcmd to install the assetto server.
// If the "ServerInstallPath" exists, this function will exit without installing - unless force == true.
func InstallAssettoCorsaServer(login, password string, force bool) error {
Expand Down

0 comments on commit 51538e9

Please sign in to comment.