Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Service Monitors for the Prometheus exporters #1983

Merged
merged 32 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
751bcf8
Create Service Monitors for the Prometheus exporters
iblancasa Aug 3, 2023
f2d5383
Remove testing changes
iblancasa Aug 3, 2023
caebbab
Remove pull policy
iblancasa Aug 3, 2023
4096ff2
Merge branch 'main' into task/1963
iblancasa Aug 3, 2023
23dea2c
Merge branch 'main' into task/1963
iblancasa Aug 4, 2023
3a97d18
Merge branch 'main' of github.com:open-telemetry/opentelemetry-operat…
iblancasa Aug 7, 2023
ef3fbbd
Apply changes requested in PR
iblancasa Aug 7, 2023
f2961d7
Merge branch 'task/1963' of github.com:iblancasa/opentelemetry-operat…
iblancasa Aug 7, 2023
a831f9b
Merge branch 'main' into task/1963
iblancasa Aug 7, 2023
72f66eb
Fix E2E test
iblancasa Aug 8, 2023
78d01ab
Merge branch 'task/1963' of github.com:iblancasa/opentelemetry-operat…
iblancasa Aug 8, 2023
26ed5e3
Update E2E test to use the enableMetrics flag
iblancasa Aug 8, 2023
5771b65
Use the enable metrics to create the SM or not
iblancasa Aug 8, 2023
73efcaf
Update field description
iblancasa Aug 8, 2023
bf29cca
Add missing docs
iblancasa Aug 8, 2023
24e76ad
Merge branch 'main' of github.com:open-telemetry/opentelemetry-operat…
iblancasa Aug 9, 2023
8d1db38
Merge branch 'main' into task/1963
iblancasa Aug 9, 2023
ab4b983
Merge branch 'main' of github.com:open-telemetry/opentelemetry-operat…
iblancasa Aug 10, 2023
1431608
Remove config
iblancasa Aug 10, 2023
dcff1a7
Merge branch 'task/1963' of github.com:iblancasa/opentelemetry-operat…
iblancasa Aug 10, 2023
08848a2
Merge branch 'main' into task/1963
iblancasa Aug 10, 2023
2bc7426
Merge branch 'main' of github.com:open-telemetry/opentelemetry-operat…
iblancasa Aug 11, 2023
d44744a
Merge branch 'task/1963' of github.com:iblancasa/opentelemetry-operat…
iblancasa Aug 11, 2023
b0977cc
Merge branch 'main' of github.com:open-telemetry/opentelemetry-operat…
iblancasa Aug 16, 2023
4e7a760
Ensue the ServiceMonitor matches a specific OpenTelemetry Collector i…
iblancasa Aug 16, 2023
b3464f6
Merge branch 'main' of github.com:open-telemetry/opentelemetry-operat…
iblancasa Aug 16, 2023
93b6605
Update generated files
iblancasa Aug 16, 2023
a8593d4
Fix comment
iblancasa Aug 16, 2023
2ca5206
Merge branch 'main' into task/1963
iblancasa Aug 17, 2023
8b52936
Merge branch 'main' into task/1963
iblancasa Aug 17, 2023
0eabd95
Merge branch 'main' of github.com:open-telemetry/opentelemetry-operat…
iblancasa Aug 21, 2023
0737352
Merge branch 'task/1963' of github.com:iblancasa/opentelemetry-operat…
iblancasa Aug 21, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. operator, target allocator, github action)
component: operator

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Create ServiceMonitors when the Prometheus exporters are used.

# One or more tracking issues related to the change
issues: [1963]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
2 changes: 1 addition & 1 deletion apis/v1alpha1/opentelemetrycollector_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ type AutoscalerSpec struct {

// MetricsConfigSpec defines a metrics config.
type MetricsConfigSpec struct {
// EnableMetrics specifies if ServiceMonitors should be created for the OpenTelemetry Collector.
// EnableMetrics specifies if ServiceMonitor should be created for the OpenTelemetry Collector and Prometheus Exporters.
iblancasa marked this conversation as resolved.
Show resolved Hide resolved
// The operator.observability.prometheus feature gate must be enabled to use this feature.
//
// +optional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ metadata:
categories: Logging & Tracing
certified: "false"
containerImage: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator
createdAt: "2023-08-09T22:53:11Z"
createdAt: "2023-08-16T14:39:45Z"
description: Provides the OpenTelemetry components, including the Collector
operators.operatorframework.io/builder: operator-sdk-v1.29.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
Expand Down Expand Up @@ -83,9 +83,9 @@ spec:
- description: Metrics defines the metrics configuration for operands.
displayName: Metrics Config
path: observability.metrics
- description: EnableMetrics specifies if ServiceMonitors should be created
for the OpenTelemetry Collector. The operator.observability.prometheus feature
gate must be enabled to use this feature.
- description: EnableMetrics specifies if ServiceMonitor should be created for
iblancasa marked this conversation as resolved.
Show resolved Hide resolved
the OpenTelemetry Collector and Prometheus Exporters. The operator.observability.prometheus
feature gate must be enabled to use this feature.
displayName: Create ServiceMonitors for OpenTelemetry Collector
path: observability.metrics.enableMetrics
version: v1alpha1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3680,9 +3680,9 @@ spec:
description: Metrics defines the metrics configuration for operands.
properties:
enableMetrics:
description: EnableMetrics specifies if ServiceMonitors should
be created for the OpenTelemetry Collector. The operator.observability.prometheus
feature gate must be enabled to use this feature.
description: EnableMetrics specifies if ServiceMonitor should
be created for the OpenTelemetry Collector and Prometheus
Exporters. The operator.observability.
type: boolean
type: object
type: object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3677,9 +3677,9 @@ spec:
description: Metrics defines the metrics configuration for operands.
properties:
enableMetrics:
description: EnableMetrics specifies if ServiceMonitors should
be created for the OpenTelemetry Collector. The operator.observability.prometheus
feature gate must be enabled to use this feature.
description: EnableMetrics specifies if ServiceMonitor should
be created for the OpenTelemetry Collector and Prometheus
Exporters. The operator.observability.
type: boolean
type: object
type: object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ spec:
- description: Metrics defines the metrics configuration for operands.
displayName: Metrics Config
path: observability.metrics
- description: EnableMetrics specifies if ServiceMonitors should be created
for the OpenTelemetry Collector. The operator.observability.prometheus feature
gate must be enabled to use this feature.
- description: EnableMetrics specifies if ServiceMonitor should be created for
the OpenTelemetry Collector and Prometheus Exporters. The operator.observability.prometheus
feature gate must be enabled to use this feature.
displayName: Create ServiceMonitors for OpenTelemetry Collector
path: observability.metrics.enableMetrics
version: v1alpha1
Expand Down
2 changes: 1 addition & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -11396,7 +11396,7 @@ Metrics defines the metrics configuration for operands.
<td><b>enableMetrics</b></td>
<td>boolean</td>
<td>
EnableMetrics specifies if ServiceMonitors should be created for the OpenTelemetry Collector. The operator.observability.prometheus feature gate must be enabled to use this feature.<br/>
EnableMetrics specifies if ServiceMonitor should be created for the OpenTelemetry Collector and Prometheus Exporters. The operator.observability.<br/>
</td>
<td>false</td>
</tr></tbody>
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4
go.opentelemetry.io/collector/featuregate v0.77.0
go.opentelemetry.io/collector/semconv v0.82.0
go.opentelemetry.io/otel v1.16.0
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.27.4
Expand Down
4 changes: 3 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4=
Expand Down Expand Up @@ -539,6 +539,8 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/collector/featuregate v0.77.0 h1:m1/IzaXoQh6SgF6CM80vrBOCf5zSJ2GVISfA27fYzGU=
go.opentelemetry.io/collector/featuregate v0.77.0/go.mod h1:/kVAsGUCyJXIDSgHftCN63QiwAEVHRLX2Kh/S+dqgHY=
go.opentelemetry.io/collector/semconv v0.82.0 h1:WUeT2a+uZjI6kLvwcBaJnGvo7KSQ/9dIFRcxOQdXucc=
go.opentelemetry.io/collector/semconv v0.82.0/go.mod h1:TlYPtzvsXyHOgr5eATi43qEMqwSmIziivJB2uctKswo=
go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s=
go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4=
go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs=
Expand Down
97 changes: 95 additions & 2 deletions internal/manifests/collector/adapters/config_to_ports.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,91 @@ import (
"github.com/mitchellh/mapstructure"
corev1 "k8s.io/api/core/v1"

"github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser"
exporterParser "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser/exporter"
receiverParser "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser/receiver"
)

var (
// ErrNoExporters indicates that there are no exporters in the configuration.
ErrNoExporters = errors.New("no exporters available as part of the configuration")

// ErrNoReceivers indicates that there are no receivers in the configuration.
ErrNoReceivers = errors.New("no receivers available as part of the configuration")

// ErrReceiversNotAMap indicates that the receivers property isn't a map of values.
ErrReceiversNotAMap = errors.New("receivers property in the configuration doesn't contain valid receivers")

// ErrExportersNotAMap indicates that the receivers property isn't a map of values.
iblancasa marked this conversation as resolved.
Show resolved Hide resolved
ErrExportersNotAMap = errors.New("exporters property in the configuration doesn't contain valid exporters")
)

// ConfigToExporterPorts converts the incoming configuration object into a set of service ports required by the exporters.
func ConfigToExporterPorts(logger logr.Logger, config map[interface{}]interface{}) ([]corev1.ServicePort, error) {
// now, we gather which ports we might need to open
// for that, we get all the exporters and check their `endpoint` properties,
// extracting the port from it. The port name has to be a "DNS_LABEL", so, we try to make it follow the pattern:
// ${instance.Name}-${exporter.name}-${exporter.qualifier}
// the exporter-name is typically the node name from the exporters map
// the exporter-qualifier is what comes after the slash in the exporter name, but typically nil
// examples:
// ```yaml
// exporters:
// exampleexporter:
// endpoint: 0.0.0.0:12345
// exampleexporter/settings:
// endpoint: 0.0.0.0:12346
// in this case, we have two ports, named: "exampleexporter" and "exampleexporter-settings"
exportersProperty, ok := config["exporters"]
if !ok {
return nil, ErrNoExporters
}
expEnabled := GetEnabledExporters(logger, config)
if expEnabled == nil {
return nil, ErrExportersNotAMap
}
exporters, ok := exportersProperty.(map[interface{}]interface{})
if !ok {
return nil, ErrExportersNotAMap
}

ports := []corev1.ServicePort{}
for key, val := range exporters {
// This check will pass only the enabled exporters,
// then only the related ports will be opened.
if !expEnabled[key] {
continue
}
exporter, ok := val.(map[interface{}]interface{})
if !ok {
logger.Info("exporter doesn't seem to be a map of properties", "exporter", key)
exporter = map[interface{}]interface{}{}
}

exprtName := key.(string)
exprtParser, err := exporterParser.For(logger, exprtName, exporter)
if err != nil {
logger.V(2).Info("no parser found for '%s'", exprtName)
continue
}

exprtPorts, err := exprtParser.Ports()
if err != nil {
logger.Error(err, "parser for '%s' has returned an error: %w", exprtName, err)
continue
}

if len(exprtPorts) > 0 {
ports = append(ports, exprtPorts...)
}
}

sort.Slice(ports, func(i, j int) bool {
return ports[i].Name < ports[j].Name
})

return ports, nil
}

// ConfigToReceiverPorts converts the incoming configuration object into a set of service ports required by the receivers.
func ConfigToReceiverPorts(logger logr.Logger, config map[interface{}]interface{}) ([]corev1.ServicePort, error) {
// now, we gather which ports we might need to open
Expand Down Expand Up @@ -78,7 +152,7 @@ func ConfigToReceiverPorts(logger logr.Logger, config map[interface{}]interface{
}

rcvrName := key.(string)
rcvrParser := parser.For(logger, rcvrName, receiver)
rcvrParser := receiverParser.For(logger, rcvrName, receiver)

rcvrPorts, err := rcvrParser.Ports()
if err != nil {
Expand All @@ -101,6 +175,25 @@ func ConfigToReceiverPorts(logger logr.Logger, config map[interface{}]interface{
return ports, nil
}

func ConfigToPorts(logger logr.Logger, config map[interface{}]interface{}) []corev1.ServicePort {
ports, err := ConfigToReceiverPorts(logger, config)
if err != nil {
logger.Error(err, "there was a problem while getting the ports from the receivers")
}

exporterPorts, err := ConfigToExporterPorts(logger, config)
if err != nil {
logger.Error(err, "there was a problem while getting the ports from the exporters")
}
ports = append(ports, exporterPorts...)

sort.Slice(ports, func(i, j int) bool {
return ports[i].Name < ports[j].Name
})

return ports
}

// ConfigToMetricsPort gets the port number for the metrics endpoint from the collector config if it has been set.
func ConfigToMetricsPort(logger logr.Logger, config map[interface{}]interface{}) (int32, error) {
// we don't need to unmarshal the whole config, just follow the keys down to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
logf "sigs.k8s.io/controller-runtime/pkg/log"

"github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/adapters"
"github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser"
"github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser/receiver"
)

var logger = logf.Log.WithName("unit-tests")
Expand Down Expand Up @@ -179,7 +179,7 @@ func TestParserFailed(t *testing.T) {
return nil, errors.New("mocked error")
},
}
parser.Register("mock", func(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ReceiverParser {
receiver.Register("mock", func(logger logr.Logger, name string, config map[interface{}]interface{}) receiver.ReceiverParser {
return mockParser
})

Expand Down
42 changes: 25 additions & 17 deletions internal/manifests/collector/adapters/config_validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,33 @@ import (
// Following Otel Doc: Configuring a receiver does not enable it. The receivers are enabled via pipelines within the service section.
// GetEnabledReceivers returns all enabled receivers as a true flag set. If it can't find any receiver, it will return a nil interface.
func GetEnabledReceivers(_ logr.Logger, config map[interface{}]interface{}) map[interface{}]bool {
cfgReceivers, ok := config["receivers"]
return getEnabledComponents(config, "receivers")
}

func GetEnabledExporters(_ logr.Logger, config map[interface{}]interface{}) map[interface{}]bool {
return getEnabledComponents(config, "exporters")
}

func getEnabledComponents(config map[interface{}]interface{}, componentType string) map[interface{}]bool {
cfgComponents, ok := config[componentType]
if !ok {
return nil
}
receivers, ok := cfgReceivers.(map[interface{}]interface{})
components, ok := cfgComponents.(map[interface{}]interface{})
if !ok {
return nil
}
availableReceivers := map[interface{}]bool{}
availableComponents := map[interface{}]bool{}

for recvID := range receivers {
for compID := range components {

//Safe Cast
receiverID, withReceiver := recvID.(string)
if !withReceiver {
componentID, withComponent := compID.(string)
if !withComponent {
return nil
}
//Getting all receivers present in the receivers section and setting them to false.
availableReceivers[receiverID] = false
//Getting all components present in the components (exporters,receivers...) section and setting them to false.
availableComponents[componentID] = false
}

cfgService, withService := config["service"].(map[interface{}]interface{})
Expand Down Expand Up @@ -77,35 +85,35 @@ func GetEnabledReceivers(_ logr.Logger, config map[interface{}]interface{}) map[
return nil
}
for pipSpecID, pipSpecCfg := range pipelineDesc {
if pipSpecID.(string) == "receivers" {
if pipSpecID.(string) == componentType {
receiversList, ok := pipSpecCfg.([]interface{})
if !ok {
continue
}
// If receiversList is empty means that we haven't any enabled Receiver.
if len(receiversList) == 0 {
availableReceivers = nil
availableComponents = nil
} else {
// All enabled receivers will be set as true
for _, recKey := range receiversList {
for _, comKey := range receiversList {
//Safe Cast
receiverKey, ok := recKey.(string)
receiverKey, ok := comKey.(string)
if !ok {
return nil
}
availableReceivers[receiverKey] = true
availableComponents[receiverKey] = true
}
}
//Removing all non-enabled receivers
for recID, recKey := range availableReceivers {
if !(recKey) {
delete(availableReceivers, recID)
for comID, comKey := range availableComponents {
if !(comKey) {
delete(availableComponents, comID)
}
}
}
}
}
}
}
return availableReceivers
return availableComponents
}
Loading