Skip to content

Commit ecf537e

Browse files
authored
Merge pull request #6 from cha87de/improve-phases
improve phases and periods
2 parents bf371e1 + dab3eeb commit ecf537e

File tree

26 files changed

+1705
-330
lines changed

26 files changed

+1705
-330
lines changed

api/tsprofiler.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ type TSProfiler interface {
1313
// Get generates an returns a profile based on previously put data
1414
Get() models.TSProfile
1515

16-
GetCurrentState() map[string]models.TSStats
16+
GetCurrentStats() map[string]models.TSStats
17+
GetCurrentState() []models.TSState
1718
GetCurrentPhase() int
19+
GetCurrentPeriodPath() []int
1820

1921
// Terminate stops and removes the profiler
2022
Terminate()

cmd/csv2tsprofile/main.go

Lines changed: 83 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ package main
22

33
import (
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

2018
var 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

3742
var tsprofiler api.TSProfiler
3843
var phasesfile *os.File
44+
var periodsfile *os.File
45+
var statesfile *os.File
3946

4047
func 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

6392
func 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
}

cmd/csv2tsprofile/output.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"io/ioutil"
7+
8+
"github.com/cha87de/tsprofiler/models"
9+
)
10+
11+
func outputHistory() {
12+
if options.Historyfile == "" {
13+
// output disabled, ignore method call
14+
return
15+
}
16+
state := tsprofiler.GetCurrentState()
17+
historicStates := make([]map[string]string, 1)
18+
historicStates[0] = make(map[string]string)
19+
for _, s := range state {
20+
historicStates[0][s.Metric] = fmt.Sprintf("%d", s.State.Value)
21+
}
22+
23+
history := models.History{
24+
CurrentPhase: tsprofiler.GetCurrentPhase(),
25+
PeriodPath: tsprofiler.GetCurrentPeriodPath(),
26+
HistoricStates: historicStates,
27+
}
28+
29+
json, err := json.Marshal(history)
30+
if err != nil {
31+
fmt.Printf("cannot create json: %s (original: %+v)\n", err, history)
32+
return
33+
}
34+
35+
// print to stdout
36+
if options.Historyfile == "-" {
37+
// print to stdout
38+
fmt.Printf("%s\n", json)
39+
} else {
40+
// write to file
41+
err := ioutil.WriteFile(options.Historyfile, json, 0644)
42+
if err != nil {
43+
fmt.Printf("cannot write json to file %s: %s\n", options.Historyfile, err)
44+
return
45+
}
46+
}
47+
}
48+
49+
func outputProfile() {
50+
profile := tsprofiler.Get()
51+
json, err := json.Marshal(profile)
52+
if err != nil {
53+
fmt.Printf("cannot create json: %s (original: %+v)\n", err, profile)
54+
return
55+
}
56+
57+
if options.Outputfile == "-" {
58+
// print to stdout
59+
fmt.Printf("%s\n", json)
60+
} else {
61+
// write to file
62+
err := ioutil.WriteFile(options.Outputfile, json, 0644)
63+
if err != nil {
64+
fmt.Printf("cannot write json to file %s: %s\n", options.Outputfile, err)
65+
return
66+
}
67+
}
68+
}

cmd/tspredictor/main.go

Lines changed: 33 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package main
33
import (
44
"fmt"
55
"os"
6+
"strings"
7+
8+
"github.com/cha87de/tsprofiler/cmd/tspredictor/task"
69

710
"github.com/cha87de/tsprofiler/models"
811
"github.com/cha87de/tsprofiler/predictor"
@@ -11,30 +14,46 @@ import (
1114
)
1215

1316
var options struct {
14-
Steps int `long:"steps" default:"40"`
15-
Mode predictor.PredictionMode `long:"mode" default:"0"`
16-
Inputfile string
17+
Steps int `long:"steps" default:"40"`
18+
Mode predictor.PredictionMode `long:"mode" default:"0"`
19+
PeriodDepth int `long:"periodDepth" default:"0"`
20+
Profilefile string `long:"profile" short:"p"`
21+
Historyfile string `long:"history" short:"h"`
22+
Task string
1723
}
1824

1925
func main() {
2026
initializeFlags()
2127

22-
profile := utils.ReadProfileFromFile(options.Inputfile)
23-
predictor := predictor.NewPredictor(profile)
24-
predictor.SetMode(options.Mode)
25-
/*predictor.SetState(map[string]string{
26-
"metric_0": "0",
27-
})*/
28-
simulation := predictor.Simulate(options.Steps)
28+
profile := utils.ReadProfileFromFile(options.Profilefile)
29+
history := models.ReadHistoryFromFile(options.Historyfile)
30+
31+
var err error
2932

30-
printSimulation(simulation)
33+
switch options.Task {
34+
case "simulate":
35+
simulate := task.NewSimulate(profile, options.Mode, history)
36+
err = simulate.Run(options.Steps, options.PeriodDepth)
37+
simulate.Print()
38+
case "likeliness":
39+
likeliness := task.NewLikeliness(profile, options.Mode, history)
40+
likeliness.Run(options.PeriodDepth)
41+
default:
42+
fmt.Printf("task %s unknown. Select \"simulate\" or \"likeliness\" as task.", options.Task)
43+
}
44+
45+
if err != nil {
46+
fmt.Fprintf(os.Stderr, "%s", err)
47+
os.Exit(1)
48+
}
49+
os.Exit(0)
3150
}
3251

3352
func initializeFlags() {
3453
// initialize parser for flags
3554
parser := flags.NewParser(&options, flags.Default)
3655
parser.ShortDescription = "tspredictor"
37-
parser.LongDescription = "Simulates the next steps for a given tsprofile json file"
56+
parser.LongDescription = "Reads a TSProfile from file and runs tasks on in (Simulate or Likeliness)"
3857
parser.ArgsRequired = true
3958

4059
// Parse parameters
@@ -53,34 +72,8 @@ func initializeFlags() {
5372
}
5473

5574
if len(args) < 1 {
56-
fmt.Printf("No input file specified.\n")
75+
fmt.Printf("No task specified. Select \"simulate\" or \"likeliness\" as task.\n")
5776
os.Exit(1)
5877
}
59-
options.Inputfile = args[0]
60-
}
61-
62-
func printSimulation(simulation [][]models.TSState) {
63-
if len(simulation) <= 0 {
64-
return
65-
}
66-
67-
// print header
68-
for i, tsstate := range simulation[0] {
69-
if i > 0 {
70-
fmt.Printf(",")
71-
}
72-
fmt.Printf("%s", tsstate.Metric)
73-
}
74-
fmt.Printf("\n")
75-
76-
// print rows
77-
for _, simstep := range simulation {
78-
for i, tsstate := range simstep {
79-
if i > 0 {
80-
fmt.Printf(",")
81-
}
82-
fmt.Printf("%d", tsstate.State.Value)
83-
}
84-
fmt.Printf("\n")
85-
}
78+
options.Task = strings.ToLower(args[0])
8679
}

0 commit comments

Comments
 (0)