OpenWriter opens a new file writer.
()
| 185 | |
| 186 | // OpenWriter opens a new file writer. |
| 187 | func (fw FileWriter) OpenWriter() (io.WriteCloser, error) { |
| 188 | modeIfCreating := os.FileMode(fw.Mode) |
| 189 | if modeIfCreating == 0 { |
| 190 | modeIfCreating = 0o600 |
| 191 | } |
| 192 | |
| 193 | // roll log files as a sensible default to avoid disk space exhaustion |
| 194 | roll := fw.Roll == nil || *fw.Roll |
| 195 | |
| 196 | // Ensure directory exists before opening the file. |
| 197 | dirPath := filepath.Dir(fw.Filename) |
| 198 | switch strings.ToLower(strings.TrimSpace(fw.DirMode)) { |
| 199 | case "", "0": |
| 200 | // Preserve current behavior: locked-down directories by default. |
| 201 | if err := os.MkdirAll(dirPath, 0o700); err != nil { |
| 202 | return nil, err |
| 203 | } |
| 204 | case "inherit": |
| 205 | if err := mkdirAllInherit(dirPath); err != nil { |
| 206 | return nil, err |
| 207 | } |
| 208 | case "from_file": |
| 209 | if err := mkdirAllFromFile(dirPath, os.FileMode(fw.Mode)); err != nil { |
| 210 | return nil, err |
| 211 | } |
| 212 | default: |
| 213 | dm, err := parseFileMode(fw.DirMode) |
| 214 | if err != nil { |
| 215 | return nil, fmt.Errorf("dir_mode: %w", err) |
| 216 | } |
| 217 | if err := os.MkdirAll(dirPath, dm); err != nil { |
| 218 | return nil, err |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | // create/open the file |
| 223 | file, err := os.OpenFile(fw.Filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, modeIfCreating) |
| 224 | if err != nil { |
| 225 | return nil, err |
| 226 | } |
| 227 | info, err := file.Stat() |
| 228 | if roll { |
| 229 | file.Close() // timberjack will reopen it on its own |
| 230 | } |
| 231 | |
| 232 | // Ensure already existing files have the right mode, since OpenFile will not set the mode in such case. |
| 233 | if configuredMode := os.FileMode(fw.Mode); configuredMode != 0 { |
| 234 | if err != nil { |
| 235 | return nil, fmt.Errorf("unable to stat log file to see if we need to set permissions: %v", err) |
| 236 | } |
| 237 | // only chmod if the configured mode is different |
| 238 | if info.Mode()&os.ModePerm != configuredMode&os.ModePerm { |
| 239 | if err = os.Chmod(fw.Filename, configuredMode); err != nil { |
| 240 | return nil, err |
| 241 | } |
| 242 | } |
| 243 | } |
| 244 |