Skip to content

Commit 74245fd

Browse files
Add an otelcol.processor.resourcedetection component (#5764)
* Add a otelcol.processor.resourcedetection component * PR review suggestions * Make k8s API config authentication options const. * Fail validation if an incorrect detector is supplied. * Remove unnecessary Consul attributes. --------- Co-authored-by: Clayton Cornell <[email protected]>
1 parent 25f8b51 commit 74245fd

File tree

24 files changed

+3751
-0
lines changed

24 files changed

+3751
-0
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Main (unreleased)
2020

2121
- A new `pyroscope.java` component for profiling Java processes using async-profiler. (@korniltsev)
2222

23+
- A new `otelcol.processor.resourcedetection` component which inserts resource attributes
24+
to OTLP telemetry based on the host on which Grafana Agent is running. (@ptodev)
25+
2326
### Enhancements
2427

2528
- Include line numbers in profiles produced by `pyrsocope.java` component. (@korniltsev)

component/all/all.go

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ import (
8282
_ "github.com/grafana/agent/component/otelcol/processor/k8sattributes" // Import otelcol.processor.k8sattributes
8383
_ "github.com/grafana/agent/component/otelcol/processor/memorylimiter" // Import otelcol.processor.memory_limiter
8484
_ "github.com/grafana/agent/component/otelcol/processor/probabilistic_sampler" // Import otelcol.processor.probabilistic_sampler
85+
_ "github.com/grafana/agent/component/otelcol/processor/resourcedetection" // Import otelcol.processor.resourcedetection
8586
_ "github.com/grafana/agent/component/otelcol/processor/span" // Import otelcol.processor.span
8687
_ "github.com/grafana/agent/component/otelcol/processor/tail_sampling" // Import otelcol.processor.tail_sampling
8788
_ "github.com/grafana/agent/component/otelcol/processor/transform" // Import otelcol.processor.transform

component/otelcol/config_k8s.go

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package otelcol
2+
3+
import "fmt"
4+
5+
const (
6+
KubernetesAPIConfig_AuthType_None = "none"
7+
KubernetesAPIConfig_AuthType_ServiceAccount = "serviceAccount"
8+
KubernetesAPIConfig_AuthType_KubeConfig = "kubeConfig"
9+
KubernetesAPIConfig_AuthType_TLS = "tls"
10+
)
11+
12+
// KubernetesAPIConfig contains options relevant to connecting to the K8s API
13+
type KubernetesAPIConfig struct {
14+
// How to authenticate to the K8s API server. This can be one of `none`
15+
// (for no auth), `serviceAccount` (to use the standard service account
16+
// token provided to the agent pod), or `kubeConfig` to use credentials
17+
// from `~/.kube/config`.
18+
AuthType string `river:"auth_type,attr,optional"`
19+
20+
// When using auth_type `kubeConfig`, override the current context.
21+
Context string `river:"context,attr,optional"`
22+
}
23+
24+
// Validate returns an error if the config is invalid.
25+
func (c *KubernetesAPIConfig) Validate() error {
26+
switch c.AuthType {
27+
case KubernetesAPIConfig_AuthType_None,
28+
KubernetesAPIConfig_AuthType_ServiceAccount,
29+
KubernetesAPIConfig_AuthType_KubeConfig,
30+
KubernetesAPIConfig_AuthType_TLS:
31+
return nil
32+
default:
33+
return fmt.Errorf("invalid auth_type %q", c.AuthType)
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package ec2
2+
3+
import (
4+
rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
5+
"github.com/grafana/river"
6+
)
7+
8+
const Name = "ec2"
9+
10+
// Config defines user-specified configurations unique to the EC2 detector
11+
type Config struct {
12+
// Tags is a list of regex's to match ec2 instance tag keys that users want
13+
// to add as resource attributes to processed data
14+
Tags []string `river:"tags,attr,optional"`
15+
ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
16+
}
17+
18+
// DefaultArguments holds default settings for Config.
19+
var DefaultArguments = Config{
20+
ResourceAttributes: ResourceAttributesConfig{
21+
CloudAccountID: rac.ResourceAttributeConfig{Enabled: true},
22+
CloudAvailabilityZone: rac.ResourceAttributeConfig{Enabled: true},
23+
CloudPlatform: rac.ResourceAttributeConfig{Enabled: true},
24+
CloudProvider: rac.ResourceAttributeConfig{Enabled: true},
25+
CloudRegion: rac.ResourceAttributeConfig{Enabled: true},
26+
HostID: rac.ResourceAttributeConfig{Enabled: true},
27+
HostImageID: rac.ResourceAttributeConfig{Enabled: true},
28+
HostName: rac.ResourceAttributeConfig{Enabled: true},
29+
HostType: rac.ResourceAttributeConfig{Enabled: true},
30+
},
31+
}
32+
33+
var _ river.Defaulter = (*Config)(nil)
34+
35+
// SetToDefault implements river.Defaulter.
36+
func (args *Config) SetToDefault() {
37+
*args = DefaultArguments
38+
}
39+
40+
func (args Config) Convert() map[string]interface{} {
41+
return map[string]interface{}{
42+
"tags": append([]string{}, args.Tags...),
43+
"resource_attributes": args.ResourceAttributes.Convert(),
44+
}
45+
}
46+
47+
// ResourceAttributesConfig provides config to enable and disable resource attributes.
48+
type ResourceAttributesConfig struct {
49+
CloudAccountID rac.ResourceAttributeConfig `river:"cloud.account.id,block,optional"`
50+
CloudAvailabilityZone rac.ResourceAttributeConfig `river:"cloud.availability_zone,block,optional"`
51+
CloudPlatform rac.ResourceAttributeConfig `river:"cloud.platform,block,optional"`
52+
CloudProvider rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
53+
CloudRegion rac.ResourceAttributeConfig `river:"cloud.region,block,optional"`
54+
HostID rac.ResourceAttributeConfig `river:"host.id,block,optional"`
55+
HostImageID rac.ResourceAttributeConfig `river:"host.image.id,block,optional"`
56+
HostName rac.ResourceAttributeConfig `river:"host.name,block,optional"`
57+
HostType rac.ResourceAttributeConfig `river:"host.type,block,optional"`
58+
}
59+
60+
func (r ResourceAttributesConfig) Convert() map[string]interface{} {
61+
return map[string]interface{}{
62+
"cloud.account.id": r.CloudAccountID.Convert(),
63+
"cloud.availability_zone": r.CloudAvailabilityZone.Convert(),
64+
"cloud.platform": r.CloudPlatform.Convert(),
65+
"cloud.provider": r.CloudProvider.Convert(),
66+
"cloud.region": r.CloudRegion.Convert(),
67+
"host.id": r.HostID.Convert(),
68+
"host.image.id": r.HostImageID.Convert(),
69+
"host.name": r.HostName.Convert(),
70+
"host.type": r.HostType.Convert(),
71+
}
72+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package ecs
2+
3+
import (
4+
rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
5+
"github.com/grafana/river"
6+
)
7+
8+
const Name = "ecs"
9+
10+
type Config struct {
11+
ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
12+
}
13+
14+
// DefaultArguments holds default settings for Config.
15+
var DefaultArguments = Config{
16+
ResourceAttributes: ResourceAttributesConfig{
17+
AwsEcsClusterArn: rac.ResourceAttributeConfig{Enabled: true},
18+
AwsEcsLaunchtype: rac.ResourceAttributeConfig{Enabled: true},
19+
AwsEcsTaskArn: rac.ResourceAttributeConfig{Enabled: true},
20+
AwsEcsTaskFamily: rac.ResourceAttributeConfig{Enabled: true},
21+
AwsEcsTaskRevision: rac.ResourceAttributeConfig{Enabled: true},
22+
AwsLogGroupArns: rac.ResourceAttributeConfig{Enabled: true},
23+
AwsLogGroupNames: rac.ResourceAttributeConfig{Enabled: true},
24+
AwsLogStreamArns: rac.ResourceAttributeConfig{Enabled: true},
25+
AwsLogStreamNames: rac.ResourceAttributeConfig{Enabled: true},
26+
CloudAccountID: rac.ResourceAttributeConfig{Enabled: true},
27+
CloudAvailabilityZone: rac.ResourceAttributeConfig{Enabled: true},
28+
CloudPlatform: rac.ResourceAttributeConfig{Enabled: true},
29+
CloudProvider: rac.ResourceAttributeConfig{Enabled: true},
30+
CloudRegion: rac.ResourceAttributeConfig{Enabled: true},
31+
},
32+
}
33+
34+
var _ river.Defaulter = (*Config)(nil)
35+
36+
// SetToDefault implements river.Defaulter.
37+
func (args *Config) SetToDefault() {
38+
*args = DefaultArguments
39+
}
40+
41+
func (args *Config) Convert() map[string]interface{} {
42+
if args == nil {
43+
return nil
44+
}
45+
46+
return map[string]interface{}{
47+
"resource_attributes": args.ResourceAttributes.Convert(),
48+
}
49+
}
50+
51+
// ResourceAttributesConfig provides config for ecs resource attributes.
52+
type ResourceAttributesConfig struct {
53+
AwsEcsClusterArn rac.ResourceAttributeConfig `river:"aws.ecs.cluster.arn,block,optional"`
54+
AwsEcsLaunchtype rac.ResourceAttributeConfig `river:"aws.ecs.launchtype,block,optional"`
55+
AwsEcsTaskArn rac.ResourceAttributeConfig `river:"aws.ecs.task.arn,block,optional"`
56+
AwsEcsTaskFamily rac.ResourceAttributeConfig `river:"aws.ecs.task.family,block,optional"`
57+
AwsEcsTaskRevision rac.ResourceAttributeConfig `river:"aws.ecs.task.revision,block,optional"`
58+
AwsLogGroupArns rac.ResourceAttributeConfig `river:"aws.log.group.arns,block,optional"`
59+
AwsLogGroupNames rac.ResourceAttributeConfig `river:"aws.log.group.names,block,optional"`
60+
AwsLogStreamArns rac.ResourceAttributeConfig `river:"aws.log.stream.arns,block,optional"`
61+
AwsLogStreamNames rac.ResourceAttributeConfig `river:"aws.log.stream.names,block,optional"`
62+
CloudAccountID rac.ResourceAttributeConfig `river:"cloud.account.id,block,optional"`
63+
CloudAvailabilityZone rac.ResourceAttributeConfig `river:"cloud.availability_zone,block,optional"`
64+
CloudPlatform rac.ResourceAttributeConfig `river:"cloud.platform,block,optional"`
65+
CloudProvider rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
66+
CloudRegion rac.ResourceAttributeConfig `river:"cloud.region,block,optional"`
67+
}
68+
69+
func (r ResourceAttributesConfig) Convert() map[string]interface{} {
70+
return map[string]interface{}{
71+
"aws.ecs.cluster.arn": r.AwsEcsClusterArn.Convert(),
72+
"aws.ecs.launchtype": r.AwsEcsLaunchtype.Convert(),
73+
"aws.ecs.task.arn": r.AwsEcsTaskArn.Convert(),
74+
"aws.ecs.task.family": r.AwsEcsTaskFamily.Convert(),
75+
"aws.ecs.task.revision": r.AwsEcsTaskRevision.Convert(),
76+
"aws.log.group.arns": r.AwsLogGroupArns.Convert(),
77+
"aws.log.group.names": r.AwsLogGroupNames.Convert(),
78+
"aws.log.stream.arns": r.AwsLogStreamArns.Convert(),
79+
"aws.log.stream.names": r.AwsLogStreamNames.Convert(),
80+
"cloud.account.id": r.CloudAccountID.Convert(),
81+
"cloud.availability_zone": r.CloudAvailabilityZone.Convert(),
82+
"cloud.platform": r.CloudPlatform.Convert(),
83+
"cloud.provider": r.CloudProvider.Convert(),
84+
"cloud.region": r.CloudRegion.Convert(),
85+
}
86+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package eks
2+
3+
import (
4+
rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
5+
"github.com/grafana/river"
6+
)
7+
8+
const Name = "eks"
9+
10+
type Config struct {
11+
ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
12+
}
13+
14+
// DefaultArguments holds default settings for Config.
15+
var DefaultArguments = Config{
16+
ResourceAttributes: ResourceAttributesConfig{
17+
CloudPlatform: rac.ResourceAttributeConfig{Enabled: true},
18+
CloudProvider: rac.ResourceAttributeConfig{Enabled: true},
19+
},
20+
}
21+
22+
var _ river.Defaulter = (*Config)(nil)
23+
24+
// SetToDefault implements river.Defaulter.
25+
func (args *Config) SetToDefault() {
26+
*args = DefaultArguments
27+
}
28+
29+
func (args Config) Convert() map[string]interface{} {
30+
return map[string]interface{}{
31+
"resource_attributes": args.ResourceAttributes.Convert(),
32+
}
33+
}
34+
35+
// ResourceAttributesConfig provides config for eks resource attributes.
36+
type ResourceAttributesConfig struct {
37+
CloudPlatform rac.ResourceAttributeConfig `river:"cloud.platform,block,optional"`
38+
CloudProvider rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
39+
}
40+
41+
func (r ResourceAttributesConfig) Convert() map[string]interface{} {
42+
return map[string]interface{}{
43+
"cloud.platform": r.CloudPlatform.Convert(),
44+
"cloud.provider": r.CloudProvider.Convert(),
45+
}
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package elasticbeanstalk
2+
3+
import (
4+
rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
5+
"github.com/grafana/river"
6+
)
7+
8+
const Name = "elasticbeanstalk"
9+
10+
type Config struct {
11+
ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
12+
}
13+
14+
// DefaultArguments holds default settings for Config.
15+
var DefaultArguments = Config{
16+
ResourceAttributes: ResourceAttributesConfig{
17+
CloudPlatform: rac.ResourceAttributeConfig{Enabled: true},
18+
CloudProvider: rac.ResourceAttributeConfig{Enabled: true},
19+
DeploymentEnvironment: rac.ResourceAttributeConfig{Enabled: true},
20+
ServiceInstanceID: rac.ResourceAttributeConfig{Enabled: true},
21+
ServiceVersion: rac.ResourceAttributeConfig{Enabled: true},
22+
},
23+
}
24+
25+
var _ river.Defaulter = (*Config)(nil)
26+
27+
// SetToDefault implements river.Defaulter.
28+
func (args *Config) SetToDefault() {
29+
*args = DefaultArguments
30+
}
31+
32+
func (args Config) Convert() map[string]interface{} {
33+
return map[string]interface{}{
34+
"resource_attributes": args.ResourceAttributes.Convert(),
35+
}
36+
}
37+
38+
// ResourceAttributesConfig provides config for elastic_beanstalk resource attributes.
39+
type ResourceAttributesConfig struct {
40+
CloudPlatform rac.ResourceAttributeConfig `river:"cloud.platform,block,optional"`
41+
CloudProvider rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
42+
DeploymentEnvironment rac.ResourceAttributeConfig `river:"deployment.environment,block,optional"`
43+
ServiceInstanceID rac.ResourceAttributeConfig `river:"service.instance.id,block,optional"`
44+
ServiceVersion rac.ResourceAttributeConfig `river:"service.version,block,optional"`
45+
}
46+
47+
func (r ResourceAttributesConfig) Convert() map[string]interface{} {
48+
return map[string]interface{}{
49+
"cloud.platform": r.CloudPlatform.Convert(),
50+
"cloud.provider": r.CloudProvider.Convert(),
51+
"deployment.environment": r.DeploymentEnvironment.Convert(),
52+
"service.instance.id": r.ServiceInstanceID.Convert(),
53+
"service.version": r.ServiceVersion.Convert(),
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package lambda
2+
3+
import (
4+
rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
5+
"github.com/grafana/river"
6+
)
7+
8+
const Name = "lambda"
9+
10+
type Config struct {
11+
ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
12+
}
13+
14+
// DefaultArguments holds default settings for Config.
15+
var DefaultArguments = Config{
16+
ResourceAttributes: ResourceAttributesConfig{
17+
AwsLogGroupNames: rac.ResourceAttributeConfig{Enabled: true},
18+
AwsLogStreamNames: rac.ResourceAttributeConfig{Enabled: true},
19+
CloudPlatform: rac.ResourceAttributeConfig{Enabled: true},
20+
CloudProvider: rac.ResourceAttributeConfig{Enabled: true},
21+
CloudRegion: rac.ResourceAttributeConfig{Enabled: true},
22+
FaasInstance: rac.ResourceAttributeConfig{Enabled: true},
23+
FaasMaxMemory: rac.ResourceAttributeConfig{Enabled: true},
24+
FaasName: rac.ResourceAttributeConfig{Enabled: true},
25+
FaasVersion: rac.ResourceAttributeConfig{Enabled: true},
26+
},
27+
}
28+
29+
var _ river.Defaulter = (*Config)(nil)
30+
31+
// SetToDefault implements river.Defaulter.
32+
func (args *Config) SetToDefault() {
33+
*args = DefaultArguments
34+
}
35+
36+
func (args Config) Convert() map[string]interface{} {
37+
return map[string]interface{}{
38+
"resource_attributes": args.ResourceAttributes.Convert(),
39+
}
40+
}
41+
42+
// ResourceAttributesConfig provides config for lambda resource attributes.
43+
type ResourceAttributesConfig struct {
44+
AwsLogGroupNames rac.ResourceAttributeConfig `river:"aws.log.group.names,block,optional"`
45+
AwsLogStreamNames rac.ResourceAttributeConfig `river:"aws.log.stream.names,block,optional"`
46+
CloudPlatform rac.ResourceAttributeConfig `river:"cloud.platform,block,optional"`
47+
CloudProvider rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
48+
CloudRegion rac.ResourceAttributeConfig `river:"cloud.region,block,optional"`
49+
FaasInstance rac.ResourceAttributeConfig `river:"faas.instance,block,optional"`
50+
FaasMaxMemory rac.ResourceAttributeConfig `river:"faas.max_memory,block,optional"`
51+
FaasName rac.ResourceAttributeConfig `river:"faas.name,block,optional"`
52+
FaasVersion rac.ResourceAttributeConfig `river:"faas.version,block,optional"`
53+
}
54+
55+
func (r ResourceAttributesConfig) Convert() map[string]interface{} {
56+
return map[string]interface{}{
57+
"aws.log.group.names": r.AwsLogGroupNames.Convert(),
58+
"aws.log.stream.names": r.AwsLogStreamNames.Convert(),
59+
"cloud.platform": r.CloudPlatform.Convert(),
60+
"cloud.provider": r.CloudProvider.Convert(),
61+
"cloud.region": r.CloudRegion.Convert(),
62+
"faas.instance": r.FaasInstance.Convert(),
63+
"faas.max_memory": r.FaasMaxMemory.Convert(),
64+
"faas.name": r.FaasName.Convert(),
65+
"faas.version": r.FaasVersion.Convert(),
66+
}
67+
}

0 commit comments

Comments
 (0)