Ai
1 Star 0 Fork 0

ryancartoon/sensu-go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
check.go 6.95 KB
一键复制 编辑 原始数据 按行查看 历史
Simon Plourde 提交于 2019-06-11 23:20 +08:00 . APId Refactoring (#3018)
package v2
import (
"errors"
"fmt"
"net/url"
"path"
"sort"
"time"
jsoniter "github.com/json-iterator/go"
"github.com/robfig/cron"
utilstrings "github.com/sensu/sensu-go/util/strings"
)
const (
// CheckRequestType is the message type string for check request.
CheckRequestType = "check_request"
// ChecksResource is the name of this resource type
ChecksResource = "checks"
// DefaultSplayCoverage is the default splay coverage for proxy check requests
DefaultSplayCoverage = 90.0
// NagiosOutputMetricFormat is the accepted string to represent the output metric format of
// Nagios Perf Data
NagiosOutputMetricFormat = "nagios_perfdata"
// GraphiteOutputMetricFormat is the accepted string to represent the output metric format of
// Graphite Plain Text
GraphiteOutputMetricFormat = "graphite_plaintext"
// OpenTSDBOutputMetricFormat is the accepted string to represent the output metric format of
// OpenTSDB Line
OpenTSDBOutputMetricFormat = "opentsdb_line"
// InfluxDBOutputMetricFormat is the accepted string to represent the output metric format of
// InfluxDB Line
InfluxDBOutputMetricFormat = "influxdb_line"
)
// OutputMetricFormats represents all the accepted output_metric_format's a check can have
var OutputMetricFormats = []string{NagiosOutputMetricFormat, GraphiteOutputMetricFormat, OpenTSDBOutputMetricFormat, InfluxDBOutputMetricFormat}
// FixtureCheck returns a fixture for a Check object.
func FixtureCheck(id string) *Check {
t := time.Now().Unix()
config := FixtureCheckConfig(id)
history := make([]CheckHistory, 21)
for i := 0; i < 21; i++ {
history[i] = CheckHistory{
Status: 0,
Executed: t - (60 * int64(i+1)),
}
}
c := NewCheck(config)
c.Issued = t
c.Executed = t + 1
c.Duration = 1.0
c.History = history
return c
}
// NewCheck creates a new Check. It copies the fields from CheckConfig that
// match with Check's fields.
//
// Because CheckConfig uses extended attributes, embedding CheckConfig was
// deemed to be too complicated, due to interactions between promoted methods
// and encoding/json.
func NewCheck(c *CheckConfig) *Check {
check := &Check{
ObjectMeta: ObjectMeta{
Name: c.Name,
Namespace: c.Namespace,
Labels: c.Labels,
Annotations: c.Annotations,
},
Command: c.Command,
Handlers: c.Handlers,
HighFlapThreshold: c.HighFlapThreshold,
Interval: c.Interval,
LowFlapThreshold: c.LowFlapThreshold,
Publish: c.Publish,
RuntimeAssets: c.RuntimeAssets,
Subscriptions: c.Subscriptions,
ProxyEntityName: c.ProxyEntityName,
CheckHooks: c.CheckHooks,
Stdin: c.Stdin,
Subdue: c.Subdue,
Cron: c.Cron,
Ttl: c.Ttl,
Timeout: c.Timeout,
ProxyRequests: c.ProxyRequests,
RoundRobin: c.RoundRobin,
OutputMetricFormat: c.OutputMetricFormat,
OutputMetricHandlers: c.OutputMetricHandlers,
EnvVars: c.EnvVars,
DiscardOutput: c.DiscardOutput,
MaxOutputSize: c.MaxOutputSize,
}
if check.Labels == nil {
check.Labels = make(map[string]string)
}
if check.Annotations == nil {
check.Annotations = make(map[string]string)
}
return check
}
// SetNamespace sets the namespace of the resource.
func (c *Check) SetNamespace(namespace string) {
c.Namespace = namespace
}
// StorePrefix returns the path prefix to this resource in the store
func (c *Check) StorePrefix() string {
return ChecksResource
}
// URIPath returns the path component of a check URI.
func (c *Check) URIPath() string {
return path.Join(URLPrefix, "namespaces", url.PathEscape(c.Namespace), ChecksResource, url.PathEscape(c.Name))
}
// Validate returns an error if the check does not pass validation tests.
func (c *Check) Validate() error {
if err := ValidateName(c.Name); err != nil {
return errors.New("check name " + err.Error())
}
if c.Cron != "" {
if c.Interval > 0 {
return errors.New("must only specify either an interval or a cron schedule")
}
if _, err := cron.ParseStandard(c.Cron); err != nil {
return errors.New("check cron string is invalid")
}
} else {
if c.Interval < 1 {
return errors.New("check interval must be greater than or equal to 1")
}
}
if c.Ttl > 0 && c.Ttl <= int64(c.Interval) {
return errors.New("ttl must be greater than check interval")
}
if c.Ttl > 0 && c.Ttl < 5 {
return errors.New("minimum ttl is 5 seconds")
}
for _, assetName := range c.RuntimeAssets {
if err := ValidateAssetName(assetName); err != nil {
return fmt.Errorf("asset's %s", err)
}
}
// The entity can be empty but can't contain invalid characters (only
// alphanumeric string)
if c.ProxyEntityName != "" {
if err := ValidateName(c.ProxyEntityName); err != nil {
return errors.New("proxy entity name " + err.Error())
}
}
if c.ProxyRequests != nil {
if err := c.ProxyRequests.Validate(); err != nil {
return err
}
}
if c.OutputMetricFormat != "" {
if err := ValidateOutputMetricFormat(c.OutputMetricFormat); err != nil {
return err
}
}
if c.LowFlapThreshold != 0 && c.HighFlapThreshold != 0 && c.LowFlapThreshold >= c.HighFlapThreshold {
return errors.New("invalid flap thresholds")
}
if err := ValidateEnvVars(c.EnvVars); err != nil {
return err
}
if c.MaxOutputSize < 0 {
return fmt.Errorf("MaxOutputSize must be >= 0")
}
return c.Subdue.Validate()
}
// MarshalJSON implements the json.Marshaler interface.
func (c *Check) MarshalJSON() ([]byte, error) {
if c == nil {
return []byte("null"), nil
}
if c.Subscriptions == nil {
c.Subscriptions = []string{}
}
if c.Handlers == nil {
c.Handlers = []string{}
}
type Clone Check
clone := &Clone{}
*clone = Clone(*c)
return jsoniter.Marshal(clone)
}
// MergeWith updates the current Check with the history of the check given as
// an argument, updating the current check's history appropriately.
func (c *Check) MergeWith(prevCheck *Check) {
history := prevCheck.History
histEntry := CheckHistory{
Status: c.Status,
Executed: c.Executed,
}
history = append(history, histEntry)
sort.Sort(ByExecuted(history))
if len(history) > 21 {
history = history[1:]
}
c.History = history
c.LastOK = prevCheck.LastOK
c.Occurrences = prevCheck.Occurrences
c.OccurrencesWatermark = prevCheck.OccurrencesWatermark
updateCheckState(c)
}
// ValidateOutputMetricFormat returns an error if the string is not a valid metric
// format
func ValidateOutputMetricFormat(format string) error {
if utilstrings.InArray(format, OutputMetricFormats) {
return nil
}
return errors.New("output metric format is not valid")
}
// ByExecuted implements the sort.Interface for []CheckHistory based on the
// Executed field.
//
// Example:
//
// sort.Sort(ByExecuted(check.History))
type ByExecuted []CheckHistory
func (b ByExecuted) Len() int { return len(b) }
func (b ByExecuted) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
func (b ByExecuted) Less(i, j int) bool { return b[i].Executed < b[j].Executed }
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ryancartoon/sensu-go.git
git@gitee.com:ryancartoon/sensu-go.git
ryancartoon
sensu-go
sensu-go
v5.10.1

搜索帮助