diff --git a/sql/n9e_rdb-patch.sql b/sql/n9e_rdb-patch.sql index e69de29b..399c87f8 100644 --- a/sql/n9e_rdb-patch.sql +++ b/sql/n9e_rdb-patch.sql @@ -0,0 +1,9 @@ +set names utf8; +use n9e_rdb; + +CREATE TABLE `stats` +( + `name` varchar(64) not null, + `value` bigint not null default 0, + PRIMARY KEY (`name`) +) ENGINE = InnoDB DEFAULT CHARSET = utf8; diff --git a/sql/n9e_rdb.sql b/sql/n9e_rdb.sql index c8f42b81..4a25e9b8 100644 --- a/sql/n9e_rdb.sql +++ b/sql/n9e_rdb.sql @@ -355,3 +355,11 @@ CREATE TABLE `session` ( KEY (`username`), KEY (`updated_at`) ) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8; + + +CREATE TABLE `stats` +( + `name` varchar(64) not null, + `value` bigint not null default 0, + PRIMARY KEY (`name`) +) ENGINE = InnoDB DEFAULT CHARSET = utf8; diff --git a/src/models/session.go b/src/models/session.go index a896cd84..b107885a 100644 --- a/src/models/session.go +++ b/src/models/session.go @@ -64,7 +64,7 @@ func SessionCleanupByUpdatedAt(ts int64) error { return err } func (s *Session) Update(cols ...string) error { - _, err := DB["rdb"].Where("id=?", s.Sid).Cols(cols...).Update(s) + _, err := DB["rdb"].Where("sid=?", s.Sid).Cols(cols...).Update(s) return err } @@ -118,7 +118,6 @@ func SessionGetUserWithCache(sid string) (*User, error) { return nil, fmt.Errorf("user not found") } return UserMustGet("username=?", s.Username) - } func SessionTotal(where string, args ...interface{}) (int64, error) { diff --git a/src/models/stats.go b/src/models/stats.go new file mode 100644 index 00000000..68fe1d95 --- /dev/null +++ b/src/models/stats.go @@ -0,0 +1,62 @@ +package models + +type Stats struct { + Name string `json:"name"` + Value int64 `json:"value"` +} + +func NewStats(name string) (*Stats, error) { + c := Stats{Name: name} + + has, err := DB["rdb"].Where("name=?", c.Name).Get(&c) + if err != nil { + return nil, err + } + + if !has { + c.Save() + } + + return &c, nil +} + +func MustNewStats(name string) *Stats { + m, err := NewStats(name) + if err != nil { + panic(err) + } + + return m +} + +func (p *Stats) Get() int64 { + var s Stats + has, _ := DB["rdb"].Where("name=?", p.Name).Get(&s) + if !has { + p.Save() + } + return s.Value +} + +func (p *Stats) Save() error { + _, err := DB["rdb"].Insert(p) + return err +} + +func (p *Stats) Del() error { + _, err := DB["rdb"].Where("name=?", p.Name).Delete(p) + return err +} + +// for GAUAGE +func (p *Stats) Update(i int64) error { + p.Value = i + _, err := DB["rdb"].Where("name=?", p.Name).Cols("value").Update(p) + return err +} + +// for COUNTER +func (p *Stats) Inc(i int) error { + _, err := DB["rdb"].Exec("update stats set value = value + ? where name=?", i, p.Name) + return err +} diff --git a/src/modules/monapi/plugins/prometheus/prometheus_test.go b/src/modules/monapi/plugins/prometheus/prometheus_test.go index 90f395b3..f97527fc 100644 --- a/src/modules/monapi/plugins/prometheus/prometheus_test.go +++ b/src/modules/monapi/plugins/prometheus/prometheus_test.go @@ -38,6 +38,11 @@ helo_stats_test_histogram_count{region="bj",zone="test_1"} 56 # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge go_goroutines 15 1490802350000 +# HELP test_guage guage +# TYPE test_guage gauge +test_guauge{label="1"} 1.1 +test_guauge{label="2"} 1.2 +test_guauge{label="3"} 1.3 ` func TestCollect(t *testing.T) { diff --git a/src/modules/prober/config/plugin.go b/src/modules/prober/config/plugin.go index 8fd57cf8..f63517f0 100644 --- a/src/modules/prober/config/plugin.go +++ b/src/modules/prober/config/plugin.go @@ -129,7 +129,7 @@ func (p *Metric) parse() (err error) { return } -func (p *Metric) Calc(vars map[string]*dataobj.MetricValue) (float64, error) { +func (p *Metric) Calc(vars map[string][]*dataobj.MetricValue) (float64, error) { return p.notations.Calc(vars) } diff --git a/src/modules/prober/expr/expr.go b/src/modules/prober/expr/expr.go index ec3b7711..b0f85d0f 100644 --- a/src/modules/prober/expr/expr.go +++ b/src/modules/prober/expr/expr.go @@ -62,17 +62,17 @@ func (s *StackFloat) Push(f float64) { *s = append(*s, f) } func (s *StackFloat) Pop() float64 { n := (*s)[len(*s)-1]; *s = (*s)[:len(*s)-1]; return n } func (s *StackFloat) Len() int { return len(*s) } -func (rpn Notations) Calc(vars map[string]*dataobj.MetricValue) (float64, error) { +func (rpn Notations) Calc(vars map[string][]*dataobj.MetricValue) (float64, error) { var s StackFloat for i := 0; i < rpn.Len(); i++ { tn := rpn[i] switch tn.tokenType { case tokenVar: - if v, ok := vars[tn.tokenVariable]; !ok { + if v, ok := vars[tn.tokenVariable]; !ok && len(v) == 0 { return 0, fmt.Errorf("variable %s is not set", tn.tokenVariable) } else { - logger.Debugf("get %s %f", tn.tokenVariable, v.Value) - s.Push(v.Value) + logger.Debugf("get %s %f", tn.tokenVariable, v[0].Value) + s.Push(v[0].Value) } case tokenConst: s.Push(tn.tokenConst) diff --git a/src/modules/prober/manager/collectrule.go b/src/modules/prober/manager/collectrule.go index 95353b55..408f4d16 100644 --- a/src/modules/prober/manager/collectrule.go +++ b/src/modules/prober/manager/collectrule.go @@ -97,10 +97,15 @@ func (p *collectRule) prepareMetrics() (metrics []*dataobj.MetricValue, err erro return } - vars := map[string]*dataobj.MetricValue{} + vars := map[string][]*dataobj.MetricValue{} for _, v := range metrics { logger.Debugf("get v[%s] %f", v.Metric, v.Value) - vars[v.Metric] = v + if _, ok := vars[v.Metric]; ok { + vars[v.Metric] = []*dataobj.MetricValue{v} + } else { + vars[v.Metric] = append(vars[v.Metric], v) + } + } metrics = metrics[:0] @@ -123,31 +128,33 @@ func (p *collectRule) prepareMetrics() (metrics []*dataobj.MetricValue, err erro } for k, v := range vars { - if metric, ok := pluginConfig.Metrics[k]; ok { - metrics = append(metrics, &dataobj.MetricValue{ - Nid: nid, - Metric: k, - Timestamp: ts, - Step: p.Step, - CounterType: metric.Type, - TagsMap: v.TagsMap, - Value: v.Value, - ValueUntyped: v.ValueUntyped, - }) - } else { - if pluginConfig.Mode == config.PluginModeWhitelist { - continue + for _, v2 := range v { + if metric, ok := pluginConfig.Metrics[k]; ok { + metrics = append(metrics, &dataobj.MetricValue{ + Nid: nid, + Metric: k, + Timestamp: ts, + Step: p.Step, + CounterType: metric.Type, + TagsMap: v2.TagsMap, + Value: v2.Value, + ValueUntyped: v2.ValueUntyped, + }) + } else { + if pluginConfig.Mode == config.PluginModeWhitelist { + continue + } + metrics = append(metrics, &dataobj.MetricValue{ + Nid: nid, + Metric: k, + Timestamp: ts, + Step: p.Step, + CounterType: "GAUGE", + TagsMap: v2.TagsMap, + Value: v2.Value, + ValueUntyped: v2.ValueUntyped, + }) } - metrics = append(metrics, &dataobj.MetricValue{ - Nid: nid, - Metric: k, - Timestamp: ts, - Step: p.Step, - CounterType: "GAUGE", - TagsMap: v.TagsMap, - Value: v.Value, - ValueUntyped: v.ValueUntyped, - }) } } return diff --git a/src/modules/rdb/auth/authenticator.go b/src/modules/rdb/auth/authenticator.go index 280740f5..9c2fdf53 100644 --- a/src/modules/rdb/auth/authenticator.go +++ b/src/modules/rdb/auth/authenticator.go @@ -370,7 +370,7 @@ func (p *Authenticator) updateUserStatus() { now := time.Now().Unix() if p.frozenTime > 0 { // 3个月以上未登录,用户自动变为休眠状态 - if _, err := models.DB["rdb"].Exec("update user set status=?, updated_at=?, locked_at=? where ((logged_at > 0 and logged_at 0 and logged_at