coder/coderd/healthcheck/health/model.go

121 lines
3.1 KiB
Go

package health
import (
"fmt"
"strings"
"github.com/coder/coder/v2/buildinfo"
"github.com/coder/coder/v2/coderd/util/ptr"
)
const (
SeverityOK Severity = "ok"
SeverityWarning Severity = "warning"
SeverityError Severity = "error"
// CodeUnknown is a catch-all health code when something unexpected goes wrong (for example, a panic).
CodeUnknown Code = "EUNKNOWN"
CodeProxyUpdate Code = "EWP01"
CodeProxyFetch Code = "EWP02"
// CodeProxyVersionMismatch is no longer used as it's no longer a critical
// error.
// CodeProxyVersionMismatch Code = "EWP03"
CodeProxyUnhealthy Code = "EWP04"
CodeDatabasePingFailed Code = "EDB01"
CodeDatabasePingSlow Code = "EDB02"
CodeWebsocketDial Code = "EWS01"
CodeWebsocketEcho Code = "EWS02"
CodeWebsocketMsg Code = "EWS03"
CodeAccessURLNotSet Code = "EACS01"
CodeAccessURLInvalid Code = "EACS02"
CodeAccessURLFetch Code = "EACS03"
CodeAccessURLNotOK Code = "EACS04"
CodeDERPNodeUsesWebsocket Code = `EDERP01`
CodeDERPOneNodeUnhealthy Code = `EDERP02`
CodeSTUNNoNodes = `ESTUN01`
CodeSTUNMapVaryDest = `ESTUN02`
CodeProvisionerDaemonsNoProvisionerDaemons Code = `EPD01`
CodeProvisionerDaemonVersionMismatch Code = `EPD02`
CodeProvisionerDaemonAPIMajorVersionDeprecated Code = `EPD03`
)
// Default docs URL
var (
docsURLDefault = "https://coder.com/docs/v2"
)
// @typescript-generate Severity
type Severity string
var severityRank = map[Severity]int{
SeverityOK: 0,
SeverityWarning: 1,
SeverityError: 2,
}
func (s Severity) Value() int {
return severityRank[s]
}
// @typescript-generate Message
type Message struct {
Code Code `json:"code"`
Message string `json:"message"`
}
func (m Message) String() string {
var sb strings.Builder
_, _ = sb.WriteString(string(m.Code))
_, _ = sb.WriteRune(':')
_, _ = sb.WriteRune(' ')
_, _ = sb.WriteString(m.Message)
return sb.String()
}
// URL returns a link to the admin/healthcheck docs page for the given Message.
// NOTE: if using a custom docs URL, specify base.
func (m Message) URL(base string) string {
var codeAnchor string
if m.Code == "" {
codeAnchor = strings.ToLower(string(CodeUnknown))
} else {
codeAnchor = strings.ToLower(string(m.Code))
}
if base == "" {
base = docsURLDefault
versionPath := buildinfo.Version()
if buildinfo.IsDev() {
// for development versions, just use latest
versionPath = "latest"
}
return fmt.Sprintf("%s/%s/admin/healthcheck#%s", base, versionPath, codeAnchor)
}
// We don't assume that custom docs URLs are versioned.
return fmt.Sprintf("%s/admin/healthcheck#%s", base, codeAnchor)
}
// Code is a stable identifier used to link to documentation.
// @typescript-generate Code
type Code string
// Messagef is a convenience function for returning a health.Message
func Messagef(code Code, msg string, args ...any) Message {
return Message{
Code: code,
Message: fmt.Sprintf(msg, args...),
}
}
// Errorf is a convenience function for returning a stringly-typed version of a Message.
func Errorf(code Code, msg string, args ...any) *string {
return ptr.Ref(Messagef(code, msg, args...).String())
}