This is an automated email from the ASF dual-hosted git repository.

humingcheng pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/servicecomb-service-center.git


The following commit(s) were added to refs/heads/dev by this push:
     new de7b2cd6 修复计数为0时无指标问题和更新类型同步事件处理错误 (#1508)
de7b2cd6 is described below

commit de7b2cd67710bd2dcc488f08b130065cfbdec0a1
Author: Wanghb1 <[email protected]>
AuthorDate: Thu Aug 7 10:10:39 2025 +0800

    修复计数为0时无指标问题和更新类型同步事件处理错误 (#1508)
    
    * 修改指标暴露逻辑,Gauge/Counter类指标,0也是有效值,应该被显式暴露
    
    * 修复处理update同步事件的逻辑
    
    ---------
    
    Co-authored-by: w30049875 <[email protected]>
---
 datasource/etcd/metrics.go                     | 44 +++++++++------
 datasource/etcd/metrics_test.go                | 77 ++++++++++++++++++++++++++
 datasource/metrics.go                          |  1 +
 pkg/metrics/metrics.go                         | 17 +++++-
 server/metrics/meta_reporter.go                |  9 ++-
 syncer/service/replicator/resource/resource.go |  2 +-
 6 files changed, 129 insertions(+), 21 deletions(-)

diff --git a/datasource/etcd/metrics.go b/datasource/etcd/metrics.go
index 9a30c11d..37c89c2d 100644
--- a/datasource/etcd/metrics.go
+++ b/datasource/etcd/metrics.go
@@ -33,6 +33,15 @@ import (
 type MetricsManager struct {
 }
 
+var (
+       defaultLabel = datasource.MetricsLabels{
+               Domain:           datasource.RegistryDomain,
+               Project:          datasource.RegistryProject,
+               Framework:        discovery.Unknown,
+               FrameworkVersion: discovery.Unknown,
+       }
+)
+
 func (m *MetricsManager) Report(ctx context.Context, r 
datasource.MetricsReporter) error {
        reportDomains(ctx, r)
        reportServices(ctx, r)
@@ -63,6 +72,7 @@ func reportSchemas(ctx context.Context, r 
datasource.MetricsReporter) {
                log.Error("query all schemas failed", err)
                return
        }
+       isSchemaMetricSet := false
        for _, keyValue := range schemaKeysResp.Kvs {
                domainProject, _, _ := 
path.GetInfoFromSchemaSummaryKV(keyValue.Key)
                domain, project := path.SplitDomainProject(domainProject)
@@ -71,6 +81,10 @@ func reportSchemas(ctx context.Context, r 
datasource.MetricsReporter) {
                        Project: project,
                }
                r.SchemaAdd(1, labels)
+               isSchemaMetricSet = true
+       }
+       if !isSchemaMetricSet {
+               r.SchemaAdd(0, defaultLabel)
        }
 }
 
@@ -84,6 +98,7 @@ func reportServices(ctx context.Context, r 
datasource.MetricsReporter) {
                log.Error("query all microservices failed", err)
                return
        }
+       isMetricSet := false
        for _, keyValue := range servicesResp.Kvs {
                service := keyValue.Value.(*discovery.MicroService)
                _, domainProject := path.GetInfoFromSvcKV(keyValue.Key)
@@ -99,12 +114,20 @@ func reportServices(ctx context.Context, r 
datasource.MetricsReporter) {
                        FrameworkVersion: frameworkVersion,
                }
                r.ServiceAdd(1, labels)
-
-               reportInstances(ctx, r, domainProject, service)
+               instanceCount := getInstanceCount4Service(ctx, domainProject, 
service)
+               r.FrameworkSet(labels)
+               r.InstanceAdd(float64(instanceCount), labels)
+               isMetricSet = true
+       }
+       // 0也应该是有效的指标,无指标是异常场景
+       if !isMetricSet {
+               r.ServiceAdd(0, defaultLabel)
+               r.SetFrameworkValue(0, defaultLabel)
+               r.InstanceAdd(0, defaultLabel)
        }
 }
 
-func reportInstances(ctx context.Context, r datasource.MetricsReporter, 
domainProject string, service *discovery.MicroService) {
+func getInstanceCount4Service(ctx context.Context, domainProject string, 
service *discovery.MicroService) (instanceCount int64) {
        instancesResp, err := sd.Instance().Search(ctx,
                etcdadpt.WithCacheOnly(), etcdadpt.WithCountOnly(),
                etcdadpt.WithStrKey(path.GenerateInstanceKey(domainProject, 
service.ServiceId, "")),
@@ -113,18 +136,5 @@ func reportInstances(ctx context.Context, r 
datasource.MetricsReporter, domainPr
                log.Error(fmt.Sprintf("query microservice %s isntances failed", 
service.ServiceId), err)
                return
        }
-       if instancesResp.Count == 0 {
-               return
-       }
-       count := float64(instancesResp.Count)
-       domain, project := path.SplitDomainProject(domainProject)
-       frameworkName, frameworkVersion := discovery.ToFrameworkLabel(service)
-       labels := datasource.MetricsLabels{
-               Domain:           domain,
-               Project:          project,
-               Framework:        frameworkName,
-               FrameworkVersion: frameworkVersion,
-       }
-       r.FrameworkSet(labels)
-       r.InstanceAdd(count, labels)
+       return instancesResp.Count
 }
diff --git a/datasource/etcd/metrics_test.go b/datasource/etcd/metrics_test.go
new file mode 100644
index 00000000..35249ee9
--- /dev/null
+++ b/datasource/etcd/metrics_test.go
@@ -0,0 +1,77 @@
+package etcd
+
+import (
+       "context"
+       "reflect"
+       "testing"
+
+       "github.com/go-chassis/cari/discovery"
+       io_prometheus_client "github.com/prometheus/client_model/go"
+       "github.com/stretchr/testify/assert"
+
+       "github.com/apache/servicecomb-service-center/datasource"
+       pkgmetrics "github.com/apache/servicecomb-service-center/pkg/metrics"
+       "github.com/apache/servicecomb-service-center/server/metrics"
+)
+
+func TestMetricsManager_Report(t *testing.T) {
+       m := &MetricsManager{}
+       reporter := &metrics.MetaReporter{}
+       err := m.Report(context.TODO(), reporter)
+       assert.NoError(t, err)
+
+       expectedLabels := map[string]string{
+               "domain":           datasource.RegistryDomain,
+               "project":          datasource.RegistryProject,
+               "framework":        discovery.Unknown,
+               "frameworkVersion": discovery.Unknown,
+               "instance":         pkgmetrics.InstanceName(),
+       }
+
+       domainTotal, err := pkgmetrics.GetMetrics(metrics.KeyDomainTotal)
+       assert.NoError(t, err)
+       assert.NotNil(t, domainTotal)
+       assert.True(t, len(domainTotal.Metric) == 1)
+       assert.True(t, labelEqual(domainTotal.Metric[0].Label, 
map[string]string{"instance": pkgmetrics.InstanceName()}))
+
+       serviceTotal, err := pkgmetrics.GetMetrics(metrics.KeyServiceTotal)
+       assert.NoError(t, err)
+       assert.NotNil(t, serviceTotal)
+       assert.True(t, len(serviceTotal.Metric) == 1)
+       assert.True(t, labelEqual(serviceTotal.Metric[0].Label, expectedLabels))
+
+       instanceTotal, err := pkgmetrics.GetMetrics(metrics.KeyInstanceTotal)
+       assert.NoError(t, err)
+       assert.NotNil(t, instanceTotal)
+       assert.True(t, len(instanceTotal.Metric) == 1)
+       assert.True(t, labelEqual(instanceTotal.Metric[0].Label, 
expectedLabels))
+
+       frameworkTotal, err := pkgmetrics.GetMetrics(metrics.KeyFrameworkTotal)
+       assert.NoError(t, err)
+       assert.True(t, len(frameworkTotal.Metric) == 1)
+       assert.True(t, labelEqual(frameworkTotal.Metric[0].Label, 
expectedLabels))
+
+       schemaTotal, err := pkgmetrics.GetMetrics(metrics.KeySchemaTotal)
+       assert.NoError(t, err)
+       assert.NotNil(t, schemaTotal)
+       assert.True(t, len(schemaTotal.Metric) == 1)
+       assert.True(t, labelEqual(schemaTotal.Metric[0].Label, 
map[string]string{
+               "instance": pkgmetrics.InstanceName(),
+               "domain":   datasource.RegistryDomain,
+               "project":  datasource.RegistryProject}))
+}
+
+func labelEqual(pairs []*io_prometheus_client.LabelPair, expect 
map[string]string) bool {
+       if len(expect) != len(pairs) {
+               return false
+       }
+
+       labels := make(map[string]string, len(pairs))
+       for _, pair := range pairs {
+               if pair == nil || pair.Name == nil || pair.Value == nil {
+                       return false
+               }
+               labels[*pair.Name] = *pair.Value
+       }
+       return reflect.DeepEqual(labels, expect)
+}
diff --git a/datasource/metrics.go b/datasource/metrics.go
index 914d4328..8b1bf0f9 100644
--- a/datasource/metrics.go
+++ b/datasource/metrics.go
@@ -32,6 +32,7 @@ type MetricsReporter interface {
        InstanceAdd(delta float64, labels MetricsLabels)
        SchemaAdd(delta float64, labels MetricsLabels)
        FrameworkSet(labels MetricsLabels)
+       SetFrameworkValue(value float64, labels MetricsLabels)
 }
 
 type MetricsManager interface {
diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go
index 23297c87..f9d41230 100644
--- a/pkg/metrics/metrics.go
+++ b/pkg/metrics/metrics.go
@@ -21,8 +21,10 @@ import (
        "reflect"
        "strings"
 
-       "github.com/apache/servicecomb-service-center/pkg/buffer"
+       "github.com/go-chassis/go-chassis/v2/pkg/metrics"
        dto "github.com/prometheus/client_model/go"
+
+       "github.com/apache/servicecomb-service-center/pkg/buffer"
 )
 
 // Pxx represents p99 p90 p50
@@ -167,3 +169,16 @@ func ToLabelNames(structure interface{}) []string {
        }
        return labelNames
 }
+
+func GetMetrics(name string) (*dto.MetricFamily, error) {
+       fmls, err := metrics.GetSystemPrometheusRegistry().Gather()
+       if err != nil {
+               return nil, err
+       }
+       for _, family := range fmls {
+               if family.GetName() == name {
+                       return family, nil
+               }
+       }
+       return nil, nil
+}
diff --git a/server/metrics/meta_reporter.go b/server/metrics/meta_reporter.go
index 4463d10e..284da7dc 100644
--- a/server/metrics/meta_reporter.go
+++ b/server/metrics/meta_reporter.go
@@ -20,12 +20,13 @@ package metrics
 import (
        "context"
 
+       "github.com/go-chassis/go-chassis/v2/pkg/metrics"
+
        "github.com/apache/servicecomb-service-center/datasource"
        "github.com/apache/servicecomb-service-center/pkg/log"
        metricsvc "github.com/apache/servicecomb-service-center/pkg/metrics"
        promutil "github.com/apache/servicecomb-service-center/pkg/prometheus"
        quotasvc 
"github.com/apache/servicecomb-service-center/server/service/quota"
-       "github.com/go-chassis/go-chassis/v2/pkg/metrics"
 )
 
 var metaReporter = &MetaReporter{}
@@ -108,6 +109,10 @@ func (m *MetaReporter) SchemaAdd(delta float64, ml 
datasource.MetricsLabels) {
        }
 }
 func (m *MetaReporter) FrameworkSet(ml datasource.MetricsLabels) {
+       m.SetFrameworkValue(1, ml)
+}
+
+func (m *MetaReporter) SetFrameworkValue(value float64, ml 
datasource.MetricsLabels) {
        instance := metricsvc.InstanceName()
        labels := map[string]string{
                "instance":         instance,
@@ -116,7 +121,7 @@ func (m *MetaReporter) FrameworkSet(ml 
datasource.MetricsLabels) {
                "domain":           ml.Domain,
                "project":          ml.Project,
        }
-       if err := metrics.GaugeSet(KeyFrameworkTotal, 1, labels); err != nil {
+       if err := metrics.GaugeSet(KeyFrameworkTotal, value, labels); err != 
nil {
                log.Error("gauge set failed", err)
        }
 }
diff --git a/syncer/service/replicator/resource/resource.go 
b/syncer/service/replicator/resource/resource.go
index 7d8c7950..4671c45d 100644
--- a/syncer/service/replicator/resource/resource.go
+++ b/syncer/service/replicator/resource/resource.go
@@ -348,7 +348,7 @@ func (o *checker) needOperate(ctx context.Context) *Result {
                if len(o.resourceID) == 0 {
                        return nil
                }
-               if o.event.Timestamp+oneDaySecond >= time.Now().Unix() {
+               if time.Now().Unix()-o.event.Timestamp >= oneDaySecond {
                        return SkipResult()
                }
 

Reply via email to