Skip to content

Add new awsebsnvmereceiver #1603

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

Merged
merged 23 commits into from
Apr 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ require (
go.opentelemetry.io/collector/exporter/nopexporter v0.115.0
go.opentelemetry.io/collector/extension v0.115.0
go.opentelemetry.io/collector/extension/zpagesextension v0.115.0
go.opentelemetry.io/collector/filter v0.115.0
go.opentelemetry.io/collector/otelcol v0.115.0
go.opentelemetry.io/collector/processor v0.115.0
go.opentelemetry.io/collector/processor/batchprocessor v0.115.0
Expand Down Expand Up @@ -224,6 +225,7 @@ require (
go.opentelemetry.io/collector/processor/processortest v0.115.0
go.opentelemetry.io/collector/receiver/receivertest v0.115.0
go.opentelemetry.io/collector/scraper v0.115.0
go.uber.org/goleak v1.3.0
)

require (
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1681,6 +1681,8 @@ go.opentelemetry.io/collector/extension/zpagesextension v0.115.0 h1:zYrZZocc7n0Z
go.opentelemetry.io/collector/extension/zpagesextension v0.115.0/go.mod h1:OaXwNHF3MAcInBzCXrhXbTNHfIi9b7YGhXjtCFZqxNY=
go.opentelemetry.io/collector/featuregate v1.22.0 h1:1TUcdqA5VpEsX1Lrr6GG15CptZxDXxiu5AXgwpeNSR4=
go.opentelemetry.io/collector/featuregate v1.22.0/go.mod h1:3GaXqflNDVwWndNGBJ1+XJFy3Fv/XrFgjMN60N3z7yg=
go.opentelemetry.io/collector/filter v0.115.0 h1:pYnHUFDSHSjEIFZit+CU09itVkDXgV+WcV2HOkjvQcE=
go.opentelemetry.io/collector/filter v0.115.0/go.mod h1:aewQ+jmvpH88gPVWpNXiWSm+wwJVxTK4f23ex2NMd2c=
go.opentelemetry.io/collector/internal/fanoutconsumer v0.115.0 h1:6DRiSECeApFq6Jj5ug77rG53R6FzJEZBfygkyMEXdpg=
go.opentelemetry.io/collector/internal/fanoutconsumer v0.115.0/go.mod h1:vgQf5HQdmLQqpDHpDq2S3nTRoUuKtRcZpRTsy+UiwYw=
go.opentelemetry.io/collector/internal/memorylimiter v0.115.0 h1:U07IJxyHZXM6eLn8cOq/Lycx6DhQZhpDOuYtIRw/d6I=
Expand Down
19 changes: 19 additions & 0 deletions receiver/awsebsnvmereceiver/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

package awsebsnvmereceiver

import (
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/receiver/scraperhelper"

"github.com/aws/amazon-cloudwatch-agent/receiver/awsebsnvmereceiver/internal/metadata"
)

type Config struct {
scraperhelper.ControllerConfig `mapstructure:",squash"`
metadata.MetricsBuilderConfig `mapstructure:",squash"`
Devices []string `mapstructure:"devices,omitempty"`
}

var _ component.Config = (*Config)(nil)
51 changes: 51 additions & 0 deletions receiver/awsebsnvmereceiver/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

package awsebsnvmereceiver

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestConfigValidate(t *testing.T) {
c := Config{}
err := c.Validate()
require.NotNil(t, err)
}

func TestConfigWithDevices(t *testing.T) {
testCases := []struct {
name string
devices []string
}{
{
name: "empty devices",
devices: []string{},
},
{
name: "single device",
devices: []string{"nvme0n1"},
},
{
name: "multiple devices",
devices: []string{"nvme0n1", "nvme1n1"},
},
{
name: "wildcard",
devices: []string{"*"},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
cfg := createDefaultConfig().(*Config)
cfg.Devices = tc.devices

// Just verify we can set the devices field
assert.Equal(t, tc.devices, cfg.Devices)
})
}
}
117 changes: 117 additions & 0 deletions receiver/awsebsnvmereceiver/documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
[comment]: <> (Code generated by mdatagen. DO NOT EDIT.)

# awsebsnvmereceiver

## Default Metrics

The following metrics are emitted by default. Each of them can be disabled by applying the following configuration:

```yaml
metrics:
<metric_name>:
enabled: false
```

### diskio_ebs_total_read_ops

The total number of completed read operations

| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
| ---- | ----------- | ---------- | ----------------------- | --------- |
| 1 | Sum | Int | Cumulative | true |

## Optional Metrics

The following metrics are not emitted by default. Each of them can be enabled by applying the following configuration:

```yaml
metrics:
<metric_name>:
enabled: true
```

### diskio_ebs_ec2_instance_performance_exceeded_iops

The total time, in microseconds, that the EBS volume exceeded the attached Amazon EC2 instance's maximum IOPS performance

| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
| ---- | ----------- | ---------- | ----------------------- | --------- |
| us | Sum | Int | Cumulative | true |

### diskio_ebs_ec2_instance_performance_exceeded_tp

The total time, in microseconds, that the EBS volume exceeded the attached Amazon EC2 instance's maximum throughput performance

| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
| ---- | ----------- | ---------- | ----------------------- | --------- |
| us | Sum | Int | Cumulative | true |

### diskio_ebs_total_read_bytes

The total number of read bytes transferred

| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
| ---- | ----------- | ---------- | ----------------------- | --------- |
| By | Sum | Int | Cumulative | true |

### diskio_ebs_total_read_time

The total time spent, in microseconds, by all completed read operations

| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
| ---- | ----------- | ---------- | ----------------------- | --------- |
| us | Sum | Int | Cumulative | true |

### diskio_ebs_total_write_bytes

The total number of write bytes transferred

| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
| ---- | ----------- | ---------- | ----------------------- | --------- |
| By | Sum | Int | Cumulative | true |

### diskio_ebs_total_write_ops

The total number of completed write operations

| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
| ---- | ----------- | ---------- | ----------------------- | --------- |
| 1 | Sum | Int | Cumulative | true |

### diskio_ebs_total_write_time

The total time spent, in microseconds, by all completed write operations

| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
| ---- | ----------- | ---------- | ----------------------- | --------- |
| us | Sum | Int | Cumulative | true |

### diskio_ebs_volume_performance_exceeded_iops

The total time, in microseconds, that IOPS demand exceeded the volume's provisioned IOPS performance

| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
| ---- | ----------- | ---------- | ----------------------- | --------- |
| us | Sum | Int | Cumulative | true |

### diskio_ebs_volume_performance_exceeded_tp

The total time, in microseconds, that throughput demand exceeded the volume's provisioned throughput performance

| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
| ---- | ----------- | ---------- | ----------------------- | --------- |
| us | Sum | Int | Cumulative | true |

### diskio_ebs_volume_queue_length

The number of read and write operations waiting to be completed

| Unit | Metric Type | Value Type |
| ---- | ----------- | ---------- |
| 1 | Gauge | Int |

## Resource Attributes

| Name | Description | Values | Enabled |
| ---- | ----------- | ------ | ------- |
| VolumeId | Unique identifier to the EBS volume | Any Str | true |
51 changes: 51 additions & 0 deletions receiver/awsebsnvmereceiver/factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

package awsebsnvmereceiver

import (
"context"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/consumer"
"go.opentelemetry.io/collector/receiver"
"go.opentelemetry.io/collector/receiver/scraperhelper"
otelscraper "go.opentelemetry.io/collector/scraper"

"github.com/aws/amazon-cloudwatch-agent/internal/util/collections"
"github.com/aws/amazon-cloudwatch-agent/receiver/awsebsnvmereceiver/internal/metadata"
"github.com/aws/amazon-cloudwatch-agent/receiver/awsebsnvmereceiver/internal/nvme"
)

func NewFactory() receiver.Factory {
return receiver.NewFactory(metadata.Type,
createDefaultConfig,
receiver.WithMetrics(createMetricsReceiver, metadata.MetricsStability))
}

func createDefaultConfig() component.Config {
return &Config{
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(),
Devices: []string{},
}
}

func createMetricsReceiver(
_ context.Context,
settings receiver.Settings,
baseCfg component.Config,
consumer consumer.Metrics,
) (receiver.Metrics, error) {
cfg := baseCfg.(*Config)
nvmeScraper := newScraper(cfg, settings, &nvme.Util{}, collections.NewSet[string](cfg.Devices...))
scraper, err := otelscraper.NewMetrics(nvmeScraper.scrape, otelscraper.WithStart(nvmeScraper.start), otelscraper.WithShutdown(nvmeScraper.shutdown))
if err != nil {
return nil, err
}

return scraperhelper.NewScraperControllerReceiver(
&cfg.ControllerConfig, settings, consumer,
scraperhelper.AddScraper(metadata.Type, scraper),
)
}
57 changes: 57 additions & 0 deletions receiver/awsebsnvmereceiver/factory_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

package awsebsnvmereceiver

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/consumer/consumertest"
"go.opentelemetry.io/collector/receiver/receivertest"
)

func TestCreateDefaultConfig(t *testing.T) {
config := createDefaultConfig().(*Config)
assert.NotNil(t, config)
assert.Empty(t, config.Devices)
}

func TestCreateMetricsReceiver(t *testing.T) {
testCases := []struct {
name string
devices []string
}{
{
name: "no devices",
devices: []string{},
},
{
name: "with devices",
devices: []string{"nvme0n1", "nvme1n1"},
},
{
name: "with wildcard",
devices: []string{"*"},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
cfg := createDefaultConfig().(*Config)
cfg.Devices = tc.devices

receiver, err := createMetricsReceiver(
context.Background(),
receivertest.NewNopSettings(),
cfg,
consumertest.NewNop(),
)

require.NoError(t, err)
require.NotNil(t, receiver)
})
}
}
69 changes: 69 additions & 0 deletions receiver/awsebsnvmereceiver/generated_component_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading