pomerium/pkg/envoy/envoy_linux.go
Caleb Doxsey d062f9d68d
core/logs: remove warnings (#5235)
* core/logs: remove warnings

* switch to error
2024-08-27 09:38:50 -06:00

113 lines
2.4 KiB
Go

//go:build linux
// +build linux
package envoy
import (
"context"
"os"
"strconv"
"sync"
"syscall"
"time"
"go.opencensus.io/stats/view"
"github.com/pomerium/pomerium/internal/log"
"github.com/pomerium/pomerium/internal/telemetry/metrics"
)
const baseIDPath = "/tmp/pomerium-envoy-base-id"
var restartEpoch struct {
sync.Mutex
value int
}
var sysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
Pdeathsig: syscall.SIGTERM,
}
func (srv *Server) runProcessCollector(ctx context.Context) {
pc := metrics.NewProcessCollector("envoy")
if err := view.Register(pc.Views()...); err != nil {
log.Error(ctx).Err(err).Msg("failed to register envoy process metric views")
}
defer view.Unregister(pc.Views()...)
const collectInterval = time.Second * 10
ticker := time.NewTicker(collectInterval)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
}
var pid int
srv.mu.Lock()
if srv.cmd != nil && srv.cmd.Process != nil {
pid = srv.cmd.Process.Pid
}
srv.mu.Unlock()
if pid > 0 {
err := pc.Measure(ctx, pid)
if err != nil {
log.Error(ctx).Err(err).Msg("failed to measure envoy process metrics")
}
}
}
}
func (srv *Server) prepareRunEnvoyCommand(ctx context.Context, sharedArgs []string) (exePath string, args []string) {
// release the previous process so we can hot-reload
if srv.cmd != nil && srv.cmd.Process != nil {
log.Info(ctx).Msg("envoy: releasing envoy process for hot-reload")
err := srv.cmd.Process.Release()
if err != nil {
log.Error(ctx).Err(err).Str("service", "envoy").Msg("envoy: failed to release envoy process for hot-reload")
}
}
args = make([]string, len(sharedArgs))
copy(args, sharedArgs)
restartEpoch.Lock()
if baseID, ok := readBaseID(); ok {
args = append(args,
"--base-id", strconv.Itoa(baseID),
"--restart-epoch", strconv.Itoa(restartEpoch.value),
"--drain-time-s", "60",
"--parent-shutdown-time-s", "120",
"--drain-strategy", "immediate",
)
restartEpoch.value++
} else {
args = append(args,
"--use-dynamic-base-id",
"--base-id-path", baseIDPath,
)
restartEpoch.value = 1
}
restartEpoch.Unlock()
return srv.envoyPath, args
}
func readBaseID() (int, bool) {
bs, err := os.ReadFile(baseIDPath)
if err != nil {
return 0, false
}
baseID, err := strconv.Atoi(string(bs))
if err != nil {
return 0, false
}
return baseID, true
}