-
Notifications
You must be signed in to change notification settings - Fork 1
/
logdir.go
133 lines (116 loc) · 3.07 KB
/
logdir.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package rotatefile
import (
"os"
"os/signal"
"os/user"
"path/filepath"
"strconv"
"syscall"
"github.com/bingoohuang/q"
"github.com/bingoohuang/rotatefile/flock"
)
// getLogFileName 获取可执行文件 binName 的日志文件路径
func getLogFileName(appName, logDir, prefix, logName string, tryLock bool) (string, *flock.Flock) {
if p := FindLogDir(appName, logDir); p != "" {
if logName == "" {
logName = appName + currentDirBase + ".log"
}
var logLock *flock.Flock
if tryLock {
logLock = flock.New(filepath.Join(p, logName+".lock"))
if lock, _ := logLock.TryLock(); !lock {
logName = logName[:len(logName)-len(".log")] + "." + pid + ".log"
}
}
logFileName := filepath.Join(p, prefix+logName)
writeLogFile(logFileName)
return logFileName, logLock
}
panic("日志已经无处安放,君欲何为?")
}
// GetFilename 获得当前进程的日志文件路径
func GetFilename() string {
logdirFile := filepath.Join(os.TempDir(), "logfile."+pid)
logfile, _ := os.ReadFile(logdirFile)
return string(logfile)
}
var pid = strconv.Itoa(os.Getpid())
func writeLogFile(logFileName string) {
q.Q(logFileName)
logdirFile := filepath.Join(os.TempDir(), "logfile."+pid)
_ = q.AppendFile(logdirFile, []byte(logFileName+"\n"), os.ModePerm)
}
func handleSigint(f func()) {
ch := make(chan os.Signal, 1)
signal.Notify(ch, os.Interrupt)
signal.Notify(ch, syscall.SIGTERM)
go func() {
<-ch
f()
}()
}
// FindLogDir 寻找日志合理的写入目录
// 0. 配置指定目录 /var/log/xxx/
// 1. $HOME/log/{appName}/{appName}_{appWorkDirBase}.log
// 2. $PWD/log/{appName}_{appWorkDirBase}.log
// 3. /var/log/apps/{appName}/{appName}_{appWorkDirBase}.log
// 4. $TMPDIR/{appName}/{appName}_{appWorkDirBase}.log
func FindLogDir(appName, logDir string) string {
if logDir != "" {
if IsDirWritable(logDir) {
return logDir
}
}
if home, _ := HomeDir(); home != "" {
if p := filepath.Join(home, "log", appName); IsDirWritable(p) {
return p
}
}
if wd, _ := os.Getwd(); wd != "" {
if p := filepath.Join(wd, "log", appName); IsDirWritable(p) {
return p
}
}
if p := filepath.Join("/var/log/apps", appName); IsDirWritable(p) {
return p
}
if p := os.TempDir(); IsDirWritable(p) {
return p
}
return ""
}
// IsDirWritable 测试目录是否可写
func IsDirWritable(dir string) bool {
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
if err := MkdirAll(dir, os.ModePerm); err != nil {
return false
}
}
temp, err := os.CreateTemp(dir, "*")
if err != nil {
return false
}
defer func() {
temp.Close()
os.Remove(temp.Name())
}()
const s = "bingoohuang_log_test"
n, err := temp.WriteString(s)
return err == nil && n == len(s)
}
var currentDirBase = func() string {
wd, _ := os.Getwd()
if wd != "" {
return "_" + filepath.Base(wd)
}
return ""
}()
// HomeDir 返回当前用户的主目录
// 注意:有可能有的Linux用户没有主目录,此时,日志文件可能需要产生在 /var/log 目录下
func HomeDir() (string, error) {
u, err := user.Current()
if err != nil {
return "", err
}
return u.HomeDir, nil
}