返回 DeepSeek-Reasonix
log.go
1 //go:build windows
2
3 package desktopinstance
4
5 import (
6 "crypto/rand"
7 "fmt"
8 "os"
9 "path/filepath"
10 "time"
11 )
12
13 // Diagnostics stay on this computer and contain no business configuration.
14 // Each recovery log and its single backup are bounded to approximately 1 MiB.
15 func AttemptLog(home, action, root string) func(error) {
16 id := fmt.Sprintf("%x", randomID())
17 writeRecoveryLog(home, fmt.Sprintf("attempt=%s action=%s root=%q phase=begin", id, action, root))
18 return func(err error) {
19 result := "completed"
20 if err != nil {
21 result = err.Error()
22 }
23 writeRecoveryLog(home, fmt.Sprintf("attempt=%s action=%s result=%q", id, action, result))
24 }
25 }
26
27 func randomID() []byte { b := make([]byte, 16); _, _ = rand.Read(b); return b }
28
29 func writeRecoveryLog(home, message string) {
30 path := filepath.Join(home, "desktop-shell", "logs", "recovery.log")
31 if os.MkdirAll(filepath.Dir(path), 0700) != nil {
32 return
33 }
34 if info, err := os.Stat(path); err == nil && info.Size() >= 1024*1024 {
35 _ = os.Remove(path + ".1")
36 _ = os.Rename(path, path+".1")
37 }
38 f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
39 if err != nil {
40 return
41 }
42 defer f.Close()
43 if len(message) > 16*1024 {
44 message = message[:16*1024]
45 }
46 _, _ = fmt.Fprintf(f, "%s %s\n", time.Now().UTC().Format(time.RFC3339Nano), message)
47 }
48
49 // LogPortableLocationRejected records only the storage classification. In
50 // particular, it never records the UNC server/share or the user's full path.
51 func LogPortableLocationRejected(home, locationType string, interactive bool) {
52 locationType = portableLocationType(locationType)
53 launchMode := "noninteractive"
54 if interactive {
55 launchMode = "interactive"
56 }
57 writeRecoveryLog(home, fmt.Sprintf("event=portable_location_rejected platform=windows location_type=%s launch_mode=%s", locationType, launchMode))
58 }
59
59 lines GO