From e3f9bc3a80e3e92e952297e777fa283889048ab9 Mon Sep 17 00:00:00 2001 From: foghost Date: Fri, 25 Aug 2023 12:19:47 +0800 Subject: [PATCH 1/3] change metric config to url like other module --- common/constant/key.go | 24 +++++++------ common/constant/metric.go | 56 ++++++++++++++++++++++++++++++ config/metric_config.go | 23 ++++++++++-- config/root_config.go | 2 +- metrics/api.go | 34 ++++++++++-------- metrics/app_info/collector.go | 3 +- metrics/common.go | 32 ++++++++--------- metrics/config_center/collector.go | 5 +-- metrics/metadata/collector.go | 3 +- metrics/prometheus/constant.go | 6 ++-- metrics/prometheus/registry.go | 4 ++- metrics/registry/collector.go | 3 +- 12 files changed, 141 insertions(+), 54 deletions(-) create mode 100644 common/constant/metric.go diff --git a/common/constant/key.go b/common/constant/key.go index 383b57e57c..f200528785 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -176,10 +176,6 @@ const ( const ( ApplicationKey = "application" - ApplicationNameKey = "application_name" - ApplicationVersionKey = "application_version" - HostnameKey = "hostname" - IpKey = "ip" OrganizationKey = "organization" NameKey = "name" ModuleKey = "module" @@ -198,10 +194,6 @@ const ( ProvidersCategory = "providers" RouterKey = "router" ExportKey = "export" - GitCommitIdKey = "git_commit_id" - ConfigCenterKey = "config_center" - ChangeTypeKey = "change_type" - KeyKey = "key" ) // config center keys @@ -412,9 +404,19 @@ const ( // metrics key const ( - MetricsRegistry = "dubbo.metrics.registry" - MetricsMetadata = "dubbo.metrics.metadata" - MetricApp = "dubbo.metrics.app" + AggregationEnabledKey = "aggregation.enabled" + AggregationBucketNumKey = "aggregation.bucket.num" + AggregationTimeWindowSecondsKey = "aggregation.time.window.seconds" + HistogramEnabledKey = "histogram.enabled" + PrometheusExporterEnabledKey = "prometheus.exporter.enabled" + PrometheusExporterMetricsPortKey = "prometheus.exporter.metrics.port" + PrometheusExporterMetricsPathKey = "prometheus.exporter.metrics.path" + PrometheusPushgatewayEnabledKey = "prometheus.pushgateway.enabled" + PrometheusPushgatewayBaseUrlKey = "prometheus.pushgateway.base.url" + PrometheusPushgatewayUsernameKey = "prometheus.pushgateway.username" + PrometheusPushgatewayPasswordKey = "prometheus.pushgateway.password" + PrometheusPushgatewayPushIntervalKey = "prometheus.pushgateway.push.interval" + PrometheusPushgatewayJobKey = "prometheus.pushgateway.job" ) // default meta cache config diff --git a/common/constant/metric.go b/common/constant/metric.go new file mode 100644 index 0000000000..23fe5ad66e --- /dev/null +++ b/common/constant/metric.go @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 constant + +// metrics type +const ( + MetricsRegistry = "dubbo.metrics.registry" + MetricsMetadata = "dubbo.metrics.metadata" + MetricsApp = "dubbo.metrics.app" + MetricsConfigCenter = "dubbo.metrics.configCenter" +) + +const ( + TagApplicationName = "application_name" + TagApplicationVersion = "application_version" + TagHostname = "hostname" + TagIp = "ip" + TagGitCommitId = "git_commit_id" + TagConfigCenter = "config_center" + TagChangeType = "change_type" + TagKey = "key" + TagPid = "pid" + TagInterface = "interface" + TagMethod = "method" + TagGroup = "group" + TagVersion = "version" + TagErrorCode = "error" +) +const ( + MetricNamespace = "dubbo" + ProtocolPrometheus = "prometheus" + ProtocolDefault = ProtocolPrometheus + AggregationCollectorKey = "aggregation" + AggregationDefaultBucketNum = 10 + AggregationDefaultTimeWindowSeconds = 120 + PrometheusDefaultMetricsPath = "/metrics" + PrometheusDefaultMetricsPort = "9090" + PrometheusDefaultPushInterval = 30 + PrometheusDefaultJobName = "default_dubbo_job" + MetricFilterStartTime = "metric_filter_start_time" +) diff --git a/config/metric_config.go b/config/metric_config.go index a6b874987f..52387852df 100644 --- a/config/metric_config.go +++ b/config/metric_config.go @@ -17,6 +17,10 @@ package config +import ( + "strconv" +) + import ( "github.com/creasty/defaults" @@ -26,6 +30,8 @@ import ( ) import ( + "dubbo.apache.org/dubbo-go/v3/common" + "dubbo.apache.org/dubbo-go/v3/common/constant" "dubbo.apache.org/dubbo-go/v3/common/extension" "dubbo.apache.org/dubbo-go/v3/metrics" ) @@ -40,6 +46,7 @@ type MetricConfig struct { PushGatewayAddress string `default:"" yaml:"push-gateway-address" json:"push-gateway-address,omitempty" property:"push-gateway-address"` SummaryMaxAge int64 `default:"600000000000" yaml:"summary-max-age" json:"summary-max-age,omitempty" property:"summary-max-age"` Protocol string `default:"prometheus" yaml:"protocol" json:"protocol,omitempty" property:"protocol"` + rootConfig *RootConfig } func (mc *MetricConfig) ToReporterConfig() *metrics.ReporterConfig { @@ -60,7 +67,7 @@ func (mc *MetricConfig) ToReporterConfig() *metrics.ReporterConfig { return defaultMetricsReportConfig } -func (mc *MetricConfig) Init() error { +func (mc *MetricConfig) Init(rc *RootConfig) error { if mc == nil { return errors.New("metrics config is null") } @@ -70,10 +77,11 @@ func (mc *MetricConfig) Init() error { if err := verify(mc); err != nil { return err } + mc.rootConfig = rc metrics.InitAppInfo(GetRootConfig().Application.Name, GetRootConfig().Application.Version) config := mc.ToReporterConfig() extension.GetMetricReporter(mc.Protocol, config) - metrics.Init(config) + metrics.Init(mc.toURL()) return nil } @@ -100,3 +108,14 @@ func (mc *MetricConfig) DynamicUpdateProperties(newMetricConfig *MetricConfig) { } } } + +// prometheus://localhost:9090?&histogram.enabled=false&prometheus.exporter.enabled=false +func (mc *MetricConfig) toURL() *common.URL { + url, _ := common.NewURL("localhost", common.WithProtocol(mc.Protocol)) + url.SetParam(constant.PrometheusExporterEnabledKey, strconv.FormatBool(*mc.Enable)) + url.SetParam(constant.PrometheusExporterMetricsPortKey, mc.Port) + url.SetParam(constant.PrometheusExporterMetricsPathKey, mc.Path) + url.SetParam(constant.ApplicationKey, mc.rootConfig.Application.Name) + url.SetParam(constant.AppVersionKey, mc.rootConfig.Application.Version) + return url +} diff --git a/config/root_config.go b/config/root_config.go index 724af48ab0..e578464fe4 100644 --- a/config/root_config.go +++ b/config/root_config.go @@ -182,7 +182,7 @@ func (rc *RootConfig) Init() error { if err := rc.Otel.Init(rc.Application); err != nil { return err } - if err := rc.Metric.Init(); err != nil { + if err := rc.Metric.Init(rc); err != nil { return err } for _, t := range rc.Tracing { diff --git a/metrics/api.go b/metrics/api.go index 4c19e63cfd..5fbcc0be77 100644 --- a/metrics/api.go +++ b/metrics/api.go @@ -17,37 +17,41 @@ package metrics +import ( + "dubbo.apache.org/dubbo-go/v3/common" + "dubbo.apache.org/dubbo-go/v3/common/constant" +) + var ( - registries = make(map[string]func(*ReporterConfig) MetricRegistry) + registries = make(map[string]func(*common.URL) MetricRegistry) collectors = make([]CollectorFunc, 0) registry MetricRegistry ) // CollectorFunc used to extend more indicators -type CollectorFunc func(MetricRegistry, *ReporterConfig) +type CollectorFunc func(MetricRegistry, *common.URL) // Init Metrics module -func Init(config *ReporterConfig) { - if config.Enable { - // defalut protocol is already set in metricConfig - regFunc, ok := registries[config.Protocol] - if ok { - registry = regFunc(config) - for _, co := range collectors { - co(registry, config) - } - registry.Export() +func Init(url *common.URL) { + InitAppInfo(url.GetParam(constant.ApplicationKey, ""), url.GetParam(constant.AppVersionKey, "")) + // defalut protocol is already set in metricConfig + regFunc, ok := registries[url.Protocol] + if ok { + registry = regFunc(url) + for _, co := range collectors { + co(registry, url) } + registry.Export() } } // SetRegistry extend more MetricRegistry, default PrometheusRegistry -func SetRegistry(name string, v func(*ReporterConfig) MetricRegistry) { +func SetRegistry(name string, v func(*common.URL) MetricRegistry) { registries[name] = v } // AddCollector add more indicators, like metadata、sla、configcenter etc -func AddCollector(name string, fun func(MetricRegistry, *ReporterConfig)) { +func AddCollector(name string, fun func(MetricRegistry, *common.URL)) { collectors = append(collectors, fun) } @@ -74,7 +78,7 @@ type RtOpts struct { // rs []MetricRegistry // } -// Type metric type, save with micrometer +// Type metric type, same with micrometer type Type uint8 const ( diff --git a/metrics/app_info/collector.go b/metrics/app_info/collector.go index a2bae022fe..98abeb4092 100644 --- a/metrics/app_info/collector.go +++ b/metrics/app_info/collector.go @@ -18,6 +18,7 @@ package app_info import ( + "dubbo.apache.org/dubbo-go/v3/common" "dubbo.apache.org/dubbo-go/v3/metrics" ) @@ -29,7 +30,7 @@ import ( var info = metrics.NewMetricKey("dubbo_application_info_total", "Total Application Info") // Total Application Info include application name、version etc func init() { - metrics.AddCollector("application_info", func(mr metrics.MetricRegistry, config *metrics.ReporterConfig) { + metrics.AddCollector("application_info", func(mr metrics.MetricRegistry, _ *common.URL) { mr.Counter(&metrics.MetricId{Name: info.Name, Desc: info.Desc, Tags: metrics.GetApplicationLevel().Tags()}).Inc() }) } diff --git a/metrics/common.go b/metrics/common.go index 3dbe51bd1a..8d8562e869 100644 --- a/metrics/common.go +++ b/metrics/common.go @@ -64,11 +64,11 @@ func GetApplicationLevel() *ApplicationMetricLevel { func (m *ApplicationMetricLevel) Tags() map[string]string { tags := make(map[string]string) - tags[constant.IpKey] = m.Ip - tags[constant.HostnameKey] = m.HostName - tags[constant.ApplicationNameKey] = m.ApplicationName - tags[constant.ApplicationVersionKey] = m.Version - tags[constant.GitCommitIdKey] = m.GitCommitId + tags[constant.TagIp] = m.Ip + tags[constant.TagHostname] = m.HostName + tags[constant.TagApplicationName] = m.ApplicationName + tags[constant.TagApplicationVersion] = m.Version + tags[constant.TagGitCommitId] = m.GitCommitId return tags } @@ -83,7 +83,7 @@ func NewServiceMetric(interfaceName string) *ServiceMetricLevel { func (m ServiceMetricLevel) Tags() map[string]string { tags := m.ApplicationMetricLevel.Tags() - tags[constant.InterfaceKey] = m.Interface + tags[constant.TagInterface] = m.Interface return tags } @@ -96,9 +96,9 @@ type MethodMetricLevel struct { func (m MethodMetricLevel) Tags() map[string]string { tags := m.ServiceMetricLevel.Tags() - tags[constant.MethodKey] = m.Method - tags[constant.GroupKey] = m.Group - tags[constant.VersionKey] = m.Version + tags[constant.TagMethod] = m.Method + tags[constant.TagGroup] = m.Group + tags[constant.TagVersion] = m.Version return tags } @@ -126,12 +126,12 @@ func NewConfigCenterLevel(key string, group string, configCenter string, changeT func (l ConfigCenterLevel) Tags() map[string]string { tags := make(map[string]string) - tags[constant.ApplicationKey] = l.ApplicationName - tags[constant.IpKey] = l.Ip - tags[constant.HostnameKey] = l.HostName - tags[constant.KeyKey] = l.Key - tags[constant.GroupKey] = l.Group - tags[constant.ConfigCenterKey] = l.ConfigCenter - tags[constant.ChangeTypeKey] = l.ChangeType + tags[constant.TagApplicationName] = l.ApplicationName + tags[constant.TagIp] = l.Ip + tags[constant.TagHostname] = l.HostName + tags[constant.TagKey] = l.Key + tags[constant.TagGroup] = l.Group + tags[constant.TagConfigCenter] = l.ConfigCenter + tags[constant.TagChangeType] = l.ChangeType return tags } diff --git a/metrics/config_center/collector.go b/metrics/config_center/collector.go index 7236501882..9ae551f0e5 100644 --- a/metrics/config_center/collector.go +++ b/metrics/config_center/collector.go @@ -18,18 +18,19 @@ package metrics import ( + "dubbo.apache.org/dubbo-go/v3/common" "dubbo.apache.org/dubbo-go/v3/common/constant" "dubbo.apache.org/dubbo-go/v3/metrics" "dubbo.apache.org/dubbo-go/v3/remoting" ) -const eventType = constant.MetricApp +const eventType = constant.MetricsConfigCenter var ch = make(chan metrics.MetricsEvent, 10) var info = metrics.NewMetricKey("dubbo_configcenter_total", "Config Changed Total") func init() { - metrics.AddCollector("application_info", func(mr metrics.MetricRegistry, config *metrics.ReporterConfig) { + metrics.AddCollector("config_center", func(mr metrics.MetricRegistry, _ *common.URL) { c := &configCenterCollector{r: mr} c.start() }) diff --git a/metrics/metadata/collector.go b/metrics/metadata/collector.go index 23921242f1..7125fb1f14 100644 --- a/metrics/metadata/collector.go +++ b/metrics/metadata/collector.go @@ -22,6 +22,7 @@ import ( ) import ( + "dubbo.apache.org/dubbo-go/v3/common" "dubbo.apache.org/dubbo-go/v3/common/constant" "dubbo.apache.org/dubbo-go/v3/metrics" ) @@ -31,7 +32,7 @@ const eventType = constant.MetricsMetadata var ch = make(chan metrics.MetricsEvent, 10) func init() { - metrics.AddCollector("metadata", func(mr metrics.MetricRegistry, rc *metrics.ReporterConfig) { + metrics.AddCollector("metadata", func(mr metrics.MetricRegistry, _ *common.URL) { l := &MetadataMetricCollector{metrics.BaseCollector{R: mr}} l.start() }) diff --git a/metrics/prometheus/constant.go b/metrics/prometheus/constant.go index 41904dba3e..c9e9090018 100644 --- a/metrics/prometheus/constant.go +++ b/metrics/prometheus/constant.go @@ -23,11 +23,11 @@ import ( const ( reporterName = "prometheus" - applicationNameKey = constant.ApplicationNameKey + applicationNameKey = constant.TagApplicationName groupKey = constant.GroupKey - hostnameKey = constant.HostnameKey + hostnameKey = constant.TagHostname interfaceKey = constant.InterfaceKey - ipKey = constant.IpKey + ipKey = constant.TagIp methodKey = constant.MethodKey versionKey = constant.VersionKey ) diff --git a/metrics/prometheus/registry.go b/metrics/prometheus/registry.go index 21ebc0d6d3..7570a8a583 100644 --- a/metrics/prometheus/registry.go +++ b/metrics/prometheus/registry.go @@ -29,11 +29,13 @@ import ( ) import ( + "dubbo.apache.org/dubbo-go/v3/common" + "dubbo.apache.org/dubbo-go/v3/common/constant" "dubbo.apache.org/dubbo-go/v3/metrics" ) func init() { - metrics.SetRegistry("prometheus", func(rc *metrics.ReporterConfig) metrics.MetricRegistry { + metrics.SetRegistry(constant.ProtocolPrometheus, func(url *common.URL) metrics.MetricRegistry { return &promMetricRegistry{r: prom.DefaultRegisterer} }) } diff --git a/metrics/registry/collector.go b/metrics/registry/collector.go index fcd94b9740..53a5d71b30 100644 --- a/metrics/registry/collector.go +++ b/metrics/registry/collector.go @@ -18,6 +18,7 @@ package registry import ( + "dubbo.apache.org/dubbo-go/v3/common" "dubbo.apache.org/dubbo-go/v3/common/constant" "dubbo.apache.org/dubbo-go/v3/metrics" ) @@ -27,7 +28,7 @@ var ( ) func init() { - metrics.AddCollector("registry", func(m metrics.MetricRegistry, c *metrics.ReporterConfig) { + metrics.AddCollector("registry", func(m metrics.MetricRegistry, _ *common.URL) { rc := ®istryCollector{metrics.BaseCollector{R: m}} go rc.start() }) From 501cefeca20d6c8a195faa2528e239487bd81655 Mon Sep 17 00:00:00 2001 From: foghost Date: Mon, 28 Aug 2023 11:11:31 +0800 Subject: [PATCH 2/3] fix unit test --- config/metric_config.go | 1 - config/metric_config_test.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/config/metric_config.go b/config/metric_config.go index 52387852df..b0e45d06aa 100644 --- a/config/metric_config.go +++ b/config/metric_config.go @@ -78,7 +78,6 @@ func (mc *MetricConfig) Init(rc *RootConfig) error { return err } mc.rootConfig = rc - metrics.InitAppInfo(GetRootConfig().Application.Name, GetRootConfig().Application.Version) config := mc.ToReporterConfig() extension.GetMetricReporter(mc.Protocol, config) metrics.Init(mc.toURL()) diff --git a/config/metric_config_test.go b/config/metric_config_test.go index 14804b3c7c..70dce11b1e 100644 --- a/config/metric_config_test.go +++ b/config/metric_config_test.go @@ -27,7 +27,7 @@ import ( func TestMetricConfigBuilder(t *testing.T) { config := NewMetricConfigBuilder().Build() - err := config.Init() + err := config.Init(&RootConfig{Application: &ApplicationConfig{Name: "dubbo", Version: "1.0.0"}}) assert.NoError(t, err) reporterConfig := config.ToReporterConfig() assert.Equal(t, string(reporterConfig.Mode), "pull") From 298d4ea911c63a425489e69aa9e58a0df54da184 Mon Sep 17 00:00:00 2001 From: foghost Date: Mon, 28 Aug 2023 19:14:23 +0800 Subject: [PATCH 3/3] fix: metric module init exactly once when there is multiple service or reference --- metrics/api.go | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/metrics/api.go b/metrics/api.go index 5fbcc0be77..b6398c49ea 100644 --- a/metrics/api.go +++ b/metrics/api.go @@ -17,6 +17,10 @@ package metrics +import ( + "sync" +) + import ( "dubbo.apache.org/dubbo-go/v3/common" "dubbo.apache.org/dubbo-go/v3/common/constant" @@ -26,6 +30,7 @@ var ( registries = make(map[string]func(*common.URL) MetricRegistry) collectors = make([]CollectorFunc, 0) registry MetricRegistry + once sync.Once ) // CollectorFunc used to extend more indicators @@ -33,16 +38,18 @@ type CollectorFunc func(MetricRegistry, *common.URL) // Init Metrics module func Init(url *common.URL) { - InitAppInfo(url.GetParam(constant.ApplicationKey, ""), url.GetParam(constant.AppVersionKey, "")) - // defalut protocol is already set in metricConfig - regFunc, ok := registries[url.Protocol] - if ok { - registry = regFunc(url) - for _, co := range collectors { - co(registry, url) + once.Do(func() { + InitAppInfo(url.GetParam(constant.ApplicationKey, ""), url.GetParam(constant.AppVersionKey, "")) + // defalut protocol is already set in metricConfig + regFunc, ok := registries[url.Protocol] + if ok { + registry = regFunc(url) + for _, co := range collectors { + co(registry, url) + } + registry.Export() } - registry.Export() - } + }) } // SetRegistry extend more MetricRegistry, default PrometheusRegistry