diff --git a/CHANGELOG.md b/CHANGELOG.md index c3a7c42f..a5201e3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ - Fix 4699: Remove Remove goyaml2 dependency. [4755](https://github.com/beego/beego/pull/4755) - Fix 4698: Prompt error when config format is incorrect. [4757](https://github.com/beego/beego/pull/4757) - Fix 4674: Tx Orm missing debug log [4756](https://github.com/beego/beego/pull/4756) +- Fix 4759: fix numeric notation of permissions [4759](https://github.com/beego/beego/pull/4759) ## Fix Sonar - [4677](https://github.com/beego/beego/pull/4677) diff --git a/core/logs/file.go b/core/logs/file.go index 80114db2..3234a674 100644 --- a/core/logs/file.go +++ b/core/logs/file.go @@ -64,15 +64,17 @@ type fileLogWriter struct { hourlyOpenTime time.Time Level int `json:"level"` - + // Permissions for log file Perm string `json:"perm"` + // Permissions for directory if it is specified in FileName + DirPerm string `json:"dirperm"` RotatePerm string `json:"rotateperm"` fileNameOnly, suffix string // like "project.log", project is fileNameOnly and .log is suffix - formatter LogFormatter - Formatter string `json:"formatter"` + logFormatter LogFormatter + Formatter string `json:"formatter"` } // newFileWriter creates a FileLogWriter returning as LoggerInterface. @@ -86,15 +88,16 @@ func newFileWriter() Logger { RotatePerm: "0440", Level: LevelTrace, Perm: "0660", + DirPerm: "0770", MaxLines: 10000000, MaxFiles: 999, MaxSize: 1 << 28, } - w.formatter = w + w.logFormatter = w return w } -func (w *fileLogWriter) Format(lm *LogMsg) string { +func (*fileLogWriter) Format(lm *LogMsg) string { msg := lm.OldStyleFormat() hd, _, _ := formatTimeHeader(lm.When) msg = fmt.Sprintf("%s %s\n", string(hd), msg) @@ -102,7 +105,7 @@ func (w *fileLogWriter) Format(lm *LogMsg) string { } func (w *fileLogWriter) SetFormatter(f LogFormatter) { - w.formatter = f + w.logFormatter = f } // Init file logger with json config. @@ -121,7 +124,7 @@ func (w *fileLogWriter) Init(config string) error { if err != nil { return err } - if len(w.Filename) == 0 { + if w.Filename == "" { return errors.New("jsonconfig must have filename") } w.suffix = filepath.Ext(w.Filename) @@ -133,9 +136,9 @@ func (w *fileLogWriter) Init(config string) error { if len(w.Formatter) > 0 { fmtr, ok := GetFormatter(w.Formatter) if !ok { - return errors.New(fmt.Sprintf("the formatter with name: %s not found", w.Formatter)) + return fmt.Errorf("the formatter with name: %s not found", w.Formatter) } - w.formatter = fmtr + w.logFormatter = fmtr } err = w.startLogger() return err @@ -174,7 +177,7 @@ func (w *fileLogWriter) WriteMsg(lm *LogMsg) error { _, d, h := formatTimeHeader(lm.When) - msg := w.formatter.Format(lm) + msg := w.logFormatter.Format(lm) if w.Rotate { w.RLock() if w.needRotateHourly(h) { @@ -217,8 +220,13 @@ func (w *fileLogWriter) createLogFile() (*os.File, error) { return nil, err } + dirperm, err := strconv.ParseInt(w.DirPerm, 8, 64) + if err != nil { + return nil, err + } + filepath := path.Dir(w.Filename) - os.MkdirAll(filepath, os.FileMode(perm)) + os.MkdirAll(filepath, os.FileMode(dirperm)) fd, err := os.OpenFile(w.Filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.FileMode(perm)) if err == nil { diff --git a/core/logs/file_test.go b/core/logs/file_test.go index 16220936..6aac919a 100644 --- a/core/logs/file_test.go +++ b/core/logs/file_test.go @@ -48,6 +48,57 @@ func TestFilePerm(t *testing.T) { os.Remove("test.log") } +func TestFileWithPrefixPath(t *testing.T) { + log := NewLogger(10000) + log.SetLogger("file", `{"filename":"log/test.log"}`) + log.Debug("debug") + log.Informational("info") + log.Notice("notice") + log.Warning("warning") + log.Error("error") + log.Alert("alert") + log.Critical("critical") + log.Emergency("emergency") + _, err := os.Stat("log/test.log") + if err != nil { + t.Fatal(err) + } + os.Remove("log/test.log") + os.Remove("log") +} + +func TestFilePermWithPrefixPath(t *testing.T) { + log := NewLogger(10000) + log.SetLogger("file", `{"filename":"mylogpath/test.log", "perm": "0220", "dirperm": "0770"}`) + log.Debug("debug") + log.Informational("info") + log.Notice("notice") + log.Warning("warning") + log.Error("error") + log.Alert("alert") + log.Critical("critical") + log.Emergency("emergency") + + dir, err := os.Stat("mylogpath") + if err != nil { + t.Fatal(err) + } + if !dir.IsDir() { + t.Fatal("mylogpath expected to be a directory") + } + + file, err := os.Stat("mylogpath/test.log") + if err != nil { + t.Fatal(err) + } + if file.Mode() != 0o0220 { + t.Fatal("unexpected file permission") + } + + os.Remove("mylogpath/test.log") + os.Remove("mylogpath") +} + func TestFile1(t *testing.T) { log := NewLogger(10000) log.SetLogger("file", `{"filename":"test.log"}`) @@ -269,17 +320,18 @@ func testFileRotate(t *testing.T, fn1, fn2 string, daily, hourly bool) { Rotate: true, Level: LevelTrace, Perm: "0660", + DirPerm: "0770", RotatePerm: "0440", } - fw.formatter = fw + fw.logFormatter = fw - if daily { + if fw.Daily { fw.Init(fmt.Sprintf(`{"filename":"%v","maxdays":1}`, fn1)) fw.dailyOpenTime = time.Now().Add(-24 * time.Hour) fw.dailyOpenDate = fw.dailyOpenTime.Day() } - if hourly { + if fw.Hourly { fw.Init(fmt.Sprintf(`{"filename":"%v","maxhours":1}`, fn1)) fw.hourlyOpenTime = time.Now().Add(-1 * time.Hour) fw.hourlyOpenDate = fw.hourlyOpenTime.Day() @@ -310,9 +362,10 @@ func testFileDailyRotate(t *testing.T, fn1, fn2 string) { Rotate: true, Level: LevelTrace, Perm: "0660", + DirPerm: "0770", RotatePerm: "0440", } - fw.formatter = fw + fw.logFormatter = fw fw.Init(fmt.Sprintf(`{"filename":"%v","maxdays":1}`, fn1)) fw.dailyOpenTime = time.Now().Add(-24 * time.Hour) @@ -344,10 +397,11 @@ func testFileHourlyRotate(t *testing.T, fn1, fn2 string) { Rotate: true, Level: LevelTrace, Perm: "0660", + DirPerm: "0770", RotatePerm: "0440", } - fw.formatter = fw + fw.logFormatter = fw fw.Init(fmt.Sprintf(`{"filename":"%v","maxhours":1}`, fn1)) fw.hourlyOpenTime = time.Now().Add(-1 * time.Hour) fw.hourlyOpenDate = fw.hourlyOpenTime.Hour()