Skip to content

Commit

Permalink
feat: send logs using agent api v2 if available (#264)
Browse files Browse the repository at this point in the history
Closes #260

- Removes manually vendored codersdk, we're back on the real deal now
- Moves logging setup to package internal/eblog
- Modifies logging to use new agent api v2 methods, falling back to PatchLogs
- Adds ENVBUILDER_VERBOSE

Tested manually against Coder version 2.8.0, 2.9.0, and 2.13.0.

(cherry picked from commit 5be0611)
  • Loading branch information
johnstcn committed Jul 5, 2024
1 parent bb37c71 commit 2538741
Show file tree
Hide file tree
Showing 22 changed files with 1,053 additions and 891 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ jobs:
with:
go-version: "~1.22"

- name: Download Go modules
run: go mod download

- name: Lint
run: make -j lint

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ lint: lint/go lint/shellcheck
.PHONY: lint/go
lint/go: $(GO_SRC_FILES)
go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)
golangci-lint run
golangci-lint run --timeout=10m

.PHONY: lint/shellcheck
lint/shellcheck: $(SHELL_SRC_FILES)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,4 +388,5 @@ On MacOS or Windows systems, we recommend either using a VM or the provided `.de
| `--coder-agent-subsystem` | `CODER_AGENT_SUBSYSTEM` | | Coder agent subsystems to report when forwarding logs. The envbuilder subsystem is always included. |
| `--push-image` | `ENVBUILDER_PUSH_IMAGE` | | Push the built image to a remote registry. This option forces a reproducible build. |
| `--get-cached-image` | `ENVBUILDER_GET_CACHED_IMAGE` | | Print the digest of the cached image, if available. Exits with an error if not found. |
| `--verbose` | `ENVBUILDER_VERBOSE` | | Enable verbose logging. |
<!--- END docsgen --->
66 changes: 20 additions & 46 deletions cmd/envbuilder/main.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
package main

import (
"context"
"crypto/tls"
"errors"
"fmt"
"net/http"
"net/url"
"os"
"slices"
"strings"
"time"

"cdr.dev/slog"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/envbuilder"
"github.com/coder/envbuilder/internal/notcodersdk"
"github.com/coder/envbuilder/internal/log"
"github.com/coder/serpent"

// *Never* remove this. Certificates are not bundled as part
Expand All @@ -38,58 +34,36 @@ func envbuilderCmd() serpent.Command {
Use: "envbuilder",
Options: options.CLI(),
Handler: func(inv *serpent.Invocation) error {
var sendLogs func(ctx context.Context, log ...notcodersdk.Log) error
if options.CoderAgentToken != "" {
if options.CoderAgentURL == "" {
options.Logger = log.New(os.Stderr, options.Verbose)
if options.CoderAgentURL != "" {
if options.CoderAgentToken == "" {
return errors.New("CODER_AGENT_URL must be set if CODER_AGENT_TOKEN is set")
}
u, err := url.Parse(options.CoderAgentURL)
if err != nil {
return fmt.Errorf("unable to parse CODER_AGENT_URL as URL: %w", err)
}
client := notcodersdk.New(u)
client.SetSessionToken(options.CoderAgentToken)
client.HTTPClient = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: options.Insecure,
},
},
}
var flushAndClose func(ctx context.Context) error
// nolint: staticcheck // FIXME: https://github.com/coder/envbuilder/issues/260
sendLogs, flushAndClose = notcodersdk.LogsSender(notcodersdk.ExternalLogSourceID, client.PatchLogs, slog.Logger{})
defer func() {
_ = flushAndClose(inv.Context())
}()

// This adds the envbuilder subsystem.
// If telemetry is enabled in a Coder deployment,
// this will be reported and help us understand
// envbuilder usage.
if !slices.Contains(options.CoderAgentSubsystem, string(notcodersdk.AgentSubsystemEnvbuilder)) {
options.CoderAgentSubsystem = append(options.CoderAgentSubsystem, string(notcodersdk.AgentSubsystemEnvbuilder))
_ = os.Setenv("CODER_AGENT_SUBSYSTEM", strings.Join(options.CoderAgentSubsystem, ","))
}
}

options.Logger = func(level notcodersdk.LogLevel, format string, args ...interface{}) {
output := fmt.Sprintf(format, args...)
_, _ = fmt.Fprintln(inv.Stderr, output)
if sendLogs != nil {
if err := sendLogs(inv.Context(), notcodersdk.Log{
CreatedAt: time.Now(),
Output: output,
Level: level,
}); err != nil {
_, _ = fmt.Fprintf(inv.Stderr, "failed to send logs: %s\n", err.Error())
coderLog, closeLogs, err := log.Coder(inv.Context(), u, options.CoderAgentToken)
if err == nil {
options.Logger = log.Wrap(options.Logger, coderLog)
defer closeLogs()
// This adds the envbuilder subsystem.
// If telemetry is enabled in a Coder deployment,
// this will be reported and help us understand
// envbuilder usage.
if !slices.Contains(options.CoderAgentSubsystem, string(codersdk.AgentSubsystemEnvbuilder)) {
options.CoderAgentSubsystem = append(options.CoderAgentSubsystem, string(codersdk.AgentSubsystemEnvbuilder))
_ = os.Setenv("CODER_AGENT_SUBSYSTEM", strings.Join(options.CoderAgentSubsystem, ","))
}
} else {
// Failure to log to Coder should cause a fatal error.
options.Logger(log.LevelError, "unable to send logs to Coder: %s", err.Error())
}
}

err := envbuilder.Run(inv.Context(), options)
if err != nil {
options.Logger(notcodersdk.LogLevelError, "error: %s", err)
options.Logger(log.LevelError, "error: %s", err)
}
return err
},
Expand Down
84 changes: 0 additions & 84 deletions cmd/envbuilder/main_test.go

This file was deleted.

Loading

0 comments on commit 2538741

Please sign in to comment.