(args []string)
| 52 | } |
| 53 | |
| 54 | func LogOutputOption(args []string) (log.Output, error) { |
| 55 | outs := make([]log.Output, 0, len(args)) |
| 56 | for i, arg := range args { |
| 57 | switch arg { |
| 58 | case "stderr": |
| 59 | outs = append(outs, log.WriterOutput(os.Stderr, false)) |
| 60 | case "stderr_ts": |
| 61 | outs = append(outs, log.WriterOutput(os.Stderr, true)) |
| 62 | case "syslog": |
| 63 | syslogOut, err := log.SyslogOutput() |
| 64 | if err != nil { |
| 65 | return nil, fmt.Errorf("failed to connect to syslog daemon: %v", err) |
| 66 | } |
| 67 | outs = append(outs, syslogOut) |
| 68 | case "off": |
| 69 | if len(args) != 1 { |
| 70 | return nil, errors.New("'off' can't be combined with other log targets") |
| 71 | } |
| 72 | return log.NopOutput{}, nil |
| 73 | default: |
| 74 | // log file paths are converted to absolute to make sure |
| 75 | // we will be able to recreate them in right location |
| 76 | // after changing working directory to the state dir. |
| 77 | absPath, err := filepath.Abs(arg) |
| 78 | if err != nil { |
| 79 | return nil, err |
| 80 | } |
| 81 | // We change the actual argument, so logOut object will |
| 82 | // keep the absolute path for reinitialization. |
| 83 | args[i] = absPath |
| 84 | |
| 85 | w, err := os.OpenFile(absPath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0o666) |
| 86 | if err != nil { |
| 87 | return nil, fmt.Errorf("failed to create log file: %v", err) |
| 88 | } |
| 89 | |
| 90 | outs = append(outs, log.WriteCloserOutput(w, true)) |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | if len(outs) == 1 { |
| 95 | return logOut{args, outs[0]}, nil |
| 96 | } |
| 97 | return logOut{args, log.MultiOutput(outs...)}, nil |
| 98 | } |
| 99 | |
| 100 | func defaultLogOutput() (interface{}, error) { |
| 101 | return nil, nil |
no test coverage detected