Skip to content

Commit

Permalink
Add component type cpu and memory
Browse files Browse the repository at this point in the history
  • Loading branch information
teeratpitakrat committed Mar 20, 2017
1 parent ab63a37 commit 205ba92
Show file tree
Hide file tree
Showing 14 changed files with 139 additions and 76 deletions.
4 changes: 3 additions & 1 deletion adm/adm.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ type ADM map[string]DependencyInfo
type Component struct {
Name string `json:"name"`
Hostname string `json:"hostname"`
Type string `json:"type"`
}

func New() ADM {
return make(ADM)
}

func (c *Component) UniqName() string {
name := c.Hostname + "_" + c.Name
name := c.Type + "_" + c.Hostname + "_" + c.Name
// TODO: use strings.Replacer
name = strings.Replace(name, ".", "_", -1)
name = strings.Replace(name, ",", "_", -1)
name = strings.Replace(name, ";", "_", -1)
Expand Down
16 changes: 8 additions & 8 deletions adm/adm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import (
func TestADMSmall(t *testing.T) {
m := New()

compA := Component{"method1()", "host-1"}
compB := Component{"method2(param)", "host-2"}
compC := Component{"method3()", "host-3"}
compD := Component{"method4(param1, param2)", "host-4"}
compA := Component{"method1()", "host-1", "responsetime"}
compB := Component{"method2(param)", "host-2", "responsetime"}
compC := Component{"method3()", "host-3", "responsetime"}
compD := Component{"method4(param1, param2)", "host-4", "responsetime"}

depA := DependencyInfo{compA, make([]Dependency, 2, 2)}
depA.Component = compA
Expand Down Expand Up @@ -39,26 +39,26 @@ func TestADMSmall(t *testing.T) {
if len(v.Dependencies) != expected {
t.Error("Expected: ", expected, " but got ", len(v.Dependencies))
}
if v.Dependencies[0].Component.UniqName() != "host_2_method2_param_" || v.Dependencies[0].Weight != 0.5 {
if v.Dependencies[0].Component.UniqName() != "responsetime_host_2_method2_param_" || v.Dependencies[0].Weight != 0.5 {
t.Error("Wrong value")
}
if v.Dependencies[1].Component.UniqName() != "host_3_method3__" || v.Dependencies[1].Weight != 0.5 {
if v.Dependencies[1].Component.UniqName() != "responsetime_host_3_method3__" || v.Dependencies[1].Weight != 0.5 {
t.Error("Wrong value")
}
case compB.UniqName():
expected := 1
if len(v.Dependencies) != expected {
t.Error("Expected: ", expected, " but got ", len(v.Dependencies))
}
if v.Dependencies[0].Component.UniqName() != "host_4_method4_param1__param2_" || v.Dependencies[0].Weight != 1 {
if v.Dependencies[0].Component.UniqName() != "responsetime_host_4_method4_param1__param2_" || v.Dependencies[0].Weight != 1 {
t.Error("Wrong value")
}
case compC.UniqName():
expected := 1
if len(v.Dependencies) != expected {
t.Error("Expected: ", expected, " but got ", len(v.Dependencies))
}
if v.Dependencies[0].Component.UniqName() != "host_4_method4_param1__param2_" || v.Dependencies[0].Weight != 1 {
if v.Dependencies[0].Component.UniqName() != "responsetime_host_4_method4_param1__param2_" || v.Dependencies[0].Weight != 1 {
t.Error("Wrong value")
}
case compD.UniqName():
Expand Down
8 changes: 4 additions & 4 deletions adm/fileio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import (
func TestReadWriteFile(t *testing.T) {
// Export
m := New()
compA := Component{"method1()", "host-1"}
compB := Component{"method2(param)", "host-2"}
compC := Component{"method3()", "host-3"}
compD := Component{"method4(param1, param2)", "host-4"}
compA := Component{"method1()", "host-1", "responsetime"}
compB := Component{"method2(param)", "host-2", "responsetime"}
compC := Component{"method3()", "host-3", "responsetime"}
compD := Component{"method4(param1, param2)", "host-4", "responsetime"}

depA := DependencyInfo{compA, make([]Dependency, 2, 2)}
depA.Component = compA
Expand Down
8 changes: 4 additions & 4 deletions adm/netio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ func TestNetReader(t *testing.T) {

m := New()

compA := Component{"method1()", "host-1"}
compB := Component{"method2(param)", "host-2"}
compC := Component{"method3()", "host-3"}
compD := Component{"method4(param1, param2)", "host-4"}
compA := Component{"method1()", "host-1", "responsetime"}
compB := Component{"method2(param)", "host-2", "responsetime"}
compC := Component{"method3()", "host-3", "responsetime"}
compD := Component{"method4(param1, param2)", "host-4", "responsetime"}

depA := DependencyInfo{compA, make([]Dependency, 2, 2)}
depA.Component = compA
Expand Down
4 changes: 2 additions & 2 deletions cfp/arima-r_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
var testdat = []float64{60, 43, 67, 50, 56, 42, 50, 65, 68, 43, 65, 34, 47, 34, 49, 41, 13, 35, 53, 56}

func TestInsert(t *testing.T) {
c := adm.Component{"A", "host1"}
c := adm.Component{"A", "host1", "responsetime"}
a, err := NewArimaR(c, time.Minute, 5*time.Minute, 20*time.Minute, 70)
if err != nil {
t.Error("Error getting new ArimaR", err)
Expand All @@ -34,7 +34,7 @@ func TestInsert(t *testing.T) {
}

func TestPredict(t *testing.T) {
c := adm.Component{"A", "host1"}
c := adm.Component{"A", "host1", "responsetime"}
a, err := NewArimaR(c, time.Minute, 5*time.Minute, 20*time.Minute, 70)
if err != nil {
t.Error("Error getting new ArimaR", err)
Expand Down
31 changes: 25 additions & 6 deletions cfp/cfp.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,32 @@ func (c *CfpController) start() {
// TODO: choose predictor based on component type
interval := viper.GetDuration("prediction.interval")
leadtime := viper.GetDuration("prediction.leadtime")
history := viper.GetDuration("cfp.responsetime.history")
threshold := float64(viper.GetDuration("cfp.responsetime.threshold") / viper.GetDuration("cfp.responsetime.unit"))
cfp, err = NewArimaR(comp, interval, leadtime, history, threshold)
if err != nil {
log.Print(err)
switch comp.Type {
case "responsetime":
history := viper.GetDuration("cfp.responsetime.history")
threshold := float64(viper.GetDuration("cfp.responsetime.threshold") / viper.GetDuration("cfp.responsetime.unit"))
cfp, err = NewArimaR(comp, interval, leadtime, history, threshold)
if err != nil {
log.Print(err)
}
c.cfps[comp.UniqName()] = cfp
case "cpu":
history := viper.GetDuration("cfp.cpu.history")
threshold := viper.GetFloat64("cfp.cpu.threshold")
cfp, err = NewArimaR(comp, interval, leadtime, history, threshold)
if err != nil {
log.Print(err)
}
c.cfps[comp.UniqName()] = cfp
case "memory":
history := viper.GetDuration("cfp.memory.history")
threshold := viper.GetFloat64("cfp.memory.threshold")
cfp, err = NewArimaR(comp, interval, leadtime, history, threshold)
if err != nil {
log.Print(err)
}
c.cfps[comp.UniqName()] = cfp
}
c.cfps[comp.UniqName()] = cfp
}
cfp.Insert(tsPoint)
res, err := cfp.Predict()
Expand Down
12 changes: 10 additions & 2 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,24 @@ title = "Hora configuration"
[cfp]
[cfp.responsetime]
unit = "1ns"
threshold = "500ms"
threshold = "100ms"
predictor = "arima"
history = "20m"
aggregation = "percentile"
aggregationvalue = 95
[cfp.errorrate]
[cfp.cpu]
threshold = 1000
predictor = "arima"
history = "20m"
aggregation = "percentile"
aggregationvalue = 95
[cfp.memory]
threshold = 100
threshold = 2000000000
predictor = "arima"
history = "20m"
aggregation = "percentile"
aggregationvalue = 95
[fpm]
updateinterval = "10ms"
[rserve]
Expand Down
7 changes: 7 additions & 0 deletions fpm/bayesnet-r.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ func NewBayesNetR(m adm.ADM) (BayesNetR, <-chan Result, error) {
}

func (f *BayesNetR) createBayesNet() error {
// See documentation of bnlearn package in R for more details
// Example: https://rstudio-pubs-static.s3.amazonaws.com/124744_09170b0a7e414cb8bf492daa6773f2fe.html
// and http://sujitpal.blogspot.de/2013/07/bayesian-network-inference-with-r-and.html

// Create structure
cmd := "net <- model2network(\""
for _, v := range f.admodel {
Expand Down Expand Up @@ -105,6 +109,9 @@ func (f *BayesNetR) createBayesNet() error {
for i, mask := 0, 1; i < nDeps; i, mask = i+1, mask<<1 {
if pState&mask > 0 {
failProb += v.Dependencies[nDeps-i-1].Weight
if failProb > 1.0 {
failProb = 1.0
}
}
}
cmd += ", " + strconv.FormatFloat(1-failProb, 'f', 6, 64)
Expand Down
62 changes: 31 additions & 31 deletions fpm/bayesnet-r_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import (
func TestCreate(t *testing.T) {
m := make(adm.ADM)

compA := adm.Component{"A", "host1"}
compB := adm.Component{"B", "host2"}
compC := adm.Component{"C", "host3"}
compD := adm.Component{"D", "host4"}
compA := adm.Component{"A", "host1", "responsetime"}
compB := adm.Component{"B", "host2", "responsetime"}
compC := adm.Component{"C", "host3", "responsetime"}
compD := adm.Component{"D", "host4", "responsetime"}

depA := adm.DependencyInfo{compA, make([]adm.Dependency, 2, 2)}
depA.Component = compA
Expand Down Expand Up @@ -46,124 +46,124 @@ func TestCreate(t *testing.T) {
t.Error("Error creating BayesNetR", err)
}

cfpResult := cfp.Result{adm.Component{"D", "host4"}, time.Unix(0, 0), time.Unix(0, 300), 0.0}
cfpResult := cfp.Result{adm.Component{"D", "host4", "responsetime"}, time.Unix(0, 0), time.Unix(0, 300), 0.0}
f.UpdateCfpResult(cfpResult)
fpmResult := <-fpmResultCh
if err != nil {
t.Error("Error making prediction", err)
}
// TODO: more precision checks
fprobA := fpmResult.FailProbs[adm.Component{"A", "host1"}]
fprobA := fpmResult.FailProbs[adm.Component{"A", "host1", "responsetime"}]
if fprobA != 0 {
t.Error("Expected: 0 but got", fprobA)
}
fprobB := fpmResult.FailProbs[adm.Component{"B", "host2"}]
fprobB := fpmResult.FailProbs[adm.Component{"B", "host2", "responsetime"}]
if fprobB != 0 {
t.Error("Expected: 0 but got", fprobB)
}
fprobC := fpmResult.FailProbs[adm.Component{"C", "host3"}]
fprobC := fpmResult.FailProbs[adm.Component{"C", "host3", "responsetime"}]
if fprobC != 0 {
t.Error("Expected: 0 but got", fprobC)
}
fprobD := fpmResult.FailProbs[adm.Component{"D", "host4"}]
fprobD := fpmResult.FailProbs[adm.Component{"D", "host4", "responsetime"}]
if fprobD != 0 {
t.Error("Expected: 0 but got", fprobD)
}

cfpResult = cfp.Result{adm.Component{"D", "host4"}, time.Unix(0, 0), time.Unix(0, 300), 0.1}
cfpResult = cfp.Result{adm.Component{"D", "host4", "responsetime"}, time.Unix(0, 0), time.Unix(0, 300), 0.1}
f.UpdateCfpResult(cfpResult)
fpmResult = <-fpmResultCh
if err != nil {
t.Error("Error making prediction", err)
}
fprobA = fpmResult.FailProbs[adm.Component{"A", "host1"}]
fprobA = fpmResult.FailProbs[adm.Component{"A", "host1", "responsetime"}]
if fprobA > 0.12 {
t.Error("Expected: 0 but got", fprobA)
}
fprobB = fpmResult.FailProbs[adm.Component{"B", "host2"}]
fprobB = fpmResult.FailProbs[adm.Component{"B", "host2", "responsetime"}]
if fprobB > 0.12 {
t.Error("Expected: 0 but got", fprobB)
}
fprobC = fpmResult.FailProbs[adm.Component{"C", "host3"}]
fprobC = fpmResult.FailProbs[adm.Component{"C", "host3", "responsetime"}]
if fprobC > 0.12 {
t.Error("Expected: 0 but got", fprobC)
}
fprobD = fpmResult.FailProbs[adm.Component{"D", "host4"}]
fprobD = fpmResult.FailProbs[adm.Component{"D", "host4", "responsetime"}]
if fprobD > 0.12 {
t.Error("Expected: 0 but got", fprobD)
}

cfpResult = cfp.Result{adm.Component{"D", "host4"}, time.Unix(0, 0), time.Unix(0, 300), 0.9}
cfpResult = cfp.Result{adm.Component{"D", "host4", "responsetime"}, time.Unix(0, 0), time.Unix(0, 300), 0.9}
f.UpdateCfpResult(cfpResult)
fpmResult = <-fpmResultCh
if err != nil {
t.Error("Error making prediction", err)
}
fprobA = fpmResult.FailProbs[adm.Component{"A", "host1"}]
fprobA = fpmResult.FailProbs[adm.Component{"A", "host1", "responsetime"}]
if fprobA < 0.89 {
t.Error("Expected: 0 but got", fprobA)
}
fprobB = fpmResult.FailProbs[adm.Component{"B", "host2"}]
fprobB = fpmResult.FailProbs[adm.Component{"B", "host2", "responsetime"}]
if fprobB < 0.89 {
t.Error("Expected: 0 but got", fprobB)
}
fprobC = fpmResult.FailProbs[adm.Component{"C", "host3"}]
fprobC = fpmResult.FailProbs[adm.Component{"C", "host3", "responsetime"}]
if fprobC < 0.89 {
t.Error("Expected: 0 but got", fprobC)
}
fprobD = fpmResult.FailProbs[adm.Component{"D", "host4"}]
fprobD = fpmResult.FailProbs[adm.Component{"D", "host4", "responsetime"}]
if fprobD < 0.89 {
t.Error("Expected: 0 but got", fprobD)
}

cfpResultD := cfp.Result{adm.Component{"D", "host4"}, time.Unix(0, 0), time.Unix(0, 300), 0.0}
cfpResultD := cfp.Result{adm.Component{"D", "host4", "responsetime"}, time.Unix(0, 0), time.Unix(0, 300), 0.0}
f.UpdateCfpResult(cfpResultD)
fpmResult = <-fpmResultCh
cfpResultB := cfp.Result{adm.Component{"B", "host2"}, time.Unix(0, 0), time.Unix(0, 300), 0.1}
cfpResultB := cfp.Result{adm.Component{"B", "host2", "responsetime"}, time.Unix(0, 0), time.Unix(0, 300), 0.1}
f.UpdateCfpResult(cfpResultB)
fpmResult = <-fpmResultCh
if err != nil {
t.Error("Error making prediction", err)
}
fprobA = fpmResult.FailProbs[adm.Component{"A", "host1"}]
fprobA = fpmResult.FailProbs[adm.Component{"A", "host1", "responsetime"}]
if fprobA > 0.12 {
t.Error("Expected: 0 but got", fprobA)
}
fprobB = fpmResult.FailProbs[adm.Component{"B", "host2"}]
fprobB = fpmResult.FailProbs[adm.Component{"B", "host2", "responsetime"}]
if fprobB > 0.12 {
t.Error("Expected: 0 but got", fprobB)
}
fprobC = fpmResult.FailProbs[adm.Component{"C", "host3"}]
fprobC = fpmResult.FailProbs[adm.Component{"C", "host3", "responsetime"}]
if fprobC != 0 {
t.Error("Expected: 0 but got", fprobC)
}
fprobD = fpmResult.FailProbs[adm.Component{"D", "host4"}]
fprobD = fpmResult.FailProbs[adm.Component{"D", "host4", "responsetime"}]
if fprobD != 0 {
t.Error("Expected: 0 but got", fprobD)
}

cfpResultB = cfp.Result{adm.Component{"B", "host2"}, time.Unix(0, 0), time.Unix(0, 300), 0.0}
cfpResultA := cfp.Result{adm.Component{"A", "host1"}, time.Unix(0, 0), time.Unix(0, 300), 0.1}
cfpResultB = cfp.Result{adm.Component{"B", "host2", "responsetime"}, time.Unix(0, 0), time.Unix(0, 300), 0.0}
cfpResultA := cfp.Result{adm.Component{"A", "host1", "responsetime"}, time.Unix(0, 0), time.Unix(0, 300), 0.1}
f.UpdateCfpResult(cfpResultB)
fpmResult = <-fpmResultCh
f.UpdateCfpResult(cfpResultA)
fpmResult = <-fpmResultCh
if err != nil {
t.Error("Error making prediction", err)
}
fprobA = fpmResult.FailProbs[adm.Component{"A", "host1"}]
fprobA = fpmResult.FailProbs[adm.Component{"A", "host1", "responsetime"}]
if fprobA > 0.12 {
t.Error("Expected: 0 but got", fprobA)
}
fprobB = fpmResult.FailProbs[adm.Component{"B", "host2"}]
fprobB = fpmResult.FailProbs[adm.Component{"B", "host2", "responsetime"}]
if fprobB > 0.1 {
t.Error("Expected: 0 but got", fprobB)
}
fprobC = fpmResult.FailProbs[adm.Component{"C", "host3"}]
fprobC = fpmResult.FailProbs[adm.Component{"C", "host3", "responsetime"}]
if fprobC != 0 {
t.Error("Expected: 0 but got", fprobC)
}
fprobD = fpmResult.FailProbs[adm.Component{"D", "host4"}]
fprobD = fpmResult.FailProbs[adm.Component{"D", "host4", "responsetime"}]
if fprobD != 0 {
t.Error("Expected: 0 but got", fprobD)
}
Expand Down
3 changes: 2 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ func main() {
Addr: viper.GetString("influxdb.addr"),
Username: viper.GetString("influxdb.username"),
Password: viper.GetString("influxdb.password"),
Db: viper.GetString("influxdb.db.kieker"),
KiekerDb: viper.GetString("influxdb.db.kieker"),
K8sDb: viper.GetString("influxdb.db.k8s"),
Batch: viper.GetBool("influxdb.batch"),
Interval: viper.GetDuration("prediction.interval"),
}
Expand Down
Loading

0 comments on commit 205ba92

Please sign in to comment.