/
pipeline.go
146 lines (121 loc) · 3.25 KB
/
pipeline.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package vox
import (
"io"
"os"
"strings"
"github.com/spf13/afero"
)
var fs = afero.NewOsFs()
// PipelineConfig is the configuration for a pipeline
// The pipeline config should be returned from the Config function for any
// pipeline structure.
type PipelineConfig struct {
// Plain - If set to true all color information and some formatting will be
// stripped from the output. This is normally used for outputs directed towards
// files.
Plain bool
}
// Pipeline represents a specific log pipeline
type Pipeline interface {
Config() *PipelineConfig
Write([]byte) (int, error)
Initialize() error
}
// ConsolePipeline a log pipeline that outputs directly to STDERR
type ConsolePipeline struct{}
// Config returns the pipeline configuration
func (c *ConsolePipeline) Config() *PipelineConfig {
return &PipelineConfig{
Plain: false,
}
}
// Write sends data to the output Stdout
func (c *ConsolePipeline) Write(b []byte) (int, error) {
return os.Stdout.Write(b)
}
// Initialize has no logic for a ConsolePipeline
func (c *ConsolePipeline) Initialize() error {
return nil
}
// FilePipeline sends output into a local file
type FilePipeline struct {
Filepath string
file afero.File
}
//Close closes the file pointer
func (f *FilePipeline) Close() {
f.file.Close()
}
// Config returns the pipline configuration
func (f *FilePipeline) Config() *PipelineConfig {
return &PipelineConfig{
Plain: true,
}
}
// Write sends the data to the local filepath
func (f *FilePipeline) Write(b []byte) (int, error) {
num, err := f.file.Write(b)
if num > 0 {
f.file.Sync()
}
return num, err
}
// Initialize opens the local file for reading
func (f *FilePipeline) Initialize() error {
var err error
f.file, err = fs.OpenFile(f.Filepath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0700)
return err
}
// TestPipeline a pipeline that can be used in tests
type TestPipeline struct {
LogLines []string
Plain bool
}
// Config returns the pipline configuration
func (t *TestPipeline) Config() *PipelineConfig {
return &PipelineConfig{
Plain: t.Plain,
}
}
func (t *TestPipeline) Write(b []byte) (int, error) {
t.LogLines = append(t.LogLines, string(b))
return len(b), nil
}
// Initialize sets up the testing pipeline
func (t *TestPipeline) Initialize() error {
t.LogLines = []string{}
return nil
}
// All returns all output data
func (t *TestPipeline) All() string {
return strings.Join(t.LogLines, "")
}
// Last returns the last section of data sent
func (t *TestPipeline) Last() string {
if len(t.LogLines) == 0 {
return ""
}
return t.LogLines[len(t.LogLines)-1]
}
// Clear removes all items in the pipelines buffer
func (t *TestPipeline) Clear() {
t.LogLines = []string{}
}
// WriterPipeline implements a generic pipeline powered by an io.Writer stream
type WriterPipeline struct {
Writer io.Writer
Plain bool
}
// Config returns a configuration for the pipeline. Plain is specified on the
// pipeline itself and patched into the configuration.
func (w *WriterPipeline) Config() *PipelineConfig {
return &PipelineConfig{Plain: w.Plain}
}
// Write sends data into the specified writer.
func (w *WriterPipeline) Write(b []byte) (int, error) {
return w.Writer.Write(b)
}
// Initialize has no logic in a WriterPipeline
func (w *WriterPipeline) Initialize() error {
return nil
}