Skip to content

Commit

Permalink
feat(debug): trace system calls to log file
Browse files Browse the repository at this point in the history
  • Loading branch information
JanDeDobbeleer committed Aug 1, 2021
1 parent c4db62c commit 073f18f
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 8 deletions.
64 changes: 64 additions & 0 deletions src/environment.go
Expand Up @@ -3,7 +3,9 @@ package main
import (
"context"
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
Expand Down Expand Up @@ -97,10 +99,45 @@ func (c *commandCache) get(command string) (string, bool) {
return "", false
}

type tracer struct {
file *os.File
debug bool
}

func (t *tracer) init(home string) {
if !t.debug {
return
}
var err error
fileName := home + "/oh-my-posh.log"
t.file, err = os.OpenFile(fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalf("error opening file: %v", err)
}
log.SetOutput(t.file)
}

func (t *tracer) close() {
if !t.debug {
return
}
_ = t.file.Close()
}

func (t *tracer) trace(start time.Time, function string, args ...string) {
if !t.debug {
return
}
elapsed := time.Since(start)
trace := fmt.Sprintf("func: %s duration: %s, args: %s", function, elapsed, strings.Trim(fmt.Sprint(args), "[]"))
log.Println(trace)
}

type environment struct {
args *args
cwd string
cmdCache *commandCache
tracer *tracer
}

func (env *environment) init(args *args) {
Expand All @@ -110,13 +147,20 @@ func (env *environment) init(args *args) {
lock: sync.RWMutex{},
}
env.cmdCache = cmdCache
tracer := &tracer{
debug: *args.Debug,
}
tracer.init(env.homeDir())
env.tracer = tracer
}

func (env *environment) getenv(key string) string {
defer env.tracer.trace(time.Now(), "getenv", key)
return os.Getenv(key)
}

func (env *environment) getcwd() string {
defer env.tracer.trace(time.Now(), "getcwd")
if env.cwd != "" {
return env.cwd
}
Expand All @@ -137,6 +181,7 @@ func (env *environment) getcwd() string {
}

func (env *environment) hasFiles(pattern string) bool {
defer env.tracer.trace(time.Now(), "hasFiles", pattern)
cwd := env.getcwd()
pattern = cwd + env.getPathSeperator() + pattern
matches, err := filepath.Glob(pattern)
Expand All @@ -147,6 +192,7 @@ func (env *environment) hasFiles(pattern string) bool {
}

func (env *environment) hasFilesInDir(dir, pattern string) bool {
defer env.tracer.trace(time.Now(), "hasFilesInDir", pattern)
pattern = dir + env.getPathSeperator() + pattern
matches, err := filepath.Glob(pattern)
if err != nil {
Expand All @@ -156,11 +202,13 @@ func (env *environment) hasFilesInDir(dir, pattern string) bool {
}

func (env *environment) hasFolder(folder string) bool {
defer env.tracer.trace(time.Now(), "hasFolder", folder)
_, err := os.Stat(folder)
return !os.IsNotExist(err)
}

func (env *environment) getFileContent(file string) string {
defer env.tracer.trace(time.Now(), "getFileContent", file)
content, err := ioutil.ReadFile(file)
if err != nil {
return ""
Expand All @@ -169,10 +217,12 @@ func (env *environment) getFileContent(file string) string {
}

func (env *environment) getPathSeperator() string {
defer env.tracer.trace(time.Now(), "getPathSeperator")
return string(os.PathSeparator)
}

func (env *environment) getCurrentUser() string {
defer env.tracer.trace(time.Now(), "getCurrentUser")
user := os.Getenv("USER")
if user == "" {
user = os.Getenv("USERNAME")
Expand All @@ -181,6 +231,7 @@ func (env *environment) getCurrentUser() string {
}

func (env *environment) getHostName() (string, error) {
defer env.tracer.trace(time.Now(), "getHostName")
hostName, err := os.Hostname()
if err != nil {
return "", err
Expand All @@ -189,10 +240,12 @@ func (env *environment) getHostName() (string, error) {
}

func (env *environment) getRuntimeGOOS() string {
defer env.tracer.trace(time.Now(), "getRuntimeGOOS")
return runtime.GOOS
}

func (env *environment) getPlatform() string {
defer env.tracer.trace(time.Now(), "getPlatform")
if runtime.GOOS == windowsPlatform {
return windowsPlatform
}
Expand All @@ -202,6 +255,7 @@ func (env *environment) getPlatform() string {
}

func (env *environment) runCommand(command string, args ...string) (string, error) {
defer env.tracer.trace(time.Now(), "runCommand", append([]string{command}, args...)...)
if cmd, ok := env.cmdCache.get(command); ok {
command = cmd
}
Expand All @@ -218,11 +272,13 @@ func (env *environment) runCommand(command string, args ...string) (string, erro
}

func (env *environment) runShellCommand(shell, command string) string {
defer env.tracer.trace(time.Now(), "runShellCommand", shell, command)
out, _ := env.runCommand(shell, "-c", command)
return out
}

func (env *environment) hasCommand(command string) bool {
defer env.tracer.trace(time.Now(), "hasCommand", command)
if _, ok := env.cmdCache.get(command); ok {
return true
}
Expand All @@ -235,25 +291,30 @@ func (env *environment) hasCommand(command string) bool {
}

func (env *environment) lastErrorCode() int {
defer env.tracer.trace(time.Now(), "lastErrorCode")
return *env.args.ErrorCode
}

func (env *environment) executionTime() float64 {
defer env.tracer.trace(time.Now(), "executionTime")
if *env.args.ExecutionTime < 0 {
return 0
}
return *env.args.ExecutionTime
}

func (env *environment) getArgs() *args {
defer env.tracer.trace(time.Now(), "getArgs")
return env.args
}

func (env *environment) getBatteryInfo() ([]*battery.Battery, error) {
defer env.tracer.trace(time.Now(), "getBatteryInfo")
return battery.GetAll()
}

func (env *environment) getShellName() string {
defer env.tracer.trace(time.Now(), "getShellName")
if *env.args.Shell != "" {
return *env.args.Shell
}
Expand All @@ -276,6 +337,7 @@ func (env *environment) getShellName() string {
}

func (env *environment) doGet(url string) ([]byte, error) {
defer env.tracer.trace(time.Now(), "doGet", url)
ctx, cncl := context.WithTimeout(context.Background(), time.Millisecond*20)
defer cncl()
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
Expand All @@ -295,6 +357,7 @@ func (env *environment) doGet(url string) ([]byte, error) {
}

func (env *environment) hasParentFilePath(path string) (*fileInfo, error) {
defer env.tracer.trace(time.Now(), "hasParentFilePath", path)
currentFolder := env.getcwd()
for {
searchPath := filepath.Join(currentFolder, path)
Expand All @@ -318,6 +381,7 @@ func (env *environment) hasParentFilePath(path string) (*fileInfo, error) {
}

func (env *environment) stackCount() int {
defer env.tracer.trace(time.Now(), "stackCount")
if *env.args.StackCount < 0 {
return 0
}
Expand Down
4 changes: 4 additions & 0 deletions src/environment_unix.go
Expand Up @@ -5,11 +5,13 @@ package main
import (
"errors"
"os"
"time"

terminal "github.com/wayneashleyberry/terminal-dimensions"
)

func (env *environment) isRunningAsRoot() bool {
defer env.tracer.trace(time.Now(), "isRunningAsRoot")
return os.Geteuid() == 0
}

Expand All @@ -22,6 +24,7 @@ func (env *environment) getWindowTitle(imageName, windowTitleRegex string) (stri
}

func (env *environment) isWsl() bool {
defer env.tracer.trace(time.Now(), "isWsl")
// one way to check
// version := env.getFileContent("/proc/version")
// return strings.Contains(version, "microsoft")
Expand All @@ -30,6 +33,7 @@ func (env *environment) isWsl() bool {
}

func (env *environment) getTerminalWidth() (int, error) {
defer env.tracer.trace(time.Now(), "getTerminalWidth")
width, err := terminal.Width()
return int(width), err
}
5 changes: 5 additions & 0 deletions src/environment_windows.go
Expand Up @@ -5,11 +5,13 @@ package main
import (
"errors"
"os"
"time"

"golang.org/x/sys/windows"
)

func (env *environment) isRunningAsRoot() bool {
defer env.tracer.trace(time.Now(), "isRunningAsRoot")
var sid *windows.SID

// Although this looks scary, it is directly copied from the
Expand Down Expand Up @@ -57,13 +59,16 @@ func (env *environment) homeDir() string {
}

func (env *environment) getWindowTitle(imageName, windowTitleRegex string) (string, error) {
defer env.tracer.trace(time.Now(), "getWindowTitle", imageName, windowTitleRegex)
return getWindowTitle(imageName, windowTitleRegex)
}

func (env *environment) isWsl() bool {
defer env.tracer.trace(time.Now(), "isWsl")
return false
}

func (env *environment) getTerminalWidth() (int, error) {
defer env.tracer.trace(time.Now(), "getTerminalWidth")
return 0, errors.New("Unsupported on Windows")
}
1 change: 1 addition & 0 deletions src/main.go
Expand Up @@ -155,6 +155,7 @@ func main() {
flag.Parse()
env := &environment{}
env.init(args)
defer env.tracer.close()
if *args.Millis {
fmt.Print(time.Now().UnixNano() / 1000000)
return
Expand Down
40 changes: 32 additions & 8 deletions src/segment_command_test.go
Expand Up @@ -10,7 +10,10 @@ import (

func TestExecuteCommand(t *testing.T) {
env := &environment{}
env.init(nil)
debug := false
env.init(&args{
Debug: &debug,
})
props := &properties{
values: map[Property]interface{}{
Command: "echo hello",
Expand All @@ -27,7 +30,10 @@ func TestExecuteCommand(t *testing.T) {

func TestExecuteMultipleCommandsOrFirst(t *testing.T) {
env := &environment{}
env.init(nil)
debug := false
env.init(&args{
Debug: &debug,
})
props := &properties{
values: map[Property]interface{}{
Command: "exit 1 || echo hello",
Expand All @@ -44,7 +50,10 @@ func TestExecuteMultipleCommandsOrFirst(t *testing.T) {

func TestExecuteMultipleCommandsOrSecond(t *testing.T) {
env := &environment{}
env.init(nil)
debug := false
env.init(&args{
Debug: &debug,
})
props := &properties{
values: map[Property]interface{}{
Command: "echo hello || echo world",
Expand All @@ -61,7 +70,10 @@ func TestExecuteMultipleCommandsOrSecond(t *testing.T) {

func TestExecuteMultipleCommandsAnd(t *testing.T) {
env := &environment{}
env.init(nil)
debug := false
env.init(&args{
Debug: &debug,
})
props := &properties{
values: map[Property]interface{}{
Command: "echo hello && echo world",
Expand All @@ -78,7 +90,10 @@ func TestExecuteMultipleCommandsAnd(t *testing.T) {

func TestExecuteSingleCommandEmpty(t *testing.T) {
env := &environment{}
env.init(nil)
debug := false
env.init(&args{
Debug: &debug,
})
props := &properties{
values: map[Property]interface{}{
Command: "",
Expand All @@ -94,7 +109,10 @@ func TestExecuteSingleCommandEmpty(t *testing.T) {

func TestExecuteSingleCommandNoCommandProperty(t *testing.T) {
env := &environment{}
env.init(nil)
debug := false
env.init(&args{
Debug: &debug,
})
props := &properties{}
c := &command{
props: props,
Expand All @@ -107,7 +125,10 @@ func TestExecuteSingleCommandNoCommandProperty(t *testing.T) {

func TestExecuteMultipleCommandsAndDisabled(t *testing.T) {
env := &environment{}
env.init(nil)
debug := false
env.init(&args{
Debug: &debug,
})
props := &properties{
values: map[Property]interface{}{
Command: "echo && echo",
Expand All @@ -123,7 +144,10 @@ func TestExecuteMultipleCommandsAndDisabled(t *testing.T) {

func TestExecuteMultipleCommandsOrDisabled(t *testing.T) {
env := &environment{}
env.init(nil)
debug := false
env.init(&args{
Debug: &debug,
})
props := &properties{
values: map[Property]interface{}{
Command: "echo|| echo",
Expand Down

0 comments on commit 073f18f

Please sign in to comment.