Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

- Drop support for [Go 1.25]. (#8876)

### Fixed

- Normalize global `OTEL_EXPORTER_OTLP_ENDPOINT` path joining in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` so trailing-slash base URLs do not produce double-slash log export paths. (#8864)

<!-- Released section -->
<!-- Don't change this section unless doing release -->

Expand Down
7 changes: 4 additions & 3 deletions exporters/otlp/otlplog/otlploghttp/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/http"
"net/url"
"os"
"path"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -467,8 +468,8 @@ var readFile = os.ReadFile

// loadCertPool loads and returns the *x509.CertPool found at path if it exists
// and is valid. Otherwise, nil and an error are returned.
func loadCertPool(path string) (*x509.CertPool, error) {
b, err := readFile(path)
func loadCertPool(filePath string) (*x509.CertPool, error) {
b, err := readFile(filePath)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -560,7 +561,7 @@ func convPath(s string) (string, error) {
if err != nil {
return "", err
}
return u.Path + "/v1/logs", nil
return path.Join(u.Path, defaultPath), nil
}

// convInsecure converts s from a string to a bool without case sensitivity.
Expand Down
35 changes: 27 additions & 8 deletions exporters/otlp/otlplog/otlploghttp/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ func TestNewConfig(t *testing.T) {

headers := map[string]string{"a": "A"}
rc := retry.Config{}
const (
httpEndpointURL = "http" + "://test:8080/path"
httpsEndpointURL = "https" + "://test:8080/path"
httpsEndpointURL2 = "https" + "://test2/path2"
ignoredEndpointURL = "http" + "://ignored:9090/alt"
)

testcases := []struct {
name string
Expand Down Expand Up @@ -127,7 +133,7 @@ func TestNewConfig(t *testing.T) {
{
name: "WithEndpointURL",
options: []Option{
WithEndpointURL("http://test:8080/path"),
WithEndpointURL(httpEndpointURL),
},
want: config{
endpoint: newSetting("test:8080"),
Expand All @@ -140,7 +146,7 @@ func TestNewConfig(t *testing.T) {
{
name: "EndpointPrecedence",
options: []Option{
WithEndpointURL("https://test:8080/path"),
WithEndpointURL(httpsEndpointURL),
WithEndpoint("not-test:9090"),
WithURLPath("/alt"),
WithInsecure(),
Expand All @@ -159,7 +165,7 @@ func TestNewConfig(t *testing.T) {
WithEndpoint("not-test:9090"),
WithURLPath("/alt"),
WithInsecure(),
WithEndpointURL("https://test:8080/path"),
WithEndpointURL(httpsEndpointURL),
},
want: config{
endpoint: newSetting("test:8080"),
Expand All @@ -175,7 +181,7 @@ func TestNewConfig(t *testing.T) {
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT": "http://env.endpoint:8080/prefix",
},
options: []Option{
WithEndpointURL("https://test:8080/path"),
WithEndpointURL(httpsEndpointURL),
},
want: config{
endpoint: newSetting("test:8080"),
Expand All @@ -191,7 +197,7 @@ func TestNewConfig(t *testing.T) {
"OTEL_EXPORTER_OTLP_LOGS_INSECURE": "true",
},
options: []Option{
WithEndpointURL("https://test:8080/path"),
WithEndpointURL(httpsEndpointURL),
},
want: config{
endpoint: newSetting("test:8080"),
Expand Down Expand Up @@ -258,6 +264,19 @@ func TestNewConfig(t *testing.T) {
retryCfg: newSetting(defaultRetryCfg),
},
},
{
name: "OTLPEnvironmentVariablesTrailingSlash",
envars: map[string]string{
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://env.endpoint:8080/prefix/",
},
want: config{
endpoint: newSetting("env.endpoint:8080"),
path: newSetting("/prefix/v1/logs"),
insecure: newSetting(true),
timeout: newSetting(defaultTimeout),
retryCfg: newSetting(defaultRetryCfg),
},
},
{
name: "OTLPEndpointEnvironmentVariablesDefaultPath",
envars: map[string]string{
Expand All @@ -274,7 +293,7 @@ func TestNewConfig(t *testing.T) {
{
name: "EnvironmentVariablesPrecedence",
envars: map[string]string{
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://ignored:9090/alt",
"OTEL_EXPORTER_OTLP_ENDPOINT": ignoredEndpointURL,
"OTEL_EXPORTER_OTLP_HEADERS": "b=B",
"OTEL_EXPORTER_OTLP_COMPRESSION": "none",
"OTEL_EXPORTER_OTLP_TIMEOUT": "30000",
Expand Down Expand Up @@ -304,7 +323,7 @@ func TestNewConfig(t *testing.T) {
{
name: "OptionsPrecedence",
envars: map[string]string{
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://ignored:9090/alt",
"OTEL_EXPORTER_OTLP_ENDPOINT": ignoredEndpointURL,
"OTEL_EXPORTER_OTLP_HEADERS": "b=B",
"OTEL_EXPORTER_OTLP_COMPRESSION": "none",
"OTEL_EXPORTER_OTLP_TIMEOUT": "30000",
Expand All @@ -322,7 +341,7 @@ func TestNewConfig(t *testing.T) {
},
options: []Option{
WithEndpoint("test"),
WithEndpointURL("https://test2/path2"),
WithEndpointURL(httpsEndpointURL2),
WithURLPath("/path"),
WithInsecure(),
WithTLSClientConfig(tlsCfg),
Expand Down
Loading