mirror of
https://github.com/yusing/godoxy.git
synced 2025-06-09 21:02:34 +02:00
use docker healthcheck result if possible
This commit is contained in:
parent
b6c806a789
commit
be81415a75
3 changed files with 73 additions and 2 deletions
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/yusing/go-proxy/internal/common"
|
"github.com/yusing/go-proxy/internal/common"
|
||||||
|
"github.com/yusing/go-proxy/internal/docker"
|
||||||
"github.com/yusing/go-proxy/internal/docker/idlewatcher"
|
"github.com/yusing/go-proxy/internal/docker/idlewatcher"
|
||||||
E "github.com/yusing/go-proxy/internal/error"
|
E "github.com/yusing/go-proxy/internal/error"
|
||||||
gphttp "github.com/yusing/go-proxy/internal/net/http"
|
gphttp "github.com/yusing/go-proxy/internal/net/http"
|
||||||
|
@ -92,7 +93,16 @@ func (r *HTTPRoute) Start(providerSubtask task.Task) E.Error {
|
||||||
r.handler = waker
|
r.handler = waker
|
||||||
r.HealthMon = waker
|
r.HealthMon = waker
|
||||||
case entry.UseHealthCheck(r):
|
case entry.UseHealthCheck(r):
|
||||||
r.HealthMon = monitor.NewHTTPHealthMonitor(r.rp.TargetURL, r.HealthCheck)
|
if entry.IsDocker(r) {
|
||||||
|
client, err := docker.ConnectClient(r.Idlewatcher.DockerHost)
|
||||||
|
if err == nil {
|
||||||
|
fallback := monitor.NewHTTPHealthChecker(r.rp.TargetURL, r.HealthCheck)
|
||||||
|
r.HealthMon = monitor.NewDockerHealthMonitor(client, r.Idlewatcher.ContainerID, r.HealthCheck, fallback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if r.HealthMon == nil {
|
||||||
|
r.HealthMon = monitor.NewHTTPHealthMonitor(r.rp.TargetURL, r.HealthCheck)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.handler == nil {
|
if r.handler == nil {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/yusing/go-proxy/internal/docker"
|
||||||
"github.com/yusing/go-proxy/internal/docker/idlewatcher"
|
"github.com/yusing/go-proxy/internal/docker/idlewatcher"
|
||||||
E "github.com/yusing/go-proxy/internal/error"
|
E "github.com/yusing/go-proxy/internal/error"
|
||||||
net "github.com/yusing/go-proxy/internal/net/types"
|
net "github.com/yusing/go-proxy/internal/net/types"
|
||||||
|
@ -67,7 +68,16 @@ func (r *StreamRoute) Start(providerSubtask task.Task) E.Error {
|
||||||
r.Stream = waker
|
r.Stream = waker
|
||||||
r.HealthMon = waker
|
r.HealthMon = waker
|
||||||
case entry.UseHealthCheck(r):
|
case entry.UseHealthCheck(r):
|
||||||
r.HealthMon = monitor.NewRawHealthMonitor(r.TargetURL(), r.HealthCheck)
|
if entry.IsDocker(r) {
|
||||||
|
client, err := docker.ConnectClient(r.Idlewatcher.DockerHost)
|
||||||
|
if err == nil {
|
||||||
|
fallback := monitor.NewRawHealthChecker(r.TargetURL(), r.HealthCheck)
|
||||||
|
r.HealthMon = monitor.NewDockerHealthMonitor(client, r.Idlewatcher.ContainerID, r.HealthCheck, fallback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if r.HealthMon == nil {
|
||||||
|
r.HealthMon = monitor.NewRawHealthMonitor(r.TargetURL(), r.HealthCheck)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := r.Stream.Setup(); err != nil {
|
if err := r.Stream.Setup(); err != nil {
|
||||||
|
|
51
internal/watcher/health/monitor/docker.go
Normal file
51
internal/watcher/health/monitor/docker.go
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
package monitor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/yusing/go-proxy/internal/docker"
|
||||||
|
"github.com/yusing/go-proxy/internal/net/types"
|
||||||
|
|
||||||
|
dockerTypes "github.com/docker/docker/api/types"
|
||||||
|
"github.com/yusing/go-proxy/internal/watcher/health"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DockerHealthMonitor struct {
|
||||||
|
*monitor
|
||||||
|
client *docker.SharedClient
|
||||||
|
containerID string
|
||||||
|
fallback health.HealthChecker
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDockerHealthMonitor(client *docker.SharedClient, containerID string, config *health.HealthCheckConfig, fallback health.HealthChecker) *DockerHealthMonitor {
|
||||||
|
mon := new(DockerHealthMonitor)
|
||||||
|
mon.client = client
|
||||||
|
mon.containerID = containerID
|
||||||
|
mon.monitor = newMonitor(types.URL{}, config, mon.CheckHealth)
|
||||||
|
mon.fallback = fallback
|
||||||
|
return mon
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mon *DockerHealthMonitor) CheckHealth() (result *health.HealthCheckResult, err error) {
|
||||||
|
cont, err := mon.client.ContainerInspect(mon.task.Context(), mon.containerID)
|
||||||
|
if err != nil {
|
||||||
|
return mon.fallback.CheckHealth()
|
||||||
|
}
|
||||||
|
if cont.State.Health == nil {
|
||||||
|
return mon.fallback.CheckHealth()
|
||||||
|
}
|
||||||
|
result = new(health.HealthCheckResult)
|
||||||
|
result.Healthy = cont.State.Health.Status == dockerTypes.Healthy
|
||||||
|
detail := new(bytes.Buffer)
|
||||||
|
for _, status := range cont.State.Health.Log {
|
||||||
|
detail.WriteString(status.Output)
|
||||||
|
detail.WriteString("\n")
|
||||||
|
}
|
||||||
|
result.Detail = detail.String()
|
||||||
|
if len(cont.State.Health.Log) > 0 {
|
||||||
|
last := cont.State.Health.Log[len(cont.State.Health.Log)-1].End
|
||||||
|
first := cont.State.Health.Log[0].Start
|
||||||
|
result.Latency = last.Sub(first)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue