summaryrefslogtreecommitdiff
path: root/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/log/filelogger.go
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/log/filelogger.go')
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/log/filelogger.go114
1 files changed, 114 insertions, 0 deletions
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/log/filelogger.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/log/filelogger.go
new file mode 100644
index 0000000..e3ff42b
--- /dev/null
+++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/log/filelogger.go
@@ -0,0 +1,114 @@
+package log
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "path/filepath"
+ "regexp"
+ "sync"
+ "time"
+)
+
+type FileLogger struct {
+ file *os.File
+ writer *bufio.Writer
+ logPath string
+ mu sync.Mutex
+ stopChan chan struct{}
+ doneChan chan struct{}
+ passwordRe *regexp.Regexp
+}
+
+func NewFileLogger() (*FileLogger, error) {
+ timestamp := time.Now().Unix()
+
+ // Use DANKINSTALL_LOG_DIR if set, otherwise fall back to /tmp.
+ logDir := os.Getenv("DANKINSTALL_LOG_DIR")
+ if logDir == "" {
+ logDir = "/tmp"
+ }
+ if err := os.MkdirAll(logDir, 0o755); err != nil {
+ return nil, fmt.Errorf("failed to create log directory: %w", err)
+ }
+ logPath := filepath.Join(logDir, fmt.Sprintf("dankinstall-%d.log", timestamp))
+
+ file, err := os.Create(logPath)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create log file: %w", err)
+ }
+
+ passwordRe := regexp.MustCompile(`(?i)(password[:\s=]+)[^\s]+`)
+
+ logger := &FileLogger{
+ file: file,
+ writer: bufio.NewWriter(file),
+ logPath: logPath,
+ stopChan: make(chan struct{}),
+ doneChan: make(chan struct{}),
+ passwordRe: passwordRe,
+ }
+
+ header := fmt.Sprintf("=== DankInstall Log ===\nStarted: %s\n\n", time.Now().Format(time.RFC3339))
+ logger.writeToFile(header)
+
+ return logger, nil
+}
+
+func (l *FileLogger) GetLogPath() string {
+ return l.logPath
+}
+
+func (l *FileLogger) redactPassword(message string) string {
+ redacted := l.passwordRe.ReplaceAllString(message, "${1}[REDACTED]")
+
+ redacted = regexp.MustCompile(`echo\s+'[^']+'`).ReplaceAllString(redacted, "echo '[REDACTED]'")
+
+ return redacted
+}
+
+func (l *FileLogger) writeToFile(message string) {
+ l.mu.Lock()
+ defer l.mu.Unlock()
+
+ redacted := l.redactPassword(message)
+ timestamp := time.Now().Format("15:04:05.000")
+
+ fmt.Fprintf(l.writer, "[%s] %s\n", timestamp, redacted)
+ l.writer.Flush()
+}
+
+func (l *FileLogger) StartListening(logChan <-chan string) {
+ go func() {
+ defer close(l.doneChan)
+ for {
+ select {
+ case msg, ok := <-logChan:
+ if !ok {
+ return
+ }
+ l.writeToFile(msg)
+ case <-l.stopChan:
+ return
+ }
+ }
+ }()
+}
+
+func (l *FileLogger) Close() error {
+ close(l.stopChan)
+ <-l.doneChan
+
+ l.mu.Lock()
+ defer l.mu.Unlock()
+
+ footer := fmt.Sprintf("\n=== DankInstall Log End ===\nCompleted: %s\n", time.Now().Format(time.RFC3339))
+ l.writer.WriteString(footer) //nolint:errcheck
+ l.writer.Flush()
+
+ if err := l.file.Sync(); err != nil {
+ return err
+ }
+
+ return l.file.Close()
+}