-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Instana exporter overall structure (#13452)
* Add Instana exporter overall structure Signed-off-by: Martin Hickey <[email protected]> Co-authored-by: Martin Hickey <[email protected]> Co-authored-by: Cedric Ziel <[email protected]> Co-authored-by: Willian Carvalho <[email protected]> * Update after reviews Review comments: - #13452 (review) Signed-off-by: Martin Hickey <[email protected]> * Update after review Review comments: - #13452 (comment) Signed-off-by: Martin Hickey <[email protected]> * Integrate exporter into the components Signed-off-by: Martin Hickey <[email protected]> * Update changelog Signed-off-by: Martin Hickey <[email protected]> * Add porto changes Signed-off-by: Martin Hickey <[email protected]> * unit tests Signed-off-by: Martin Hickey <[email protected]> * Update after review Review comments: - #13452 (comment) - #13452 (comment) Signed-off-by: Martin Hickey <[email protected]> Signed-off-by: Martin Hickey <[email protected]> Co-authored-by: Cedric Ziel <[email protected]> Co-authored-by: Willian Carvalho <[email protected]>
- Loading branch information
1 parent
383db3a
commit 3d3f291
Showing
12 changed files
with
767 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
include ../../Makefile.Common |
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,73 @@ | ||
# Instana Exporter | ||
|
||
| Status | | | ||
| ------------------------ |------------------| | ||
| Stability | [in-development] | | ||
| Supported pipeline types | traces | | ||
| Distributions | [contrib] | | ||
|
||
The Instana Exporter converts OpenTelemetry trace data and then sends it to the [Instana Backend](https://www.ibm.com/docs/en/instana-observability/current?topic=setting-up-managing-instana). | ||
|
||
## Exporter Configuration | ||
|
||
The following exporter configuration parameters are supported. | ||
|
||
|
||
| Parameter | Description | | ||
|----------------|-------------| | ||
| endpoint | The Instana backend endpoint that the Exporter connects to. It depends on your region and it starts with ``https://serverless-``. It corresponds to the Instana environment variable ``INSTANA_ENDPOINT_URL`` | | ||
| agent_key | Your Instana Agent key. The same agent key can be used for host agents and serverless monitoring. It corresponds to the Instana environment variable ``INSTANA_AGENT_KEY`` | | ||
|
||
> These parameters match the Instana Serverless Monitoring environment variables and can be found [here](https://www.ibm.com/docs/en/instana-observability/current?topic=references-environment-variables#serverless-monitoring). | ||
### Sample Configuration | ||
|
||
The code snippet below shows how your configuration file should look like: | ||
|
||
```yaml | ||
[...] | ||
|
||
exporters: | ||
instana: | ||
endpoint: ${INSTANA_ENDPOINT_URL} | ||
agent_key: ${INSTANA_AGENT_KEY} | ||
|
||
[...] | ||
|
||
service: | ||
pipelines: | ||
traces: | ||
exporters: [instana] | ||
|
||
[...] | ||
``` | ||
|
||
### Full Example | ||
|
||
```yaml | ||
receivers: | ||
otlp: | ||
protocols: | ||
grpc: | ||
http: | ||
|
||
processors: | ||
batch: | ||
exporters: | ||
logging: | ||
loglevel: debug | ||
instana: | ||
loglevel: debug | ||
endpoint: ${INSTANA_ENDPOINT_URL} | ||
agent_key: ${INSTANA_AGENT_KEY} | ||
|
||
service: | ||
pipelines: | ||
traces: | ||
receivers: [otlp] | ||
processors: [batch] | ||
exporters: [instana] | ||
``` | ||
[in-development]:https://github.com/open-telemetry/opentelemetry-collector#in-development | ||
[contrib]:https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib |
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,54 @@ | ||
// Copyright 2022, 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 instanaexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/instanaexporter" | ||
|
||
import ( | ||
"errors" | ||
"strings" | ||
|
||
"go.opentelemetry.io/collector/config" | ||
"go.opentelemetry.io/collector/config/confighttp" | ||
) | ||
|
||
// Config defines configuration for the Instana exporter | ||
type Config struct { | ||
config.ExporterSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct | ||
|
||
Endpoint string `mapstructure:"endpoint"` | ||
|
||
AgentKey string `mapstructure:"agent_key"` | ||
|
||
confighttp.HTTPClientSettings `mapstructure:",squash"` | ||
} | ||
|
||
var _ config.Exporter = (*Config)(nil) | ||
|
||
// Validate checks if the exporter configuration is valid | ||
func (cfg *Config) Validate() error { | ||
|
||
if cfg.Endpoint == "" { | ||
return errors.New("no Instana endpoint set") | ||
} | ||
|
||
if cfg.AgentKey == "" { | ||
return errors.New("no Instana agent key set") | ||
} | ||
|
||
if !(strings.HasPrefix(cfg.Endpoint, "http://") || strings.HasPrefix(cfg.Endpoint, "https://")) { | ||
return errors.New("endpoint must start with http:// or https://") | ||
} | ||
|
||
return 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,51 @@ | ||
// Copyright 2022, 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 instanaexporter | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestConfig_Validate(t *testing.T) { | ||
t.Run("Empty configuration", func(t *testing.T) { | ||
c := &Config{} | ||
err := c.Validate() | ||
assert.Error(t, err) | ||
}) | ||
|
||
t.Run("Valid configuration", func(t *testing.T) { | ||
c := &Config{Endpoint: "http://example.com/", AgentKey: "key1"} | ||
err := c.Validate() | ||
assert.NoError(t, err) | ||
|
||
assert.Equal(t, "http://example.com/", c.Endpoint, "no Instana endpoint set") | ||
}) | ||
|
||
t.Run("Invalid Endpoint", func(t *testing.T) { | ||
c := &Config{Endpoint: "example.com", AgentKey: "key1"} | ||
err := c.Validate() | ||
assert.Error(t, err) | ||
|
||
assert.Equal(t, "example.com", c.Endpoint, "endpoint must start with http:// or https://") | ||
}) | ||
|
||
t.Run("No Agent key", func(t *testing.T) { | ||
c := &Config{Endpoint: "http://example.com/"} | ||
err := c.Validate() | ||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Copyright 2022, 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 instanaexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/instanaexporter" | ||
|
||
import ( | ||
"context" | ||
"time" | ||
|
||
"go.opentelemetry.io/collector/component" | ||
"go.opentelemetry.io/collector/config" | ||
"go.opentelemetry.io/collector/config/confighttp" | ||
"go.opentelemetry.io/collector/consumer" | ||
"go.opentelemetry.io/collector/exporter/exporterhelper" | ||
) | ||
|
||
const ( | ||
// The value of "type" key in configuration. | ||
typeStr = "instana" | ||
// The stability level of the exporter. | ||
stability = component.StabilityLevelInDevelopment | ||
) | ||
|
||
// NewFactory creates an Instana exporter factory | ||
func NewFactory() component.ExporterFactory { | ||
return component.NewExporterFactory( | ||
typeStr, | ||
createDefaultConfig, | ||
component.WithTracesExporter(createTracesExporter, stability), | ||
) | ||
} | ||
|
||
// createDefaultConfig creates the default exporter configuration | ||
func createDefaultConfig() config.Exporter { | ||
return &Config{ | ||
ExporterSettings: config.NewExporterSettings(config.NewComponentID(typeStr)), | ||
HTTPClientSettings: confighttp.HTTPClientSettings{ | ||
Endpoint: "", | ||
Timeout: 30 * time.Second, | ||
Headers: map[string]string{}, | ||
WriteBufferSize: 512 * 1024, | ||
}, | ||
} | ||
} | ||
|
||
// createTracesExporter creates a trace exporter based on this configuration | ||
func createTracesExporter(ctx context.Context, set component.ExporterCreateSettings, config config.Exporter) (component.TracesExporter, error) { | ||
// TODO: Lines commented out until implementation is available | ||
// cfg := config.(*Config) | ||
|
||
ctx, cancel := context.WithCancel(ctx) | ||
|
||
// TODO: Lines commented out until implementation is available | ||
var pushConvertedTraces consumer.ConsumeTracesFunc | ||
/*instanaExporter, err := newInstanaExporter(cfg, set) | ||
if err != nil { | ||
cancel() | ||
return nil, err | ||
}*/ | ||
|
||
//TODO: Lines commented out until implementation is available | ||
return exporterhelper.NewTracesExporterWithContext( | ||
ctx, | ||
set, | ||
config, | ||
// instanaExporter.pushConvertedTraces, | ||
pushConvertedTraces, | ||
exporterhelper.WithCapabilities(consumer.Capabilities{MutatesData: false}), | ||
// exporterhelper.WithStart(instanaExporter.start), | ||
// Disable Timeout/RetryOnFailure and SendingQueue | ||
exporterhelper.WithTimeout(exporterhelper.TimeoutSettings{Timeout: 0}), | ||
exporterhelper.WithRetry(exporterhelper.RetrySettings{Enabled: false}), | ||
exporterhelper.WithQueue(exporterhelper.QueueSettings{Enabled: false}), | ||
exporterhelper.WithShutdown(func(context.Context) error { | ||
cancel() | ||
return 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,90 @@ | ||
// Copyright 2022, 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 instanaexporter | ||
|
||
import ( | ||
"path/filepath" | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
"go.opentelemetry.io/collector/component/componenttest" | ||
"go.opentelemetry.io/collector/config" | ||
"go.opentelemetry.io/collector/config/confighttp" | ||
"go.opentelemetry.io/collector/config/configtest" | ||
"go.opentelemetry.io/collector/service/servicetest" | ||
) | ||
|
||
// Test that the factory creates the default configuration | ||
func TestCreateDefaultConfig(t *testing.T) { | ||
factory := NewFactory() | ||
cfg := factory.CreateDefaultConfig() | ||
|
||
assert.Equal(t, &Config{ | ||
ExporterSettings: config.NewExporterSettings(config.NewComponentID(typeStr)), | ||
HTTPClientSettings: confighttp.HTTPClientSettings{ | ||
Endpoint: "", | ||
Timeout: 30 * time.Second, | ||
Headers: map[string]string{}, | ||
WriteBufferSize: 512 * 1024, | ||
}, | ||
}, cfg, "failed to create default config") | ||
|
||
assert.NoError(t, configtest.CheckConfigStruct(cfg)) | ||
} | ||
|
||
// TestLoadConfig tests that the configuration is loaded correctly | ||
func TestLoadConfig(t *testing.T) { | ||
factories, err := componenttest.NopFactories() | ||
assert.NoError(t, err) | ||
|
||
factory := NewFactory() | ||
factories.Exporters[typeStr] = factory | ||
cfg, err := servicetest.LoadConfig(filepath.Join("testdata", "config.yml"), factories) | ||
|
||
require.NoError(t, err) | ||
require.NotNil(t, cfg) | ||
|
||
t.Run("valid config", func(t *testing.T) { | ||
validConfig := cfg.Exporters[config.NewComponentIDWithName(typeStr, "valid")].(*Config) | ||
err = validConfig.Validate() | ||
|
||
require.NoError(t, err) | ||
assert.Equal(t, &Config{ | ||
ExporterSettings: config.NewExporterSettings(config.NewComponentIDWithName(typeStr, "valid")), | ||
HTTPClientSettings: confighttp.HTTPClientSettings{ | ||
Endpoint: "http://example.com/api/", | ||
Timeout: 30 * time.Second, | ||
Headers: map[string]string{}, | ||
WriteBufferSize: 512 * 1024, | ||
}, | ||
Endpoint: "http://example.com/api/", | ||
AgentKey: "key1", | ||
}, validConfig) | ||
}) | ||
|
||
t.Run("bad endpoint", func(t *testing.T) { | ||
badEndpointConfig := cfg.Exporters[config.NewComponentIDWithName(typeStr, "bad_endpoint")].(*Config) | ||
err = badEndpointConfig.Validate() | ||
require.Error(t, err) | ||
}) | ||
|
||
t.Run("missing agent key", func(t *testing.T) { | ||
missingAgentConfig := cfg.Exporters[config.NewComponentIDWithName(typeStr, "missing_agent_key")].(*Config) | ||
err = missingAgentConfig.Validate() | ||
require.Error(t, err) | ||
}) | ||
} |
Oops, something went wrong.