-
Notifications
You must be signed in to change notification settings - Fork 576
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add log support for autoexport (#5733)
Resolve #5730 --------- Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
- Loading branch information
Showing
6 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package autoexport // import "go.opentelemetry.io/contrib/exporters/autoexport" | ||
|
||
import ( | ||
"context" | ||
"os" | ||
|
||
"go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp" | ||
"go.opentelemetry.io/otel/exporters/stdout/stdoutlog" | ||
"go.opentelemetry.io/otel/sdk/log" | ||
) | ||
|
||
// LogOption applies an autoexport configuration option. | ||
type LogOption = option[log.Exporter] | ||
|
||
var logsSignal = newSignal[log.Exporter]("OTEL_LOGS_EXPORTER") | ||
|
||
// NewLogExporter returns a configured [go.opentelemetry.io/otel/sdk/log.Exporter] | ||
// defined using the environment variables described below. | ||
// | ||
// OTEL_LOGS_EXPORTER defines the logs exporter; supported values: | ||
// - "none" - "no operation" exporter | ||
// - "otlp" (default) - OTLP exporter; see [go.opentelemetry.io/otel/exporters/otlp/otlplog] | ||
// - "console" - Standard output exporter; see [go.opentelemetry.io/otel/exporters/stdout/stdoutlog] | ||
// | ||
// OTEL_EXPORTER_OTLP_PROTOCOL defines OTLP exporter's transport protocol; | ||
// supported values: | ||
// - "http/protobuf" (default) - protobuf-encoded data over HTTP connection; | ||
// see: [go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp] | ||
// | ||
// An error is returned if an environment value is set to an unhandled value. | ||
// | ||
// Use [RegisterLogExporter] to handle more values of OTEL_LOGS_EXPORTER. | ||
// | ||
// Use [WithFallbackLogExporter] option to change the returned exporter | ||
// when OTEL_LOGS_EXPORTER is unset or empty. | ||
// | ||
// Use [IsNoneLogExporter] to check if the returned exporter is a "no operation" exporter. | ||
func NewLogExporter(ctx context.Context, opts ...LogOption) (log.Exporter, error) { | ||
return logsSignal.create(ctx, opts...) | ||
} | ||
|
||
// RegisterLogExporter sets the log.Exporter factory to be used when the | ||
// OTEL_LOGS_EXPORTER environment variable contains the exporter name. | ||
// This will panic if name has already been registered. | ||
func RegisterLogExporter(name string, factory func(context.Context) (log.Exporter, error)) { | ||
must(logsSignal.registry.store(name, factory)) | ||
} | ||
|
||
func init() { | ||
RegisterLogExporter("otlp", func(ctx context.Context) (log.Exporter, error) { | ||
proto := os.Getenv(otelExporterOTLPProtoEnvKey) | ||
if proto == "" { | ||
proto = "http/protobuf" | ||
} | ||
|
||
switch proto { | ||
// grpc is not supported yet, should comment out when it is supported | ||
// case "grpc": | ||
// return otlploggrpc.New(ctx) | ||
case "http/protobuf": | ||
return otlploghttp.New(ctx) | ||
default: | ||
return nil, errInvalidOTLPProtocol | ||
} | ||
}) | ||
RegisterLogExporter("console", func(ctx context.Context) (log.Exporter, error) { | ||
return stdoutlog.New() | ||
}) | ||
RegisterLogExporter("none", func(ctx context.Context) (log.Exporter, error) { | ||
return noopLogExporter{}, nil | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package autoexport // import "go.opentelemetry.io/contrib/exporters/autoexport" | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
|
||
"go.opentelemetry.io/otel/exporters/stdout/stdoutlog" | ||
"go.opentelemetry.io/otel/sdk/log" | ||
) | ||
|
||
func TestLogExporterNone(t *testing.T) { | ||
t.Setenv("OTEL_LOGS_EXPORTER", "none") | ||
got, err := NewLogExporter(context.Background()) | ||
assert.NoError(t, err) | ||
t.Cleanup(func() { | ||
assert.NoError(t, got.ForceFlush(context.Background())) | ||
assert.NoError(t, got.Shutdown(context.Background())) | ||
}) | ||
assert.NoError(t, got.Export(context.Background(), nil)) | ||
assert.True(t, IsNoneLogExporter(got)) | ||
} | ||
|
||
func TestLogExporterConsole(t *testing.T) { | ||
t.Setenv("OTEL_LOGS_EXPORTER", "console") | ||
got, err := NewLogExporter(context.Background()) | ||
assert.NoError(t, err) | ||
assert.IsType(t, &stdoutlog.Exporter{}, got) | ||
} | ||
|
||
func TestLogExporterOTLP(t *testing.T) { | ||
t.Setenv("OTEL_LOGS_EXPORTER", "otlp") | ||
|
||
for _, tc := range []struct { | ||
protocol, clientType string | ||
}{ | ||
{"http/protobuf", "atomic.Pointer[go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp.client]"}, | ||
{"", "atomic.Pointer[go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp.client]"}, | ||
} { | ||
t.Run(fmt.Sprintf("protocol=%q", tc.protocol), func(t *testing.T) { | ||
t.Setenv("OTEL_EXPORTER_OTLP_PROTOCOL", tc.protocol) | ||
|
||
got, err := NewLogExporter(context.Background()) | ||
assert.NoError(t, err) | ||
t.Cleanup(func() { | ||
assert.NoError(t, got.Shutdown(context.Background())) | ||
}) | ||
assert.Implements(t, new(log.Exporter), got) | ||
|
||
// Implementation detail hack. This may break when bumping OTLP exporter modules as it uses unexported API. | ||
clientType := reflect.Indirect(reflect.ValueOf(got)).FieldByName("client").Type() | ||
assert.Equal(t, tc.clientType, clientType.String()) | ||
}) | ||
} | ||
} | ||
|
||
func TestLogExporterOTLPOverInvalidProtocol(t *testing.T) { | ||
t.Setenv("OTEL_LOGS_EXPORTER", "otlp") | ||
t.Setenv("OTEL_EXPORTER_OTLP_PROTOCOL", "invalid-protocol") | ||
|
||
_, err := NewLogExporter(context.Background()) | ||
assert.Error(t, err) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters