feat: Add logging options for coder agent (#7474)

Similar to logging options in the coderd server, but for the agent
running in workspaces. Meant to make hollistic log collection and
querying simpler.
This commit is contained in:
goodspark
2023-05-24 07:32:40 -07:00
committed by GitHub
parent b6c8e5be48
commit 71c52ea93c
2 changed files with 86 additions and 9 deletions

View File

@ -22,6 +22,8 @@ import (
"cdr.dev/slog" "cdr.dev/slog"
"cdr.dev/slog/sloggers/sloghuman" "cdr.dev/slog/sloggers/sloghuman"
"cdr.dev/slog/sloggers/slogjson"
"cdr.dev/slog/sloggers/slogstackdriver"
"github.com/coder/coder/agent" "github.com/coder/coder/agent"
"github.com/coder/coder/agent/reaper" "github.com/coder/coder/agent/reaper"
"github.com/coder/coder/buildinfo" "github.com/coder/coder/buildinfo"
@ -32,14 +34,17 @@ import (
func (r *RootCmd) workspaceAgent() *clibase.Cmd { func (r *RootCmd) workspaceAgent() *clibase.Cmd {
var ( var (
auth string auth string
logDir string logDir string
pprofAddress string pprofAddress string
noReap bool noReap bool
sshMaxTimeout time.Duration sshMaxTimeout time.Duration
tailnetListenPort int64 tailnetListenPort int64
prometheusAddress string prometheusAddress string
debugAddress string debugAddress string
slogHumanPath string
slogJSONPath string
slogStackdriverPath string
) )
cmd := &clibase.Cmd{ cmd := &clibase.Cmd{
Use: "agent", Use: "agent",
@ -62,7 +67,46 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
MaxSize: 5, // MB MaxSize: 5, // MB
} }
defer logWriter.Close() defer logWriter.Close()
logger := slog.Make(sloghuman.Sink(inv.Stderr), sloghuman.Sink(logWriter)).Leveled(slog.LevelDebug)
sinks := []slog.Sink{sloghuman.Sink(logWriter)}
closers := []func() error{}
addSinkIfProvided := func(sinkFn func(io.Writer) slog.Sink, loc string) error {
switch loc {
case "":
case "/dev/stdout":
sinks = append(sinks, sinkFn(inv.Stdout))
case "/dev/stderr":
sinks = append(sinks, sinkFn(inv.Stderr))
default:
fi, err := os.OpenFile(loc, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o644)
if err != nil {
return xerrors.Errorf("open log file %q: %w", loc, err)
}
closers = append(closers, fi.Close)
sinks = append(sinks, sinkFn(fi))
}
return nil
}
if err := addSinkIfProvided(sloghuman.Sink, slogHumanPath); err != nil {
return xerrors.Errorf("add human sink: %w", err)
}
if err := addSinkIfProvided(slogjson.Sink, slogJSONPath); err != nil {
return xerrors.Errorf("add json sink: %w", err)
}
if err := addSinkIfProvided(slogstackdriver.Sink, slogStackdriverPath); err != nil {
return xerrors.Errorf("add stackdriver sink: %w", err)
}
logger := slog.Make(sinks...).Leveled(slog.LevelDebug)
defer func() {
for _, closer := range closers {
_ = closer()
}
}()
logger.Info(ctx, "spawning reaper process") logger.Info(ctx, "spawning reaper process")
// Do not start a reaper on the child process. It's important // Do not start a reaper on the child process. It's important
@ -290,6 +334,30 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
Value: clibase.StringOf(&debugAddress), Value: clibase.StringOf(&debugAddress),
Description: "The bind address to serve a debug HTTP server.", Description: "The bind address to serve a debug HTTP server.",
}, },
{
Name: "Human Log Location",
Description: "Output human-readable logs to a given file.",
Flag: "log-human",
Env: "CODER_AGENT_LOGGING_HUMAN",
Default: "/dev/stderr",
Value: clibase.StringOf(&slogHumanPath),
},
{
Name: "JSON Log Location",
Description: "Output JSON logs to a given file.",
Flag: "log-json",
Env: "CODER_AGENT_LOGGING_JSON",
Default: "",
Value: clibase.StringOf(&slogJSONPath),
},
{
Name: "Stackdriver Log Location",
Description: "Output Stackdriver compatible logs to a given file.",
Flag: "log-stackdriver",
Env: "CODER_AGENT_LOGGING_STACKDRIVER",
Default: "",
Value: clibase.StringOf(&slogStackdriverPath),
},
} }
return cmd return cmd

View File

@ -3,6 +3,15 @@ Usage: coder agent [flags]
Starts the Coder workspace agent. Starts the Coder workspace agent.
Options Options
--log-human string, $CODER_AGENT_LOGGING_HUMAN (default: /dev/stderr)
Output human-readable logs to a given file.
--log-json string, $CODER_AGENT_LOGGING_JSON
Output JSON logs to a given file.
--log-stackdriver string, $CODER_AGENT_LOGGING_STACKDRIVER
Output Stackdriver compatible logs to a given file.
--auth string, $CODER_AGENT_AUTH (default: token) --auth string, $CODER_AGENT_AUTH (default: token)
Specify the authentication type to use for the agent. Specify the authentication type to use for the agent.