Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: allow callers to directly set logfile location #2545

Merged
merged 7 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/cmd/common/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
package common

import (
"fmt"
"io"
"os"
"time"

"github.com/defenseunicorns/zarf/src/config"
"github.com/defenseunicorns/zarf/src/config/lang"
Expand Down Expand Up @@ -51,14 +53,20 @@ func SetupCLI() {
}

if !config.SkipLogFile {
logFile, err := message.UseLogFile("")
ts := time.Now().Format("2006-01-02-15-04-05")

f, err := os.CreateTemp("", fmt.Sprintf("zarf-%s-*.log", ts))
if err != nil {
message.WarnErr(err, "Error creating a log file in a temporary directory")
return
}
logFile, err := message.UseLogFile(f)
if err != nil {
message.WarnErr(err, "Error saving a log file to a temporary directory")
return
}

pterm.SetDefaultOutput(io.MultiWriter(os.Stderr, logFile))
location := message.LogFileLocation()
message.Notef("Saving log file to %s", location)
message.Notef("Saving log file to %s", f.Name())
}
}
8 changes: 4 additions & 4 deletions src/pkg/message/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ func PrintCredentialTable(state *types.ZarfState, componentsToDeploy []types.Dep

// Pause the logfile's output to avoid credentials being printed to the log file
if logFile != nil {
logFile.pause()
defer logFile.resume()
logFile.Pause()
defer logFile.Resume()
}

loginData := [][]string{}
Expand Down Expand Up @@ -95,8 +95,8 @@ func PrintComponentCredential(state *types.ZarfState, componentName string) {
func PrintCredentialUpdates(oldState *types.ZarfState, newState *types.ZarfState, services []string) {
// Pause the logfile's output to avoid credentials being printed to the log file
if logFile != nil {
logFile.pause()
defer logFile.resume()
logFile.Pause()
defer logFile.Resume()
}

for _, service := range services {
Expand Down
29 changes: 5 additions & 24 deletions src/pkg/message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package message
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"runtime/debug"
Expand Down Expand Up @@ -49,7 +48,7 @@ var RuleLine = strings.Repeat("━", TermWidth)
var logLevel = InfoLevel

// logFile acts as a buffer for logFile generation
var logFile *pausableLogFile
var logFile *PausableWriter

// DebugWriter represents a writer interface that writes to message.Debug
type DebugWriter struct{}
Expand Down Expand Up @@ -77,32 +76,14 @@ func init() {
pterm.SetDefaultOutput(os.Stderr)
}

// UseLogFile writes output to stderr and a logFile.
func UseLogFile(dir string) (io.Writer, error) {
// Prepend the log filename with a timestamp.
ts := time.Now().Format("2006-01-02-15-04-05")

f, err := os.CreateTemp(dir, fmt.Sprintf("zarf-%s-*.log", ts))
if err != nil {
return nil, err
}

logFile = &pausableLogFile{
wr: f,
f: f,
}
// UseLogFile wraps a given file in a PausableWriter
// and sets it as the log file used by the message package.
func UseLogFile(f *os.File) (*PausableWriter, error) {
logFile = NewPausableWriter(f)

return logFile, nil
}

// LogFileLocation returns the location of the log file.
func LogFileLocation() string {
if logFile == nil {
return ""
}
return logFile.f.Name()
}

// SetLogLevel sets the log level.
func SetLogLevel(lvl LogLevel) {
logLevel = lvl
Expand Down
31 changes: 17 additions & 14 deletions src/pkg/message/pausable.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,29 @@ package message

import (
"io"
"os"
)

// pausableLogFile is a pausable log file
type pausableLogFile struct {
wr io.Writer
f *os.File
// PausableWriter is a pausable writer
type PausableWriter struct {
out, wr io.Writer
}

// pause the log file
func (l *pausableLogFile) pause() {
l.wr = io.Discard
// NewPausableWriter creates a new pausable writer
func NewPausableWriter(wr io.Writer) *PausableWriter {
return &PausableWriter{out: wr, wr: wr}
}

// resume the log file
func (l *pausableLogFile) resume() {
l.wr = l.f
// Pause sets the output writer to io.Discard
func (pw *PausableWriter) Pause() {
pw.out = io.Discard
}

// Write writes the data to the log file
func (l *pausableLogFile) Write(p []byte) (n int, err error) {
return l.wr.Write(p)
// Resume sets the output writer back to the original writer
func (pw *PausableWriter) Resume() {
pw.out = pw.wr
}

// Write writes the data to the underlying output writer
func (pw *PausableWriter) Write(p []byte) (n int, err error) {
return pw.out.Write(p)
}
39 changes: 39 additions & 0 deletions src/pkg/message/pausable_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2021-Present The Zarf Authors

package message

import (
"bytes"
"testing"

"github.com/stretchr/testify/require"
)

func TestPausableWriter(t *testing.T) {
var buf bytes.Buffer

pw := NewPausableWriter(&buf)

n, err := pw.Write([]byte("foo"))
require.NoError(t, err)
require.Equal(t, 3, n)

require.Equal(t, "foo", buf.String())

pw.Pause()

n, err = pw.Write([]byte("bar"))
require.NoError(t, err)
require.Equal(t, 3, n)

require.Equal(t, "foo", buf.String())

pw.Resume()

n, err = pw.Write([]byte("baz"))
require.NoError(t, err)
require.Equal(t, 3, n)

require.Equal(t, "foobaz", buf.String())
}
Loading