refactor: use slog instead of log
Some checks are pending
Go CI Pipeline / ci (push) Waiting to run
Release Builds / GoReleaser build (push) Successful in 1m4s

This commit is contained in:
Patryk Hegenberg 2025-06-11 22:41:48 +02:00
parent fcffccc145
commit d8743e54c1
8 changed files with 180 additions and 165 deletions

101
app.go
View file

@ -2,7 +2,7 @@ package main
import (
"fmt"
"log"
"log/slog"
"os"
"os/exec"
"strings"
@ -44,7 +44,7 @@ func (a *App) Close() error {
func (a *App) connect() (*SSHConnection, error) { // Rückgabetyp geändert
if err := a.timeStore.StartTracking(TagWork); err != nil {
log.Printf("WARN: Failed to start time tracking for '%s': %v", TagWork, err)
slog.Warn(fmt.Sprintf("Failed to start time tracking for '%s': %v", TagWork, err))
}
a.wakeWorkstation()
@ -54,24 +54,31 @@ func (a *App) connect() (*SSHConnection, error) { // Rückgabetyp geändert
return nil, fmt.Errorf("failed to establish primary SSH connection: %w", err)
}
log.Println("INFO: SSH connection established. Setting up tunnels...")
// slog.Info("SSH connection established. Setting up tunnels...")
slog.Info("SSH connection established. Setting up tunnels...")
sshForwarder := NewPortForwarder(sshCon.client, "2048", "22", a.cfg.WorkstationIP)
go func() {
log.Println("INFO: Starting SSH forwarder (local :2048 -> remote workstation:22)")
// slog.Info("Starting SSH forwarder (local :2048 -> remote workstation:22)")
slog.Info("Starting SSH forwarder (local :2048 -> remote workstation:22)")
if err := sshForwarder.forward(); err != nil {
log.Printf("ERROR: SSH forwarder failed: %v", err)
// slog.Error(fmt.Sprintf("SSH forwarder failed: %v", err)
slog.Error(fmt.Sprintf("SSH forwarder failed: %v", err))
}
log.Println("INFO: SSH forwarder stopped.")
// slog.Info("SSH forwarder stopped.")
slog.Info("SSH forwarder stopped.")
}()
rdpForwarder := NewPortForwarder(sshCon.client, "6000", "3389", a.cfg.WorkstationIP)
go func() {
log.Println("INFO: Starting RDP forwarder (local :6000 -> remote workstation:3389)")
// slog.Info("Starting RDP forwarder (local :6000 -> remote workstation:3389)")
slog.Info("Starting RDP forwarder (local :6000 -> remote workstation:3389)")
if err := rdpForwarder.forward(); err != nil {
log.Printf("ERROR: RDP forwarder failed: %v", err)
// slog.Error(fmt.Sprintf("RDP forwarder failed: %v", err)
slog.Error(fmt.Sprintf("ERROR: RDP forwarder failed: %v", err))
}
log.Println("INFO: RDP forwarder stopped.")
// slog.Info("RDP forwarder stopped.")
slog.Info("RDP forwarder stopped.")
}()
time.Sleep(500 * time.Millisecond)
@ -80,22 +87,22 @@ func (a *App) connect() (*SSHConnection, error) { // Rückgabetyp geändert
}
func (a *App) runCommand(name string, args ...string) error {
log.Printf("INFO: Executing command: %s %s", name, strings.Join(args, " "))
slog.Info(fmt.Sprintf("Executing command: %s %s", name, strings.Join(args, " ")))
cmd := exec.Command(name, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
err := cmd.Run()
if err != nil {
log.Printf("ERROR: Command failed: %s %s -> %v", name, strings.Join(args, " "), err)
slog.Error(fmt.Sprintf("Command failed: %s %s -> %v", name, strings.Join(args, " "), err))
return fmt.Errorf("command execution failed: %w", err)
}
log.Printf("INFO: Command finished successfully: %s", name)
slog.Info(fmt.Sprintf("Command finished successfully: %s", name))
return nil
}
func (a *App) wakeWorkstation() {
log.Println("INFO: Attempting to wake workstation...")
slog.Info("Attempting to wake workstation...")
innerSSHCmd := fmt.Sprintf("ssh -tt %s@%s \"wakeonlan %s && echo 'Wake-on-LAN packet sent.' && exit\"",
a.cfg.JumpUser,
a.cfg.JumpHost,
@ -109,14 +116,14 @@ func (a *App) wakeWorkstation() {
}
if err := a.runCommand("ssh", outerSSHCmd...); err != nil {
log.Println("WARN: Failed to send Wake-on-LAN packet via SSH jump. Workstation might already be awake or command failed.")
slog.Warn("Failed to send Wake-on-LAN packet via SSH jump. Workstation might already be awake or command failed.")
} else {
log.Println("INFO: Wake-on-LAN command executed.")
slog.Info("Wake-on-LAN command executed.")
}
}
func (a *App) connectToJump() {
log.Println("INFO: Connecting to Jump Host with Port Forwarding...")
slog.Info("Connecting to Jump Host with Port Forwarding...")
sshArgs := []string{
"-tt",
"-L", fmt.Sprintf("2048:%s:22", a.cfg.WorkstationHost),
@ -128,7 +135,7 @@ func (a *App) connectToJump() {
}
func (a *App) connectToWorkstation() {
log.Println("INFO: Connecting to Workstation via local tunnel (localhost:2048)...")
slog.Info("Connecting to Workstation via local tunnel (localhost:2048)...")
sshArgs := []string{
"-tt",
"-L", fmt.Sprintf("6000:%s:3389", a.cfg.WorkstationHost),
@ -140,7 +147,7 @@ func (a *App) connectToWorkstation() {
}
func (a *App) startRDPConnection() {
log.Println("INFO: Starting RDP connection to localhost:6000...")
slog.Info("Starting RDP connection to localhost:6000...")
rdpCommand := fmt.Sprintf("xfreerdp /u:%s /p:%s /v:127.0.0.1:6000 /size:3000x1350 +clipboard /dynamic-resolution",
a.cfg.RDPUser,
a.cfg.SSHPassword,
@ -182,7 +189,7 @@ func (a *App) makeChoice() {
fmt.Println("Operation cancelled.")
return
}
log.Printf("ERROR: Form execution failed: %v", err)
slog.Error(fmt.Sprintf("Form execution failed: %v", err))
return
}
@ -191,30 +198,30 @@ func (a *App) makeChoice() {
a.connect()
case "stop work":
if err := a.timeStore.StopTracking(); err != nil {
log.Printf("ERROR: Failed to stop time tracking: %v", err)
slog.Error(fmt.Sprintf("Failed to stop time tracking: %v", err))
}
if err := a.killForwardings(); err != nil {
log.Printf("WARN: Could not kill all forwardings: %v", err)
slog.Warn(fmt.Sprintf("Could not kill all forwardings: %v", err))
}
case "start break":
if err := a.timeStore.StartTracking(TagBreak); err != nil {
log.Printf("ERROR: Failed to start break tracking: %v", err)
slog.Error(fmt.Sprintf("Failed to start break tracking: %v", err))
}
case "stop break":
if err := a.timeStore.StartTracking(TagWork); err != nil {
log.Printf("ERROR: Failed to stop break (start work): %v", err)
slog.Error(fmt.Sprintf("Failed to stop break (start work): %v", err))
}
case "show day summary":
if err := a.timeStore.ShowSummary("today"); err != nil {
log.Printf("ERROR: Failed to show day summary: %v", err)
slog.Error(fmt.Sprintf("Failed to show day summary: %v", err))
}
case "show week summary":
if err := a.timeStore.ShowSummary("week"); err != nil {
log.Printf("ERROR: Failed to show week summary: %v", err)
slog.Error(fmt.Sprintf("ERROR: Failed to show week summary: %v", err))
}
case "show month summary":
if err := a.timeStore.ShowSummary("month"); err != nil {
log.Printf("ERROR: Failed to show month summary: %v", err)
slog.Error(fmt.Sprintf("Failed to show month summary: %v", err))
}
case "export":
filename := "Arbeitszeiten_" + time.Now().Format("2006") + ".xlsx"
@ -222,7 +229,7 @@ func (a *App) makeChoice() {
filename = a.flags.ExportName
}
if err := a.timeStore.ExportSummary(filename); err != nil {
log.Printf("ERROR: Failed to export summary to '%s': %v", filename, err)
slog.Error(fmt.Sprintf("Failed to export summary to '%s': %v", filename, err))
}
case "connect to jump":
a.connectToJump()
@ -234,15 +241,15 @@ func (a *App) makeChoice() {
a.wakeWorkstation()
case "kill tunnels":
if err := a.killForwardings(); err != nil {
log.Printf("ERROR: Failed to kill forwardings: %v", err)
slog.Error(fmt.Sprintf("Failed to kill forwardings: %v", err))
} else {
log.Println("INFO: Attempted to kill processes on ports 2048 and 6000.")
slog.Info("Attempted to kill processes on ports 2048 and 6000.")
}
case "exit":
fmt.Println("Exiting.")
return
default:
log.Printf("WARN: Unhandled choice '%s'", choice)
slog.Warn(fmt.Sprintf("Unhandled choice '%s'", choice))
}
if choice != "exit" && choice != "connect to jump" && choice != "connect to workstation" && choice != "start rdp connection" {
@ -257,7 +264,7 @@ func (a *App) getSSHAuth() ssh.AuthMethod {
keyBytes, err := os.ReadFile(keyPath)
if err != nil {
log.Printf("ERROR: Unable to read private key '%s': %v", keyPath, err)
slog.Error(fmt.Sprintf("Unable to read private key '%s': %v", keyPath, err))
return nil
}
@ -265,19 +272,19 @@ func (a *App) getSSHAuth() ssh.AuthMethod {
key, err = ssh.ParsePrivateKey(keyBytes)
if err != nil {
if _, ok := err.(*ssh.PassphraseMissingError); ok {
log.Printf("INFO: Private key '%s' requires a passphrase. Trying with RDP password from config.", keyPath)
slog.Info(fmt.Sprintf("Private key '%s' requires a passphrase. Trying with RDP password from config.", keyPath))
key, err = ssh.ParsePrivateKeyWithPassphrase(keyBytes, []byte(a.cfg.RDPPassword))
if err != nil {
log.Printf("ERROR: Unable to parse private key '%s' with passphrase: %v", keyPath, err)
slog.Error(fmt.Sprintf("Unable to parse private key '%s' with passphrase: %v", keyPath, err))
return nil
}
} else {
log.Printf("ERROR: Unable to parse private key '%s': %v", keyPath, err)
slog.Error(fmt.Sprintf("Unable to parse private key '%s': %v", keyPath, err))
return nil
}
}
log.Printf("INFO: Successfully loaded private key '%s'", keyPath)
slog.Info(fmt.Sprintf("Successfully loaded private key '%s'", keyPath))
return ssh.PublicKeys(key)
}
@ -295,13 +302,13 @@ func (a *App) newSSHConnection() (*SSHConnection, error) {
}
target := fmt.Sprintf("%s:%d", a.cfg.SSHHost, a.cfg.SSHPort)
log.Printf("INFO: Dialing SSH to %s...", target)
slog.Info(fmt.Sprintf("Dialing SSH to %s...", target))
client, err := ssh.Dial("tcp", target, sshConfig)
if err != nil {
return nil, fmt.Errorf("SSH dial to %s failed: %w", target, err)
}
log.Printf("INFO: SSH connection to %s successful.", target)
slog.Info(fmt.Sprintf("SSH connection to %s successful.", target))
session, err := client.NewSession()
if err != nil {
@ -320,16 +327,16 @@ func (a *App) killForwardings() error {
killedSomething := false
var lastErr error
log.Println("INFO: Attempting to kill processes listening on ports:", strings.Join(ports, ", "))
slog.Info(fmt.Sprintf("Attempting to kill processes listening on ports: %v", strings.Join(ports, ", ")))
for _, port := range ports {
cmd := exec.Command("lsof", "-i", "tcp:"+port, "-t")
output, err := cmd.Output()
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok && exitErr.ExitCode() == 1 {
log.Printf("INFO: No process found listening on port %s.", port)
slog.Info(fmt.Sprintf("No process found listening on port %s.", port))
} else {
log.Printf("WARN: 'lsof' command failed for port %s: %v", port, err)
slog.Warn(fmt.Sprintf("'lsof' command failed for port %s: %v", port, err))
lastErr = fmt.Errorf("lsof failed for port %s: %w", port, err)
}
continue
@ -341,29 +348,29 @@ func (a *App) killForwardings() error {
if pid == "" {
continue
}
log.Printf("INFO: Found process PID %s on port %s. Attempting to kill...", pid, port)
slog.Info(fmt.Sprintf("Found process PID %s on port %s. Attempting to kill...", pid, port))
killCmd := exec.Command("kill", pid)
if err := killCmd.Run(); err != nil {
log.Printf("WARN: Failed to kill PID %s (port %s): %v. Trying kill -9...", pid, port, err)
slog.Warn(fmt.Sprintf("Failed to kill PID %s (port %s): %v. Trying kill -9...", pid, port, err))
forceKillCmd := exec.Command("kill", "-9", pid)
if err := forceKillCmd.Run(); err != nil {
log.Printf("ERROR: Failed to force kill PID %s (port %s): %v", pid, port, err)
slog.Error(fmt.Sprintf("Failed to force kill PID %s (port %s): %v", pid, port, err))
lastErr = fmt.Errorf("kill -9 failed for PID %s: %w", pid, err)
} else {
log.Printf("INFO: Force killed PID %s (port %s).", pid, port)
slog.Info(fmt.Sprintf("Force killed PID %s (port %s).", pid, port))
killedSomething = true
}
} else {
log.Printf("INFO: Killed PID %s (port %s).", pid, port)
slog.Info(fmt.Sprintf("Killed PID %s (port %s).", pid, port))
killedSomething = true
}
}
}
if killedSomething {
log.Println("INFO: Finished attempting to kill forwarding processes.")
slog.Info("Finished attempting to kill forwarding processes.")
} else {
log.Println("INFO: No forwarding processes found or killed.")
slog.Info("No forwarding processes found or killed.")
}
return lastErr