1- // fileMan maintains opened files shared by multiple logMan
1+ // fileMan maintains opened files shared by multiple loggerChan
22
33package serverLog
44
@@ -8,165 +8,67 @@ import (
88 "sync"
99)
1010
11- const chanBuffer = 128
1211const 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
2213type 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
10518func (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
16567func (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
17880func (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+
185106func (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
189130func NewFileMan () * FileMan {
0 commit comments