Skip to content

Commit ab7cc37

Browse files
gravufoedmocosta
andauthored
feat(azuremonitorexporter): add support for authenticator extensions (open-telemetry#41107)
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description Add support for authenticator extensions in Azure Monitor exporter. <!-- Issue number (e.g. #1234) or full URL to issue, if applicable. --> #### Link to tracking issue Fixes open-telemetry#41004 <!--Describe the documentation added.--> #### Documentation Updated `Authentication.md` with an example. Signed-off-by: Christian Artin <[email protected]> Co-authored-by: Edmo Vamerlatti Costa <[email protected]>
1 parent 9592eae commit ab7cc37

File tree

12 files changed

+129
-9
lines changed

12 files changed

+129
-9
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: exporter/azuremonitor
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: "Add authenticator extension support to the Azure Monitor exporter."
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [41004]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: [user]

exporter/azuremonitorexporter/AUTHENTICATION.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ exporters:
2020
connection_string: ${env:APPLICATIONINSIGHTS_CONNECTION_STRING}
2121
```
2222
23+
## Authenticator Extension
24+
25+
You can use any standard OTEL authenticator extension to add authentication to outgoing requests.
26+
This is an example using [azureauthextension](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/azureauthextension):
27+
28+
```yaml
29+
exporters:
30+
azuremonitor:
31+
auth:
32+
authenticator: azureauth
33+
```
34+
2335
## AAD/Entra Authentication
2436
2537
Local Authentication can be disabled in [Application Insights](https://learn.microsoft.com/en-us/azure/azure-monitor/app/azure-ad-authentication) and an AAD based identity can be used in conjunction with the instrumentation key.

exporter/azuremonitorexporter/azuremonitor_exporter.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,24 @@ import (
2020
type azureMonitorExporter struct {
2121
config *Config
2222
transportChannel appinsights.TelemetryChannel
23+
settings component.TelemetrySettings
2324
logger *zap.Logger
2425
packer *metricPacker
2526
}
2627

27-
func (exporter *azureMonitorExporter) Start(_ context.Context, _ component.Host) (err error) {
28+
func (exporter *azureMonitorExporter) Start(ctx context.Context, host component.Host) (err error) {
2829
connectionVars, err := parseConnectionString(exporter.config)
2930
if err != nil {
3031
return err
3132
}
3233

3334
exporter.config.InstrumentationKey = configopaque.String(connectionVars.InstrumentationKey)
34-
exporter.config.Endpoint = connectionVars.IngestionURL
35+
exporter.config.ClientConfig.Endpoint = connectionVars.IngestionURL
3536
telemetryConfiguration := appinsights.NewTelemetryConfiguration(connectionVars.InstrumentationKey)
37+
telemetryConfiguration.Client, err = exporter.config.ClientConfig.ToClient(ctx, host, exporter.settings)
38+
if err != nil {
39+
return err
40+
}
3641
telemetryConfiguration.EndpointUrl = connectionVars.IngestionURL
3742
telemetryConfiguration.MaxBatchSize = exporter.config.MaxBatchSize
3843
telemetryConfiguration.MaxBatchInterval = exporter.config.MaxBatchInterval

exporter/azuremonitorexporter/config.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ package azuremonitorexporter // import "github.com/open-telemetry/opentelemetry-
66
import (
77
"time"
88

9+
"go.opentelemetry.io/collector/config/confighttp"
910
"go.opentelemetry.io/collector/config/configopaque"
1011
"go.opentelemetry.io/collector/exporter/exporterhelper"
1112
)
1213

1314
// Config defines configuration for Azure Monitor
1415
type Config struct {
1516
QueueSettings exporterhelper.QueueBatchConfig `mapstructure:"sending_queue"`
16-
Endpoint string `mapstructure:"endpoint"`
1717
ConnectionString configopaque.String `mapstructure:"connection_string"`
1818
InstrumentationKey configopaque.String `mapstructure:"instrumentation_key"`
1919
MaxBatchSize int `mapstructure:"maxbatchsize"`
@@ -22,4 +22,5 @@ type Config struct {
2222
ShutdownTimeout time.Duration `mapstructure:"shutdown_timeout"`
2323
CustomEventsEnabled bool `mapstructure:"custom_events_enabled"`
2424
ExceptionEventsEnabled bool `mapstructure:"exception_events_enabled"`
25+
ClientConfig confighttp.ClientConfig `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct.
2526
}

exporter/azuremonitorexporter/config_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/stretchr/testify/assert"
1212
"github.com/stretchr/testify/require"
1313
"go.opentelemetry.io/collector/component"
14+
"go.opentelemetry.io/collector/config/confighttp"
1415
"go.opentelemetry.io/collector/confmap/confmaptest"
1516
"go.opentelemetry.io/collector/confmap/xconfmap"
1617
"go.opentelemetry.io/collector/exporter/exporterhelper"
@@ -37,12 +38,14 @@ func TestLoadConfig(t *testing.T) {
3738
{
3839
id: component.NewIDWithName(metadata.Type, "2"),
3940
expected: &Config{
40-
Endpoint: "https://dc.services.visualstudio.com/v2/track",
4141
ConnectionString: "InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://ingestion.azuremonitor.com/",
4242
InstrumentationKey: "00000000-0000-0000-0000-000000000000",
4343
MaxBatchSize: 100,
4444
MaxBatchInterval: 10 * time.Second,
4545
SpanEventsEnabled: false,
46+
ClientConfig: confighttp.ClientConfig{
47+
Endpoint: "https://dc.services.visualstudio.com/v2/track",
48+
},
4649
QueueSettings: func() exporterhelper.QueueBatchConfig {
4750
queue := exporterhelper.NewDefaultQueueConfig()
4851
queue.QueueSize = 1000

exporter/azuremonitorexporter/connection_string_parser.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ func parseConnectionString(exporterConfig *Config) (*connectionVars, error) {
4545
}
4646
if connectionString == "" {
4747
connectionVars.InstrumentationKey = instrumentationKey
48-
if exporterConfig.Endpoint == "" {
48+
if exporterConfig.ClientConfig.Endpoint == "" {
4949
connectionVars.IngestionURL = getIngestionURL(DefaultIngestionEndpoint)
5050
} else {
51-
connectionVars.IngestionURL = getIngestionURL(exporterConfig.Endpoint)
51+
connectionVars.IngestionURL = getIngestionURL(exporterConfig.ClientConfig.Endpoint)
5252
}
5353
return connectionVars, nil
5454
}

exporter/azuremonitorexporter/factory.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,10 @@ func getOrCreateAzureMonitorExporter(cfg component.Config, set exporter.Settings
128128
conf := cfg.(*Config)
129129
ame := exporters.GetOrAdd(set.ID, func() component.Component {
130130
return &azureMonitorExporter{
131-
config: conf,
132-
logger: set.Logger,
133-
packer: newMetricPacker(set.Logger),
131+
config: conf,
132+
logger: set.Logger,
133+
packer: newMetricPacker(set.Logger),
134+
settings: set.TelemetrySettings,
134135
}
135136
})
136137

exporter/azuremonitorexporter/go.mod

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ require (
99
github.com/stretchr/testify v1.11.1
1010
go.opentelemetry.io/collector/component v1.44.0
1111
go.opentelemetry.io/collector/component/componenttest v0.138.0
12+
go.opentelemetry.io/collector/config/confighttp v0.138.0
1213
go.opentelemetry.io/collector/config/configopaque v1.44.0
1314
go.opentelemetry.io/collector/confmap v1.44.0
1415
go.opentelemetry.io/collector/confmap/xconfmap v0.138.0
@@ -25,33 +26,47 @@ require (
2526
code.cloudfoundry.org/clock v0.0.0-20180518195852-02e53af36e6c // indirect
2627
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
2728
github.com/davecgh/go-spew v1.1.1 // indirect
29+
github.com/felixge/httpsnoop v1.0.4 // indirect
30+
github.com/foxboron/go-tpm-keyfiles v0.0.0-20250903184740-5d135037bd4d // indirect
31+
github.com/fsnotify/fsnotify v1.9.0 // indirect
2832
github.com/go-logr/logr v1.4.3 // indirect
2933
github.com/go-logr/stdr v1.2.2 // indirect
3034
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
3135
github.com/gobwas/glob v0.2.3 // indirect
3236
github.com/gofrs/uuid v4.0.0+incompatible // indirect
3337
github.com/gogo/protobuf v1.3.2 // indirect
38+
github.com/golang/snappy v1.0.0 // indirect
39+
github.com/google/go-tpm v0.9.6 // indirect
3440
github.com/google/uuid v1.6.0 // indirect
3541
github.com/hashicorp/go-version v1.7.0 // indirect
3642
github.com/json-iterator/go v1.1.12 // indirect
43+
github.com/klauspost/compress v1.18.0 // indirect
3744
github.com/knadh/koanf/maps v0.1.2 // indirect
3845
github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
3946
github.com/knadh/koanf/v2 v2.3.0 // indirect
4047
github.com/mitchellh/copystructure v1.2.0 // indirect
4148
github.com/mitchellh/reflectwalk v1.0.2 // indirect
4249
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
4350
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
51+
github.com/pierrec/lz4/v4 v4.1.22 // indirect
4452
github.com/pmezard/go-difflib v1.0.0 // indirect
53+
github.com/rs/cors v1.11.1 // indirect
4554
github.com/stretchr/objx v0.5.2 // indirect
4655
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
4756
go.opentelemetry.io/collector/client v1.44.0 // indirect
57+
go.opentelemetry.io/collector/config/configauth v1.44.0 // indirect
58+
go.opentelemetry.io/collector/config/configcompression v1.44.0 // indirect
59+
go.opentelemetry.io/collector/config/configmiddleware v1.44.0 // indirect
4860
go.opentelemetry.io/collector/config/configoptional v1.44.0 // indirect
4961
go.opentelemetry.io/collector/config/configretry v1.44.0 // indirect
62+
go.opentelemetry.io/collector/config/configtls v1.44.0 // indirect
5063
go.opentelemetry.io/collector/consumer v1.44.0 // indirect
5164
go.opentelemetry.io/collector/consumer/consumertest v0.138.0 // indirect
5265
go.opentelemetry.io/collector/consumer/xconsumer v0.138.0 // indirect
5366
go.opentelemetry.io/collector/exporter/xexporter v0.138.0 // indirect
5467
go.opentelemetry.io/collector/extension v1.44.0 // indirect
68+
go.opentelemetry.io/collector/extension/extensionauth v1.44.0 // indirect
69+
go.opentelemetry.io/collector/extension/extensionmiddleware v0.138.0 // indirect
5570
go.opentelemetry.io/collector/extension/xextension v0.138.0 // indirect
5671
go.opentelemetry.io/collector/featuregate v1.44.0 // indirect
5772
go.opentelemetry.io/collector/internal/telemetry v0.138.0 // indirect
@@ -62,13 +77,15 @@ require (
6277
go.opentelemetry.io/collector/receiver/receivertest v0.138.0 // indirect
6378
go.opentelemetry.io/collector/receiver/xreceiver v0.138.0 // indirect
6479
go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 // indirect
80+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
6581
go.opentelemetry.io/otel/log v0.14.0 // indirect
6682
go.opentelemetry.io/otel/metric v1.38.0 // indirect
6783
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
6884
go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
6985
go.opentelemetry.io/otel/trace v1.38.0 // indirect
7086
go.uber.org/multierr v1.11.0 // indirect
7187
go.yaml.in/yaml/v3 v3.0.4 // indirect
88+
golang.org/x/crypto v0.41.0 // indirect
7289
golang.org/x/net v0.43.0 // indirect
7390
golang.org/x/sys v0.36.0 // indirect
7491
golang.org/x/text v0.29.0 // indirect

0 commit comments

Comments
 (0)