Files
cloudpods/pkg/cloudmon/misc/statusprobe.go
2025-05-19 22:28:20 +08:00

138 lines
3.8 KiB
Go

// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package misc
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/cloudmon/options"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
baseOptions "yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/util/influxdb"
)
func StatusProbe(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
if options.Options.EnableStatusProbeDebug {
log.Debugf("Start resource status probe")
}
if !options.Options.EnableStatusProbe {
if options.Options.EnableStatusProbeDebug {
log.Debugf("Resource status probe is disabled")
}
return
}
sess := auth.GetSession(ctx, userCred, options.Options.Region)
metrics := make([]influxdb.SMetricData, 0)
for _, model := range options.Options.StatusProbeModels {
mts, err := doModelStatusProbe(sess, model)
if err != nil {
log.Errorf("doModelStatusProbe failed: %s", err)
}
metrics = append(metrics, mts...)
}
err := sendMetrics(sess, metrics, "system")
if err != nil {
log.Errorf("StatusProbe SendMetrics error: %s", err)
}
}
func doModelStatusProbe(sess *mcclient.ClientSession, modelName string) ([]influxdb.SMetricData, error) {
model, err := modulebase.GetModule(sess, modelName)
if err != nil {
return nil, errors.Wrap(err, "GetModule")
}
listOpts := baseOptions.BaseListOptions{}
listOpts.Scope = "max"
listOpts.SummaryStats = true
limit := 0
listOpts.Limit = &limit
results, err := model.List(sess, jsonutils.Marshal(listOpts))
if err != nil {
return nil, errors.Wrap(err, "List")
}
statusInfoTotal := struct {
apis.TotalCountBase
StatusInfo []apis.StatusStatisticStatusInfo
}{}
err = results.Totals.Unmarshal(&statusInfoTotal)
if err != nil {
return nil, errors.Wrap(err, "Unmarshal statusInfoTotal")
}
log.Infof("statusInfoTotal: %s", jsonutils.Marshal(statusInfoTotal))
metrics := make([]influxdb.SMetricData, 0)
totalCount := int64(0)
pendingDeletedCount := int64(0)
for _, statusInfo := range statusInfoTotal.StatusInfo {
metrics = append(metrics, genStatusMetricData(model, statusInfo.Status, statusInfo.TotalCount, statusInfo.PendingDeletedCount))
totalCount += statusInfo.TotalCount
pendingDeletedCount += statusInfo.PendingDeletedCount
}
metrics = append(metrics, genStatusMetricData(model, "total", totalCount, pendingDeletedCount))
if options.Options.EnableStatusProbeDebug {
log.Debugf("StatusProbe for model %s metrics: %s", modelName, jsonutils.Marshal(metrics))
}
return metrics, nil
}
func genStatusMetricData(model modulebase.Manager, status string, count int64, pendingDeletedCount int64) influxdb.SMetricData {
return influxdb.SMetricData{
Name: "status_probe",
Tags: influxdb.TKeyValuePairs{
influxdb.SKeyValue{
Key: "service",
Value: model.ServiceType(),
},
influxdb.SKeyValue{
Key: "model",
Value: model.GetKeyword(),
},
influxdb.SKeyValue{
Key: "status",
Value: status,
},
},
Metrics: influxdb.TKeyValuePairs{
influxdb.SKeyValue{
Key: "count",
Value: fmt.Sprintf("%d", count),
},
influxdb.SKeyValue{
Key: "pending_deleted",
Value: fmt.Sprintf("%d", pendingDeletedCount),
},
},
}
}