Skip to content

Commit

Permalink
[exporter/azuremonitor] Add environment variable support for connecti…
Browse files Browse the repository at this point in the history
…on string (#31523)

This PR introduces the ability to configure the Azure Monitor Exporter
connection string through the `APPLICATIONINSIGHTS_CONNECTION_STRING`
environment variable.

Updated tests & readme.
  • Loading branch information
rajkumar-rangaraj authored Mar 1, 2024
1 parent b65f2d7 commit d728657
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use this changelog template to create an entry for release notes.

# 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. filelogreceiver)
component: azuremonitorexporter

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Added support for configuring the Azure Monitor Exporter connection string via the `APPLICATIONINSIGHTS_CONNECTION_STRING` environment variable.

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [31523]

# (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:

# If your change doesn't affect end users or the exported elements of any package,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: [user]
17 changes: 17 additions & 0 deletions exporter/azuremonitorexporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ To configure the Azure Monitor Exporter, you must specify one of the following s
- `connection_string` (recommended): The Azure Application Insights Connection String is required to send telemetry data to the monitoring service. It is the recommended method for configuring the exporter, aligning with Azure Monitor's best practices. If you need guidance on creating Azure resources, please refer to the step-by-step guides to [Create an Application Insights resource](https://docs.microsoft.com/azure/azure-monitor/app/create-new-resource) and [find your connection string](https://docs.microsoft.com/azure/azure-monitor/app/sdk-connection-string?tabs=net#find-your-connection-string).
- `instrumentation_key`: Application Insights instrumentation key, which can be found in the Application Insights resource in the Azure Portal. While it is currently supported, its use is discouraged and it is slated for deprecation. It is highly encouraged to use the `connection_string` setting for new configurations and migrate existing configurations to use the `connection_string` as soon as possible.

### Environment Variable Support

In addition to the above configuration options, the Azure Monitor Exporter now supports setting the connection string via the `APPLICATIONINSIGHTS_CONNECTION_STRING` environment variable. This method is particularly useful for cloud or containerized environments where managing configuration through environment variables is standard practice.

**Note:** If both the environment variable and the `connection_string` configuration option are provided, the environment variable takes precedence.

### Configuration Options

**Important**: Only one of `connection_string` or `instrumentation_key` should be specified in your configuration. If both are provided, `connection_string` will be used as the priority setting.

The following settings can be optionally configured:
Expand Down Expand Up @@ -58,6 +66,15 @@ exporters:
instrumentation_key: b1cd0778-85fc-4677-a3fa-79d3c23e0efd
```
Example using environment variable:
Ensure `APPLICATIONINSIGHTS_CONNECTION_STRING` is set in your environment, then configure the exporter without specifying a connection string or instrumentation key:

```yaml
exporters:
azuremonitor:
```

## Attribute mapping

### Traces
Expand Down
19 changes: 14 additions & 5 deletions exporter/azuremonitorexporter/connection_string_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package azuremonitorexporter // import "github.com/open-telemetry/opentelemetry-
import (
"fmt"
"net/url"
"os"
"path"
"strings"
)
Expand All @@ -16,14 +17,22 @@ type ConnectionVars struct {
}

const (
DefaultIngestionEndpoint = "https://dc.services.visualstudio.com/"
IngestionEndpointKey = "IngestionEndpoint"
InstrumentationKey = "InstrumentationKey"
ConnectionStringMaxLength = 4096
ApplicationInsightsConnectionString = "APPLICATIONINSIGHTS_CONNECTION_STRING"
DefaultIngestionEndpoint = "https://dc.services.visualstudio.com/"
IngestionEndpointKey = "IngestionEndpoint"
InstrumentationKey = "InstrumentationKey"
ConnectionStringMaxLength = 4096
)

func parseConnectionString(exporterConfig *Config) (*ConnectionVars, error) {
connectionString := string(exporterConfig.ConnectionString)
// First, try to get the connection string from the environment variable
connectionString := os.Getenv(ApplicationInsightsConnectionString)

// If not found in the environment, use the one from the configuration
if connectionString == "" {
connectionString = string(exporterConfig.ConnectionString)
}

instrumentationKey := string(exporterConfig.InstrumentationKey)
connectionVars := &ConnectionVars{}

Expand Down
30 changes: 30 additions & 0 deletions exporter/azuremonitorexporter/connection_string_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package azuremonitorexporter

import (
"os"
"strings"
"testing"

Expand All @@ -15,6 +16,7 @@ import (
func TestParseConnectionString(t *testing.T) {
tests := []struct {
name string
envValue string
config *Config
want *ConnectionVars
wantError bool
Expand Down Expand Up @@ -116,10 +118,38 @@ func TestParseConnectionString(t *testing.T) {
want: nil,
wantError: true,
},
{
name: "Environment variable only",
envValue: "InstrumentationKey=00000000-0000-0000-0000-00000000ENV;IngestionEndpoint=https://ingestion.env.azuremonitor.com/",
config: &Config{},
want: &ConnectionVars{
InstrumentationKey: "00000000-0000-0000-0000-00000000ENV",
IngestionURL: "https://ingestion.env.azuremonitor.com/v2.1/track",
},
wantError: false,
},
{
name: "Environment variable override",
envValue: "InstrumentationKey=00000000-0000-0000-0000-00000000ENV;IngestionEndpoint=https://ingestion.override.azuremonitor.com/",
config: &Config{
ConnectionString: "InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://ingestion.azuremonitor.com/",
InstrumentationKey: "00000000-0000-0000-0000-00000000IKEY",
},
want: &ConnectionVars{
InstrumentationKey: "00000000-0000-0000-0000-00000000ENV",
IngestionURL: "https://ingestion.override.azuremonitor.com/v2.1/track",
},
wantError: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.envValue != "" {
os.Setenv(ApplicationInsightsConnectionString, tt.envValue)
defer os.Unsetenv(ApplicationInsightsConnectionString)
}

got, err := parseConnectionString(tt.config)
if tt.wantError {
require.Error(t, err, "Expected an error but got none")
Expand Down

0 comments on commit d728657

Please sign in to comment.