@@ -2,10 +2,8 @@ package main
22
33import (
44 "encoding/csv"
5- "encoding/json"
65 "fmt"
76 "io"
8- "io/ioutil"
97 "log"
108 "os"
119 "strconv"
@@ -18,24 +16,33 @@ import (
1816)
1917
2018var options struct {
21- States int `long:"states" default:"4"`
22- BufferSize int `long:"buffersize" default:"10"`
23- History int `long:"history" default:"1"`
24- FilterStdDevs int `long:"filterstddevs" default:"2"`
25- FixedBound bool `long:"fixedbound"`
26- FixedMin float64 `long:"fixedmin" default:"0" description:"if fixedbound is set, set the min value"`
27- FixedMax float64 `long:"fixedmax" default:"100" description:"if fixedbound is set, set the max value"`
28- PeriodSize string `long:"periodsize" default:"" description:"comma separated list of ints, specifies descrete states per period"`
29- PeriodChangeRatio float64 `long:"periodchangeratio" default:"0.2" description:"accepted ratio [0,1] for changes, alert if above"`
30- PhaseChangeLikeliness float32 `long:"phasechangelikeliness" default:"0.6"`
31- PhaseChangeMincount int64 `long:"phasechangemincount" default:"60"`
32- Outputfile string `long:"output" default:"-" description:"path to write profile to, stdout if '-'"`
33- PhasesFile string `long:"out.phases" default:""`
34- Inputfile string
19+ States int `long:"states" default:"4"`
20+ BufferSize int `long:"buffersize" default:"10"`
21+ History int `long:"history" default:"1"`
22+ FilterStdDevs int `long:"filterstddevs" default:"2"`
23+
24+ FixedBound bool `long:"fixedbound"`
25+ FixedMin float64 `long:"fixedmin" default:"0" description:"if fixedbound is set, set the min value"`
26+ FixedMax float64 `long:"fixedmax" default:"100" description:"if fixedbound is set, set the max value"`
27+
28+ PeriodSize string `long:"periodsize" default:"" description:"comma separated list of ints, specifies descrete states per period"`
29+
30+ PhaseChangeLikeliness float32 `long:"phasechangelikeliness" default:""`
31+ PhaseChangeHistory int64 `long:"phasechangehistory" default:"1"`
32+
33+ Outputfile string `long:"output" default:"-" description:"path to write profile to, stdout if '-'"`
34+ Historyfile string `long:"out.history" default:"" description:"path to write last historic values to, stdout if '-', empty to disable"`
35+ PhasesFile string `long:"out.phases" default:""`
36+ PeriodsFile string `long:"out.periods" default:""`
37+ StatesFile string `long:"out.states" default:""`
38+
39+ Inputfile string
3540}
3641
3742var tsprofiler api.TSProfiler
3843var phasesfile * os.File
44+ var periodsfile * os.File
45+ var statesfile * os.File
3946
4047func main () {
4148 initializeFlags ()
@@ -46,18 +53,40 @@ func main() {
4653 // create & open output file
4754 if options .PhasesFile != "" && options .PhasesFile != "-" {
4855 var err error
49- phasesfile , err = os .OpenFile (options .PhasesFile , os .O_APPEND | os .O_CREATE | os .O_WRONLY , 0644 )
56+ phasesfile , err = os .OpenFile (options .PhasesFile , os .O_TRUNC | os .O_CREATE | os .O_WRONLY , 0644 )
5057 if err != nil {
5158 log .Fatal (err )
5259 }
5360 defer phasesfile .Close ()
5461 }
62+ if options .PeriodsFile != "" && options .PeriodsFile != "-" {
63+ var err error
64+ periodsfile , err = os .OpenFile (options .PeriodsFile , os .O_TRUNC | os .O_CREATE | os .O_WRONLY , 0644 )
65+ if err != nil {
66+ log .Fatal (err )
67+ }
68+ defer periodsfile .Close ()
69+ }
70+ if options .StatesFile != "" && options .StatesFile != "-" {
71+ var err error
72+ statesfile , err = os .OpenFile (options .StatesFile , os .O_TRUNC | os .O_CREATE | os .O_WRONLY , 0644 )
73+ if err != nil {
74+ log .Fatal (err )
75+ }
76+ defer statesfile .Close ()
77+ }
5578
5679 // read file line by line
5780 readFile (options .Inputfile )
5881
5982 // get and print profile
60- profileOutput ()
83+ outputProfile ()
84+
85+ // print last states and positions
86+ if options .Historyfile != "" {
87+ outputHistory ()
88+ }
89+
6190}
6291
6392func initializeFlags () {
@@ -111,7 +140,7 @@ func initProfiler() {
111140 FixBound : options .FixedBound ,
112141 PeriodSize : periodSize ,
113142 PhaseChangeLikeliness : options .PhaseChangeLikeliness ,
114- PhaseChangeMincount : options .PhaseChangeMincount ,
143+ PhaseChangeHistory : options .PhaseChangeHistory ,
115144 })
116145}
117146
@@ -160,41 +189,57 @@ func putMeasurement(utilValue []float64) {
160189 }
161190 tsprofiler .Put (tsinput )
162191
163- //state := tsprofiler.GetCurrentState()
192+ // print phases
164193 phaseid := tsprofiler .GetCurrentPhase ()
165- // handle phases output
166- row := fmt .Sprintf ("%d\n " , phaseid )
167194 if options .PhasesFile == "-" {
168195 // use stdout
196+ row := fmt .Sprintf ("%d\n " , phaseid )
169197 fmt .Print (row )
170198 } else if options .PhasesFile == "" {
171199 // ignore likeliness
172200 } else {
173201 // print to file
202+ row := fmt .Sprintf ("%d\n " , phaseid )
174203 if _ , err := phasesfile .Write ([]byte (row )); err != nil {
175204 log .Fatal (err )
176205 }
177206 }
178- }
179207
180- func profileOutput () {
181- profile := tsprofiler .Get ()
182- json , err := json .Marshal (profile )
183- if err != nil {
184- fmt .Printf ("cannot create json: %s (original: %+v)\n " , err , profile )
185- return
208+ // print periods
209+ periodPath := strings .Trim (strings .Replace (fmt .Sprint (tsprofiler .GetCurrentPeriodPath ()), " " , "," , - 1 ), "[]" )
210+ if options .PeriodsFile == "-" {
211+ // use stdout
212+ row := fmt .Sprintf ("%s\n " , periodPath )
213+ fmt .Print (row )
214+ } else if options .PeriodsFile == "" {
215+ // ignore
216+ } else {
217+ // print to file
218+ row := fmt .Sprintf ("%s\n " , periodPath )
219+ if _ , err := periodsfile .Write ([]byte (row )); err != nil {
220+ log .Fatal (err )
221+ }
186222 }
187223
188- if options .Outputfile == "-" {
189- // print to stdout
190- fmt .Printf ("%s\n " , json )
224+ // print states
225+ state := tsprofiler .GetCurrentState ()
226+ stateRow := ""
227+ for _ , s := range state {
228+ if stateRow != "" {
229+ stateRow = stateRow + " "
230+ }
231+ stateRow = fmt .Sprintf ("%s%d" , stateRow , s .State .Value )
232+ }
233+ stateRow = stateRow + "\n "
234+ if options .StatesFile == "-" {
235+ // use stdout
236+ fmt .Print (stateRow )
237+ } else if options .StatesFile == "" {
238+ // ignore
191239 } else {
192- // write to file
193- err := ioutil .WriteFile (options .Outputfile , json , 0644 )
194- if err != nil {
195- fmt .Printf ("cannot write json to file %s: %s\n " , options .Outputfile , err )
196- return
240+ // print to file
241+ if _ , err := statesfile .Write ([]byte (stateRow )); err != nil {
242+ log .Fatal (err )
197243 }
198244 }
199-
200245}
0 commit comments