A-Tune/common/tuning/rule_tunning.go
Zhipeng Xie 4335408875 atune: init code
upload code to gitee

Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
2019-11-13 17:14:15 +08:00

138 lines
3.2 KiB
Go

/*
* Copyright (c) 2019 Huawei Technologies Co., Ltd.
* A-Tune is licensed under the Mulan PSL v1.
* You can use this software according to the terms and conditions of the Mulan PSL v1.
* You may obtain a copy of Mulan PSL v1 at:
* http://license.coscl.org.cn/MulanPSL
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
* PURPOSE.
* See the Mulan PSL v1 for more details.
* Create: 2019-10-29
*/
package tuning
import (
"atune/common/config"
"atune/common/http"
"atune/common/log"
"atune/common/profile"
"atune/common/sqlstore"
"encoding/json"
"fmt"
"io/ioutil"
"strings"
"github.com/caibirdme/yql"
)
// RuleBody : the body send to monitor service
type RuleBody struct {
Module string `json:"module"`
Purpose string `json:"purpose"`
Field string `json:"field"`
}
// Post method calling the monitor service
func (r *RuleBody) Post() (*map[string]interface{}, error) {
url := config.GetUrl(config.MonitorURI)
res, err := http.Post(url, r)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != 200 {
log.Errorf("URL: %s, response code: %d", url, res.StatusCode)
return nil, fmt.Errorf("get monitor data faild, url: %s", url)
}
respBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
respPostIns := new(map[string]interface{})
err = json.Unmarshal(respBody, respPostIns)
if err != nil {
return nil, err
}
return respPostIns, nil
}
/*
RuleTuned method will be tuned the system parameter depend on the rules int the table
if rule mached, it will perform the corresponding operation
*/
func RuleTuned(workloadType string) error {
rules := &sqlstore.GetRuleTuned{Class: workloadType}
if err := sqlstore.GetRuleTuneds(rules); err != nil {
return err
}
if len(rules.Result) < 1 {
log.Info("no rules to tuned")
return nil
}
for _, rule := range rules.Result {
rulePostBody := new(RuleBody)
monitors := strings.Split(rule.Monitor, ".")
if len(monitors) != 2 {
log.Errorf("profile: %s, rule: %d, Monitor is not correct", workloadType, rule.ID)
continue
}
rulePostBody.Module = monitors[0]
rulePostBody.Purpose = monitors[1]
rulePostBody.Field = rule.Field
respPostIns, err := rulePostBody.Post()
if err != nil {
return err
}
if rule.Name == "hpre" {
support, err := IsSupportHpre()
if err != nil {
continue
}
if !support {
log.Info("current system is not support hpre")
continue
}
match, _ := HpreTuned(*respPostIns, rule.Expression)
if match {
ruleAction(workloadType, rule.Action)
} else {
ruleAction(workloadType, rule.OppositeAction)
}
return nil
}
log.Info("response from server:", respPostIns)
ruler, _ := yql.Rule(rule.Expression)
match, err := ruler.Match(*respPostIns)
if err != nil {
log.Errorf("profile: %s, rule: %d, match error: %v", workloadType, rule.ID, err)
continue
}
if match {
ruleAction(workloadType, rule.Action)
} else {
ruleAction(workloadType, rule.OppositeAction)
}
}
return nil
}
func ruleAction(workloadType string, action string) {
pro, _ := profile.LoadFromWorkloadType(workloadType)
pro.ActiveTuned(nil, action)
}