This is an automated email from the ASF dual-hosted git repository.
github-actions[bot] pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-kubernetes.git
The following commit(s) were added to refs/heads/master by this push:
new 04a44213 Refactoring for observability (#1018)
04a44213 is described below
commit 04a442135aa558c89c8307c44d28430ac56fdec0
Author: mfordjody <[email protected]>
AuthorDate: Fri Aug 14 19:12:42 2026 +0800
Refactoring for observability (#1018)
---
.../pkg/bootstrap/inherent_grpc_controller.go | 98 ++++++++++++++++++----
.../pkg/bootstrap/inherent_grpc_controller_test.go | 64 +++++++++++++-
.../pkg/config/kube/crd/conversion_test.go | 2 +-
.../pkg/config/kube/crdclient/types.gen.go | 28 +++----
.../config/kube/gateway/deployment_controller.go | 2 +-
.../kube/gateway/deployment_controller_test.go | 4 +-
go.mod | 8 +-
go.sum | 8 +-
manifests/charts/base/files/crd-all.gen.yaml | 74 ++++++++++++++--
.../schema/codegen/templates/clients.go.tmpl | 2 +-
.../schema/codegen/templates/crdclient.go.tmpl | 2 +-
pkg/config/schema/codegen/templates/types.go.tmpl | 2 +-
pkg/config/schema/collections/collections.gen.go | 10 +--
pkg/config/schema/gvk/resources.gen.go | 2 +-
pkg/config/schema/gvr/resources.gen.go | 2 +-
pkg/config/schema/kubeclient/resources.gen.go | 16 ++--
pkg/config/schema/kubetypes/resources.gen.go | 8 +-
pkg/config/schema/metadata.yaml | 6 +-
pkg/config/telemetry/telemetry.go | 79 ++++++++++++++++-
pkg/config/telemetry/telemetry_test.go | 76 ++++++++++++++++-
pkg/config/validation/validators.go | 55 +++++++++++-
pkg/config/validation/validators_test.go | 56 ++++++++++++-
pkg/webhooks/server/server.go | 2 +-
pkg/webhooks/server/server_test.go | 2 +-
samples/addons/telemetry.yaml | 47 +++--------
25 files changed, 538 insertions(+), 117 deletions(-)
diff --git a/dubbod/discovery/pkg/bootstrap/inherent_grpc_controller.go
b/dubbod/discovery/pkg/bootstrap/inherent_grpc_controller.go
index aa0970ba..64e2b814 100644
--- a/dubbod/discovery/pkg/bootstrap/inherent_grpc_controller.go
+++ b/dubbod/discovery/pkg/bootstrap/inherent_grpc_controller.go
@@ -31,7 +31,9 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/config/constants"
configlabels "github.com/apache/dubbo-kubernetes/pkg/config/labels"
meshconfig "github.com/apache/dubbo-kubernetes/pkg/config/mesh"
+ "github.com/apache/dubbo-kubernetes/pkg/config/schema/gvk"
"github.com/apache/dubbo-kubernetes/pkg/config/schema/kind"
+ telemetryconfig
"github.com/apache/dubbo-kubernetes/pkg/config/telemetry"
"github.com/apache/dubbo-kubernetes/pkg/grpcxds"
kubelib "github.com/apache/dubbo-kubernetes/pkg/kube"
"github.com/apache/dubbo-kubernetes/pkg/kube/controllers"
@@ -239,7 +241,7 @@ func inherentGRPCRuntimeConfigNeedsUpdate(req
*discoverymodel.PushRequest) bool
}
for cfg := range req.ConfigsUpdated {
switch cfg.Kind {
- case kind.HTTPRoute, kind.BackendTLSPolicy,
kind.CircuitBreakerPolicy, kind.FaultInjectionPolicy, kind.PeerAuthentication,
kind.RequestAuthentication, kind.AuthorizationPolicy, kind.Service,
kind.EndpointSlice, kind.Endpoints, kind.Pod, kind.Namespace:
+ case kind.HTTPRoute, kind.BackendTLSPolicy,
kind.CircuitBreakerPolicy, kind.FaultInjectionPolicy, kind.PeerAuthentication,
kind.RequestAuthentication, kind.AuthorizationPolicy, kind.Telemetry,
kind.Service, kind.EndpointSlice, kind.Endpoints, kind.Pod, kind.Namespace:
return true
}
}
@@ -357,15 +359,36 @@ type inherentGRPCWorkloadContext struct {
}
type inherentGRPCRuntimeConfig struct {
- Version string `json:"version"`
- Mode string `json:"mode"`
- Env map[string]string `json:"env"`
- Bootstrap inherentGRPCBootstrapRuntimeConfig `json:"bootstrap"`
- Certificates inherentGRPCCertRuntimeConfig `json:"certificates"`
- Keepalive inherentGRPCKeepaliveRuntimeConfig `json:"keepalive"`
- Workload inherentGRPCWorkloadRuntimeConfig `json:"workload"`
- Services []inherentGRPCServiceRuntimeConfig
`json:"services,omitempty"`
- Routes []inherentGRPCRouteRuntimeConfig
`json:"routes,omitempty"`
+ Version string `json:"version"`
+ Mode string `json:"mode"`
+ Env map[string]string `json:"env"`
+ Bootstrap inherentGRPCBootstrapRuntimeConfig `json:"bootstrap"`
+ Certificates inherentGRPCCertRuntimeConfig `json:"certificates"`
+ Keepalive inherentGRPCKeepaliveRuntimeConfig `json:"keepalive"`
+ Workload inherentGRPCWorkloadRuntimeConfig `json:"workload"`
+ Telemetry *inherentGRPCTelemetryRuntimeConfig
`json:"telemetry,omitempty"`
+ Services []inherentGRPCServiceRuntimeConfig
`json:"services,omitempty"`
+ Routes []inherentGRPCRouteRuntimeConfig
`json:"routes,omitempty"`
+}
+
+type inherentGRPCTelemetryRuntimeConfig struct {
+ Metrics *inherentGRPCMetricsRuntimeConfig `json:"metrics,omitempty"`
+}
+
+type inherentGRPCMetricsRuntimeConfig struct {
+ Enabled bool `json:"enabled"`
+ Providers []string
`json:"providers,omitempty"`
+ Rules []inherentGRPCMetricRuleRuntimeConfig `json:"rules,omitempty"`
+}
+
+type inherentGRPCMetricRuleRuntimeConfig struct {
+ Metric string `json:"metric"`
+ Scope string `json:"scope"`
+ Tags map[string]inherentGRPCTagOverrideRuntimeConfig
`json:"tags,omitempty"`
+}
+
+type inherentGRPCTagOverrideRuntimeConfig struct {
+ Action string `json:"action"`
}
type inherentGRPCBootstrapRuntimeConfig struct {
@@ -479,7 +502,7 @@ func (c *inherentGRPCWorkloadController) buildSecret(pod
*corev1.Pod, current *c
}
services, routes := c.buildRuntimeTrafficConfig()
- runtimeConfigJSON, err := buildRuntimeConfigJSON(workload, services,
routes)
+ runtimeConfigJSON, err := buildRuntimeConfigJSON(workload, services,
routes, c.resolveTelemetry(pod))
if err != nil {
return nil, time.Time{}, err
}
@@ -496,6 +519,22 @@ func (c *inherentGRPCWorkloadController) buildSecret(pod
*corev1.Pod, current *c
return secret, expireAt, nil
}
+func (c *inherentGRPCWorkloadController) resolveTelemetry(pod *corev1.Pod)
telemetryconfig.EffectiveTracing {
+ if c == nil || c.server == nil || c.server.environment == nil ||
c.server.environment.ConfigStore == nil || pod == nil {
+ return telemetryconfig.EffectiveTracing{}
+ }
+ meshNamespace := c.server.namespace
+ if meshNamespace == "" {
+ meshNamespace = constants.DubboSystemNamespace
+ }
+ return telemetryconfig.Resolve(
+
telemetryconfig.ResourcesFromConfigs(c.server.environment.List(gvk.Telemetry,
"")),
+ meshNamespace,
+ pod.Namespace,
+ pod.Labels,
+ )
+}
+
func buildInherentGRPCSecret(pod *corev1.Pod, bootstrapJSON,
runtimeConfigJSON, certChain, keyPEM, rootCert []byte) *corev1.Secret {
return &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
@@ -666,7 +705,12 @@ func buildBootstrapJSON(workload
*inherentGRPCWorkloadContext) ([]byte, error) {
return json.MarshalIndent(bootstrapCfg, "", " ")
}
-func buildRuntimeConfigJSON(workload *inherentGRPCWorkloadContext, services
[]inherentGRPCServiceRuntimeConfig, routes []inherentGRPCRouteRuntimeConfig)
([]byte, error) {
+func buildRuntimeConfigJSON(
+ workload *inherentGRPCWorkloadContext,
+ services []inherentGRPCServiceRuntimeConfig,
+ routes []inherentGRPCRouteRuntimeConfig,
+ effectiveTelemetry telemetryconfig.EffectiveTracing,
+) ([]byte, error) {
cfg := inherentGRPCRuntimeConfig{
Version: inherentGRPCRuntimeConfigVersion,
Mode: "inherent-grpc",
@@ -719,12 +763,38 @@ func buildRuntimeConfigJSON(workload
*inherentGRPCWorkloadContext, services []in
TrustDomain: workload.trustDomain,
ClusterID: workload.clusterID,
},
- Services: services,
- Routes: routes,
+ Telemetry: inherentGRPCTelemetryConfig(effectiveTelemetry),
+ Services: services,
+ Routes: routes,
}
return json.MarshalIndent(cfg, "", " ")
}
+func inherentGRPCTelemetryConfig(effective telemetryconfig.EffectiveTracing)
*inherentGRPCTelemetryRuntimeConfig {
+ if !effective.MetricsConfigured {
+ return nil
+ }
+ metrics := &inherentGRPCMetricsRuntimeConfig{
+ Enabled: effective.MetricsEnabled(),
+ Providers: append([]string(nil), effective.MetricProviders...),
+ Rules: make([]inherentGRPCMetricRuleRuntimeConfig, 0,
len(effective.MetricRules)),
+ }
+ for _, rule := range effective.MetricRules {
+ runtimeRule := inherentGRPCMetricRuleRuntimeConfig{
+ Metric: rule.Metric.String(),
+ Scope: rule.Scope.String(),
+ }
+ if len(rule.Tags) > 0 {
+ runtimeRule.Tags =
make(map[string]inherentGRPCTagOverrideRuntimeConfig, len(rule.Tags))
+ for _, tag := range rule.Tags {
+ runtimeRule.Tags[tag.Name] =
inherentGRPCTagOverrideRuntimeConfig{Action: tag.Action.String()}
+ }
+ }
+ metrics.Rules = append(metrics.Rules, runtimeRule)
+ }
+ return &inherentGRPCTelemetryRuntimeConfig{Metrics: metrics}
+}
+
func (c *inherentGRPCWorkloadController) buildRuntimeTrafficConfig()
([]inherentGRPCServiceRuntimeConfig, []inherentGRPCRouteRuntimeConfig) {
if c.server == nil || c.server.environment == nil {
return nil, nil
diff --git a/dubbod/discovery/pkg/bootstrap/inherent_grpc_controller_test.go
b/dubbod/discovery/pkg/bootstrap/inherent_grpc_controller_test.go
index b3c994e5..164e6ebe 100644
--- a/dubbod/discovery/pkg/bootstrap/inherent_grpc_controller_test.go
+++ b/dubbod/discovery/pkg/bootstrap/inherent_grpc_controller_test.go
@@ -31,6 +31,7 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/config/schema/collections"
"github.com/apache/dubbo-kubernetes/pkg/config/schema/gvk"
"github.com/apache/dubbo-kubernetes/pkg/config/schema/kind"
+ telemetryconfig
"github.com/apache/dubbo-kubernetes/pkg/config/telemetry"
"github.com/apache/dubbo-kubernetes/pkg/grpcxds"
"github.com/apache/dubbo-kubernetes/pkg/kube/controllers"
"github.com/apache/dubbo-kubernetes/pkg/kube/inject"
@@ -38,6 +39,7 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/util/sets"
networking "github.com/kdubbo/api/networking/v1alpha3"
security "github.com/kdubbo/api/security/v1alpha3"
+ telemetryapi "github.com/kdubbo/api/telemetry/v1alpha3"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/wrapperspb"
corev1 "k8s.io/api/core/v1"
@@ -149,7 +151,19 @@ func TestBuildRuntimeConfigJSON(t *testing.T) {
caAddress: "192.168.15.164:32049",
}
- data, err := buildRuntimeConfigJSON(workload, nil, nil)
+ effectiveTelemetry := telemetryconfig.EffectiveTracing{
+ MetricsConfigured: true,
+ MetricProviders: []string{telemetryconfig.PrometheusProvider},
+ MetricRules: []telemetryconfig.MetricRule{{
+ Metric: telemetryapi.StandardMetric_REQUEST_COUNT,
+ Scope: telemetryapi.MetricScope_CLIENT_AND_SERVER,
+ Tags: []telemetryconfig.MetricTagOverride{{
+ Name: "grpc_response_status",
+ Action: telemetryapi.TagOverride_REMOVE,
+ }},
+ }},
+ }
+ data, err := buildRuntimeConfigJSON(workload, nil, nil,
effectiveTelemetry)
if err != nil {
t.Fatalf("buildRuntimeConfigJSON() failed: %v", err)
}
@@ -222,6 +236,54 @@ func TestBuildRuntimeConfigJSON(t *testing.T) {
if got.Workload.ClusterID != workload.clusterID {
t.Fatalf("clusterId = %q, want %q", got.Workload.ClusterID,
workload.clusterID)
}
+ if got.Telemetry == nil || got.Telemetry.Metrics == nil ||
!got.Telemetry.Metrics.Enabled {
+ t.Fatalf("telemetry metrics = %#v, want enabled", got.Telemetry)
+ }
+ if len(got.Telemetry.Metrics.Rules) != 1 {
+ t.Fatalf("telemetry rules = %#v, want one",
got.Telemetry.Metrics.Rules)
+ }
+ rule := got.Telemetry.Metrics.Rules[0]
+ if rule.Metric != "REQUEST_COUNT" || rule.Scope != "CLIENT_AND_SERVER" {
+ t.Fatalf("telemetry rule = %#v", rule)
+ }
+ if tag := rule.Tags["grpc_response_status"]; tag.Action != "REMOVE" {
+ t.Fatalf("grpc_response_status override = %#v", tag)
+ }
+}
+
+func TestResolveInherentTelemetryForWorkload(t *testing.T) {
+ env, _ := newInherentRuntimeTestEnvironment(t, []config.Config{{
+ Meta: config.Meta{
+ GroupVersionKind: gvk.Telemetry,
+ Name: "metrics-tags",
+ Namespace: constants.DubboSystemNamespace,
+ },
+ Spec: &telemetryapi.Telemetry{Metrics: []*telemetryapi.Metrics{{
+ Providers:
[]*telemetryapi.Metrics_MetricsProvider{{Name:
telemetryconfig.PrometheusProvider}},
+ Rules: []*telemetryapi.MetricRule{{
+ Metric:
telemetryapi.StandardMetric_REQUEST_COUNT,
+ Scope:
telemetryapi.MetricScope_CLIENT_AND_SERVER,
+ Tags: map[string]*telemetryapi.TagOverride{
+ "grpc_response_status": {Action:
telemetryapi.TagOverride_REMOVE},
+ },
+ }},
+ }}},
+ }}, nil)
+ controller := &inherentGRPCWorkloadController{server: &Server{
+ environment: env,
+ namespace: constants.DubboSystemNamespace,
+ }}
+
+ got := controller.resolveTelemetry(&corev1.Pod{ObjectMeta:
metav1.ObjectMeta{
+ Namespace: "app",
+ Labels: map[string]string{"app": "frontend"},
+ }})
+ if !got.MetricsEnabled() || len(got.MetricRules) != 1 {
+ t.Fatalf("resolved telemetry = %#v", got)
+ }
+ if got.MetricRules[0].Scope !=
telemetryapi.MetricScope_CLIENT_AND_SERVER {
+ t.Fatalf("scope = %s, want CLIENT_AND_SERVER",
got.MetricRules[0].Scope)
+ }
}
func TestBuildWorkloadContextUsesInjectedRemoteValues(t *testing.T) {
diff --git a/dubbod/discovery/pkg/config/kube/crd/conversion_test.go
b/dubbod/discovery/pkg/config/kube/crd/conversion_test.go
index fe45627a..59321b14 100644
--- a/dubbod/discovery/pkg/config/kube/crd/conversion_test.go
+++ b/dubbod/discovery/pkg/config/kube/crd/conversion_test.go
@@ -19,7 +19,7 @@ import (
"testing"
"github.com/apache/dubbo-kubernetes/pkg/config/schema/collections"
- telemetry "github.com/kdubbo/api/telemetry/v1alpha1"
+ telemetry "github.com/kdubbo/api/telemetry/v1alpha3"
)
func TestFromJSONTelemetryScalarWrappers(t *testing.T) {
diff --git a/dubbod/discovery/pkg/config/kube/crdclient/types.gen.go
b/dubbod/discovery/pkg/config/kube/crdclient/types.gen.go
index 731cc4db..67eb7da9 100755
--- a/dubbod/discovery/pkg/config/kube/crdclient/types.gen.go
+++ b/dubbod/discovery/pkg/config/kube/crdclient/types.gen.go
@@ -17,10 +17,10 @@ import (
githubcomkdubboapimetav1alpha1 "github.com/kdubbo/api/meta/v1alpha1"
githubcomkdubboapinetworkingv1alpha3
"github.com/kdubbo/api/networking/v1alpha3"
githubcomkdubboapisecurityv1alpha3
"github.com/kdubbo/api/security/v1alpha3"
- githubcomkdubboapitelemetryv1alpha1
"github.com/kdubbo/api/telemetry/v1alpha1"
+ githubcomkdubboapitelemetryv1alpha3
"github.com/kdubbo/api/telemetry/v1alpha3"
apigithubcomapachedubbokubernetesapinetworkingv1alpha3
"github.com/kdubbo/client-go/pkg/apis/networking/v1alpha3"
apigithubcomapachedubbokubernetesapisecurityv1alpha3
"github.com/kdubbo/client-go/pkg/apis/security/v1alpha3"
- apigithubcomapachedubbokubernetesapitelemetryv1alpha1
"github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha1"
+ apigithubcomapachedubbokubernetesapitelemetryv1alpha3
"github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha3"
k8sioapiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1"
k8sioapiappsv1 "k8s.io/api/apps/v1"
k8sioapiautoscalingv2 "k8s.io/api/autoscaling/v2"
@@ -101,9 +101,9 @@ func create(c kube.Client, cfg config.Config, objMeta
metav1.ObjectMeta) (metav1
Spec:
*(cfg.Spec.(*githubcomkdubboapinetworkingv1alpha3.ServiceEntry)),
}, metav1.CreateOptions{})
case gvk.Telemetry:
- return
c.Dubbo().TelemetryV1alpha1().Telemetries(cfg.Namespace).Create(context.TODO(),
&apigithubcomapachedubbokubernetesapitelemetryv1alpha1.Telemetry{
+ return
c.Dubbo().TelemetryV1alpha3().Telemetries(cfg.Namespace).Create(context.TODO(),
&apigithubcomapachedubbokubernetesapitelemetryv1alpha3.Telemetry{
ObjectMeta: objMeta,
- Spec:
*(cfg.Spec.(*githubcomkdubboapitelemetryv1alpha1.Telemetry)),
+ Spec:
*(cfg.Spec.(*githubcomkdubboapitelemetryv1alpha3.Telemetry)),
}, metav1.CreateOptions{})
case gvk.WorkloadEntry:
return
c.Dubbo().NetworkingV1alpha3().WorkloadEntries(cfg.Namespace).Create(context.TODO(),
&apigithubcomapachedubbokubernetesapinetworkingv1alpha3.WorkloadEntry{
@@ -183,9 +183,9 @@ func update(c kube.Client, cfg config.Config, objMeta
metav1.ObjectMeta) (metav1
Spec:
*(cfg.Spec.(*githubcomkdubboapinetworkingv1alpha3.ServiceEntry)),
}, metav1.UpdateOptions{})
case gvk.Telemetry:
- return
c.Dubbo().TelemetryV1alpha1().Telemetries(cfg.Namespace).Update(context.TODO(),
&apigithubcomapachedubbokubernetesapitelemetryv1alpha1.Telemetry{
+ return
c.Dubbo().TelemetryV1alpha3().Telemetries(cfg.Namespace).Update(context.TODO(),
&apigithubcomapachedubbokubernetesapitelemetryv1alpha3.Telemetry{
ObjectMeta: objMeta,
- Spec:
*(cfg.Spec.(*githubcomkdubboapitelemetryv1alpha1.Telemetry)),
+ Spec:
*(cfg.Spec.(*githubcomkdubboapitelemetryv1alpha3.Telemetry)),
}, metav1.UpdateOptions{})
case gvk.WorkloadEntry:
return
c.Dubbo().NetworkingV1alpha3().WorkloadEntries(cfg.Namespace).Update(context.TODO(),
&apigithubcomapachedubbokubernetesapinetworkingv1alpha3.WorkloadEntry{
@@ -260,7 +260,7 @@ func updateStatus(c kube.Client, cfg config.Config, objMeta
metav1.ObjectMeta) (
Status:
*(cfg.Status.(*githubcomkdubboapimetav1alpha1.DubboStatus)),
}, metav1.UpdateOptions{})
case gvk.Telemetry:
- return
c.Dubbo().TelemetryV1alpha1().Telemetries(cfg.Namespace).UpdateStatus(context.TODO(),
&apigithubcomapachedubbokubernetesapitelemetryv1alpha1.Telemetry{
+ return
c.Dubbo().TelemetryV1alpha3().Telemetries(cfg.Namespace).UpdateStatus(context.TODO(),
&apigithubcomapachedubbokubernetesapitelemetryv1alpha3.Telemetry{
ObjectMeta: objMeta,
Status:
*(cfg.Status.(*githubcomkdubboapimetav1alpha1.DubboStatus)),
}, metav1.UpdateOptions{})
@@ -475,19 +475,19 @@ func patch(c kube.Client, orig config.Config, origMeta
metav1.ObjectMeta, mod co
return
c.Dubbo().NetworkingV1alpha3().ServiceEntries(orig.Namespace).
Patch(context.TODO(), orig.Name, typ, patchBytes,
metav1.PatchOptions{FieldManager: "pilot-discovery"})
case gvk.Telemetry:
- oldRes :=
&apigithubcomapachedubbokubernetesapitelemetryv1alpha1.Telemetry{
+ oldRes :=
&apigithubcomapachedubbokubernetesapitelemetryv1alpha3.Telemetry{
ObjectMeta: origMeta,
- Spec:
*(orig.Spec.(*githubcomkdubboapitelemetryv1alpha1.Telemetry)),
+ Spec:
*(orig.Spec.(*githubcomkdubboapitelemetryv1alpha3.Telemetry)),
}
- modRes :=
&apigithubcomapachedubbokubernetesapitelemetryv1alpha1.Telemetry{
+ modRes :=
&apigithubcomapachedubbokubernetesapitelemetryv1alpha3.Telemetry{
ObjectMeta: modMeta,
- Spec:
*(mod.Spec.(*githubcomkdubboapitelemetryv1alpha1.Telemetry)),
+ Spec:
*(mod.Spec.(*githubcomkdubboapitelemetryv1alpha3.Telemetry)),
}
patchBytes, err := genPatchBytes(oldRes, modRes, typ)
if err != nil {
return nil, err
}
- return
c.Dubbo().TelemetryV1alpha1().Telemetries(orig.Namespace).
+ return
c.Dubbo().TelemetryV1alpha3().Telemetries(orig.Namespace).
Patch(context.TODO(), orig.Name, typ, patchBytes,
metav1.PatchOptions{FieldManager: "pilot-discovery"})
case gvk.WorkloadEntry:
oldRes :=
&apigithubcomapachedubbokubernetesapinetworkingv1alpha3.WorkloadEntry{
@@ -542,7 +542,7 @@ func delete(c kube.Client, typ config.GroupVersionKind,
name, namespace string,
case gvk.ServiceEntry:
return
c.Dubbo().NetworkingV1alpha3().ServiceEntries(namespace).Delete(context.TODO(),
name, deleteOptions)
case gvk.Telemetry:
- return
c.Dubbo().TelemetryV1alpha1().Telemetries(namespace).Delete(context.TODO(),
name, deleteOptions)
+ return
c.Dubbo().TelemetryV1alpha3().Telemetries(namespace).Delete(context.TODO(),
name, deleteOptions)
case gvk.WorkloadEntry:
return
c.Dubbo().NetworkingV1alpha3().WorkloadEntries(namespace).Delete(context.TODO(),
name, deleteOptions)
default:
@@ -1107,7 +1107,7 @@ var translationMap = map[config.GroupVersionKind]func(r
runtime.Object) config.C
}
},
gvk.Telemetry: func(r runtime.Object) config.Config {
- obj :=
r.(*apigithubcomapachedubbokubernetesapitelemetryv1alpha1.Telemetry)
+ obj :=
r.(*apigithubcomapachedubbokubernetesapitelemetryv1alpha3.Telemetry)
return config.Config{
Meta: config.Meta{
GroupVersionKind: gvk.Telemetry,
diff --git a/dubbod/discovery/pkg/config/kube/gateway/deployment_controller.go
b/dubbod/discovery/pkg/config/kube/gateway/deployment_controller.go
index 8ce60041..6e4ccd28 100644
--- a/dubbod/discovery/pkg/config/kube/gateway/deployment_controller.go
+++ b/dubbod/discovery/pkg/config/kube/gateway/deployment_controller.go
@@ -55,7 +55,7 @@ import (
dubbolog "github.com/apache/dubbo-kubernetes/pkg/log"
networking "github.com/kdubbo/api/networking/v1alpha3"
clientnetworking
"github.com/kdubbo/client-go/pkg/apis/networking/v1alpha3"
- clienttelemetry
"github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha1"
+ clienttelemetry
"github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha3"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/wrapperspb"
)
diff --git
a/dubbod/discovery/pkg/config/kube/gateway/deployment_controller_test.go
b/dubbod/discovery/pkg/config/kube/gateway/deployment_controller_test.go
index 05784f99..a3fbcd87 100644
--- a/dubbod/discovery/pkg/config/kube/gateway/deployment_controller_test.go
+++ b/dubbod/discovery/pkg/config/kube/gateway/deployment_controller_test.go
@@ -30,7 +30,7 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/kube/inject"
"github.com/google/go-cmp/cmp"
networking "github.com/kdubbo/api/networking/v1alpha3"
- apitelemetry "github.com/kdubbo/api/telemetry/v1alpha1"
+ apitelemetry "github.com/kdubbo/api/telemetry/v1alpha3"
typeapi "github.com/kdubbo/api/type/v1alpha3"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/wrapperspb"
@@ -768,6 +768,7 @@ func TestKubeGatewayTemplateRendersDxgateResources(t
*testing.T) {
!strings.Contains(rendered[4], `value:
"http://tracing.dubbo-system.svc:4317"`) {
t.Fatalf("deployment did not render dxgate OTEL endpoint:\n%s",
rendered[4])
}
+
}
// TestKubeGatewayTemplateRendersHighAvailabilityResources covers the path a
@@ -874,7 +875,6 @@ func TestResolveGatewayObservabilityTelemetryHierarchy(t
*testing.T) {
if cfg.OtelTags != `{"userId":"unknown"}` {
t.Fatalf("otel tags = %q", cfg.OtelTags)
}
-
resources = append(resources, telemetryconfig.Resource{
Name: "workload-override", Namespace: "app", CreationTimestamp:
time.Unix(3, 0),
Spec: &apitelemetry.Telemetry{
diff --git a/go.mod b/go.mod
index 8089457e..44e1549a 100644
--- a/go.mod
+++ b/go.mod
@@ -17,6 +17,10 @@ module github.com/apache/dubbo-kubernetes
go 1.25.12
+replace github.com/kdubbo/api => ../api
+
+replace github.com/kdubbo/client-go => ../client-go
+
require (
k8s.io/apimachinery v0.34.1
k8s.io/client-go v0.34.1
@@ -42,8 +46,8 @@ require (
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/kdubbo/api v0.0.0-20260811085311-7752d1da2bcb
- github.com/kdubbo/client-go v0.0.0-20260811085609-07dfedad5b33
- github.com/kdubbo/xds-api v0.0.0-20260811085311-5a7b086ecdc6
+ github.com/kdubbo/client-go v0.0.0-20260809042806-04a31db14165
+ github.com/kdubbo/xds-api v0.0.0-20260809042456-0d57cc43a21a
github.com/prometheus/client_golang v1.23.2
github.com/prometheus/client_model v0.6.2
github.com/spf13/cobra v1.10.2
diff --git a/go.sum b/go.sum
index 45722ad4..bab6d2cf 100644
--- a/go.sum
+++ b/go.sum
@@ -154,12 +154,8 @@ github.com/inconshreveable/mousetrap v1.1.0
h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
github.com/inconshreveable/mousetrap v1.1.0/go.mod
h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/json-iterator/go v1.1.12
h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod
h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
-github.com/kdubbo/api v0.0.0-20260811085311-7752d1da2bcb
h1:BYIqwRc/1D9xsHXonODshRwgEgMIip6nAWF1oMuWFhI=
-github.com/kdubbo/api v0.0.0-20260811085311-7752d1da2bcb/go.mod
h1:8BtJiIovg7QCPsCxXcw3gDf922VcvYq5ihOSvj49Rq8=
-github.com/kdubbo/client-go v0.0.0-20260811085609-07dfedad5b33
h1:Xtv/mwzQdww5uGk0t+En7X843chTKgFWen1DCDmSq8s=
-github.com/kdubbo/client-go v0.0.0-20260811085609-07dfedad5b33/go.mod
h1:J7zo0kp1Q+2JanfPHasOvasgsCJ+I5RZpd42DhcMMuw=
-github.com/kdubbo/xds-api v0.0.0-20260811085311-5a7b086ecdc6
h1:Oodawr6d7r8N6hXImlXkpMs9+dECFbRWCZZ0nIiG00k=
-github.com/kdubbo/xds-api v0.0.0-20260811085311-5a7b086ecdc6/go.mod
h1:o2HDUgL1ntaDbWomZ4cD2tt8jBamuG2qRtjXOa1zZ0Q=
+github.com/kdubbo/xds-api v0.0.0-20260809042456-0d57cc43a21a
h1:stTvOOGy4r6DoxquO928mB9AGGoFBvjVHxqAGIGiSkI=
+github.com/kdubbo/xds-api v0.0.0-20260809042456-0d57cc43a21a/go.mod
h1:o2HDUgL1ntaDbWomZ4cD2tt8jBamuG2qRtjXOa1zZ0Q=
github.com/kisielk/errcheck v1.5.0/go.mod
h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod
h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.18.6
h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao=
diff --git a/manifests/charts/base/files/crd-all.gen.yaml
b/manifests/charts/base/files/crd-all.gen.yaml
index f95f087b..6ca35631 100644
--- a/manifests/charts/base/files/crd-all.gen.yaml
+++ b/manifests/charts/base/files/crd-all.gen.yaml
@@ -1593,14 +1593,74 @@ spec:
jsonPath: .metadata.creationTimestamp
name: Age
type: date
- name: v1alpha1
+ name: v1alpha3
schema:
openAPIV3Schema:
properties:
spec:
- description: 'Telemetry configuration for workloads. See more
details
- at: '
+ description: 'Telemetry configuration for Inherent workloads. See
more
+ details at: '
properties:
+ metrics:
+ description: Metrics configures metric generation for selected
workloads.
+ items:
+ properties:
+ enabled:
+ description: Controls metric generation.
+ nullable: true
+ type: boolean
+ providers:
+ description: Providers used for metric reporting.
+ items:
+ properties:
+ name:
+ description: REQUIRED.
+ type: string
+ type: object
+ type: array
+ rules:
+ description: Rules customize standard metrics.
+ items:
+ properties:
+ metric:
+ description: |-
+ REQUIRED.
+
+ Valid Options: REQUEST_COUNT
+ enum:
+ - STANDARD_METRIC_UNSPECIFIED
+ - REQUEST_COUNT
+ type: string
+ scope:
+ description: |-
+ REQUIRED.
+
+ Valid Options: CLIENT, SERVER, CLIENT_AND_SERVER
+ enum:
+ - METRIC_SCOPE_UNSPECIFIED
+ - CLIENT
+ - SERVER
+ - CLIENT_AND_SERVER
+ type: string
+ tags:
+ additionalProperties:
+ properties:
+ action:
+ description: |-
+ REQUIRED.
+
+ Valid Options: REMOVE
+ enum:
+ - ACTION_UNSPECIFIED
+ - REMOVE
+ type: string
+ type: object
+ description: Tag overrides keyed by metric tag
name.
+ type: object
+ type: object
+ type: array
+ type: object
+ type: array
selector:
description: The selector determines the workloads to apply
the Telemetry
on.
@@ -1621,12 +1681,11 @@ spec:
rule: self.all(key, key.size() != 0)
type: object
tracing:
- description: Tracing configures the tracing behavior for all
selected
- workloads.
+ description: Tracing configures tracing behavior for selected
workloads.
items:
properties:
disableSpanReporting:
- description: Controls span reporting.
+ description: Disables span reporting for selected
workloads.
nullable: true
type: boolean
providers:
@@ -1639,8 +1698,7 @@ spec:
type: object
type: array
randomSamplingPercentage:
- description: Controls the rate at which traffic will be
selected
- for tracing if no prior sampling decision has been
made.
+ description: Sampling percentage in range [0.0, 100.0].
format: double
nullable: true
type: number
diff --git a/pkg/config/schema/codegen/templates/clients.go.tmpl
b/pkg/config/schema/codegen/templates/clients.go.tmpl
index 89d314fb..7f8be9d5 100644
--- a/pkg/config/schema/codegen/templates/clients.go.tmpl
+++ b/pkg/config/schema/codegen/templates/clients.go.tmpl
@@ -19,7 +19,7 @@ import (
apigithubcomapachedubbokubernetesapinetworkingv1alpha3
"github.com/kdubbo/client-go/pkg/apis/networking/v1alpha3"
apigithubcomapachedubbokubernetesapisecurityv1alpha3
"github.com/kdubbo/client-go/pkg/apis/security/v1alpha3"
- apigithubcomapachedubbokubernetesapitelemetryv1alpha1
"github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha1"
+ apigithubcomapachedubbokubernetesapitelemetryv1alpha3
"github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha3"
{{- range .Packages}}
{{.ImportName}} "{{.PackageName}}"
{{- end}}
diff --git a/pkg/config/schema/codegen/templates/crdclient.go.tmpl
b/pkg/config/schema/codegen/templates/crdclient.go.tmpl
index d2edadec..0017546e 100644
--- a/pkg/config/schema/codegen/templates/crdclient.go.tmpl
+++ b/pkg/config/schema/codegen/templates/crdclient.go.tmpl
@@ -16,7 +16,7 @@ import (
apigithubcomapachedubbokubernetesapinetworkingv1alpha3
"github.com/kdubbo/client-go/pkg/apis/networking/v1alpha3"
apigithubcomapachedubbokubernetesapisecurityv1alpha3
"github.com/kdubbo/client-go/pkg/apis/security/v1alpha3"
- apigithubcomapachedubbokubernetesapitelemetryv1alpha1
"github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha1"
+ apigithubcomapachedubbokubernetesapitelemetryv1alpha3
"github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha3"
{{- range .Packages}}
{{.ImportName}} "{{.PackageName}}"
{{- end}}
diff --git a/pkg/config/schema/codegen/templates/types.go.tmpl
b/pkg/config/schema/codegen/templates/types.go.tmpl
index 33cd99e0..d4e6a19e 100644
--- a/pkg/config/schema/codegen/templates/types.go.tmpl
+++ b/pkg/config/schema/codegen/templates/types.go.tmpl
@@ -10,7 +10,7 @@ import (
{{- end}}
apigithubcomapachedubbokubernetesapinetworkingv1alpha3
"github.com/kdubbo/client-go/pkg/apis/networking/v1alpha3"
apigithubcomapachedubbokubernetesapisecurityv1alpha3
"github.com/kdubbo/client-go/pkg/apis/security/v1alpha3"
- apigithubcomapachedubbokubernetesapitelemetryv1alpha1
"github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha1"
+ apigithubcomapachedubbokubernetesapitelemetryv1alpha3
"github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha3"
)
func getGvk(obj any) (config.GroupVersionKind, bool) {
diff --git a/pkg/config/schema/collections/collections.gen.go
b/pkg/config/schema/collections/collections.gen.go
index 9d82b78a..3b31b9b2 100755
--- a/pkg/config/schema/collections/collections.gen.go
+++ b/pkg/config/schema/collections/collections.gen.go
@@ -15,7 +15,7 @@ import (
githubcomkdubboapimetav1alpha1 "github.com/kdubbo/api/meta/v1alpha1"
githubcomkdubboapinetworkingv1alpha3
"github.com/kdubbo/api/networking/v1alpha3"
githubcomkdubboapisecurityv1alpha3
"github.com/kdubbo/api/security/v1alpha3"
- githubcomkdubboapitelemetryv1alpha1
"github.com/kdubbo/api/telemetry/v1alpha1"
+ githubcomkdubboapitelemetryv1alpha3
"github.com/kdubbo/api/telemetry/v1alpha3"
k8sioapiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1"
k8sioapiappsv1 "k8s.io/api/apps/v1"
k8sioapiautoscalingv2 "k8s.io/api/autoscaling/v2"
@@ -514,10 +514,10 @@ var (
Group: "telemetry.dubbo.apache.org",
Kind: "Telemetry",
Plural: "telemetries",
- Version: "v1alpha1",
- Proto: "dubbo.telemetry.v1alpha1.Telemetry", StatusProto:
"dubbo.meta.v1alpha1.DubboStatus",
- ReflectType:
reflect.TypeOf(&githubcomkdubboapitelemetryv1alpha1.Telemetry{}).Elem(),
StatusType:
reflect.TypeOf(&githubcomkdubboapimetav1alpha1.DubboStatus{}).Elem(),
- ProtoPackage: "github.com/kdubbo/api/telemetry/v1alpha1",
StatusPackage: "github.com/kdubbo/api/meta/v1alpha1",
+ Version: "v1alpha3",
+ Proto: "dubbo.telemetry.v1alpha3.Telemetry", StatusProto:
"dubbo.meta.v1alpha1.DubboStatus",
+ ReflectType:
reflect.TypeOf(&githubcomkdubboapitelemetryv1alpha3.Telemetry{}).Elem(),
StatusType:
reflect.TypeOf(&githubcomkdubboapimetav1alpha1.DubboStatus{}).Elem(),
+ ProtoPackage: "github.com/kdubbo/api/telemetry/v1alpha3",
StatusPackage: "github.com/kdubbo/api/meta/v1alpha1",
ClusterScoped: false,
Synthetic: false,
Builtin: false,
diff --git a/pkg/config/schema/gvk/resources.gen.go
b/pkg/config/schema/gvk/resources.gen.go
index b094ac5c..6b5aba6c 100755
--- a/pkg/config/schema/gvk/resources.gen.go
+++ b/pkg/config/schema/gvk/resources.gen.go
@@ -46,7 +46,7 @@ var (
ServiceActivationPolicy = config.GroupVersionKind{Group:
"networking.dubbo.apache.org", Version: "v1alpha3", Kind:
"ServiceActivationPolicy"}
ServiceEntry = config.GroupVersionKind{Group:
"networking.dubbo.apache.org", Version: "v1alpha3", Kind: "ServiceEntry"}
StatefulSet = config.GroupVersionKind{Group: "apps",
Version: "v1", Kind: "StatefulSet"}
- Telemetry = config.GroupVersionKind{Group:
"telemetry.dubbo.apache.org", Version: "v1alpha1", Kind: "Telemetry"}
+ Telemetry = config.GroupVersionKind{Group:
"telemetry.dubbo.apache.org", Version: "v1alpha3", Kind: "Telemetry"}
ValidatingWebhookConfiguration = config.GroupVersionKind{Group:
"admissionregistration.k8s.io", Version: "v1", Kind:
"ValidatingWebhookConfiguration"}
WorkloadEntry = config.GroupVersionKind{Group:
"networking.dubbo.apache.org", Version: "v1alpha3", Kind: "WorkloadEntry"}
)
diff --git a/pkg/config/schema/gvr/resources.gen.go
b/pkg/config/schema/gvr/resources.gen.go
index b71d600f..69c4e42d 100755
--- a/pkg/config/schema/gvr/resources.gen.go
+++ b/pkg/config/schema/gvr/resources.gen.go
@@ -41,7 +41,7 @@ var (
ServiceActivationPolicy = schema.GroupVersionResource{Group:
"networking.dubbo.apache.org", Version: "v1alpha3", Resource:
"serviceactivationpolicies"}
ServiceEntry = schema.GroupVersionResource{Group:
"networking.dubbo.apache.org", Version: "v1alpha3", Resource: "serviceentries"}
StatefulSet = schema.GroupVersionResource{Group:
"apps", Version: "v1", Resource: "statefulsets"}
- Telemetry = schema.GroupVersionResource{Group:
"telemetry.dubbo.apache.org", Version: "v1alpha1", Resource: "telemetries"}
+ Telemetry = schema.GroupVersionResource{Group:
"telemetry.dubbo.apache.org", Version: "v1alpha3", Resource: "telemetries"}
ValidatingWebhookConfiguration = schema.GroupVersionResource{Group:
"admissionregistration.k8s.io", Version: "v1", Resource:
"validatingwebhookconfigurations"}
WorkloadEntry = schema.GroupVersionResource{Group:
"networking.dubbo.apache.org", Version: "v1alpha3", Resource: "workloadentries"}
)
diff --git a/pkg/config/schema/kubeclient/resources.gen.go
b/pkg/config/schema/kubeclient/resources.gen.go
index 61e5a3ab..be1bdd0a 100755
--- a/pkg/config/schema/kubeclient/resources.gen.go
+++ b/pkg/config/schema/kubeclient/resources.gen.go
@@ -19,7 +19,7 @@ import (
apigithubcomapachedubbokubernetesapinetworkingv1alpha3
"github.com/kdubbo/client-go/pkg/apis/networking/v1alpha3"
apigithubcomapachedubbokubernetesapisecurityv1alpha3
"github.com/kdubbo/client-go/pkg/apis/security/v1alpha3"
- apigithubcomapachedubbokubernetesapitelemetryv1alpha1
"github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha1"
+ apigithubcomapachedubbokubernetesapitelemetryv1alpha3
"github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha3"
k8sioapiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1"
k8sioapiappsv1 "k8s.io/api/apps/v1"
k8sioapiautoscalingv2 "k8s.io/api/autoscaling/v2"
@@ -94,8 +94,8 @@ func GetWriteClient[T runtime.Object](c ClientGetter,
namespace string) ktypes.W
return
c.Dubbo().NetworkingV1alpha3().ServiceEntries(namespace).(ktypes.WriteAPI[T])
case *k8sioapiappsv1.StatefulSet:
return
c.Kube().AppsV1().StatefulSets(namespace).(ktypes.WriteAPI[T])
- case *apigithubcomapachedubbokubernetesapitelemetryv1alpha1.Telemetry:
- return
c.Dubbo().TelemetryV1alpha1().Telemetries(namespace).(ktypes.WriteAPI[T])
+ case *apigithubcomapachedubbokubernetesapitelemetryv1alpha3.Telemetry:
+ return
c.Dubbo().TelemetryV1alpha3().Telemetries(namespace).(ktypes.WriteAPI[T])
case *k8sioapiadmissionregistrationv1.ValidatingWebhookConfiguration:
return
c.Kube().AdmissionregistrationV1().ValidatingWebhookConfigurations().(ktypes.WriteAPI[T])
case
*apigithubcomapachedubbokubernetesapinetworkingv1alpha3.WorkloadEntry:
@@ -167,8 +167,8 @@ func GetClient[T, TL runtime.Object](c ClientGetter,
namespace string) ktypes.Re
return
c.Dubbo().NetworkingV1alpha3().ServiceEntries(namespace).(ktypes.ReadWriteAPI[T,
TL])
case *k8sioapiappsv1.StatefulSet:
return
c.Kube().AppsV1().StatefulSets(namespace).(ktypes.ReadWriteAPI[T, TL])
- case *apigithubcomapachedubbokubernetesapitelemetryv1alpha1.Telemetry:
- return
c.Dubbo().TelemetryV1alpha1().Telemetries(namespace).(ktypes.ReadWriteAPI[T,
TL])
+ case *apigithubcomapachedubbokubernetesapitelemetryv1alpha3.Telemetry:
+ return
c.Dubbo().TelemetryV1alpha3().Telemetries(namespace).(ktypes.ReadWriteAPI[T,
TL])
case *k8sioapiadmissionregistrationv1.ValidatingWebhookConfiguration:
return
c.Kube().AdmissionregistrationV1().ValidatingWebhookConfigurations().(ktypes.ReadWriteAPI[T,
TL])
case
*apigithubcomapachedubbokubernetesapinetworkingv1alpha3.WorkloadEntry:
@@ -241,7 +241,7 @@ func gvrToObject(g schema.GroupVersionResource)
runtime.Object {
case gvr.StatefulSet:
return &k8sioapiappsv1.StatefulSet{}
case gvr.Telemetry:
- return
&apigithubcomapachedubbokubernetesapitelemetryv1alpha1.Telemetry{}
+ return
&apigithubcomapachedubbokubernetesapitelemetryv1alpha3.Telemetry{}
case gvr.ValidatingWebhookConfiguration:
return
&k8sioapiadmissionregistrationv1.ValidatingWebhookConfiguration{}
case gvr.WorkloadEntry:
@@ -468,10 +468,10 @@ func getInformerFiltered(c ClientGetter, opts
ktypes.InformerOptions, g schema.G
}
case gvr.Telemetry:
l = func(options metav1.ListOptions) (runtime.Object, error) {
- return
c.Dubbo().TelemetryV1alpha1().Telemetries(opts.Namespace).List(context.Background(),
options)
+ return
c.Dubbo().TelemetryV1alpha3().Telemetries(opts.Namespace).List(context.Background(),
options)
}
w = func(options metav1.ListOptions) (watch.Interface, error) {
- return
c.Dubbo().TelemetryV1alpha1().Telemetries(opts.Namespace).Watch(context.Background(),
options)
+ return
c.Dubbo().TelemetryV1alpha3().Telemetries(opts.Namespace).Watch(context.Background(),
options)
}
case gvr.ValidatingWebhookConfiguration:
l = func(options metav1.ListOptions) (runtime.Object, error) {
diff --git a/pkg/config/schema/kubetypes/resources.gen.go
b/pkg/config/schema/kubetypes/resources.gen.go
index ea73932a..5499ba44 100755
--- a/pkg/config/schema/kubetypes/resources.gen.go
+++ b/pkg/config/schema/kubetypes/resources.gen.go
@@ -8,10 +8,10 @@ import (
githubcomkdubboapimeshv1alpha1 "github.com/kdubbo/api/mesh/v1alpha1"
githubcomkdubboapinetworkingv1alpha3
"github.com/kdubbo/api/networking/v1alpha3"
githubcomkdubboapisecurityv1alpha3
"github.com/kdubbo/api/security/v1alpha3"
- githubcomkdubboapitelemetryv1alpha1
"github.com/kdubbo/api/telemetry/v1alpha1"
+ githubcomkdubboapitelemetryv1alpha3
"github.com/kdubbo/api/telemetry/v1alpha3"
apigithubcomapachedubbokubernetesapinetworkingv1alpha3
"github.com/kdubbo/client-go/pkg/apis/networking/v1alpha3"
apigithubcomapachedubbokubernetesapisecurityv1alpha3
"github.com/kdubbo/client-go/pkg/apis/security/v1alpha3"
- apigithubcomapachedubbokubernetesapitelemetryv1alpha1
"github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha1"
+ apigithubcomapachedubbokubernetesapitelemetryv1alpha3
"github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha3"
k8sioapiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1"
k8sioapiappsv1 "k8s.io/api/apps/v1"
k8sioapiautoscalingv2 "k8s.io/api/autoscaling/v2"
@@ -104,9 +104,9 @@ func getGvk(obj any) (config.GroupVersionKind, bool) {
return gvk.ServiceEntry, true
case *k8sioapiappsv1.StatefulSet:
return gvk.StatefulSet, true
- case *githubcomkdubboapitelemetryv1alpha1.Telemetry:
+ case *githubcomkdubboapitelemetryv1alpha3.Telemetry:
return gvk.Telemetry, true
- case *apigithubcomapachedubbokubernetesapitelemetryv1alpha1.Telemetry:
+ case *apigithubcomapachedubbokubernetesapitelemetryv1alpha3.Telemetry:
return gvk.Telemetry, true
case *k8sioapiadmissionregistrationv1.ValidatingWebhookConfiguration:
return gvk.ValidatingWebhookConfiguration, true
diff --git a/pkg/config/schema/metadata.yaml b/pkg/config/schema/metadata.yaml
index c238b616..4f5d0d40 100644
--- a/pkg/config/schema/metadata.yaml
+++ b/pkg/config/schema/metadata.yaml
@@ -306,8 +306,8 @@ resources:
- kind: Telemetry
plural: "telemetries"
group: "telemetry.dubbo.apache.org"
- version: "v1alpha1"
- proto: "dubbo.telemetry.v1alpha1.Telemetry"
- protoPackage: "github.com/kdubbo/api/telemetry/v1alpha1"
+ version: "v1alpha3"
+ proto: "dubbo.telemetry.v1alpha3.Telemetry"
+ protoPackage: "github.com/kdubbo/api/telemetry/v1alpha3"
statusProto: "dubbo.meta.v1alpha1.DubboStatus"
statusProtoPackage: "github.com/kdubbo/api/meta/v1alpha1"
diff --git a/pkg/config/telemetry/telemetry.go
b/pkg/config/telemetry/telemetry.go
index 5cce78d2..c243c930 100644
--- a/pkg/config/telemetry/telemetry.go
+++ b/pkg/config/telemetry/telemetry.go
@@ -19,18 +19,20 @@ package telemetry
import (
"encoding/json"
"fmt"
+ "slices"
"sort"
"strconv"
"strings"
"time"
"github.com/apache/dubbo-kubernetes/pkg/config"
- api "github.com/kdubbo/api/telemetry/v1alpha1"
- clientapi "github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha1"
+ api "github.com/kdubbo/api/telemetry/v1alpha3"
+ clientapi "github.com/kdubbo/client-go/pkg/apis/telemetry/v1alpha3"
)
const (
LocalTraceProvider = "localtrace"
+ PrometheusProvider = "prometheus"
OTLPPort = 4317
)
@@ -46,12 +48,27 @@ type Tag struct {
Value string
}
+type MetricTagOverride struct {
+ Name string
+ Action api.TagOverride_Action
+}
+
+type MetricRule struct {
+ Metric api.StandardMetric
+ Scope api.MetricScope
+ Tags []MetricTagOverride
+}
+
type EffectiveTracing struct {
Configured bool
Providers []string
Tags []Tag
RandomSamplingPercentage *float64
DisableSpanReporting *bool
+ MetricsConfigured bool
+ MetricProviders []string
+ EnableMetrics *bool
+ MetricRules []MetricRule
}
func ResourcesFromConfigs(configs []config.Config) []Resource {
@@ -146,6 +163,47 @@ func matches(selector, labels map[string]string) bool {
}
func apply(result *EffectiveTracing, spec *api.Telemetry) {
+ for _, metrics := range spec.GetMetrics() {
+ if metrics == nil {
+ continue
+ }
+ result.MetricsConfigured = true
+ if len(metrics.GetProviders()) > 0 {
+ result.MetricProviders = make([]string, 0,
len(metrics.GetProviders()))
+ for _, provider := range metrics.GetProviders() {
+ result.MetricProviders =
append(result.MetricProviders, provider.GetName())
+ }
+ }
+ if enabled := metrics.GetEnabled(); enabled != nil {
+ value := enabled.GetValue()
+ result.EnableMetrics = &value
+ }
+ if len(metrics.GetRules()) > 0 {
+ result.MetricRules = make([]MetricRule, 0,
len(metrics.GetRules()))
+ for _, rule := range metrics.GetRules() {
+ if rule == nil {
+ continue
+ }
+ tagNames := make([]string, 0,
len(rule.GetTags()))
+ for name := range rule.GetTags() {
+ tagNames = append(tagNames, name)
+ }
+ sort.Strings(tagNames)
+ effective := MetricRule{
+ Metric: rule.GetMetric(),
+ Scope: rule.GetScope(),
+ Tags: make([]MetricTagOverride, 0,
len(tagNames)),
+ }
+ for _, name := range tagNames {
+ effective.Tags = append(effective.Tags,
MetricTagOverride{
+ Name: name,
+ Action:
rule.GetTags()[name].GetAction(),
+ })
+ }
+ result.MetricRules = append(result.MetricRules,
effective)
+ }
+ }
+ }
for _, tracing := range spec.GetTracing() {
if tracing == nil {
continue
@@ -174,6 +232,23 @@ func apply(result *EffectiveTracing, spec *api.Telemetry) {
}
}
+func (t EffectiveTracing) MetricsEnabled() bool {
+ if !t.MetricsConfigured {
+ return false
+ }
+ if t.EnableMetrics != nil {
+ return *t.EnableMetrics
+ }
+ return slices.Contains(t.MetricProviders, PrometheusProvider)
+}
+
+func (t EffectiveTracing) MetricsProvider() string {
+ if len(t.MetricProviders) == 0 {
+ return ""
+ }
+ return t.MetricProviders[0]
+}
+
func (t EffectiveTracing) Disabled() bool {
return t.DisableSpanReporting != nil && *t.DisableSpanReporting
}
diff --git a/pkg/config/telemetry/telemetry_test.go
b/pkg/config/telemetry/telemetry_test.go
index 13ed2f44..b96c754b 100644
--- a/pkg/config/telemetry/telemetry_test.go
+++ b/pkg/config/telemetry/telemetry_test.go
@@ -20,7 +20,7 @@ import (
"testing"
"time"
- api "github.com/kdubbo/api/telemetry/v1alpha1"
+ api "github.com/kdubbo/api/telemetry/v1alpha3"
typeapi "github.com/kdubbo/api/type/v1alpha3"
"google.golang.org/protobuf/types/known/wrapperspb"
)
@@ -33,6 +33,15 @@ func TestResolveTelemetryLevels(t *testing.T) {
Providers:
[]*api.Tracing_TracingProvider{{Name: "localtrace"}},
Tags:
[]*api.Tracing_Tag{{Name: "foo", Value: "bar"}},
RandomSamplingPercentage:
wrapperspb.Double(100),
+ }}, Metrics: []*api.Metrics{{
+ Providers:
[]*api.Metrics_MetricsProvider{{Name: PrometheusProvider}},
+ Rules: []*api.MetricRule{{
+ Metric:
api.StandardMetric_REQUEST_COUNT,
+ Scope:
api.MetricScope_CLIENT_AND_SERVER,
+ Tags: map[string]*api.TagOverride{
+ "grpc_response_status":
{Action: api.TagOverride_REMOVE},
+ },
+ }},
}}},
},
{
@@ -63,6 +72,71 @@ func TestResolveTelemetryLevels(t *testing.T) {
if !got.Disabled() {
t.Fatal("workload override did not disable span reporting")
}
+ if !got.MetricsEnabled() || got.MetricsProvider() != PrometheusProvider
{
+ t.Fatalf("metrics = enabled:%v provider:%q",
got.MetricsEnabled(), got.MetricsProvider())
+ }
+ if len(got.MetricRules) != 1 ||
+ got.MetricRules[0].Metric != api.StandardMetric_REQUEST_COUNT ||
+ got.MetricRules[0].Scope != api.MetricScope_CLIENT_AND_SERVER ||
+ len(got.MetricRules[0].Tags) != 1 ||
+ got.MetricRules[0].Tags[0].Name != "grpc_response_status" ||
+ got.MetricRules[0].Tags[0].Action != api.TagOverride_REMOVE {
+ t.Fatalf("metric rules = %#v", got.MetricRules)
+ }
+}
+
+func TestResolveMetricsDisableOverride(t *testing.T) {
+ resources := []Resource{
+ {
+ Name: "mesh-default", Namespace: "dubbo-system",
+ Spec: &api.Telemetry{Metrics: []*api.Metrics{{
+ Providers:
[]*api.Metrics_MetricsProvider{{Name: PrometheusProvider}},
+ }}},
+ },
+ {
+ Name: "namespace-disable", Namespace: "myapp",
+ Spec: &api.Telemetry{Metrics: []*api.Metrics{{
+ Enabled: wrapperspb.Bool(false),
+ }}},
+ },
+ }
+
+ got := Resolve(resources, "dubbo-system", "myapp", nil)
+ if got.MetricsEnabled() {
+ t.Fatal("namespace override did not disable metrics")
+ }
+ if got.MetricsProvider() != PrometheusProvider {
+ t.Fatalf("provider = %q, want inherited prometheus",
got.MetricsProvider())
+ }
+}
+
+func TestResolveMetricsRulesOverride(t *testing.T) {
+ resources := []Resource{
+ {
+ Name: "mesh-default", Namespace: "dubbo-system",
+ Spec: &api.Telemetry{Metrics: []*api.Metrics{{
+ Providers:
[]*api.Metrics_MetricsProvider{{Name: PrometheusProvider}},
+ Rules: []*api.MetricRule{{
+ Metric:
api.StandardMetric_REQUEST_COUNT,
+ Scope: api.MetricScope_CLIENT,
+ }},
+ }}},
+ },
+ {
+ Name: "namespace-rules", Namespace: "myapp",
+ Spec: &api.Telemetry{Metrics: []*api.Metrics{{
+ Rules: []*api.MetricRule{{
+ Metric:
api.StandardMetric_REQUEST_COUNT,
+ Scope: api.MetricScope_SERVER,
+ }},
+ }}},
+ },
+ }
+
+ got := Resolve(resources, "dubbo-system", "myapp", nil)
+ if len(got.MetricRules) != 1 || got.MetricRules[0].Scope !=
api.MetricScope_SERVER {
+ t.Fatalf("metric rules = %#v, want namespace replacement",
got.MetricRules)
+ }
}
func TestMeshlevelSelectorIsIgnored(t *testing.T) {
diff --git a/pkg/config/validation/validators.go
b/pkg/config/validation/validators.go
index 20831327..ce82afb2 100644
--- a/pkg/config/validation/validators.go
+++ b/pkg/config/validation/validators.go
@@ -28,10 +28,11 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/config/constants"
"github.com/apache/dubbo-kubernetes/pkg/config/labels"
"github.com/apache/dubbo-kubernetes/pkg/config/protocol"
+ telemetryconfig
"github.com/apache/dubbo-kubernetes/pkg/config/telemetry"
"github.com/apache/dubbo-kubernetes/pkg/config/visibility"
networking "github.com/kdubbo/api/networking/v1alpha3"
security "github.com/kdubbo/api/security/v1alpha3"
- telemetry "github.com/kdubbo/api/telemetry/v1alpha1"
+ telemetry "github.com/kdubbo/api/telemetry/v1alpha3"
kvalidation "k8s.io/apimachinery/pkg/util/validation"
)
@@ -585,6 +586,58 @@ var ValidateTelemetry =
RegisterValidateFunc("ValidateTelemetry",
if cfg.Namespace == constants.DubboSystemNamespace &&
spec.GetSelector() != nil {
v = appendValidation(v, fmt.Errorf("selector is not
allowed on meshlevel Telemetry in namespace %q",
constants.DubboSystemNamespace))
}
+ for i, m := range spec.GetMetrics() {
+ if m == nil {
+ v = appendValidation(v, fmt.Errorf("metrics[%d]
must not be null", i))
+ continue
+ }
+ providers := map[string]struct{}{}
+ for j, p := range m.GetProviders() {
+ name := strings.TrimSpace(p.GetName())
+ if name == "" {
+ v = appendValidation(v,
fmt.Errorf("metrics[%d].providers[%d].name must be set", i, j))
+ continue
+ }
+ if name != telemetryconfig.PrometheusProvider {
+ v = appendValidation(v,
fmt.Errorf("metrics[%d].providers[%d].name %q is unsupported", i, j, name))
+ }
+ if _, found := providers[name]; found {
+ v = appendValidation(v,
fmt.Errorf("metrics[%d].providers[%d].name %q is duplicated", i, j, name))
+ }
+ providers[name] = struct{}{}
+ }
+ rules := map[string]struct{}{}
+ for j, rule := range m.GetRules() {
+ if rule == nil {
+ v = appendValidation(v,
fmt.Errorf("metrics[%d].rules[%d] must not be null", i, j))
+ continue
+ }
+ if rule.GetMetric() ==
telemetry.StandardMetric_STANDARD_METRIC_UNSPECIFIED {
+ v = appendValidation(v,
fmt.Errorf("metrics[%d].rules[%d].metric must be set", i, j))
+ }
+ if rule.GetScope() ==
telemetry.MetricScope_METRIC_SCOPE_UNSPECIFIED {
+ v = appendValidation(v,
fmt.Errorf("metrics[%d].rules[%d].scope must be set", i, j))
+ }
+ key := fmt.Sprintf("%d/%d", rule.GetMetric(),
rule.GetScope())
+ if _, found := rules[key]; found {
+ v = appendValidation(v,
fmt.Errorf("metrics[%d].rules[%d] duplicates metric %s with scope %s",
+ i, j, rule.GetMetric(),
rule.GetScope()))
+ }
+ rules[key] = struct{}{}
+ for name, override := range rule.GetTags() {
+ if strings.TrimSpace(name) == "" {
+ v = appendValidation(v,
fmt.Errorf("metrics[%d].rules[%d].tags contains an empty name", i, j))
+ }
+ if override == nil {
+ v = appendValidation(v,
fmt.Errorf("metrics[%d].rules[%d].tags[%q] must not be null", i, j, name))
+ continue
+ }
+ if override.GetAction() !=
telemetry.TagOverride_REMOVE {
+ v = appendValidation(v,
fmt.Errorf("metrics[%d].rules[%d].tags[%q].action must be REMOVE", i, j, name))
+ }
+ }
+ }
+ }
for i, t := range spec.GetTracing() {
if t == nil {
v = appendValidation(v, fmt.Errorf("tracing[%d]
must not be null", i))
diff --git a/pkg/config/validation/validators_test.go
b/pkg/config/validation/validators_test.go
index 179903c9..30212f26 100644
--- a/pkg/config/validation/validators_test.go
+++ b/pkg/config/validation/validators_test.go
@@ -27,7 +27,7 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/config"
networking "github.com/kdubbo/api/networking/v1alpha3"
security "github.com/kdubbo/api/security/v1alpha3"
- telemetry "github.com/kdubbo/api/telemetry/v1alpha1"
+ telemetry "github.com/kdubbo/api/telemetry/v1alpha3"
typev1alpha3 "github.com/kdubbo/api/type/v1alpha3"
)
@@ -617,6 +617,60 @@ func TestValidateTelemetry(t *testing.T) {
},
wantErr: false,
},
+ {
+ name: "valid metrics provider",
+ spec: &telemetry.Telemetry{Metrics:
[]*telemetry.Metrics{{
+ Providers:
[]*telemetry.Metrics_MetricsProvider{{Name: "prometheus"}},
+ Enabled: wrapperspb.Bool(true),
+ Rules: []*telemetry.MetricRule{{
+ Metric:
telemetry.StandardMetric_REQUEST_COUNT,
+ Scope:
telemetry.MetricScope_CLIENT_AND_SERVER,
+ Tags: map[string]*telemetry.TagOverride{
+ "grpc_response_status":
{Action: telemetry.TagOverride_REMOVE},
+ },
+ }},
+ }}},
+ wantErr: false,
+ },
+ {
+ name: "metrics rule without metric",
+ spec: &telemetry.Telemetry{Metrics:
[]*telemetry.Metrics{{
+ Rules: []*telemetry.MetricRule{{Scope:
telemetry.MetricScope_SERVER}},
+ }}},
+ wantErr: true,
+ },
+ {
+ name: "metrics rule without scope",
+ spec: &telemetry.Telemetry{Metrics:
[]*telemetry.Metrics{{
+ Rules: []*telemetry.MetricRule{{Metric:
telemetry.StandardMetric_REQUEST_COUNT}},
+ }}},
+ wantErr: true,
+ },
+ {
+ name: "metrics tag without action",
+ spec: &telemetry.Telemetry{Metrics:
[]*telemetry.Metrics{{
+ Rules: []*telemetry.MetricRule{{
+ Metric:
telemetry.StandardMetric_REQUEST_COUNT,
+ Scope: telemetry.MetricScope_CLIENT,
+ Tags:
map[string]*telemetry.TagOverride{"grpc_response_status": {}},
+ }},
+ }}},
+ wantErr: true,
+ },
+ {
+ name: "metrics provider without name",
+ spec: &telemetry.Telemetry{Metrics:
[]*telemetry.Metrics{{
+ Providers:
[]*telemetry.Metrics_MetricsProvider{{}},
+ }}},
+ wantErr: true,
+ },
+ {
+ name: "unsupported metrics provider",
+ spec: &telemetry.Telemetry{Metrics:
[]*telemetry.Metrics{{
+ Providers:
[]*telemetry.Metrics_MetricsProvider{{Name: "unknown"}},
+ }}},
+ wantErr: true,
+ },
{
name: "provider without name",
spec: &telemetry.Telemetry{
diff --git a/pkg/webhooks/server/server.go b/pkg/webhooks/server/server.go
index 31addff0..1647c33d 100644
--- a/pkg/webhooks/server/server.go
+++ b/pkg/webhooks/server/server.go
@@ -34,7 +34,7 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/config/validation"
"github.com/apache/dubbo-kubernetes/pkg/kube"
"github.com/hashicorp/go-multierror"
- telemetry "github.com/kdubbo/api/telemetry/v1alpha1"
+ telemetry "github.com/kdubbo/api/telemetry/v1alpha3"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
diff --git a/pkg/webhooks/server/server_test.go
b/pkg/webhooks/server/server_test.go
index fb2c3aba..cd7795e6 100644
--- a/pkg/webhooks/server/server_test.go
+++ b/pkg/webhooks/server/server_test.go
@@ -21,7 +21,7 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/config"
"github.com/apache/dubbo-kubernetes/pkg/config/schema/gvk"
- telemetry "github.com/kdubbo/api/telemetry/v1alpha1"
+ telemetry "github.com/kdubbo/api/telemetry/v1alpha3"
)
type fakeConfigLister struct {
diff --git a/samples/addons/telemetry.yaml b/samples/addons/telemetry.yaml
index 19fdab47..26d35c79 100644
--- a/samples/addons/telemetry.yaml
+++ b/samples/addons/telemetry.yaml
@@ -3,44 +3,19 @@
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0.
-# Exactly one selectorless Telemetry is allowed in dubbo-system. It defines
-# the meshlevel defaults.
-apiVersion: telemetry.dubbo.apache.org/v1alpha1
+# Mesh-level Prometheus metrics for Inherent client and server reporters.
+apiVersion: telemetry.dubbo.apache.org/v1alpha3
kind: Telemetry
metadata:
- name: mesh-default
+ name: metrics-tags
namespace: dubbo-system
spec:
- tracing:
+ metrics:
- providers:
- - name: localtrace
- tags:
- - name: foo
- value: bar
- randomSamplingPercentage: 100
----
-# Fields present here replace the corresponding meshlevel field. Unspecified
-# fields, including providers and sampling, remain inherited.
-apiVersion: telemetry.dubbo.apache.org/v1alpha1
-kind: Telemetry
-metadata:
- name: namespace-override
- namespace: myapp
-spec:
- tracing:
- - tags:
- - name: userId
- value: unknown
----
-# A selector applies the final workload-level override inside its namespace.
-apiVersion: telemetry.dubbo.apache.org/v1alpha1
-kind: Telemetry
-metadata:
- name: workload-override
- namespace: myapp
-spec:
- selector:
- matchLabels:
- app: frontend
- tracing:
- - disableSpanReporting: true
+ - name: prometheus
+ rules:
+ - metric: REQUEST_COUNT
+ scope: CLIENT_AND_SERVER
+ tags:
+ grpc_response_status:
+ action: REMOVE