diff --git a/controllers/monitor/builder/builder.go b/controllers/monitor/builder/builder.go
index 81c43eb7b0ee..ae4f2abe5c47 100644
--- a/controllers/monitor/builder/builder.go
+++ b/controllers/monitor/builder/builder.go
@@ -64,6 +64,7 @@ func BuildFromCUEForOTel(tplName string, fillMap map[string]any, lookupKey strin
}
value := cueValue.Value.LookupPath(cue.ParsePath(lookupKey))
+
bytes, err := value.MarshalJSON()
if err != nil {
return nil, err
diff --git a/controllers/monitor/builder/cue/exporter/prometheus.cue b/controllers/monitor/builder/cue/exporter/prometheus.cue
index 4414a7efb354..4dfc3ae1508f 100644
--- a/controllers/monitor/builder/cue/exporter/prometheus.cue
+++ b/controllers/monitor/builder/cue/exporter/prometheus.cue
@@ -28,7 +28,7 @@ output: {
endpoint: parameters.endpoint
send_timestamps: parameters.send_timestamps
metric_expiration: parameters.metric_expiration
- enable_open_metrics: prarameters.enable_open_metrics
+ enable_open_metrics: parameters.enable_open_metrics
resource_to_telemetry_conversion:
enabled: parameters.resource_to_telemetry_conversion_enabled
}
diff --git a/controllers/monitor/builder/cue/extension/apecloud_engine_observer.cue b/controllers/monitor/builder/cue/extension/apecloud_engine_observer.cue
deleted file mode 100644
index e479703ee0d7..000000000000
--- a/controllers/monitor/builder/cue/extension/apecloud_engine_observer.cue
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (C) 2022-2023 ApeCloud Co., Ltd
-//
-// This file is part of KubeBlocks project
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-parameters: {
- pod_observer: *"apecloud_k8s_observer" | string
- container_observer: *"runtime_container" | string
- scraper_config_file: *"/opt/oteld/etc/scraper.yaml" | string
-}
-
-
-
-output:
- apecloud_engine_observer: {
- pod_observer: parameters.pod_observer
- container_observer: parameters.container_observer
- scraper_config_file: parameters.scraper_config_file
- }
-
diff --git a/controllers/monitor/builder/cue/extension/runtime_container.cue b/controllers/monitor/builder/cue/extension/extensions.cue
similarity index 55%
rename from controllers/monitor/builder/cue/extension/runtime_container.cue
rename to controllers/monitor/builder/cue/extension/extensions.cue
index 6cf883e1f6a5..46b25461b507 100644
--- a/controllers/monitor/builder/cue/extension/runtime_container.cue
+++ b/controllers/monitor/builder/cue/extension/extensions.cue
@@ -20,11 +20,34 @@ parameters: {
container_runtime_type: *"containerd" | string
}
-
-output:
- runtime_contaienr: {
- enable: parameters.enable
- container_runtime_type: parameters.container_runtime_type
+output: {
+ extensions: {
+ memory_ballast:
+ size_mib: 32
+ apecloud_k8s_observer: {
+ auth_type: "kubeConfig"
+ node: "${env:NODE_NAME}"
+ observe_pods: true
+ observe_nodes: false
+ }
+ "apecloud_k8s_observer/node": {
+ auth_type: "kubeConfig"
+ node: "${env:NODE_NAME}"
+ observe_pods: false
+ observe_nodes: true
+ }
+ runtime_container: {
+ enable: true
+ auth_type: "kubeConfig"
+ kubernetes_node: "${env:NODE_NAME}"
+ }
+ apecloud_engine_observer: {
+ pod_observer: "apecloud_k8s_observer"
+ container_observer: "runtime_container"
+ scraper_config_file: "/tmp/oteld_test_work/kb_engine.yaml"
+ }
}
+}
+
diff --git a/controllers/monitor/builder/cue/processor/processors.cue b/controllers/monitor/builder/cue/processor/processors.cue
new file mode 100644
index 000000000000..37cfe2b34dcf
--- /dev/null
+++ b/controllers/monitor/builder/cue/processor/processors.cue
@@ -0,0 +1,6 @@
+output:
+ memory_limiter:{
+ limit_mib: 512
+ spike_limit_mib: 128
+ check_interval: "10s"
+ }
diff --git a/controllers/monitor/builder/cue/receiver/metrics/apecloudkubeletstats.cue b/controllers/monitor/builder/cue/receiver/metrics/apecloudkubeletstats.cue
index deada084831e..65a10461f56a 100644
--- a/controllers/monitor/builder/cue/receiver/metrics/apecloudkubeletstats.cue
+++ b/controllers/monitor/builder/cue/receiver/metrics/apecloudkubeletstats.cue
@@ -16,23 +16,23 @@
// along with this program. If not, see .
parameters: {
- auth_type: *"service_account" | string
- collection_interval: *"10s" | string
- endpoint: *"http://localhost:10255" | string
+ auth_type: *"serviceAccount" | string
+ collection_interval: *"15s" | string
+ endpoint: *"`endpoint`:`kubelet_endpoint_port`" | string
}
output:
apecloudkubeletstats: {
- auth_type: parameters.auth_type
- collection_interval: parameters.collection_interval
- endpoint: parameters.endpoint
- extra_metadata_labels:
- - k8s.volume.type
- - kubeblocks
- metric_groups:
- - container
- - pod
- - volume
+ rule: "type == \"k8s.node\""
+ config: {
+ auth_type: parameters.auth_type
+ collection_interval: parameters.collection_interval
+ endpoint: parameters.endpoint
+ extra_metadata_labels: ["k8s.volume.type", "kubeblocks"]
+ metric_groups: ["container", "pod", "volume"]
+ resource_attributes:
+ receiver: "apecloudkubeletstats"
+ }
}
diff --git a/controllers/monitor/builder/cue/receiver/metrics/apecloudmysql.cue b/controllers/monitor/builder/cue/receiver/metrics/apecloudmysql.cue
index 422ceebe8696..80366f52dfab 100644
--- a/controllers/monitor/builder/cue/receiver/metrics/apecloudmysql.cue
+++ b/controllers/monitor/builder/cue/receiver/metrics/apecloudmysql.cue
@@ -16,21 +16,26 @@
// along with this program. If not, see .
parameters: {
- username: *"${env:MYSQL_USER}" | string
- password: *"${env:MYSQL_PASSWORD}" | string
+ endpoint: *"`endpoint`:3306" | string
+ username: *"`envs[\"MYSQL_ROOT_USER\"]`" | string
+ password: *"`envs[\"MYSQL_ROOT_PASSWORD\"]" | string
allow_native_passwords: *true | bool
transport: *"tcp" | string
- collection_interval: *"${env:COLLECTION_INTERVAL}" | string
+ collection_interval: *"`settings.CollectionInterval`" | string
}
-
-
output:
apecloudmysql: {
- username: parameters.username
- password: parameters.password
- allow_native_passwords: parameters.allow_native_passwords
- transport: parameters.transport
- collection_interval: parameters.collection_interval
+ rule: "type == \"pod\" && monitor_type == \"mysql\""
+ config:{
+ endpoint: parameters.endpoint
+ username: parameters.username
+ password: parameters.password
+ allow_native_passwords: parameters.allow_native_passwords
+ transport: parameters.transport
+ collection_interval: parameters.collection_interval
+ }
+ resource_attributes:
+ receiver: "apecloudmysql"
}
diff --git a/controllers/monitor/builder/cue/receiver/metrics/apecloudnode.cue b/controllers/monitor/builder/cue/receiver/metrics/apecloudnode.cue
index 7baeca014cbe..05606294925b 100644
--- a/controllers/monitor/builder/cue/receiver/metrics/apecloudnode.cue
+++ b/controllers/monitor/builder/cue/receiver/metrics/apecloudnode.cue
@@ -22,6 +22,10 @@ parameters: {
output:
apecloudnode: {
- collection_interval: parameters.collection_interval
+ rule: "type == \"k8s.node\""
+ config:
+ collection_interval: parameters.collection_interval
+ resource_attributes:
+ receiver: "apecloudnode"
}
diff --git a/controllers/monitor/builder/cue/receiver/resource_attributes.cue b/controllers/monitor/builder/cue/receiver/resource_attributes.cue
new file mode 100644
index 000000000000..416eb49d7024
--- /dev/null
+++ b/controllers/monitor/builder/cue/receiver/resource_attributes.cue
@@ -0,0 +1,22 @@
+output:
+ resource_attributes:
+ pod: {
+ app_kubernetes_io_component: "`labels[\"app.kubernetes.io/component\"]`"
+ app_kubernetes_io_instance: "`labels[\"app.kubernetes.io/instance\"]`"
+ app_kubernetes_io_managed_by: "`labels[\"app.kubernetes.io/managed-by\"]`"
+ app_kubernetes_io_name: "`labels[\"app.kubernetes.io/name\"]`"
+ app_kubernetes_io_version: "`labels[\"app.kubernetes.io/version\"]`"
+ apps_kubeblocks_io_component_name: "`labels[\"apps.kubeblocks.io/component-name\"]`"
+ node: "${env:NODE_NAME}"
+ namespace: "`namespace`"
+ pod: "`name`"
+ job: "oteld-app"
+ }
+ "k8s.node": {
+ kubernetes_io_arch: "`labels[\"kubernetes.io/arch\"]`"
+ kubernetes_io_hostname: "`labels[\"kubernetes.io/hostname\"]`"
+ kubernetes_io_os: "`labels[\"kubernetes.io/os\"]`"
+ node: "`name`"
+ hostname: "`hostname`"
+ job: "oteld-system"
+ }
diff --git a/controllers/monitor/builder/cue/service/service.cue b/controllers/monitor/builder/cue/service/service.cue
new file mode 100644
index 000000000000..b855d7a55d6c
--- /dev/null
+++ b/controllers/monitor/builder/cue/service/service.cue
@@ -0,0 +1,16 @@
+parameters: {
+ logLevel: *"debug" | string
+ metricsPort: *6668 | int
+}
+
+output:
+ telemetry: {
+ logs:
+ level: parameters.logLevel
+ metrics:
+ address: "${env:HOST_IP}:" + "\(parameters.metricsPort)"
+ resource:
+ node: "${env:NODE_NAME}"
+ job: "oteld-telemetry"
+ }
+ extensions: ["memory_ballast", "apecloud_k8s_observer", "apecloud_k8s_observer/node", "runtime_container", "apecloud_engine_observer"]
\ No newline at end of file
diff --git a/controllers/monitor/builder/otel_config_test.go b/controllers/monitor/builder/otel_config_test.go
deleted file mode 100644
index 4ef692a68a2f..000000000000
--- a/controllers/monitor/builder/otel_config_test.go
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-Copyright (C) 2022-2023 ApeCloud Co., Ltd
-
-This file is part of KubeBlocks project
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-*/
-
-package builder
-
-import (
- "github.com/apecloud/kubeblocks/apis/monitor/v1alpha1"
- . "github.com/onsi/ginkgo/v2"
-)
-
-var _ = Describe("monitor_controller", func() {
- //var (
- // logsExporterList v1alpha1.LogsExporterSinkList
- // metricsExporterList v1alpha1.MetricsExporterSinkList
- // datasourceList v1alpha1.CollectorDataSourceList
- //)
- //
- //BeforeEach(func() {
- // logsExporterList = fakeLogsExporterSinkList()
- // metricsExporterList = fakeMetricsExporterSinkList()
- // datasourceList = fakeCollectorDataSourceList()
- //})
- //
- //It("should generate config correctly from config yaml", func() {
- // Eventually(func(g Gomega) {
- // config, err := types.LoadConfig("./data/config_test.yaml")
- // if err != nil {
- // return
- // }
- // g.Expect(config).ShouldNot(BeNil())
- // }).Should(Succeed())
- //})
- //
- //It("should generate oteld correctly", func() {
- //
- // instance := fakeOteldInstance()
- //
- // config, err := types.LoadConfig("./data/config_test.yaml")
- // Expect(err).ShouldNot(HaveOccurred())
- //
- // By("create cluster & clusterDef")
- // cg := NewConfigGenerator(config)
- // cfg := cg.GenerateOteldConfiguration(, &metricsExporterList, &logsExporterList)
- // bytes, err := yaml.Marshal(cfg)
- // Expect(err).ShouldNot(HaveOccurred())
- // Expect(len(bytes) > 0).Should(BeTrue())
- // Expect(true).Should(BeTrue())
- //})
-
-})
-
-func fakeCollectorDataSourceList() v1alpha1.CollectorDataSourceList {
- return v1alpha1.CollectorDataSourceList{
- Items: []v1alpha1.CollectorDataSource{
- {
- Spec: v1alpha1.CollectorDataSourceSpec{
- Type: v1alpha1.MetricsDatasourceType,
- ExporterRef: v1alpha1.ExporterRef{ExporterNames: []string{"prometheus"}},
- DataSourceList: []v1alpha1.DataSource{
- {Name: "apecloudmysql"},
- },
- },
- },
- {
- Spec: v1alpha1.CollectorDataSourceSpec{
- Type: v1alpha1.LogsDataSourceType,
- ExporterRef: v1alpha1.ExporterRef{ExporterNames: []string{"loki"}},
- DataSourceList: []v1alpha1.DataSource{
- {Name: "mysql"},
- },
- },
- },
- },
- }
-}
-
-func fakeMetricsExporterSinkList() v1alpha1.MetricsExporterSinkList {
- return v1alpha1.MetricsExporterSinkList{
- Items: []v1alpha1.MetricsExporterSink{
- {
- Spec: v1alpha1.MetricsExporterSinkSpec{
- Type: v1alpha1.PrometheusSinkType, MetricsSinkSource: v1alpha1.MetricsSinkSource{
- PrometheusConfig: &v1alpha1.PrometheusConfig{ServiceRef: v1alpha1.ServiceRef{Endpoint: "test"}},
- }},
- },
- },
- }
-}
-
-func fakeLogsExporterSinkList() v1alpha1.LogsExporterSinkList {
- return v1alpha1.LogsExporterSinkList{
- Items: []v1alpha1.LogsExporterSink{
- {
- Spec: v1alpha1.LogsExporterSinkSpec{
- Type: v1alpha1.LokiSinkType, SinkSource: v1alpha1.SinkSource{
- LokiConfig: &v1alpha1.LokiConfig{ServiceRef: v1alpha1.ServiceRef{Endpoint: "test"}},
- }},
- },
- {
- Spec: v1alpha1.LogsExporterSinkSpec{
- Type: v1alpha1.S3SinkType, SinkSource: v1alpha1.SinkSource{
- LokiConfig: &v1alpha1.LokiConfig{ServiceRef: v1alpha1.ServiceRef{Endpoint: "test"}},
- }},
- },
- },
- }
-}
diff --git a/controllers/monitor/reconcile/oteld.go b/controllers/monitor/reconcile/oteld.go
index 5a45232982ee..a872d89b2c41 100644
--- a/controllers/monitor/reconcile/oteld.go
+++ b/controllers/monitor/reconcile/oteld.go
@@ -70,10 +70,11 @@ func buildOteldInstance(
datasources *v1alpha1.CollectorDataSourceList,
templates *v1alpha1.OTeldCollectorTemplateList,
) error {
- err := mergeDatasourceForPipline(reqCtx, datasources)
+ instanceMap, err := BuildInstanceMapForPipline(datasources)
if err != nil {
return err
}
+ reqCtx.SetOteldInstanceMap(instanceMap)
for _, template := range templates.Items {
instance := reqCtx.GetOteldInstance(template.Spec.Mode)
@@ -89,14 +90,15 @@ func buildOteldInstance(
return nil
}
-func mergeDatasourceForPipline(reqCtx monitortype.ReconcileCtx, datasources *v1alpha1.CollectorDataSourceList) error {
+func BuildInstanceMapForPipline(datasources *v1alpha1.CollectorDataSourceList) (map[v1alpha1.Mode]*monitortype.OteldInstance, error) {
+ instanceMap := map[v1alpha1.Mode]*monitortype.OteldInstance{}
for _, dataSource := range datasources.Items {
mode := dataSource.Spec.Mode
if mode == "" {
mode = DefaultMode
}
- oteldInstance := reqCtx.GetOteldInstance(mode)
- if oteldInstance == nil {
+ oteldInstance, ok := instanceMap[mode]
+ if !ok {
oteldInstance = monitortype.NewOteldInstance()
}
switch dataSource.Spec.Type {
@@ -125,7 +127,7 @@ func mergeDatasourceForPipline(reqCtx monitortype.ReconcileCtx, datasources *v1a
}
oteldInstance.LogsPipline = append(oteldInstance.LogsPipline, pipline)
}
- reqCtx.SetOteldInstance(dataSource.Spec.Mode, oteldInstance)
+ instanceMap[dataSource.Spec.Mode] = oteldInstance
}
- return nil
+ return instanceMap, nil
}
diff --git a/controllers/monitor/reconcile/utils.go b/controllers/monitor/reconcile/utils.go
index c22a2a92298d..c3030dad0dbe 100644
--- a/controllers/monitor/reconcile/utils.go
+++ b/controllers/monitor/reconcile/utils.go
@@ -215,7 +215,7 @@ func buildConfigMapForOteld(_ *types.Config, instance *types.OteldInstance, name
constant.AppInstanceLabelKey: name,
}
- configData := gc.GenerateOteldConfiguration(instance, exporters.Metricsexporter, exporters.Logsexporter)
+ configData, _ := gc.GenerateOteldConfiguration(instance, exporters.Metricsexporter, exporters.Logsexporter)
marshal, err := yaml.Marshal(configData)
if err != nil {
return nil, err
@@ -241,7 +241,7 @@ func buildSecretForOteld(_ *types.Config, instance *types.OteldInstance, namespa
constant.AppInstanceLabelKey: name,
}
- configData := gc.GenerateOteldConfiguration(instance, exporters.Metricsexporter, exporters.Logsexporter)
+ configData, _ := gc.GenerateOteldConfiguration(instance, exporters.Metricsexporter, exporters.Logsexporter)
marshal, err := yaml.Marshal(configData)
if err != nil {
return nil, err
diff --git a/controllers/monitor/types/otel_config.go b/controllers/monitor/types/otel_config.go
index c2fe77eeb283..b2e6a125310e 100644
--- a/controllers/monitor/types/otel_config.go
+++ b/controllers/monitor/types/otel_config.go
@@ -16,6 +16,7 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
+
package types
import (
@@ -31,6 +32,9 @@ const (
ExtensionTplPattern = "extension/%s.cue"
ExporterTplPattern = "exporter/%s.cue"
ReceiverNamePattern = "receiver_creator/%s"
+ ServicePath = "service/service.cue"
+
+ ExtensionPath = "extension/extensions.cue"
)
type OteldConfigGenerater struct {
@@ -41,51 +45,56 @@ func NewConfigGenerator() *OteldConfigGenerater {
return &OteldConfigGenerater{cache: map[v1alpha1.Mode]yaml.MapSlice{}}
}
-func (cg *OteldConfigGenerater) GenerateOteldConfiguration(
- instance *OteldInstance,
- metricsExporterList []v1alpha1.MetricsExporterSink,
- logsExporterList []v1alpha1.LogsExporterSink,
-) yaml.MapSlice {
+func (cg *OteldConfigGenerater) GenerateOteldConfiguration(instance *OteldInstance, metricsExporterList []v1alpha1.MetricsExporterSink, logsExporterList []v1alpha1.LogsExporterSink) (yaml.MapSlice, error) {
if instance == nil || instance.OteldTemplate == nil {
- return nil
+ return nil, nil
}
if cg.cache == nil && cg.cache[instance.OteldTemplate.Spec.Mode] != nil {
- return cg.cache[instance.OteldTemplate.Spec.Mode]
+ return cg.cache[instance.OteldTemplate.Spec.Mode], nil
}
cfg := yaml.MapSlice{}
- cfg, _ = cg.appendExtentions(cfg)
- cfg = cg.appendReceiver(cfg, instance)
- cfg = cg.appendProcessor(cfg)
- cfg, _ = cg.appendExporter(cfg, metricsExporterList, logsExporterList)
- cfg = cg.appendServices(cfg, instance)
+ var err error
+ cfg, err = cg.appendExtentions(cfg)
+ cfg, err = cg.appendReceiver(cfg, instance)
+ cfg, err = cg.appendProcessor(cfg)
+ cfg, err = cg.appendExporter(cfg, metricsExporterList, logsExporterList)
+ cfg, err = cg.appendServices(cfg, instance)
+ if err != nil {
+ return nil, err
+ }
cg.cache[instance.OteldTemplate.Spec.Mode] = cfg
- return cfg
+ return cfg, nil
}
-func (cg *OteldConfigGenerater) appendReceiver(cfg yaml.MapSlice, instance *OteldInstance) yaml.MapSlice {
+func (cg *OteldConfigGenerater) appendReceiver(cfg yaml.MapSlice, instance *OteldInstance) (yaml.MapSlice, error) {
receiverSlice := yaml.MapSlice{}
creatorSlice, err := newReceiverCreatorSlice(instance)
if err != nil {
- return nil
+ return nil, err
}
receiverSlice = append(receiverSlice, creatorSlice...)
- return append(cfg, yaml.MapItem{Key: "receivers", Value: receiverSlice})
+ attributesSlice, err := buildSliceFromCUE("receiver/resource_attributes.cue", map[string]any{})
+ if err != nil {
+ return nil, err
+ }
+ receiverSlice = append(receiverSlice, attributesSlice...)
+ return append(cfg, yaml.MapItem{Key: "receivers", Value: receiverSlice}), nil
}
func newReceiverCreatorSlice(instance *OteldInstance) (yaml.MapSlice, error) {
creators := yaml.MapSlice{}
- for index, pipline := range instance.MetricsPipline {
- creator, err := newReceiverCreator(index, v1alpha1.MetricsDatasourceType, pipline.ReceiverMap)
+ for _, pipline := range instance.MetricsPipline {
+ creator, err := newReceiverCreator(pipline.Name, v1alpha1.MetricsDatasourceType, pipline.ReceiverMap)
if err != nil {
return nil, err
}
creators = append(creators, creator)
}
- for index, pipline := range instance.LogsPipline {
- creator, err := newReceiverCreator(index, v1alpha1.LogsDataSourceType, pipline.ReceiverMap)
+ for _, pipline := range instance.LogsPipline {
+ creator, err := newReceiverCreator(pipline.Name, v1alpha1.LogsDataSourceType, pipline.ReceiverMap)
if err != nil {
return nil, err
}
@@ -94,13 +103,16 @@ func newReceiverCreatorSlice(instance *OteldInstance) (yaml.MapSlice, error) {
return creators, nil
}
-func newReceiverCreator(index int, datasourceType v1alpha1.DataSourceType, receiverMap map[string]Receiver) (yaml.MapItem, error) {
+func newReceiverCreator(name string, datasourceType v1alpha1.DataSourceType, receiverMap map[string]Receiver) (yaml.MapItem, error) {
creator := yaml.MapSlice{}
- creator = append(creator, yaml.MapItem{Key: "watch_observers", Value: []string{"apecloud_engine_observer"}})
+ creator = append(creator, yaml.MapItem{Key: "watch_observers", Value: []string{"apecloud_engine_observer", "apecloud_k8s_observer/node"}})
receiverSlice := yaml.MapSlice{}
for name, params := range receiverMap {
tplName := fmt.Sprintf(CUEPathPattern, datasourceType, name)
- valueMap := map[string]any{"collection_interval": params.CollectionInterval}
+ valueMap := map[string]any{}
+ if params.Parameter != "" {
+ valueMap["collection_interval"] = params.CollectionInterval
+ }
builder.MergeValMapFromYamlStr(valueMap, params.Parameter)
receivers, err := buildSliceFromCUE(tplName, valueMap)
if err != nil {
@@ -109,7 +121,7 @@ func newReceiverCreator(index int, datasourceType v1alpha1.DataSourceType, recei
receiverSlice = append(receiverSlice, receivers...)
}
creator = append(creator, yaml.MapItem{Key: "receivers", Value: receiverSlice})
- return yaml.MapItem{Key: fmt.Sprintf(ReceiverNamePattern, datasourceType, index), Value: creator}, nil
+ return yaml.MapItem{Key: fmt.Sprintf(ReceiverNamePattern, name), Value: creator}, nil
}
func (cg *OteldConfigGenerater) appendExporter(cfg yaml.MapSlice, metricsExporters []v1alpha1.MetricsExporterSink, logsExporter []v1alpha1.LogsExporterSink) (yaml.MapSlice, error) {
@@ -146,18 +158,24 @@ func (cg *OteldConfigGenerater) appendExporter(cfg yaml.MapSlice, metricsExporte
return append(cfg, yaml.MapItem{Key: "exporters", Value: exporterSlice}), nil
}
-func (cg *OteldConfigGenerater) appendProcessor(cfg yaml.MapSlice) yaml.MapSlice {
- // TODO
- return cfg
+func (cg *OteldConfigGenerater) appendProcessor(cfg yaml.MapSlice) (yaml.MapSlice, error) {
+ processorSlice, err := buildSliceFromCUE("processor/processors.cue", map[string]any{})
+ if err != nil {
+ return nil, err
+ }
+ return append(cfg, yaml.MapItem{Key: "processors", Value: processorSlice}), nil
}
-func (cg *OteldConfigGenerater) appendServices(cfg yaml.MapSlice, instance *OteldInstance) yaml.MapSlice {
+func (cg *OteldConfigGenerater) appendServices(cfg yaml.MapSlice, instance *OteldInstance) (yaml.MapSlice, error) {
serviceSlice := yaml.MapSlice{}
piplneItem := cg.buildPiplineItem(instance)
serviceSlice = append(serviceSlice, piplneItem)
- extensionItem := yaml.MapItem{Key: "extensions", Value: []string{"runtime_container", "apecloud_engine_observer"}}
- serviceSlice = append(serviceSlice, extensionItem)
- return append(cfg, yaml.MapItem{Key: "service", Value: serviceSlice})
+ extensionSlice, err := buildSliceFromCUE(ServicePath, map[string]any{})
+ if err != nil {
+ return nil, err
+ }
+ serviceSlice = append(serviceSlice, extensionSlice...)
+ return append(cfg, yaml.MapItem{Key: "service", Value: serviceSlice}), nil
}
func (cg *OteldConfigGenerater) buildPiplineItem(instance *OteldInstance) yaml.MapItem {
@@ -168,9 +186,7 @@ func (cg *OteldConfigGenerater) buildPiplineItem(instance *OteldInstance) yaml.M
metricsSlice := yaml.MapSlice{}
for _, pipline := range instance.MetricsPipline {
receiverSlice := []string{}
- for _ = range pipline.ReceiverMap {
- receiverSlice = append(receiverSlice, pipline.Name)
- }
+ receiverSlice = append(receiverSlice, fmt.Sprintf(ReceiverNamePattern, pipline.Name))
metricsSlice = append(metricsSlice, yaml.MapItem{Key: "receivers", Value: receiverSlice})
exporterSlice := []string{}
for name, _ := range pipline.ExporterMap {
@@ -188,7 +204,7 @@ func (cg *OteldConfigGenerater) buildPiplineItem(instance *OteldInstance) yaml.M
for _, pipline := range instance.LogsPipline {
receiverSlice := []string{}
for _ = range pipline.ReceiverMap {
- receiverSlice = append(receiverSlice, pipline.Name)
+ receiverSlice = append(receiverSlice, fmt.Sprintf(ReceiverNamePattern, pipline.Name))
}
logsSlice = append(logsSlice, yaml.MapItem{Key: "receivers", Value: receiverSlice})
exporterSlice := []string{}
@@ -207,12 +223,7 @@ func (cg *OteldConfigGenerater) buildPiplineItem(instance *OteldInstance) yaml.M
func (cg *OteldConfigGenerater) appendExtentions(cfg yaml.MapSlice) (yaml.MapSlice, error) {
extensionSlice := yaml.MapSlice{}
- extension, err := buildSliceFromCUE(fmt.Sprintf(ExtensionTplPattern, "apecloud_engine_observer"), map[string]any{})
- if err != nil {
- return nil, err
- }
- extensionSlice = append(extensionSlice, extension...)
- extension, err = buildSliceFromCUE(fmt.Sprintf(ExtensionTplPattern, "runtime_container"), map[string]any{})
+ extension, err := buildSliceFromCUE(ExtensionPath, map[string]any{})
if err != nil {
return nil, err
}
diff --git a/controllers/monitor/types/otel_config_test.go b/controllers/monitor/types/otel_config_test.go
new file mode 100644
index 000000000000..3e52689fe0ec
--- /dev/null
+++ b/controllers/monitor/types/otel_config_test.go
@@ -0,0 +1,124 @@
+/*
+Copyright (C) 2022-2023 ApeCloud Co., Ltd
+
+This file is part of KubeBlocks project
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+*/
+
+package types
+
+import (
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+
+ "github.com/apecloud/kubeblocks/apis/monitor/v1alpha1"
+ "gopkg.in/yaml.v2"
+)
+
+var _ = Describe("monitor_controller", func() {
+ var (
+ logsExporterList v1alpha1.LogsExporterSinkList
+ metricsExporterList v1alpha1.MetricsExporterSinkList
+ )
+
+ BeforeEach(func() {
+ logsExporterList = fakeLogsExporterSinkList()
+ metricsExporterList = fakeMetricsExporterSinkList()
+ })
+
+ It("should generate config correctly from config yaml", func() {
+ Eventually(func(g Gomega) {
+ config, err := LoadConfig("./data/config_test.yaml")
+ if err != nil {
+ return
+ }
+ g.Expect(config).ShouldNot(BeNil())
+ }).Should(Succeed())
+ })
+
+ It("should generate oteld correctly", func() {
+ instance := fakeInstance()
+
+ cg := NewConfigGenerator()
+ cfg, err := cg.GenerateOteldConfiguration(instance, metricsExporterList.Items, logsExporterList.Items)
+ Expect(err).ShouldNot(HaveOccurred())
+ bytes, err := yaml.Marshal(cfg)
+ Expect(err).ShouldNot(HaveOccurred())
+ Expect(len(bytes) > 0).Should(BeTrue())
+ Expect(true).Should(BeTrue())
+ })
+
+})
+
+func fakeInstance() *OteldInstance {
+ return &OteldInstance{
+ MetricsPipline: []Pipline{
+ {
+ Name: "metrics",
+ ReceiverMap: map[string]Receiver{
+ "apecloudmysql": {},
+ "apecloudkubeletstats": {},
+ "apecloudnode": {},
+ },
+ ProcessorMap: map[string]bool{},
+ ExporterMap: map[string]bool{
+ "prometheus": true,
+ },
+ },
+ },
+ OteldTemplate: &v1alpha1.OTeldCollectorTemplate{
+ Spec: v1alpha1.OTeldCollectorTemplateSpec{
+ Mode: v1alpha1.ModeDaemonSet,
+ },
+ },
+ }
+}
+
+func fakeCollectorDataSourceList() v1alpha1.CollectorDataSourceList {
+ return v1alpha1.CollectorDataSourceList{
+ Items: []v1alpha1.CollectorDataSource{
+ {
+ Spec: v1alpha1.CollectorDataSourceSpec{
+ Type: v1alpha1.MetricsDatasourceType,
+ ExporterRef: v1alpha1.ExporterRef{ExporterNames: []string{"prometheus"}},
+ DataSourceList: []v1alpha1.DataSource{
+ {Name: "apecloudmysql"},
+ {Name: "apecloudkubeletstats"},
+ {Name: "apecloudnode"},
+ },
+ },
+ },
+ },
+ }
+}
+
+func fakeMetricsExporterSinkList() v1alpha1.MetricsExporterSinkList {
+ return v1alpha1.MetricsExporterSinkList{
+ Items: []v1alpha1.MetricsExporterSink{
+ {
+ Spec: v1alpha1.MetricsExporterSinkSpec{
+ Type: v1alpha1.PrometheusSinkType, MetricsSinkSource: v1alpha1.MetricsSinkSource{
+ PrometheusConfig: &v1alpha1.PrometheusConfig{ServiceRef: v1alpha1.ServiceRef{Endpoint: "test"}},
+ }},
+ },
+ },
+ }
+}
+
+func fakeLogsExporterSinkList() v1alpha1.LogsExporterSinkList {
+ return v1alpha1.LogsExporterSinkList{
+ Items: []v1alpha1.LogsExporterSink{},
+ }
+}
diff --git a/controllers/monitor/types/types.go b/controllers/monitor/types/types.go
index 2b63bee65a9f..53cfbc7f3e78 100644
--- a/controllers/monitor/types/types.go
+++ b/controllers/monitor/types/types.go
@@ -132,6 +132,10 @@ func (c *ReconcileCtx) VerifyOteldInstance(metricsExporterList *v1alpha1.Metrics
return nil
}
+func (c *ReconcileCtx) SetOteldInstanceMap(instanceMap map[v1alpha1.Mode]*OteldInstance) {
+ c.OteldInstanceMap = instanceMap
+}
+
type ReconcileTask interface {
Do(reqCtx ReconcileCtx) error
}