15
15
package logging
16
16
17
17
import (
18
+ "encoding/json"
18
19
"fmt"
19
20
"io"
20
21
"math"
@@ -33,6 +34,43 @@ func init() {
33
34
caddy .RegisterModule (FileWriter {})
34
35
}
35
36
37
+ // fileMode is a string made of 1 to 4 octal digits representing
38
+ // a numeric mode as specified with the `chmod` unix command.
39
+ // `"0777"` and `"777"` are thus equivalent values.
40
+ type fileMode os.FileMode
41
+
42
+ // UnmarshalJSON satisfies json.Unmarshaler.
43
+ func (m * fileMode ) UnmarshalJSON (b []byte ) error {
44
+ if len (b ) == 0 {
45
+ return io .EOF
46
+ }
47
+
48
+ var s string
49
+ if err := json .Unmarshal (b , & s ); err != nil {
50
+ return err
51
+ }
52
+
53
+ mode , err := parseFileMode (s )
54
+ if err != nil {
55
+ return err
56
+ }
57
+
58
+ * m = fileMode (mode )
59
+ return err
60
+ }
61
+
62
+ // parseFileMode parses a file mode string,
63
+ // adding support for `chmod` unix command like
64
+ // 1 to 4 digital octal values.
65
+ func parseFileMode (s string ) (os.FileMode , error ) {
66
+ modeStr := fmt .Sprintf ("%04s" , s )
67
+ mode , err := strconv .ParseUint (modeStr , 8 , 32 )
68
+ if err != nil {
69
+ return 0 , err
70
+ }
71
+ return os .FileMode (mode ), nil
72
+ }
73
+
36
74
// FileWriter can write logs to files. By default, log files
37
75
// are rotated ("rolled") when they get large, and old log
38
76
// files get deleted, to ensure that the process does not
@@ -41,6 +79,10 @@ type FileWriter struct {
41
79
// Filename is the name of the file to write.
42
80
Filename string `json:"filename,omitempty"`
43
81
82
+ // The file permissions mode.
83
+ // 0600 by default.
84
+ Mode fileMode `json:"mode,omitempty"`
85
+
44
86
// Roll toggles log rolling or rotation, which is
45
87
// enabled by default.
46
88
Roll * bool `json:"roll,omitempty"`
@@ -100,6 +142,10 @@ func (fw FileWriter) WriterKey() string {
100
142
101
143
// OpenWriter opens a new file writer.
102
144
func (fw FileWriter ) OpenWriter () (io.WriteCloser , error ) {
145
+ if fw .Mode == 0 {
146
+ fw .Mode = 0o600
147
+ }
148
+
103
149
// roll log files by default
104
150
if fw .Roll == nil || * fw .Roll {
105
151
if fw .RollSizeMB == 0 {
@@ -116,6 +162,9 @@ func (fw FileWriter) OpenWriter() (io.WriteCloser, error) {
116
162
fw .RollKeepDays = 90
117
163
}
118
164
165
+ f_tmp , _ := os .OpenFile (fw .Filename , os .O_WRONLY | os .O_APPEND | os .O_CREATE , os .FileMode (fw .Mode ))
166
+ f_tmp .Close ()
167
+
119
168
return & lumberjack.Logger {
120
169
Filename : fw .Filename ,
121
170
MaxSize : fw .RollSizeMB ,
@@ -127,12 +176,13 @@ func (fw FileWriter) OpenWriter() (io.WriteCloser, error) {
127
176
}
128
177
129
178
// otherwise just open a regular file
130
- return os .OpenFile (fw .Filename , os .O_WRONLY | os .O_APPEND | os .O_CREATE , 0o666 )
179
+ return os .OpenFile (fw .Filename , os .O_WRONLY | os .O_APPEND | os .O_CREATE , os . FileMode ( fw . Mode ) )
131
180
}
132
181
133
182
// UnmarshalCaddyfile sets up the module from Caddyfile tokens. Syntax:
134
183
//
135
184
// file <filename> {
185
+ // mode <mode>
136
186
// roll_disabled
137
187
// roll_size <size>
138
188
// roll_uncompressed
@@ -150,7 +200,7 @@ func (fw FileWriter) OpenWriter() (io.WriteCloser, error) {
150
200
// The roll_keep_for duration has day resolution.
151
201
// Fractional values are rounded up to the next whole number of days.
152
202
//
153
- // If any of the roll_size, roll_keep, or roll_keep_for subdirectives are
203
+ // If any of the mode, roll_size, roll_keep, or roll_keep_for subdirectives are
154
204
// omitted or set to a zero value, then Caddy's default value for that
155
205
// subdirective is used.
156
206
func (fw * FileWriter ) UnmarshalCaddyfile (d * caddyfile.Dispenser ) error {
@@ -165,6 +215,17 @@ func (fw *FileWriter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
165
215
166
216
for d .NextBlock (0 ) {
167
217
switch d .Val () {
218
+ case "mode" :
219
+ var modeStr string
220
+ if ! d .AllArgs (& modeStr ) {
221
+ return d .ArgErr ()
222
+ }
223
+ mode , err := parseFileMode (modeStr )
224
+ if err != nil {
225
+ return d .Errf ("parsing mode: %v" , err )
226
+ }
227
+ fw .Mode = fileMode (mode )
228
+
168
229
case "roll_disabled" :
169
230
var f bool
170
231
fw .Roll = & f
0 commit comments