Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[resourcedetectionprocessor] Azure detector #2372

Merged
merged 11 commits into from
Mar 3, 2021
119 changes: 60 additions & 59 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -14,68 +14,69 @@

* @open-telemetry/collector-contrib-approvers

exporter/alibabacloudlogserviceexporter/ @open-telemetry/collector-contrib-approvers @shabicheng @kongluoxing
exporter/awsemfexporter/ @open-telemetry/collector-contrib-approvers @anuraaga @shaochengwang @mxiamxia
exporter/awsprometheusremotewriteexporter/ @open-telemetry/collector-contrib-approvers @rakyll @alolita
exporter/awsxrayexporter/ @open-telemetry/collector-contrib-approvers @kbrockhoff @anuraaga
exporter/azuremonitorexporter/ @open-telemetry/collector-contrib-approvers @pcwiese
exporter/carbonexporter/ @open-telemetry/collector-contrib-approvers @pjanotti
exporter/datadogexporter/ @open-telemetry/collector-contrib-approvers @KSerrania @ericmustin @mx-psi
exporter/dynatraceexporter/ @open-telemetry/collector-contrib-approvers @dyladan
exporter/elasticexporter/ @open-telemetry/collector-contrib-approvers @axw @simitt @jalvz
exporter/elasticsearchexporter/ @open-telemetry/collector-contrib-approvers @urso @faec @blakerouse
exporter/f5cloudexporter/ @open-telemetry/collector-contrib-approvers @gramidt
exporter/honeycombexporter/ @open-telemetry/collector-contrib-approvers @paulosman @lizthegrey @MikeGoldsmith
exporter/jaegerthrifthttpexporter/ @open-telemetry/collector-contrib-approvers @jpkrohling @pavolloffay
exporter/awskinesisexporter/ @open-telemetry/collector-contrib-approvers @owais
exporter/loadbalancingexporter/ @open-telemetry/collector-contrib-approvers @jpkrohling
exporter/logzioexporter/ @open-telemetry/collector-contrib-approvers @yyyogev
exporter/lokiexporter/ @open-telemetry/collector-contrib-approvers @gramidt
exporter/newrelicexporter/ @open-telemetry/collector-contrib-approvers @MrAlias
exporter/sapmexporter/ @open-telemetry/collector-contrib-approvers @owais @dmitryax
exporter/sentryexporter/ @open-telemetry/collector-contrib-approvers @AbhiPrasad
exporter/signalfxexporter/ @open-telemetry/collector-contrib-approvers @pmcollins @asuresh4
exporter/signalfxcorrelationexporter/ @open-telemetry/collector-contrib-approvers @jrcamp @keitwb
exporter/splunkhecexporter/ @open-telemetry/collector-contrib-approvers @atoulme
exporter/stackdriverexporter/ @open-telemetry/collector-contrib-approvers @dashpole
exporter/sumologicexporter/ @open-telemetry/collector-contrib-approvers @pmm-sumo @sumo-drosiek
exporter/alibabacloudlogserviceexporter/ @open-telemetry/collector-contrib-approvers @shabicheng @kongluoxing
exporter/awsemfexporter/ @open-telemetry/collector-contrib-approvers @anuraaga @shaochengwang @mxiamxia
exporter/awsprometheusremotewriteexporter/ @open-telemetry/collector-contrib-approvers @rakyll @alolita
exporter/awsxrayexporter/ @open-telemetry/collector-contrib-approvers @kbrockhoff @anuraaga
exporter/azuremonitorexporter/ @open-telemetry/collector-contrib-approvers @pcwiese
exporter/carbonexporter/ @open-telemetry/collector-contrib-approvers @pjanotti
exporter/datadogexporter/ @open-telemetry/collector-contrib-approvers @KSerrania @ericmustin @mx-psi
exporter/dynatraceexporter/ @open-telemetry/collector-contrib-approvers @dyladan
exporter/elasticexporter/ @open-telemetry/collector-contrib-approvers @axw @simitt @jalvz
exporter/elasticsearchexporter/ @open-telemetry/collector-contrib-approvers @urso @faec @blakerouse
exporter/f5cloudexporter/ @open-telemetry/collector-contrib-approvers @gramidt
exporter/honeycombexporter/ @open-telemetry/collector-contrib-approvers @paulosman @lizthegrey @MikeGoldsmith
exporter/jaegerthrifthttpexporter/ @open-telemetry/collector-contrib-approvers @jpkrohling @pavolloffay
exporter/awskinesisexporter/ @open-telemetry/collector-contrib-approvers @owais
exporter/loadbalancingexporter/ @open-telemetry/collector-contrib-approvers @jpkrohling
exporter/logzioexporter/ @open-telemetry/collector-contrib-approvers @yyyogev
exporter/lokiexporter/ @open-telemetry/collector-contrib-approvers @gramidt
exporter/newrelicexporter/ @open-telemetry/collector-contrib-approvers @MrAlias
exporter/sapmexporter/ @open-telemetry/collector-contrib-approvers @owais @dmitryax
exporter/sentryexporter/ @open-telemetry/collector-contrib-approvers @AbhiPrasad
exporter/signalfxexporter/ @open-telemetry/collector-contrib-approvers @pmcollins @asuresh4
exporter/signalfxcorrelationexporter/ @open-telemetry/collector-contrib-approvers @jrcamp @keitwb
exporter/splunkhecexporter/ @open-telemetry/collector-contrib-approvers @atoulme
exporter/stackdriverexporter/ @open-telemetry/collector-contrib-approvers @dashpole
exporter/sumologicexporter/ @open-telemetry/collector-contrib-approvers @pmm-sumo @sumo-drosiek

extension/httpforwarder/ @open-telemetry/collector-contrib-approvers @asuresh4
extension/observer/ @open-telemetry/collector-contrib-approvers @asuresh4 @jrcamp
extension/httpforwarder/ @open-telemetry/collector-contrib-approvers @asuresh4
extension/observer/ @open-telemetry/collector-contrib-approvers @asuresh4 @jrcamp

internal/awsxray/ @open-telemetry/collector-contrib-approvers @anuraaga @mxiamxia
internal/k8sconfig/ @open-telemetry/collector-contrib-approvers @pmcollins @asuresh4
internal/splunk/ @open-telemetry/collector-contrib-approvers @pmcollins @asuresh4
internal/stanza/ @open-telemetry/collector-contrib-approvers @djaglowski
internal/awsxray/ @open-telemetry/collector-contrib-approvers @anuraaga @mxiamxia
internal/k8sconfig/ @open-telemetry/collector-contrib-approvers @pmcollins @asuresh4
internal/splunk/ @open-telemetry/collector-contrib-approvers @pmcollins @asuresh4
internal/stanza/ @open-telemetry/collector-contrib-approvers @djaglowski

pkg/batchpertrace/ @open-telemetry/collector-contrib-approvers @jpkrohling
pkg/batchpertrace/ @open-telemetry/collector-contrib-approvers @jpkrohling

processor/groupbyattrsprocessor/ @open-telemetry/collector-contrib-approvers @pmm-sumo
processor/groupbytraceprocessor/ @open-telemetry/collector-contrib-approvers @jpkrohling
processor/k8sprocessor/ @open-telemetry/collector-contrib-approvers @owais @dmitryax @pmm-sumo
processor/metricstransformprocessor/ @open-telemetry/collector-contrib-approvers @james-bebbington
processor/resourcedetectionprocessor/ @open-telemetry/collector-contrib-approvers @jrcamp @pmm-sumo @anuraaga @dashpole
processor/routingprocessor/ @open-telemetry/collector-contrib-approvers @jpkrohling
processor/tailsamplingprocessor/ @open-telemetry/collector-contrib-approvers @jpkrohling
processor/groupbyattrsprocessor/ @open-telemetry/collector-contrib-approvers @pmm-sumo
processor/groupbytraceprocessor/ @open-telemetry/collector-contrib-approvers @jpkrohling
processor/k8sprocessor/ @open-telemetry/collector-contrib-approvers @owais @dmitryax @pmm-sumo
processor/metricstransformprocessor/ @open-telemetry/collector-contrib-approvers @james-bebbington
processor/resourcedetectionprocessor/ @open-telemetry/collector-contrib-approvers @jrcamp @pmm-sumo @anuraaga @dashpole
processor/resourcedetectionprocessor/internal/azure @open-telemetry/collector-contrib-approvers @mx-psi
Copy link
Member Author

@mx-psi mx-psi Feb 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added myself to CODEOWNERS here (I would recommend looking at the diff hiding whitespace changes)

processor/routingprocessor/ @open-telemetry/collector-contrib-approvers @jpkrohling
processor/tailsamplingprocessor/ @open-telemetry/collector-contrib-approvers @jpkrohling

receiver/awsecscontainermetricsreceiver/ @open-telemetry/collector-contrib-approvers @kbrockhoff @anuraaga
receiver/awsxrayreceiver/ @open-telemetry/collector-contrib-approvers @kbrockhoff @anuraaga
receiver/carbonreceiver/ @open-telemetry/collector-contrib-approvers @pjanotti
receiver/collectdreceiver/ @open-telemetry/collector-contrib-approvers @owais
receiver/dockerstatsreceiver/ @open-telemetry/collector-contrib-approvers @rmfitzpatrick
receiver/jmxreceiver/ @open-telemetry/collector-contrib-approvers @rmfitzpatrick
receiver/k8sclusterreceiver/ @open-telemetry/collector-contrib-approvers @asuresh4
receiver/kubeletstatsreceiver/ @open-telemetry/collector-contrib-approvers @pmcollins @asuresh4
receiver/prometheusexecreceiver/ @open-telemetry/collector-contrib-approvers @keitwb
receiver/receivercreator/ @open-telemetry/collector-contrib-approvers @jrcamp
receiver/redisreceiver/ @open-telemetry/collector-contrib-approvers @pmcollins @jrcamp
receiver/sapmreceiver/ @open-telemetry/collector-contrib-approvers @owais
receiver/signalfxreceiver/ @open-telemetry/collector-contrib-approvers @pjanotti @asuresh4
receiver/simpleprometheusreceiver/ @open-telemetry/collector-contrib-approvers @asuresh4
receiver/splunkhecreceiver/ @open-telemetry/collector-contrib-approvers @atoulme @keitwb
receiver/filelogreceiver/ @open-telemetry/collector-contrib-approvers @djaglowski
receiver/statsdreceiver/ @open-telemetry/collector-contrib-approvers @keitwb @jmacd
receiver/wavefrontreceiver/ @open-telemetry/collector-contrib-approvers @pjanotti
receiver/windowsperfcountersreceiver/ @open-telemetry/collector-contrib-approvers @dashpole
receiver/awsecscontainermetricsreceiver/ @open-telemetry/collector-contrib-approvers @kbrockhoff @anuraaga
receiver/awsxrayreceiver/ @open-telemetry/collector-contrib-approvers @kbrockhoff @anuraaga
receiver/carbonreceiver/ @open-telemetry/collector-contrib-approvers @pjanotti
receiver/collectdreceiver/ @open-telemetry/collector-contrib-approvers @owais
receiver/dockerstatsreceiver/ @open-telemetry/collector-contrib-approvers @rmfitzpatrick
receiver/jmxreceiver/ @open-telemetry/collector-contrib-approvers @rmfitzpatrick
receiver/k8sclusterreceiver/ @open-telemetry/collector-contrib-approvers @asuresh4
receiver/kubeletstatsreceiver/ @open-telemetry/collector-contrib-approvers @pmcollins @asuresh4
receiver/prometheusexecreceiver/ @open-telemetry/collector-contrib-approvers @keitwb
receiver/receivercreator/ @open-telemetry/collector-contrib-approvers @jrcamp
receiver/redisreceiver/ @open-telemetry/collector-contrib-approvers @pmcollins @jrcamp
receiver/sapmreceiver/ @open-telemetry/collector-contrib-approvers @owais
receiver/signalfxreceiver/ @open-telemetry/collector-contrib-approvers @pjanotti @asuresh4
receiver/simpleprometheusreceiver/ @open-telemetry/collector-contrib-approvers @asuresh4
receiver/splunkhecreceiver/ @open-telemetry/collector-contrib-approvers @atoulme @keitwb
receiver/filelogreceiver/ @open-telemetry/collector-contrib-approvers @djaglowski
receiver/statsdreceiver/ @open-telemetry/collector-contrib-approvers @keitwb @jmacd
receiver/wavefrontreceiver/ @open-telemetry/collector-contrib-approvers @pjanotti
receiver/windowsperfcountersreceiver/ @open-telemetry/collector-contrib-approvers @dashpole

tracegen/ @open-telemetry/collector-contrib-approvers @jpkrohling
tracegen/ @open-telemetry/collector-contrib-approvers @jpkrohling
12 changes: 11 additions & 1 deletion processor/resourcedetectionprocessor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,20 @@ ec2:
* service.instance.id
* service.version

* Azure: Queries the [Azure Instance Metadata Service](https://aka.ms/azureimds) to retrieve the following resource attributes:

* cloud.provider (azure)
* cloud.region
* cloud.account.id (subscription ID)
* host.id (virtual machine ID)
* host.name
* azure.vm.size (virtual machine size)
* azure.resourcegroup.name (resource group name)

## Configuration

```yaml
# a list of resource detectors to run, valid options are: "env", "system", "gce", "ec2", "ecs", "elastic_beanstalk"
# a list of resource detectors to run, valid options are: "env", "system", "gce", "ec2", "ecs", "elastic_beanstalk", "azure"
detectors: [ <string> ]
# determines if existing resource attributes should be overridden or preserved, defaults to true
override: <bool>
Expand Down
2 changes: 2 additions & 0 deletions processor/resourcedetectionprocessor/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/aws/ec2"
"github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/aws/ecs"
"github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/aws/elasticbeanstalk"
"github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/azure"
"github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/env"
"github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/gcp/gce"
"github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/system"
Expand Down Expand Up @@ -59,6 +60,7 @@ func NewFactory() component.ProcessorFactory {
ec2.TypeStr: ec2.NewDetector,
ecs.TypeStr: ecs.NewDetector,
elasticbeanstalk.TypeStr: elasticbeanstalk.NewDetector,
azure.TypeStr: azure.NewDetector,
})

f := &factory{
Expand Down
64 changes: 64 additions & 0 deletions processor/resourcedetectionprocessor/internal/azure/azure.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright The 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 azure

import (
"context"
"fmt"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/consumer/pdata"
"go.opentelemetry.io/collector/translator/conventions"

"github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal"
)

const (
// TypeStr is the detector type string
TypeStr = "azure"
)

var _ internal.Detector = (*Detector)(nil)

// Detector is an Azure metadata detector
type Detector struct {
provider azureProvider
}

// NewDetector creates a new Azure metadata detector
func NewDetector(component.ProcessorCreateParams, internal.DetectorConfig) (internal.Detector, error) {
return &Detector{provider: newProvider()}, nil
}

// Detect detects system metadata and returns a resource with the available ones
func (d *Detector) Detect(ctx context.Context) (pdata.Resource, error) {
res := pdata.NewResource()
attrs := res.Attributes()

compute, err := d.provider.metadata(ctx)
if err != nil {
return res, fmt.Errorf("failed getting metadata: %w", err)
}

attrs.InsertString(conventions.AttributeCloudProvider, conventions.AttributeCloudProviderAzure)
attrs.InsertString(conventions.AttributeHostName, compute.Name)
attrs.InsertString(conventions.AttributeCloudRegion, compute.Location)
attrs.InsertString(conventions.AttributeHostID, compute.VMID)
attrs.InsertString(conventions.AttributeCloudAccount, compute.SubscriptionID)
attrs.InsertString("azure.vm.size", compute.VMSize)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tigrannajaryan thoughts on these? Do we have any policy about using things that aren't in semantic conventions?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we do. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/attribute-and-label-naming.md#recommendations-for-opentelemetry-authors and https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/attribute-and-label-naming.md#recommendations-for-application-developers

This seems applicable:

The name may be generally applicable to applications in the industry. In that case consider submitting a proposal to this specification to add a new name to the semantic conventions, and if necessary also to add a new namespace.

Or perhaps this:

The name is specific to your company and may be possibly used outside the company as well. To avoid clashes with names introduced by other companies (in a distributed system that uses applications from multiple vendors) it is recommended to prefix the new name by your company's reverse domain name, e.g. com.acme.shopname

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the Amazon ECS detector also uses attribute names that are not in the semantic conventions and they prefix them by aws.ecs.

I think the resource group one is fairly specific to how Azure works and has no equivalents on other cloud providers so it should have some Azure prefix (if azure is not okay, which one should be used?) . I thought about using host.type instead of azure.vm.size but it feels like a stretch.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can keep it for now, but think about Azure attribute name conventions and if you can please make a proposal in spec repo.

attrs.InsertString("azure.resourcegroup.name", compute.ResourceGroupName)

return res, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright The 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 azure

import (
"context"
"fmt"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/translator/conventions"
"go.uber.org/zap"

"github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal"
)

type mockProvider struct {
mock.Mock
}

func (m *mockProvider) metadata(_ context.Context) (*computeMetadata, error) {
args := m.MethodCalled("metadata")
return args.Get(0).(*computeMetadata), args.Error(1)
}

func TestNewDetector(t *testing.T) {
d, err := NewDetector(component.ProcessorCreateParams{Logger: zap.NewNop()}, nil)
require.NoError(t, err)
assert.NotNil(t, d)
}

func TestDetectAzureAvailable(t *testing.T) {
mp := &mockProvider{}
mp.On("metadata").Return(&computeMetadata{
Location: "location",
Name: "name",
VMID: "vmID",
VMSize: "vmSize",
SubscriptionID: "subscriptionID",
ResourceGroupName: "resourceGroup",
}, nil)

detector := &Detector{provider: mp}
res, err := detector.Detect(context.Background())
require.NoError(t, err)
mp.AssertExpectations(t)
res.Attributes().Sort()

expected := internal.NewResource(map[string]interface{}{
conventions.AttributeCloudProvider: conventions.AttributeCloudProviderAzure,
conventions.AttributeHostName: "name",
conventions.AttributeCloudRegion: "location",
conventions.AttributeHostID: "vmID",
conventions.AttributeCloudAccount: "subscriptionID",
"azure.vm.size": "vmSize",
"azure.resourcegroup.name": "resourceGroup",
})
expected.Attributes().Sort()

assert.Equal(t, expected, res)
}

func TestDetectError(t *testing.T) {
mp := &mockProvider{}
mp.On("metadata").Return(&computeMetadata{}, fmt.Errorf("mock error"))

detector := &Detector{provider: mp}
res, err := detector.Detect(context.Background())
assert.Error(t, err)
assert.True(t, internal.IsEmptyResource(res))
}
Loading