Skip to content

Commit

Permalink
Expose the Prometheus exporter port when specified in the config (ope…
Browse files Browse the repository at this point in the history
…n-telemetry#1953)

* Expose Prometheus exporter port in the OTEL Collector

Signed-off-by: Israel Blancas <[email protected]>

* Format

Signed-off-by: Israel Blancas <[email protected]>

* Allow the usage of multiple exporters

Signed-off-by: Israel Blancas <[email protected]>

* Format

Signed-off-by: Israel Blancas <[email protected]>

* Fix tests

Signed-off-by: Israel Blancas <[email protected]>

* Apply changes requested in CR

---------

Signed-off-by: Israel Blancas <[email protected]>
  • Loading branch information
iblancasa authored Aug 1, 2023
1 parent 32df98e commit 627af26
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .chloggen/1689-expose-prometheusexporter-pod-when-enabled.yaml
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: Expose the Prometheus exporter port in the OpenTelemetry Collector container when it is used in the configuration.

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

# (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:
59 changes: 59 additions & 0 deletions pkg/collector/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ package collector

import (
"fmt"
"net"
"sort"
"strconv"
"strings"

"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -183,9 +186,65 @@ func getConfigContainerPorts(logger logr.Logger, cfg string) map[string]corev1.C
ContainerPort: metricsPort,
Protocol: corev1.ProtocolTCP,
}

promExporterPorts, errs := getPrometheusExporterPorts(c)
for _, err := range errs {
logger.V(2).Info("There was a problem getting the prometheus exporter port: %s", err)
}
for _, promPort := range promExporterPorts {
ports[promPort.Name] = promPort
}

return ports
}

func getPrometheusExporterPort(exporterConfig map[interface{}]interface{}) (int32, error) {
var promPort int32 = 0
if endpoint, ok := exporterConfig["endpoint"]; ok {
_, port, err := net.SplitHostPort(endpoint.(string))
if err != nil {
return 0, err
}
i64, err := strconv.ParseInt(port, 10, 32)
if err != nil {
return 0, err
}
promPort = int32(i64)
}
return promPort, nil
}

func getPrometheusExporterPorts(c map[interface{}]interface{}) ([]corev1.ContainerPort, []error) {
errors := make([]error, 0)
ports := make([]corev1.ContainerPort, 0)
if exporters, ok := c["exporters"]; ok && exporters != nil {
for e, exporterConfig := range exporters.(map[interface{}]interface{}) {
exporterName := e.(string)
if strings.Contains(exporterName, "prometheus") {
containerPort, err := getPrometheusExporterPort(exporterConfig.(map[interface{}]interface{}))
if err != nil {
errors = append(errors,
fmt.Errorf(
"there was a problem getting the port. Exporter %s",
exporterName,
),
)
}
ports = append(ports,
corev1.ContainerPort{
Name: naming.PortName(exporterName),
ContainerPort: containerPort,
Protocol: corev1.ProtocolTCP,
},
)
}
}
} else {
errors = append(errors, fmt.Errorf("no exporters specified in the configuration"))
}
return ports, errors
}

func portMapToList(portMap map[string]corev1.ContainerPort) []corev1.ContainerPort {
ports := make([]corev1.ContainerPort, 0, len(portMap))
for _, p := range portMap {
Expand Down
37 changes: 37 additions & 0 deletions pkg/collector/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,43 @@ service:
},
},
},
{
description: "prometheus exporter",
specConfig: `exporters:
prometheus:
endpoint: "0.0.0.0:9090"`,
specPorts: []corev1.ServicePort{},
expectedPorts: []corev1.ContainerPort{
metricContainerPort,
{
Name: "prometheus",
ContainerPort: 9090,
Protocol: corev1.ProtocolTCP,
},
},
},
{
description: "multiple prometheus exporters",
specConfig: `exporters:
prometheus/prod:
endpoint: "0.0.0.0:9090"
prometheus/dev:
endpoint: "0.0.0.0:9091"`,
specPorts: []corev1.ServicePort{},
expectedPorts: []corev1.ContainerPort{
metricContainerPort,
{
Name: "prometheus-prod",
ContainerPort: 9090,
Protocol: corev1.ProtocolTCP,
},
{
Name: "prometheus-dev",
ContainerPort: 9091,
Protocol: corev1.ProtocolTCP,
},
},
},
}

for _, testCase := range tests {
Expand Down
40 changes: 40 additions & 0 deletions pkg/naming/ports.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package naming

import (
"strings"
"unicode/utf8"
)

// PortName returns a dns-safe string for the given name.
// Any char that is not [a-z0-9] is replaced by "-" or "a".
// Replacement character "a" is used only at the beginning or at the end of the name.
// The function does not change length of the string.
func PortName(name string) string {
var d []rune

for i, x := range strings.ToLower(name) {
if regex.Match([]byte(string(x))) {
d = append(d, x)
} else if i == 0 || i == utf8.RuneCountInString(name)-1 {
d = append(d, 'a')
} else {
d = append(d, '-')
}
}

return string(d)
}
43 changes: 43 additions & 0 deletions pkg/naming/ports_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package naming

import (
"regexp"
"testing"

"github.com/stretchr/testify/assert"
)

func TestPortName(t *testing.T) {
var tests = []struct {
in string
out string
}{
{"simplest", "simplest"},
{"prometheus/dev", "prometheus-dev"},
{"prometheus.dev", "prometheus-dev"},
{"prometheus-", "prometheusa"},
{"-prometheus", "aprometheus"},
}
rule, err := regexp.Compile(`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`)
assert.NoError(t, err)

for _, tt := range tests {
assert.Equal(t, tt.out, PortName(tt.in))
matched := rule.Match([]byte(tt.out))
assert.True(t, matched, "%v is not a valid name", tt.out)
}
}

0 comments on commit 627af26

Please sign in to comment.