Skip to content

Commit

Permalink
refactor: allow callers to directly set logfile location (#2545)
Browse files Browse the repository at this point in the history
Changes `message.UseLogFile` to accept an `f *os.File` and wrap it in a
`*message.PausableWriter`. Adds unit tests for `PausableWriter`.

## Related Issue

Fixes #2524 

## Checklist before merging

- [x] Test, docs, adr added or updated as needed
- [x] [Contributor Guide
Steps](https://github.com/defenseunicorns/zarf/blob/main/.github/CONTRIBUTING.md#developer-workflow)
followed

---------

Signed-off-by: razzle <harry@razzle.cloud>
  • Loading branch information
Noxsios committed May 23, 2024
1 parent 2a8bfe2 commit f003c94
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 45 deletions.
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())
}

0 comments on commit f003c94

Please sign in to comment.