Skip to content

Commit 7eff6df

Browse files
committed
refactor(serverLog): refine log structure
- extract `fileDest` (aka `fileEntry`) - extract `getFileInfoIfNotMatch()` - rename `logMan` to `loggerChan`
1 parent eb0dbd3 commit 7eff6df

File tree

6 files changed

+214
-208
lines changed

6 files changed

+214
-208
lines changed

src/serverLog/buffer.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import (
55
"time"
66
)
77

8+
const chanBuffer = 128
9+
const logEnding = '\n'
10+
811
func NewBuffer(cap int) []byte {
912
// prefix: 20 bytes, suffix '\n' 1 byte
1013
buf := make([]byte, 0, 21+cap)

src/serverLog/fileDest.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package serverLog
2+
3+
import (
4+
"errors"
5+
"os"
6+
)
7+
8+
func openLogFile(fsPath string) (*os.File, error) {
9+
return os.OpenFile(fsPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, fileMode)
10+
}
11+
12+
func getFileInfoIfNotMatch(fsPath string, match func(info os.FileInfo) bool) (file *os.File, info os.FileInfo, err error) {
13+
info, err = os.Stat(fsPath)
14+
15+
if os.IsNotExist(err) {
16+
file, err = openLogFile(fsPath)
17+
if err != nil {
18+
return nil, nil, err
19+
}
20+
21+
info, err = os.Stat(fsPath)
22+
if err != nil {
23+
file.Close()
24+
return nil, nil, err
25+
}
26+
27+
return
28+
}
29+
30+
if err != nil {
31+
return nil, nil, err
32+
}
33+
34+
if info.IsDir() {
35+
err = errors.New("should not be a directory")
36+
return nil, nil, err
37+
}
38+
39+
if match(info) {
40+
return nil, nil, err
41+
}
42+
43+
// use existing info, get file
44+
file, err = openLogFile(fsPath)
45+
if err != nil {
46+
return nil, nil, err
47+
}
48+
49+
return
50+
}
51+
52+
type fileDest struct {
53+
fsPath string
54+
file *os.File
55+
info os.FileInfo
56+
ch chan []byte
57+
}
58+
59+
func newFileDest(fsPath string, file *os.File, info os.FileInfo) *fileDest {
60+
ch := make(chan []byte, chanBuffer)
61+
62+
dest := &fileDest{
63+
fsPath: fsPath,
64+
file: file,
65+
info: info,
66+
ch: ch,
67+
}
68+
69+
return dest
70+
}
71+
72+
func (dest *fileDest) serve() {
73+
for payload := range dest.ch {
74+
payload = append(payload, logEnding)
75+
_, e := dest.file.Write(payload)
76+
if e != nil {
77+
os.Stderr.WriteString(e.Error() + "\n")
78+
}
79+
}
80+
if dest.info != nil { // not Stdout or Stderr
81+
dest.file.Close()
82+
}
83+
}
84+
85+
func (dest *fileDest) reopen() error {
86+
if dest.info == nil { // Stdout or Stderr
87+
return nil
88+
}
89+
90+
matched := false
91+
file, info, err := getFileInfoIfNotMatch(dest.fsPath, func(info os.FileInfo) bool {
92+
matched = os.SameFile(info, dest.info)
93+
return matched
94+
})
95+
96+
if err != nil {
97+
return err
98+
}
99+
100+
if matched {
101+
return nil
102+
}
103+
104+
oldFile := dest.file
105+
dest.info = info
106+
dest.file = file
107+
return oldFile.Close()
108+
}
109+
110+
func (dest *fileDest) close() {
111+
close(dest.ch)
112+
}

src/serverLog/fileMan.go

Lines changed: 69 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// fileMan maintains opened files shared by multiple logMan
1+
// fileMan maintains opened files shared by multiple loggerChan
22

33
package serverLog
44

@@ -8,165 +8,67 @@ import (
88
"sync"
99
)
1010

11-
const chanBuffer = 128
1211
const fileMode = 0660
13-
const logEnding = '\n'
14-
15-
type fileEntry struct {
16-
fsPath string
17-
info os.FileInfo
18-
file *os.File
19-
ch chan []byte
20-
}
2112

2213
type FileMan struct {
23-
wg *sync.WaitGroup
24-
entries []*fileEntry
25-
}
26-
27-
func openLogFile(fsPath string) (*os.File, error) {
28-
return os.OpenFile(fsPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, fileMode)
29-
}
30-
31-
func newFileEntry(fsPath string, info os.FileInfo, file *os.File) *fileEntry {
32-
ch := make(chan []byte, chanBuffer)
33-
34-
entry := &fileEntry{
35-
fsPath: fsPath,
36-
info: info,
37-
file: file,
38-
ch: ch,
39-
}
40-
41-
return entry
42-
}
43-
44-
func (entry *fileEntry) serve() {
45-
for payload := range entry.ch {
46-
payload = append(payload, logEnding)
47-
_, e := entry.file.Write(payload)
48-
if e != nil {
49-
os.Stderr.WriteString(e.Error() + "\n")
50-
}
51-
}
52-
if entry.info != nil { // not Stdout or Stderr
53-
entry.file.Close()
54-
}
55-
}
56-
57-
func (entry *fileEntry) reopen() error {
58-
if entry.info == nil { // Stdout or Stderr
59-
return nil
60-
}
61-
62-
var err error
63-
var info os.FileInfo
64-
var file *os.File
65-
66-
info, err = os.Stat(entry.fsPath)
67-
if os.IsNotExist(err) {
68-
// get file
69-
file, err = openLogFile(entry.fsPath)
70-
if err != nil {
71-
return err
72-
}
73-
// get info
74-
info, err = os.Stat(entry.fsPath)
75-
if err != nil {
76-
return err
77-
}
78-
} else {
79-
if err != nil {
80-
return err
81-
}
82-
83-
if os.SameFile(info, entry.info) {
84-
return nil
85-
}
86-
87-
// use existing info, get file
88-
file, err = openLogFile(entry.fsPath)
89-
if err != nil {
90-
return err
91-
}
92-
}
93-
94-
oldFile := entry.file
95-
entry.info = info
96-
entry.file = file
97-
98-
return oldFile.Close()
99-
}
100-
101-
func (entry *fileEntry) close() {
102-
close(entry.ch)
14+
wg *sync.WaitGroup
15+
dests []*fileDest
10316
}
10417

10518
func (fMan *FileMan) getWritingCh(fsPath string, file *os.File) (chan<- []byte, error) {
10619
if len(fsPath) == 0 && file == nil {
10720
return nil, errors.New("log file not provided")
10821
}
10922

110-
var err error
11123
var info os.FileInfo
24+
var err error
11225

11326
if file == nil { // regular file
114-
info, err = os.Stat(fsPath)
115-
if os.IsNotExist(err) {
116-
// get file
117-
file, err = openLogFile(fsPath)
118-
if err != nil {
119-
return nil, err
120-
}
121-
// get info
122-
info, err = os.Stat(fsPath)
123-
if err != nil {
124-
return nil, err
125-
}
126-
} else {
127-
if err != nil {
128-
return nil, err
129-
}
130-
131-
for _, entry := range fMan.entries {
132-
if os.SameFile(info, entry.info) {
133-
return entry.ch, nil
27+
var ch chan<- []byte
28+
file, info, err = getFileInfoIfNotMatch(fsPath, func(info os.FileInfo) bool {
29+
for _, dest := range fMan.dests {
30+
if os.SameFile(info, dest.info) {
31+
ch = dest.ch
32+
return true
13433
}
13534
}
35+
return false
36+
})
13637

137-
// use existing info, get file
138-
file, err = openLogFile(fsPath)
139-
if err != nil {
140-
return nil, err
141-
}
38+
if err != nil {
39+
return nil, err
40+
}
41+
42+
if ch != nil {
43+
return ch, nil
14244
}
14345
} else { // Stdout or Stderr
144-
for _, entry := range fMan.entries {
145-
if file == entry.file {
146-
return entry.ch, nil
46+
for _, dest := range fMan.dests {
47+
if file == dest.file {
48+
return dest.ch, nil
14749
}
14850
}
14951

15052
fsPath = file.Name()
15153
}
15254

153-
entry := newFileEntry(fsPath, info, file)
154-
fMan.entries = append(fMan.entries, entry)
55+
dest := newFileDest(fsPath, file, info)
56+
fMan.dests = append(fMan.dests, dest)
15557

15658
fMan.wg.Add(1)
15759
go func() {
158-
entry.serve()
60+
dest.serve()
15961
fMan.wg.Done()
16062
}()
16163

162-
return entry.ch, nil
64+
return dest.ch, nil
16365
}
16466

16567
func (fMan *FileMan) Reopen() []error {
16668
var errs []error
16769

168-
for _, entry := range fMan.entries {
169-
err := entry.reopen()
70+
for _, dest := range fMan.dests {
71+
err := dest.reopen()
17072
if err != nil {
17173
errs = append(errs, err)
17274
}
@@ -176,14 +78,53 @@ func (fMan *FileMan) Reopen() []error {
17678
}
17779

17880
func (fMan *FileMan) Close() {
179-
for _, entry := range fMan.entries {
180-
entry.close()
81+
for _, dest := range fMan.dests {
82+
dest.close()
18183
}
18284
fMan.wg.Wait()
18385
}
18486

87+
func (fMan *FileMan) newLogChan(fsPath string, dashFile *os.File) (loggerChan, error) {
88+
var ch chan<- []byte
89+
var err error
90+
91+
if len(fsPath) > 0 {
92+
if fsPath == "-" {
93+
ch, err = fMan.getWritingCh("", dashFile)
94+
} else {
95+
ch, err = fMan.getWritingCh(fsPath, nil)
96+
}
97+
98+
if err != nil {
99+
return nil, err
100+
}
101+
}
102+
103+
return ch, nil
104+
}
105+
185106
func (fMan *FileMan) NewLogger(accLogFilename, errLogFilename string) (*Logger, []error) {
186-
return newLogger(fMan, accLogFilename, errLogFilename)
107+
var errs []error
108+
109+
accChan, err := fMan.newLogChan(accLogFilename, os.Stdout)
110+
if err != nil {
111+
errs = append(errs, err)
112+
}
113+
114+
errChan, err := fMan.newLogChan(errLogFilename, os.Stderr)
115+
if err != nil {
116+
errs = append(errs, err)
117+
}
118+
119+
if len(errs) > 0 {
120+
return nil, errs
121+
}
122+
123+
logger := &Logger{
124+
acc: accChan,
125+
err: errChan,
126+
}
127+
return logger, nil
187128
}
188129

189130
func NewFileMan() *FileMan {

0 commit comments

Comments
 (0)