diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 586f1eac31e1..b38020c0ee3f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -125,6 +125,7 @@ receiver/googlecloudpubsubreceiver/ @open-telemetry/collector-c receiver/googlecloudspannerreceiver/ @open-telemetry/collector-contrib-approvers @ydrozhdzhal @asukhyy @khospodarysko @architjugran receiver/hostmetricsreceiver @open-telemetry/collector-contrib-approvers @dmitryax receiver/influxdbreceiver/ @open-telemetry/collector-contrib-approvers @jacobmarble +receiver/iisreceiver/ @open-telemetry/collector-contrib-approvers @mrod1598 @djaglowski receiver/jaegerreceiver/ @open-telemetry/collector-contrib-approvers @jpkrohling receiver/jmxreceiver/ @open-telemetry/collector-contrib-approvers @rmfitzpatrick receiver/journaldreceiver/ @open-telemetry/collector-contrib-approvers @pmm-sumo diff --git a/.github/workflows/build-and-test-windows.yml b/.github/workflows/build-and-test-windows.yml index 68f474e2e8aa..f13d529dd55a 100644 --- a/.github/workflows/build-and-test-windows.yml +++ b/.github/workflows/build-and-test-windows.yml @@ -14,6 +14,8 @@ jobs: steps: - name: Checkout Repo uses: actions/checkout@v3 + - name: install iis + run: Install-WindowsFeature -name Web-Server -IncludeManagementTools - name: Setup Go uses: actions/setup-go@v3 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index df7bd7cddd60..6739a8320141 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ ### 🚩 Deprecations 🚩 ### 🚀 New components 🚀 - +- `iisreceiver`: Add implementation of IIS Metric Receiver (#8832) ### 💡 Enhancements 💡 ### 🧰 Bug fixes 🧰 diff --git a/cmd/configschema/go.mod b/cmd/configschema/go.mod index 9aa894a12692..519ded2b9ff9 100644 --- a/cmd/configschema/go.mod +++ b/cmd/configschema/go.mod @@ -332,6 +332,7 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/receiver/fluentforwardreceiver v0.49.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/receiver/googlecloudspannerreceiver v0.49.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver v0.49.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver v0.0.0-00010101000000-000000000000 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/receiver/influxdbreceiver v0.49.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver v0.49.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jmxreceiver v0.49.0 // indirect @@ -727,6 +728,8 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostm replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/influxdbreceiver => ../../receiver/influxdbreceiver +replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver => ../../receiver/iisreceiver + replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver => ../../receiver/jaegerreceiver replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jmxreceiver => ../../receiver/jmxreceiver diff --git a/go.mod b/go.mod index 8e3702d09604..e508fdb41de1 100644 --- a/go.mod +++ b/go.mod @@ -91,6 +91,7 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/receiver/fluentforwardreceiver v0.49.0 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/googlecloudspannerreceiver v0.49.0 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver v0.49.0 + github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver v0.0.0-00010101000000-000000000000 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/influxdbreceiver v0.49.0 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver v0.49.0 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jmxreceiver v0.49.0 @@ -731,6 +732,8 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostm replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/influxdbreceiver => ./receiver/influxdbreceiver +replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver => ./receiver/iisreceiver + replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver => ./receiver/jaegerreceiver replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jmxreceiver => ./receiver/jmxreceiver diff --git a/internal/components/components.go b/internal/components/components.go index dc434dce839d..caed787831d2 100644 --- a/internal/components/components.go +++ b/internal/components/components.go @@ -111,6 +111,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/fluentforwardreceiver" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/googlecloudspannerreceiver" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver" + "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/influxdbreceiver" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jmxreceiver" @@ -189,6 +190,7 @@ func Components() (component.Factories, error) { googlecloudspannerreceiver.NewFactory(), hostmetricsreceiver.NewFactory(), influxdbreceiver.NewFactory(), + iisreceiver.NewFactory(), jaegerreceiver.NewFactory(), jmxreceiver.NewFactory(), journaldreceiver.NewFactory(), diff --git a/internal/components/receivers_test.go b/internal/components/receivers_test.go index 06d78f5a326c..63d1f7619be5 100644 --- a/internal/components/receivers_test.go +++ b/internal/components/receivers_test.go @@ -115,6 +115,10 @@ func TestDefaultReceivers(t *testing.T) { { receiver: "influxdb", }, + { + receiver: "iis", + skipLifecyle: true, // Requires a running windows process + }, { receiver: "jaeger", }, diff --git a/receiver/iisreceiver/Makefile b/receiver/iisreceiver/Makefile new file mode 100644 index 000000000000..ded7a36092dc --- /dev/null +++ b/receiver/iisreceiver/Makefile @@ -0,0 +1 @@ +include ../../Makefile.Common diff --git a/receiver/iisreceiver/README.md b/receiver/iisreceiver/README.md new file mode 100644 index 000000000000..ba5203a000ad --- /dev/null +++ b/receiver/iisreceiver/README.md @@ -0,0 +1,26 @@ +# Microsoft IIS Receiver + +The `iis` receiver grabs metrics about an IIS instance using the Windows Performance Counters. +Because of this, it is a Windows only receiver. + +Supported pipeline types: `metrics` + +## Configuration + +The following settings are optional: + +- `collection_interval` (default = `10s`): The interval at which metrics should be emitted by this receiver. + +Example: + +```yaml + receivers: + iis: + collection_interval: 10s +``` + +The full list of settings exposed for this receiver are documented [here](./config.go). + +## Metrics + +Details about the metrics produced by this receiver can be found in [documentation.md](./documentation.md) \ No newline at end of file diff --git a/receiver/iisreceiver/config.go b/receiver/iisreceiver/config.go new file mode 100644 index 000000000000..201a6d93e28a --- /dev/null +++ b/receiver/iisreceiver/config.go @@ -0,0 +1,27 @@ +// 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 iisreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver" + +import ( + "go.opentelemetry.io/collector/receiver/scraperhelper" + + "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver/internal/metadata" +) + +// Config defines configuration for simple prometheus receiver. +type Config struct { + scraperhelper.ScraperControllerSettings `mapstructure:",squash"` + Metrics metadata.MetricsSettings `mapstructure:"metrics"` +} diff --git a/receiver/iisreceiver/config_generator.go b/receiver/iisreceiver/config_generator.go new file mode 100644 index 000000000000..91e36d0d327b --- /dev/null +++ b/receiver/iisreceiver/config_generator.go @@ -0,0 +1,210 @@ +// 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. + +//go:build windows +// +build windows + +package iisreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver" + +import ( + windowsapi "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/winperfcounters" + "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver/internal/metadata" +) + +// getPerfCounters returns established PerfCounters for each metric. +func getScraperCfgs() []windowsapi.ObjectConfig { + return []windowsapi.ObjectConfig{ + { + Object: "Web Service", + Instances: []string{"_Total"}, + Counters: []windowsapi.CounterConfig{ + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.connection.active", + }, + Name: "Current Connections", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.network.io", + Attributes: map[string]string{ + "direction": "received", + }, + }, + Name: "Total Bytes Received", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.network.io", + Attributes: map[string]string{ + "direction": "sent", + }, + }, + Name: "Total Bytes Sent", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.connection.attempt.count", + }, + Name: "Total Connection Attempts (all instances)", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.request.count", + Attributes: map[string]string{ + metadata.A.Request: "delete", + }, + }, + Name: "Total Delete Requests", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.request.count", + Attributes: map[string]string{ + metadata.A.Request: "get", + }, + }, + + Name: "Total Get Requests", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.request.count", + Attributes: map[string]string{ + metadata.A.Request: "head", + }, + }, + + Name: "Total Head Requests", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.request.count", + Attributes: map[string]string{ + metadata.A.Request: "options", + }, + }, + + Name: "Total Options Requests", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.request.count", + Attributes: map[string]string{ + metadata.A.Request: "post", + }, + }, + + Name: "Total Post Requests", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.request.count", + Attributes: map[string]string{ + metadata.A.Request: "put", + }, + }, + + Name: "Total Put Requests", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.request.count", + Attributes: map[string]string{ + metadata.A.Request: "trace", + }, + }, + + Name: "Total Trace Requests", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.network.file.count", + Attributes: map[string]string{ + metadata.A.Direction: "received", + }, + }, + Name: "Total Files Received", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.network.file.count", + Attributes: map[string]string{ + metadata.A.Direction: "sent", + }, + }, + Name: "Total Files Sent", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.connection.anonymous", + }, + + Name: "Total Anonymous Users", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.network.blocked", + }, + + Name: "Total blocked bandwidth bytes", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.uptime", + }, + + Name: "Service Uptime", + }, + }, + }, + { + Object: "HTTP Service Request Queues", + Counters: []windowsapi.CounterConfig{ + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.request.rejected", + }, + + Name: "RejectedRequests", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.request.queue.count", + }, + + Name: "CurrentQueueSize", + }, + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.request.queue.age.max", + }, + Name: "MaxQueueItemAge", + }, + }, + }, + { + Object: "Process", + Instances: []string{"_Total"}, + Counters: []windowsapi.CounterConfig{ + { + MetricRep: windowsapi.MetricRep{ + Name: "iis.thread.active", + }, + Name: "Thread Count", + }, + }, + }, + } +} diff --git a/receiver/iisreceiver/doc.go b/receiver/iisreceiver/doc.go new file mode 100644 index 000000000000..8a3095f2987e --- /dev/null +++ b/receiver/iisreceiver/doc.go @@ -0,0 +1,17 @@ +// 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. + +//go:generate mdatagen --experimental-gen metadata.yaml + +package iisreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver" diff --git a/receiver/iisreceiver/documentation.md b/receiver/iisreceiver/documentation.md new file mode 100644 index 000000000000..c73842d54053 --- /dev/null +++ b/receiver/iisreceiver/documentation.md @@ -0,0 +1,38 @@ +[comment]: <> (Code generated by mdatagen. DO NOT EDIT.) + +# iisreceiver + +## Metrics + +These are the metrics available for this scraper. + +| Name | Description | Unit | Type | Attributes | +| ---- | ----------- | ---- | ---- | ---------- | +| **iis.connection.active** | Number of active connections. | {connections} | Sum(Int) | | +| **iis.connection.anonymous** | Number of connections established anonymously. | {connections} | Sum(Int) | | +| **iis.connection.attempt.count** | Total number of attempts to connect to the server. | {attempts} | Sum(Int) | | +| **iis.network.blocked** | Number of bytes blocked due to bandwidth throttling. | By | Sum(Int) | | +| **iis.network.file.count** | Number of transmitted files. | {files} | Sum(Int) | | +| **iis.network.io** | Total amount of bytes sent and received. | By | Sum(Int) | | +| **iis.request.count** | Total number of requests of a given type. | {requests} | Sum(Int) | | +| **iis.request.queue.age.max** | Age of oldest request in the queue. | ms | Gauge(Int) | | +| **iis.request.queue.count** | Current number of requests in the queue. | {requests} | Sum(Int) | | +| **iis.request.rejected** | Total number of requests rejected. | {requests} | Sum(Int) | | +| **iis.thread.active** | Current number of active threads. | {threads} | Sum(Int) | | +| **iis.uptime** | The amount of time the server has been up. | s | Gauge(Int) | | + +**Highlighted metrics** are emitted by default. Other metrics are optional and not emitted by default. +Any metric can be enabled or disabled with the following scraper configuration: + +```yaml +metrics: + : + enabled: +``` + +## Metric attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| direction (direction) | The direction data is moving. | sent, received | +| request (request) | The type of request sent by a client. | delete, get, head, options, post, put, trace | diff --git a/receiver/iisreceiver/factory.go b/receiver/iisreceiver/factory.go new file mode 100644 index 000000000000..325c51d20319 --- /dev/null +++ b/receiver/iisreceiver/factory.go @@ -0,0 +1,47 @@ +// 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 iisreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver" + +import ( + "time" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/receiver/scraperhelper" + + "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver/internal/metadata" +) + +const ( + typeStr = "iis" +) + +// NewFactory creates a factory for iis receiver. +func NewFactory() component.ReceiverFactory { + return component.NewReceiverFactory( + typeStr, + createDefaultConfig, + component.WithMetricsReceiver(createMetricsReceiver)) +} + +func createDefaultConfig() config.Receiver { + return &Config{ + ScraperControllerSettings: scraperhelper.ScraperControllerSettings{ + ReceiverSettings: config.NewReceiverSettings(config.NewComponentID(typeStr)), + CollectionInterval: time.Minute, + }, + Metrics: metadata.DefaultMetricsSettings(), + } +} diff --git a/receiver/iisreceiver/factory_others.go b/receiver/iisreceiver/factory_others.go new file mode 100644 index 000000000000..99db85f9592e --- /dev/null +++ b/receiver/iisreceiver/factory_others.go @@ -0,0 +1,37 @@ +// 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. + +//go:build !windows +// +build !windows + +package iisreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver" + +import ( + "context" + "errors" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/consumer" +) + +// createMetricsReceiver creates a metrics receiver based on provided config. +func createMetricsReceiver( + ctx context.Context, + params component.ReceiverCreateSettings, + cfg config.Receiver, + consumer consumer.Metrics, +) (component.MetricsReceiver, error) { + return nil, errors.New("the windows perf counters receiver is only supported on Windows") +} diff --git a/receiver/iisreceiver/factory_others_test.go b/receiver/iisreceiver/factory_others_test.go new file mode 100644 index 000000000000..b4680103a00c --- /dev/null +++ b/receiver/iisreceiver/factory_others_test.go @@ -0,0 +1,36 @@ +// 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. + +//go:build !windows +// +build !windows + +package iisreceiver + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/consumer/consumertest" +) + +func TestCreateMetricsReceiver(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + mReceiver, err := factory.CreateMetricsReceiver(context.Background(), componenttest.NewNopReceiverCreateSettings(), cfg, consumertest.NewNop()) + + assert.EqualError(t, err, "the windows perf counters receiver is only supported on Windows") + assert.Nil(t, mReceiver) +} diff --git a/receiver/iisreceiver/factory_test.go b/receiver/iisreceiver/factory_test.go new file mode 100644 index 000000000000..2eae9d11fe18 --- /dev/null +++ b/receiver/iisreceiver/factory_test.go @@ -0,0 +1,47 @@ +// 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 iisreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver" + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/receiver/scraperhelper" + + "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver/internal/metadata" +) + +func TestNewFactory(t *testing.T) { + t.Run("NewFactoryCorrectType", func(t *testing.T) { + factory := NewFactory() + require.EqualValues(t, typeStr, factory.Type()) + }) + + t.Run("NewFactoryDefaultConfig", func(t *testing.T) { + factory := NewFactory() + + var expectedCfg config.Receiver = &Config{ + ScraperControllerSettings: scraperhelper.ScraperControllerSettings{ + ReceiverSettings: config.NewReceiverSettings(config.NewComponentID(typeStr)), + CollectionInterval: 60 * time.Second, + }, + Metrics: metadata.DefaultMetricsSettings(), + } + + require.Equal(t, expectedCfg, factory.CreateDefaultConfig()) + }) +} diff --git a/receiver/iisreceiver/factory_windows.go b/receiver/iisreceiver/factory_windows.go new file mode 100644 index 000000000000..f6e47b95b2ae --- /dev/null +++ b/receiver/iisreceiver/factory_windows.go @@ -0,0 +1,49 @@ +// 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. + +//go:build windows +// +build windows + +package iisreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver" + +import ( + "context" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/receiver/scraperhelper" +) + +func createMetricsReceiver( + _ context.Context, + params component.ReceiverCreateSettings, + rConf config.Receiver, + nextConsumer consumer.Metrics, +) (component.MetricsReceiver, error) { + cfg := rConf.(*Config) + rcvr := newIisReceiver(params, cfg, nextConsumer) + + scraper, err := scraperhelper.NewScraper(typeStr, rcvr.scrape, + scraperhelper.WithStart(rcvr.start), + scraperhelper.WithShutdown(rcvr.shutdown)) + if err != nil { + return nil, err + } + + return scraperhelper.NewScraperControllerReceiver( + &cfg.ScraperControllerSettings, params, nextConsumer, + scraperhelper.AddScraper(scraper), + ) +} diff --git a/receiver/iisreceiver/factory_windows_test.go b/receiver/iisreceiver/factory_windows_test.go new file mode 100644 index 000000000000..08f8e7b548c4 --- /dev/null +++ b/receiver/iisreceiver/factory_windows_test.go @@ -0,0 +1,42 @@ +// 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. + +//go:build windows +// +build windows + +package iisreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver" + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/consumer/consumertest" +) + +func TestWindowsFactory(t *testing.T) { + f := NewFactory() + cfg := f.CreateDefaultConfig() + require.NotNil(t, cfg) + + r, err := f.CreateMetricsReceiver( + context.Background(), + componenttest.NewNopReceiverCreateSettings(), + cfg, + consumertest.NewNop(), + ) + require.NoError(t, err) + require.NotNil(t, r) +} diff --git a/receiver/iisreceiver/go.mod b/receiver/iisreceiver/go.mod new file mode 100644 index 000000000000..8c7b782bfad4 --- /dev/null +++ b/receiver/iisreceiver/go.mod @@ -0,0 +1,36 @@ +module github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver + +go 1.17 + +require ( + github.com/open-telemetry/opentelemetry-collector-contrib/pkg/winperfcounters v0.0.0-00010101000000-000000000000 + github.com/stretchr/testify v1.7.1 + go.opentelemetry.io/collector v0.49.0 + go.opentelemetry.io/collector/model v0.49.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/knadh/koanf v1.4.1 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/mapstructure v1.4.3 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/internal/scrapertest v0.49.0 + github.com/pmezard/go-difflib v1.0.0 // indirect + go.opencensus.io v0.23.0 // indirect + go.opentelemetry.io/otel v1.6.3 // indirect + go.opentelemetry.io/otel/metric v0.29.0 // indirect + go.opentelemetry.io/otel/trace v1.6.3 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.8.0 + golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect +) + +require ( + go.opentelemetry.io/collector/pdata v0.49.0 // indirect + go.uber.org/zap v1.21.0 // indirect +) + +replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/winperfcounters => ../../pkg/winperfcounters diff --git a/receiver/iisreceiver/go.sum b/receiver/iisreceiver/go.sum new file mode 100644 index 000000000000..a41836982a4a --- /dev/null +++ b/receiver/iisreceiver/go.sum @@ -0,0 +1,271 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= +github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw= +github.com/aws/aws-sdk-go-v2/credentials v1.4.3/go.mod h1:FNNC6nQZQUuyhq5aE5c7ata8o9e4ECGmS4lAXC7o1mQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.6.0/go.mod h1:gqlclDEZp4aqJOancXK6TN24aKhT0W0Ae9MHk3wzTMM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.2.4/go.mod h1:ZcBrrI3zBKlhGFNYWvju0I3TR93I7YIgAfy82Fh4lcQ= +github.com/aws/aws-sdk-go-v2/service/appconfig v1.4.2/go.mod h1:FZ3HkCe+b10uFZZkFdvf98LHW21k49W8o8J366lqVKY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.2/go.mod h1:72HRZDLMtmVQiLG2tLfQcaWLCssELvGl+Zf2WVxMmR8= +github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+IkPchKS7p7c2YPKwHmBOk= +github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g= +github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= +github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q= +github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/knadh/koanf v1.4.1 h1:Z0VGW/uo8NJmjd+L1Dc3S5frq6c62w5xQ9Yf4Mg3wFQ= +github.com/knadh/koanf v1.4.1/go.mod h1:1cfH5223ZeZUOs8FU2UdTmaNfHpqgtjV0+NHjRO43gs= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnuG+zWp9L0Uk= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/scrapertest v0.49.0 h1:AryXrR1fsgC3+L01Z/jiAgLsIrUHZQvgC2Pau33EJFo= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/scrapertest v0.49.0/go.mod h1:XrwT/hZkbbWu31L9ynvU8xMortX2kd3BAykbO4OLGCE= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA= +github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/collector v0.49.0 h1:brKMIUwlL1bt0Faxqqxvj7549KWm9FEN77Z4i4RAlDE= +go.opentelemetry.io/collector v0.49.0/go.mod h1:ErYGC1VzzrpK/uM134DJIbARX3jl9vtTqgIXsiWxjGE= +go.opentelemetry.io/collector/model v0.49.0 h1:mbUSNgpaBE3GWmzGsRb5t0xILpXIVYv7scPTTfoMt6c= +go.opentelemetry.io/collector/model v0.49.0/go.mod h1:nOYQv9KoFPs6ihJwOi24qB209EOhS9HkwhGj54YiEAw= +go.opentelemetry.io/collector/pdata v0.49.0 h1:aYj5rOlRC0x7lGXbc185LMsMMoY/pjOTXr5s1O2SzXs= +go.opentelemetry.io/collector/pdata v0.49.0/go.mod h1:YwmKuiFhNgtmhRdpi8Q8FAWPa0AwJTCSlssSsAtuRcY= +go.opentelemetry.io/otel v1.6.3 h1:FLOfo8f9JzFVFVyU+MSRJc2HdEAXQgm7pIv2uFKRSZE= +go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= +go.opentelemetry.io/otel/metric v0.29.0 h1:7unM/I13Dbc1VHw8lTPQ7zfNIgkhcb8BZhujXOS4jKc= +go.opentelemetry.io/otel/metric v0.29.0/go.mod h1:HahKFp1OC1RNTsuO/HNMBHHJR+dmHZ7wLARRgGDwjLQ= +go.opentelemetry.io/otel/sdk v1.6.3 h1:prSHYdwCQOX5DrsEzxowH3nLhoAzEBdZhvrR79scfLs= +go.opentelemetry.io/otel/trace v1.6.3 h1:IqN4L+5b0mPNjdXIiZ90Ni4Bl5BRkDQywePLWemd9bc= +go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 h1:XDXtA5hveEEV8JB2l7nhMTp3t3cHp9ZpwcdjqyEWLlo= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/receiver/iisreceiver/integration_test.go b/receiver/iisreceiver/integration_test.go new file mode 100644 index 000000000000..e66fade2f52a --- /dev/null +++ b/receiver/iisreceiver/integration_test.go @@ -0,0 +1,58 @@ +// 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. + +//go:build windows +// +build windows + +package iisreceiver + +import ( + "context" + "path/filepath" + "testing" + "time" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/consumer/consumertest" + + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/scrapertest" + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/scrapertest/golden" +) + +func TestIisIntegration(t *testing.T) { + t.Parallel() + + f := NewFactory() + cfg := f.CreateDefaultConfig().(*Config) + cfg.ScraperControllerSettings.CollectionInterval = 100 * time.Millisecond + + consumer := new(consumertest.MetricsSink) + settings := componenttest.NewNopReceiverCreateSettings() + rcvr, err := f.CreateMetricsReceiver(context.Background(), settings, cfg, consumer) + require.NoError(t, err, "failed creating metrics receiver") + require.NoError(t, rcvr.Start(context.Background(), componenttest.NewNopHost())) + require.Eventuallyf(t, func() bool { + return consumer.DataPointCount() > 0 + }, 2*time.Minute, 1*time.Second, "failed to receive more than 0 metrics") + require.NoError(t, rcvr.Shutdown(context.Background())) + + actualMetrics := consumer.AllMetrics()[0] + + expectedFile := filepath.Join("testdata", "integration", "expected.json") + expectedMetrics, err := golden.ReadMetrics(expectedFile) + require.NoError(t, err) + + require.NoError(t, scrapertest.CompareMetrics(expectedMetrics, actualMetrics, scrapertest.IgnoreMetricValues())) +} diff --git a/receiver/iisreceiver/internal/metadata/generated_metrics_v2.go b/receiver/iisreceiver/internal/metadata/generated_metrics_v2.go new file mode 100644 index 000000000000..173ea894d3fb --- /dev/null +++ b/receiver/iisreceiver/internal/metadata/generated_metrics_v2.go @@ -0,0 +1,905 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "time" + + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/pmetric" +) + +// MetricSettings provides common settings for a particular metric. +type MetricSettings struct { + Enabled bool `mapstructure:"enabled"` +} + +// MetricsSettings provides settings for iisreceiver metrics. +type MetricsSettings struct { + IisConnectionActive MetricSettings `mapstructure:"iis.connection.active"` + IisConnectionAnonymous MetricSettings `mapstructure:"iis.connection.anonymous"` + IisConnectionAttemptCount MetricSettings `mapstructure:"iis.connection.attempt.count"` + IisNetworkBlocked MetricSettings `mapstructure:"iis.network.blocked"` + IisNetworkFileCount MetricSettings `mapstructure:"iis.network.file.count"` + IisNetworkIo MetricSettings `mapstructure:"iis.network.io"` + IisRequestCount MetricSettings `mapstructure:"iis.request.count"` + IisRequestQueueAgeMax MetricSettings `mapstructure:"iis.request.queue.age.max"` + IisRequestQueueCount MetricSettings `mapstructure:"iis.request.queue.count"` + IisRequestRejected MetricSettings `mapstructure:"iis.request.rejected"` + IisThreadActive MetricSettings `mapstructure:"iis.thread.active"` + IisUptime MetricSettings `mapstructure:"iis.uptime"` +} + +func DefaultMetricsSettings() MetricsSettings { + return MetricsSettings{ + IisConnectionActive: MetricSettings{ + Enabled: true, + }, + IisConnectionAnonymous: MetricSettings{ + Enabled: true, + }, + IisConnectionAttemptCount: MetricSettings{ + Enabled: true, + }, + IisNetworkBlocked: MetricSettings{ + Enabled: true, + }, + IisNetworkFileCount: MetricSettings{ + Enabled: true, + }, + IisNetworkIo: MetricSettings{ + Enabled: true, + }, + IisRequestCount: MetricSettings{ + Enabled: true, + }, + IisRequestQueueAgeMax: MetricSettings{ + Enabled: true, + }, + IisRequestQueueCount: MetricSettings{ + Enabled: true, + }, + IisRequestRejected: MetricSettings{ + Enabled: true, + }, + IisThreadActive: MetricSettings{ + Enabled: true, + }, + IisUptime: MetricSettings{ + Enabled: true, + }, + } +} + +type metricIisConnectionActive struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills iis.connection.active metric with initial data. +func (m *metricIisConnectionActive) init() { + m.data.SetName("iis.connection.active") + m.data.SetDescription("Number of active connections.") + m.data.SetUnit("{connections}") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(false) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) +} + +func (m *metricIisConnectionActive) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricIisConnectionActive) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricIisConnectionActive) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricIisConnectionActive(settings MetricSettings) metricIisConnectionActive { + m := metricIisConnectionActive{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricIisConnectionAnonymous struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills iis.connection.anonymous metric with initial data. +func (m *metricIisConnectionAnonymous) init() { + m.data.SetName("iis.connection.anonymous") + m.data.SetDescription("Number of connections established anonymously.") + m.data.SetUnit("{connections}") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) +} + +func (m *metricIisConnectionAnonymous) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricIisConnectionAnonymous) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricIisConnectionAnonymous) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricIisConnectionAnonymous(settings MetricSettings) metricIisConnectionAnonymous { + m := metricIisConnectionAnonymous{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricIisConnectionAttemptCount struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills iis.connection.attempt.count metric with initial data. +func (m *metricIisConnectionAttemptCount) init() { + m.data.SetName("iis.connection.attempt.count") + m.data.SetDescription("Total number of attempts to connect to the server.") + m.data.SetUnit("{attempts}") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) +} + +func (m *metricIisConnectionAttemptCount) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricIisConnectionAttemptCount) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricIisConnectionAttemptCount) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricIisConnectionAttemptCount(settings MetricSettings) metricIisConnectionAttemptCount { + m := metricIisConnectionAttemptCount{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricIisNetworkBlocked struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills iis.network.blocked metric with initial data. +func (m *metricIisNetworkBlocked) init() { + m.data.SetName("iis.network.blocked") + m.data.SetDescription("Number of bytes blocked due to bandwidth throttling.") + m.data.SetUnit("By") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) +} + +func (m *metricIisNetworkBlocked) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricIisNetworkBlocked) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricIisNetworkBlocked) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricIisNetworkBlocked(settings MetricSettings) metricIisNetworkBlocked { + m := metricIisNetworkBlocked{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricIisNetworkFileCount struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills iis.network.file.count metric with initial data. +func (m *metricIisNetworkFileCount) init() { + m.data.SetName("iis.network.file.count") + m.data.SetDescription("Number of transmitted files.") + m.data.SetUnit("{files}") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricIisNetworkFileCount) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, directionAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert(A.Direction, pcommon.NewValueString(directionAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricIisNetworkFileCount) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricIisNetworkFileCount) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricIisNetworkFileCount(settings MetricSettings) metricIisNetworkFileCount { + m := metricIisNetworkFileCount{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricIisNetworkIo struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills iis.network.io metric with initial data. +func (m *metricIisNetworkIo) init() { + m.data.SetName("iis.network.io") + m.data.SetDescription("Total amount of bytes sent and received.") + m.data.SetUnit("By") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricIisNetworkIo) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, directionAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert(A.Direction, pcommon.NewValueString(directionAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricIisNetworkIo) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricIisNetworkIo) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricIisNetworkIo(settings MetricSettings) metricIisNetworkIo { + m := metricIisNetworkIo{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricIisRequestCount struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills iis.request.count metric with initial data. +func (m *metricIisRequestCount) init() { + m.data.SetName("iis.request.count") + m.data.SetDescription("Total number of requests of a given type.") + m.data.SetUnit("{requests}") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricIisRequestCount) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, requestAttributeValue string) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) + dp.Attributes().Insert(A.Request, pcommon.NewValueString(requestAttributeValue)) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricIisRequestCount) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricIisRequestCount) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricIisRequestCount(settings MetricSettings) metricIisRequestCount { + m := metricIisRequestCount{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricIisRequestQueueAgeMax struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills iis.request.queue.age.max metric with initial data. +func (m *metricIisRequestQueueAgeMax) init() { + m.data.SetName("iis.request.queue.age.max") + m.data.SetDescription("Age of oldest request in the queue.") + m.data.SetUnit("ms") + m.data.SetDataType(pmetric.MetricDataTypeGauge) +} + +func (m *metricIisRequestQueueAgeMax) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.settings.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricIisRequestQueueAgeMax) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricIisRequestQueueAgeMax) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricIisRequestQueueAgeMax(settings MetricSettings) metricIisRequestQueueAgeMax { + m := metricIisRequestQueueAgeMax{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricIisRequestQueueCount struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills iis.request.queue.count metric with initial data. +func (m *metricIisRequestQueueCount) init() { + m.data.SetName("iis.request.queue.count") + m.data.SetDescription("Current number of requests in the queue.") + m.data.SetUnit("{requests}") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(false) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) +} + +func (m *metricIisRequestQueueCount) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricIisRequestQueueCount) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricIisRequestQueueCount) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricIisRequestQueueCount(settings MetricSettings) metricIisRequestQueueCount { + m := metricIisRequestQueueCount{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricIisRequestRejected struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills iis.request.rejected metric with initial data. +func (m *metricIisRequestRejected) init() { + m.data.SetName("iis.request.rejected") + m.data.SetDescription("Total number of requests rejected.") + m.data.SetUnit("{requests}") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) +} + +func (m *metricIisRequestRejected) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricIisRequestRejected) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricIisRequestRejected) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricIisRequestRejected(settings MetricSettings) metricIisRequestRejected { + m := metricIisRequestRejected{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricIisThreadActive struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills iis.thread.active metric with initial data. +func (m *metricIisThreadActive) init() { + m.data.SetName("iis.thread.active") + m.data.SetDescription("Current number of active threads.") + m.data.SetUnit("{threads}") + m.data.SetDataType(pmetric.MetricDataTypeSum) + m.data.Sum().SetIsMonotonic(false) + m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative) +} + +func (m *metricIisThreadActive) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.settings.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricIisThreadActive) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricIisThreadActive) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricIisThreadActive(settings MetricSettings) metricIisThreadActive { + m := metricIisThreadActive{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricIisUptime struct { + data pmetric.Metric // data buffer for generated metric. + settings MetricSettings // metric settings provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills iis.uptime metric with initial data. +func (m *metricIisUptime) init() { + m.data.SetName("iis.uptime") + m.data.SetDescription("The amount of time the server has been up.") + m.data.SetUnit("s") + m.data.SetDataType(pmetric.MetricDataTypeGauge) +} + +func (m *metricIisUptime) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.settings.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntVal(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricIisUptime) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricIisUptime) emit(metrics pmetric.MetricSlice) { + if m.settings.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricIisUptime(settings MetricSettings) metricIisUptime { + m := metricIisUptime{settings: settings} + if settings.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +// MetricsBuilder provides an interface for scrapers to report metrics while taking care of all the transformations +// required to produce metric representation defined in metadata and user settings. +type MetricsBuilder struct { + startTime pcommon.Timestamp // start time that will be applied to all recorded data points. + metricsCapacity int // maximum observed number of metrics per resource. + resourceCapacity int // maximum observed number of resource attributes. + metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. + metricIisConnectionActive metricIisConnectionActive + metricIisConnectionAnonymous metricIisConnectionAnonymous + metricIisConnectionAttemptCount metricIisConnectionAttemptCount + metricIisNetworkBlocked metricIisNetworkBlocked + metricIisNetworkFileCount metricIisNetworkFileCount + metricIisNetworkIo metricIisNetworkIo + metricIisRequestCount metricIisRequestCount + metricIisRequestQueueAgeMax metricIisRequestQueueAgeMax + metricIisRequestQueueCount metricIisRequestQueueCount + metricIisRequestRejected metricIisRequestRejected + metricIisThreadActive metricIisThreadActive + metricIisUptime metricIisUptime +} + +// metricBuilderOption applies changes to default metrics builder. +type metricBuilderOption func(*MetricsBuilder) + +// WithStartTime sets startTime on the metrics builder. +func WithStartTime(startTime pcommon.Timestamp) metricBuilderOption { + return func(mb *MetricsBuilder) { + mb.startTime = startTime + } +} + +func NewMetricsBuilder(settings MetricsSettings, options ...metricBuilderOption) *MetricsBuilder { + mb := &MetricsBuilder{ + startTime: pcommon.NewTimestampFromTime(time.Now()), + metricsBuffer: pmetric.NewMetrics(), + metricIisConnectionActive: newMetricIisConnectionActive(settings.IisConnectionActive), + metricIisConnectionAnonymous: newMetricIisConnectionAnonymous(settings.IisConnectionAnonymous), + metricIisConnectionAttemptCount: newMetricIisConnectionAttemptCount(settings.IisConnectionAttemptCount), + metricIisNetworkBlocked: newMetricIisNetworkBlocked(settings.IisNetworkBlocked), + metricIisNetworkFileCount: newMetricIisNetworkFileCount(settings.IisNetworkFileCount), + metricIisNetworkIo: newMetricIisNetworkIo(settings.IisNetworkIo), + metricIisRequestCount: newMetricIisRequestCount(settings.IisRequestCount), + metricIisRequestQueueAgeMax: newMetricIisRequestQueueAgeMax(settings.IisRequestQueueAgeMax), + metricIisRequestQueueCount: newMetricIisRequestQueueCount(settings.IisRequestQueueCount), + metricIisRequestRejected: newMetricIisRequestRejected(settings.IisRequestRejected), + metricIisThreadActive: newMetricIisThreadActive(settings.IisThreadActive), + metricIisUptime: newMetricIisUptime(settings.IisUptime), + } + for _, op := range options { + op(mb) + } + return mb +} + +// updateCapacity updates max length of metrics and resource attributes that will be used for the slice capacity. +func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { + if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { + mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() + } + if mb.resourceCapacity < rm.Resource().Attributes().Len() { + mb.resourceCapacity = rm.Resource().Attributes().Len() + } +} + +// ResourceOption applies changes to provided resource. +type ResourceOption func(pcommon.Resource) + +// EmitForResource saves all the generated metrics under a new resource and updates the internal state to be ready for +// recording another set of data points as part of another resource. This function can be helpful when one scraper +// needs to emit metrics from several resources. Otherwise calling this function is not required, +// just `Emit` function can be called instead. Resource attributes should be provided as ResourceOption arguments. +func (mb *MetricsBuilder) EmitForResource(ro ...ResourceOption) { + rm := pmetric.NewResourceMetrics() + rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) + for _, op := range ro { + op(rm.Resource()) + } + ils := rm.ScopeMetrics().AppendEmpty() + ils.Scope().SetName("otelcol/iisreceiver") + ils.Metrics().EnsureCapacity(mb.metricsCapacity) + mb.metricIisConnectionActive.emit(ils.Metrics()) + mb.metricIisConnectionAnonymous.emit(ils.Metrics()) + mb.metricIisConnectionAttemptCount.emit(ils.Metrics()) + mb.metricIisNetworkBlocked.emit(ils.Metrics()) + mb.metricIisNetworkFileCount.emit(ils.Metrics()) + mb.metricIisNetworkIo.emit(ils.Metrics()) + mb.metricIisRequestCount.emit(ils.Metrics()) + mb.metricIisRequestQueueAgeMax.emit(ils.Metrics()) + mb.metricIisRequestQueueCount.emit(ils.Metrics()) + mb.metricIisRequestRejected.emit(ils.Metrics()) + mb.metricIisThreadActive.emit(ils.Metrics()) + mb.metricIisUptime.emit(ils.Metrics()) + if ils.Metrics().Len() > 0 { + mb.updateCapacity(rm) + rm.MoveTo(mb.metricsBuffer.ResourceMetrics().AppendEmpty()) + } +} + +// Emit returns all the metrics accumulated by the metrics builder and updates the internal state to be ready for +// recording another set of metrics. This function will be responsible for applying all the transformations required to +// produce metric representation defined in metadata and user settings, e.g. delta or cumulative. +func (mb *MetricsBuilder) Emit(ro ...ResourceOption) pmetric.Metrics { + mb.EmitForResource(ro...) + metrics := pmetric.NewMetrics() + mb.metricsBuffer.MoveTo(metrics) + return metrics +} + +// RecordIisConnectionActiveDataPoint adds a data point to iis.connection.active metric. +func (mb *MetricsBuilder) RecordIisConnectionActiveDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricIisConnectionActive.recordDataPoint(mb.startTime, ts, val) +} + +// RecordIisConnectionAnonymousDataPoint adds a data point to iis.connection.anonymous metric. +func (mb *MetricsBuilder) RecordIisConnectionAnonymousDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricIisConnectionAnonymous.recordDataPoint(mb.startTime, ts, val) +} + +// RecordIisConnectionAttemptCountDataPoint adds a data point to iis.connection.attempt.count metric. +func (mb *MetricsBuilder) RecordIisConnectionAttemptCountDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricIisConnectionAttemptCount.recordDataPoint(mb.startTime, ts, val) +} + +// RecordIisNetworkBlockedDataPoint adds a data point to iis.network.blocked metric. +func (mb *MetricsBuilder) RecordIisNetworkBlockedDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricIisNetworkBlocked.recordDataPoint(mb.startTime, ts, val) +} + +// RecordIisNetworkFileCountDataPoint adds a data point to iis.network.file.count metric. +func (mb *MetricsBuilder) RecordIisNetworkFileCountDataPoint(ts pcommon.Timestamp, val int64, directionAttributeValue string) { + mb.metricIisNetworkFileCount.recordDataPoint(mb.startTime, ts, val, directionAttributeValue) +} + +// RecordIisNetworkIoDataPoint adds a data point to iis.network.io metric. +func (mb *MetricsBuilder) RecordIisNetworkIoDataPoint(ts pcommon.Timestamp, val int64, directionAttributeValue string) { + mb.metricIisNetworkIo.recordDataPoint(mb.startTime, ts, val, directionAttributeValue) +} + +// RecordIisRequestCountDataPoint adds a data point to iis.request.count metric. +func (mb *MetricsBuilder) RecordIisRequestCountDataPoint(ts pcommon.Timestamp, val int64, requestAttributeValue string) { + mb.metricIisRequestCount.recordDataPoint(mb.startTime, ts, val, requestAttributeValue) +} + +// RecordIisRequestQueueAgeMaxDataPoint adds a data point to iis.request.queue.age.max metric. +func (mb *MetricsBuilder) RecordIisRequestQueueAgeMaxDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricIisRequestQueueAgeMax.recordDataPoint(mb.startTime, ts, val) +} + +// RecordIisRequestQueueCountDataPoint adds a data point to iis.request.queue.count metric. +func (mb *MetricsBuilder) RecordIisRequestQueueCountDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricIisRequestQueueCount.recordDataPoint(mb.startTime, ts, val) +} + +// RecordIisRequestRejectedDataPoint adds a data point to iis.request.rejected metric. +func (mb *MetricsBuilder) RecordIisRequestRejectedDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricIisRequestRejected.recordDataPoint(mb.startTime, ts, val) +} + +// RecordIisThreadActiveDataPoint adds a data point to iis.thread.active metric. +func (mb *MetricsBuilder) RecordIisThreadActiveDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricIisThreadActive.recordDataPoint(mb.startTime, ts, val) +} + +// RecordIisUptimeDataPoint adds a data point to iis.uptime metric. +func (mb *MetricsBuilder) RecordIisUptimeDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricIisUptime.recordDataPoint(mb.startTime, ts, val) +} + +// Reset resets metrics builder to its initial state. It should be used when external metrics source is restarted, +// and metrics builder should update its startTime and reset it's internal state accordingly. +func (mb *MetricsBuilder) Reset(options ...metricBuilderOption) { + mb.startTime = pcommon.NewTimestampFromTime(time.Now()) + for _, op := range options { + op(mb) + } +} + +// Attributes contains the possible metric attributes that can be used. +var Attributes = struct { + // Direction (The direction data is moving.) + Direction string + // Request (The type of request sent by a client.) + Request string +}{ + "direction", + "request", +} + +// A is an alias for Attributes. +var A = Attributes + +// AttributeDirection are the possible values that the attribute "direction" can have. +var AttributeDirection = struct { + Sent string + Received string +}{ + "sent", + "received", +} + +// AttributeRequest are the possible values that the attribute "request" can have. +var AttributeRequest = struct { + Delete string + Get string + Head string + Options string + Post string + Put string + Trace string +}{ + "delete", + "get", + "head", + "options", + "post", + "put", + "trace", +} diff --git a/receiver/iisreceiver/internal/metadata/recorder.go b/receiver/iisreceiver/internal/metadata/recorder.go new file mode 100644 index 000000000000..70de8fe1960d --- /dev/null +++ b/receiver/iisreceiver/internal/metadata/recorder.go @@ -0,0 +1,48 @@ +// 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 metadata // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver/internal/metadata" + +import ( + "go.opentelemetry.io/collector/model/pdata" +) + +func (mb *MetricsBuilder) RecordAny(ts pdata.Timestamp, val float64, name string, attributes map[string]string) { + switch name { + case "iis.connection.active": + mb.RecordIisConnectionActiveDataPoint(ts, int64(val)) + case "iis.connection.anonymous": + mb.RecordIisConnectionAnonymousDataPoint(ts, int64(val)) + case "iis.connection.attempt.count": + mb.RecordIisConnectionAttemptCountDataPoint(ts, int64(val)) + case "iis.network.blocked": + mb.RecordIisNetworkBlockedDataPoint(ts, int64(val)) + case "iis.network.file.count": + mb.RecordIisNetworkFileCountDataPoint(ts, int64(val), attributes[A.Direction]) + case "iis.network.io": + mb.RecordIisNetworkIoDataPoint(ts, int64(val), attributes[A.Direction]) + case "iis.request.count": + mb.RecordIisRequestCountDataPoint(ts, int64(val), attributes[A.Request]) + case "iis.request.queue.age.max": + mb.RecordIisRequestQueueAgeMaxDataPoint(ts, int64(val)) + case "iis.request.queue.count": + mb.RecordIisRequestQueueCountDataPoint(ts, int64(val)) + case "iis.request.rejected": + mb.RecordIisRequestRejectedDataPoint(ts, int64(val)) + case "iis.thread.active": + mb.RecordIisThreadActiveDataPoint(ts, int64(val)) + case "iis.uptime": + mb.RecordIisUptimeDataPoint(ts, int64(val)) + } +} diff --git a/receiver/iisreceiver/metadata.yaml b/receiver/iisreceiver/metadata.yaml new file mode 100644 index 000000000000..a73af88cd7d1 --- /dev/null +++ b/receiver/iisreceiver/metadata.yaml @@ -0,0 +1,117 @@ +name: iisreceiver + +attributes: + direction: + value: direction + description: The direction data is moving. + enum: + - sent + - received + request: + value: request + description: The type of request sent by a client. + enum: + - delete + - get + - head + - options + - post + - put + - trace + +metrics: + iis.request.count: + description: Total number of requests of a given type. + unit: "{requests}" + sum: + monotonic: true + aggregation: cumulative + value_type: int + enabled: true + attributes: [ request ] + iis.request.rejected: + description: Total number of requests rejected. + unit: "{requests}" + sum: + monotonic: true + aggregation: cumulative + value_type: int + enabled: true + iis.request.queue.count: + description: Current number of requests in the queue. + unit: "{requests}" + sum: + monotonic: false + aggregation: cumulative + value_type: int + enabled: true + iis.request.queue.age.max: + description: Age of oldest request in the queue. + unit: ms + gauge: + value_type: int + enabled: true + iis.network.file.count: + description: Number of transmitted files. + unit: "{files}" + sum: + monotonic: true + aggregation: cumulative + value_type: int + enabled: true + attributes: [ direction ] + iis.network.blocked: + description: Number of bytes blocked due to bandwidth throttling. + unit: By + sum: + monotonic: true + aggregation: cumulative + value_type: int + enabled: true + iis.network.io: + description: Total amount of bytes sent and received. + unit: By + sum: + monotonic: true + aggregation: cumulative + value_type: int + enabled: true + attributes: [ direction ] + iis.connection.attempt.count: + description: Total number of attempts to connect to the server. + unit: "{attempts}" + sum: + monotonic: true + aggregation: cumulative + value_type: int + enabled: true + iis.connection.active: + description: Number of active connections. + unit: "{connections}" + sum: + monotonic: false + aggregation: cumulative + value_type: int + enabled: true + iis.connection.anonymous: + description: Number of connections established anonymously. + unit: "{connections}" + sum: + monotonic: true + aggregation: cumulative + value_type: int + enabled: true + iis.thread.active: + description: Current number of active threads. + unit: "{threads}" + sum: + monotonic: false + aggregation: cumulative + value_type: int + enabled: true + iis.uptime: + description: The amount of time the server has been up. + unit: s + gauge: + value_type: int + enabled: true diff --git a/receiver/iisreceiver/scraper.go b/receiver/iisreceiver/scraper.go new file mode 100644 index 000000000000..f399c1bb006c --- /dev/null +++ b/receiver/iisreceiver/scraper.go @@ -0,0 +1,95 @@ +// 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. + +//go:build windows +// +build windows + +package iisreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver" + +import ( + "context" + "fmt" + "time" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/model/pdata" + "go.opentelemetry.io/collector/receiver/scrapererror" + "go.uber.org/multierr" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/winperfcounters" + "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver/internal/metadata" +) + +type iisReceiver struct { + params component.ReceiverCreateSettings + config *Config + consumer consumer.Metrics + watchers []winperfcounters.PerfCounterWatcher + metricBuilder *metadata.MetricsBuilder +} + +// new returns a iisReceiver +func newIisReceiver(params component.ReceiverCreateSettings, cfg *Config, consumer consumer.Metrics) *iisReceiver { + return &iisReceiver{params: params, config: cfg, consumer: consumer, metricBuilder: metadata.NewMetricsBuilder(cfg.Metrics)} +} + +// Start creates and starts the prometheus receiver. +func (rcvr *iisReceiver) start(ctx context.Context, host component.Host) error { + rcvr.watchers = []winperfcounters.PerfCounterWatcher{} + + var errors scrapererror.ScrapeErrors + for _, objCfg := range getScraperCfgs() { + objWatchers, err := objCfg.BuildPaths() + if err != nil { + errors.AddPartial(1, fmt.Errorf("some performance counters could not be initialized; %w", err)) + continue + } + for _, objWatcher := range objWatchers { + rcvr.watchers = append(rcvr.watchers, objWatcher) + } + } + + return errors.Combine() +} + +func (rcvr *iisReceiver) scrape(ctx context.Context) (pdata.Metrics, error) { + var errs error + now := pdata.NewTimestampFromTime(time.Now()) + + for _, watcher := range rcvr.watchers { + counterValues, err := watcher.ScrapeData() + if err != nil { + errs = multierr.Append(errs, err) + continue + } + for _, counterValue := range counterValues { + rcvr.metricBuilder.RecordAny(now, counterValue.Value, counterValue.MetricRep.Name, counterValue.MetricRep.Attributes) + } + } + + return rcvr.metricBuilder.Emit(), errs +} + +// Shutdown stops the underlying Prometheus receiver. +func (rcvr iisReceiver) shutdown(ctx context.Context) error { + var errs error + for _, watcher := range rcvr.watchers { + err := watcher.Close() + if err != nil { + errs = multierr.Append(errs, err) + } + } + return errs +} diff --git a/receiver/iisreceiver/scraper_test.go b/receiver/iisreceiver/scraper_test.go new file mode 100644 index 000000000000..7454159078e9 --- /dev/null +++ b/receiver/iisreceiver/scraper_test.go @@ -0,0 +1,121 @@ +// 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. + +//go:build windows +// +build windows + +package iisreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver" + +import ( + "context" + "fmt" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/consumer/consumertest" + + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/scrapertest" + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/scrapertest/golden" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/winperfcounters" + "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver/internal/metadata" +) + +// Test Scrape tests that the scraper assigns the metrics correctly +func TestScrape(t *testing.T) { + cfg := createDefaultConfig().(*Config) + + scraper := newIisReceiver( + componenttest.NewNopReceiverCreateSettings(), + cfg, + consumertest.NewNop(), + ) + + scraper.watchers = allFakePerfCounters() + + actualMetrics, err := scraper.scrape(context.Background()) + require.NoError(t, err) + + expectedFile := filepath.Join("testdata", "scraper", "expected.json") + golden.WriteMetrics(expectedFile, actualMetrics) + expectedMetrics, err := golden.ReadMetrics(expectedFile) + require.NoError(t, err) + + require.NoError(t, scrapertest.CompareMetrics(actualMetrics, expectedMetrics)) +} + +func TestScrapeFailure(t *testing.T) { + cfg := createDefaultConfig().(*Config) + + scraper := newIisReceiver( + componenttest.NewNopReceiverCreateSettings(), + cfg, + consumertest.NewNop(), + ) + + expectedError := "failure to collect metric" + scraper.watchers = []winperfcounters.PerfCounterWatcher{ + newMockPerfCounter(fmt.Errorf(expectedError), 1, winperfcounters.MetricRep{Name: "iis.uptime"}), + } + + _, err := scraper.scrape(context.Background()) + require.EqualError(t, err, expectedError) +} + +type mockPerfCounter struct { + watchErr error + value float64 + winperfcounters.MetricRep +} + +func allFakePerfCounters() []winperfcounters.PerfCounterWatcher { + return []winperfcounters.PerfCounterWatcher{ + newMockPerfCounter(nil, 1, winperfcounters.MetricRep{Name: "iis.connection.active"}), + newMockPerfCounter(nil, 1, winperfcounters.MetricRep{Name: "iis.connection.anonymous"}), + newMockPerfCounter(nil, 1, winperfcounters.MetricRep{Name: "iis.connection.attempt.count"}), + newMockPerfCounter(nil, 1, winperfcounters.MetricRep{Name: "iis.network.blocked"}), + newMockPerfCounter(nil, 1, winperfcounters.MetricRep{Name: "iis.network.file.count", Attributes: map[string]string{metadata.A.Direction: "received"}}), + newMockPerfCounter(nil, 1, winperfcounters.MetricRep{Name: "iis.network.io", Attributes: map[string]string{metadata.A.Direction: "sent"}}), + newMockPerfCounter(nil, 1, winperfcounters.MetricRep{Name: "iis.request.count", Attributes: map[string]string{metadata.A.Request: "get"}}), + newMockPerfCounter(nil, 1, winperfcounters.MetricRep{Name: "iis.request.queue.age.max"}), + newMockPerfCounter(nil, 1, winperfcounters.MetricRep{Name: "iis.request.queue.count"}), + newMockPerfCounter(nil, 1, winperfcounters.MetricRep{Name: "iis.request.rejected"}), + newMockPerfCounter(nil, 1, winperfcounters.MetricRep{Name: "iis.thread.active"}), + newMockPerfCounter(nil, 1, winperfcounters.MetricRep{Name: "iis.uptime"}), + } +} + +func newMockPerfCounter(watchErr error, value float64, metric winperfcounters.MetricRep) *mockPerfCounter { + return &mockPerfCounter{watchErr: watchErr, value: value, MetricRep: metric} +} + +// Path +func (mpc *mockPerfCounter) Path() string { + return "" +} + +// ScrapeData +func (mpc *mockPerfCounter) ScrapeData() ([]winperfcounters.CounterValue, error) { + return []winperfcounters.CounterValue{{Value: 1, MetricRep: mpc.MetricRep}}, mpc.watchErr +} + +// Close +func (mpc *mockPerfCounter) Close() error { + return nil +} + +func (mpc *mockPerfCounter) GetMetricRep() winperfcounters.MetricRep { + return mpc.MetricRep +} diff --git a/receiver/iisreceiver/testdata/integration/expected.json b/receiver/iisreceiver/testdata/integration/expected.json new file mode 100644 index 000000000000..2145a4452435 --- /dev/null +++ b/receiver/iisreceiver/testdata/integration/expected.json @@ -0,0 +1,268 @@ +{ + "resourceMetrics": [ + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Number of active connections.", + "name": "iis.connection.active", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "0", + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + } + ] + }, + "unit": "{connections}" + }, + { + "description": "Number of connections established anonymously.", + "name": "iis.connection.anonymous", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "1", + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + } + ], + "isMonotonic": true + }, + "unit": "{connections}" + }, + { + "description": "Total number of attempts to connect to the server.", + "name": "iis.connection.attempt.count", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "1", + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + } + ], + "isMonotonic": true + }, + "unit": "{attempts}" + }, + { + "description": "Number of transmitted files.", + "name": "iis.network.file.count", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "0", + "attributes": [ + { + "key": "direction", + "value": { + "stringValue": "received" + } + } + ], + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "direction", + "value": { + "stringValue": "sent" + } + } + ], + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + } + ], + "isMonotonic": true + }, + "unit": "{files}" + }, + { + "description": "Total amount of bytes sent and received.", + "name": "iis.network.io", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "57", + "attributes": [ + { + "key": "direction", + "value": { + "stringValue": "received" + } + } + ], + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + }, + { + "asInt": "940", + "attributes": [ + { + "key": "direction", + "value": { + "stringValue": "sent" + } + } + ], + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + } + ], + "isMonotonic": true + }, + "unit": "By" + }, + { + "description": "Total number of requests of a given type.", + "name": "iis.request.count", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "0", + "attributes": [ + { + "key": "request", + "value": { + "stringValue": "delete" + } + } + ], + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "request", + "value": { + "stringValue": "get" + } + } + ], + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + }, + { + "asInt": "0", + "attributes": [ + { + "key": "request", + "value": { + "stringValue": "head" + } + } + ], + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + }, + { + "asInt": "0", + "attributes": [ + { + "key": "request", + "value": { + "stringValue": "options" + } + } + ], + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + }, + { + "asInt": "0", + "attributes": [ + { + "key": "request", + "value": { + "stringValue": "post" + } + } + ], + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + }, + { + "asInt": "0", + "attributes": [ + { + "key": "request", + "value": { + "stringValue": "put" + } + } + ], + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + }, + { + "asInt": "0", + "attributes": [ + { + "key": "request", + "value": { + "stringValue": "trace" + } + } + ], + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + } + ], + "isMonotonic": true + }, + "unit": "{requests}" + }, + { + "description": "Current number of active threads.", + "name": "iis.thread.active", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "4659", + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + } + ] + }, + "unit": "{threads}" + }, + { + "description": "The amount of time the server has been up.", + "gauge": { + "dataPoints": [ + { + "asInt": "525146", + "startTimeUnixNano": "1649790968352648900", + "timeUnixNano": "1649790968352648900" + } + ] + }, + "name": "iis.uptime", + "unit": "s" + } + ], + "scope": { + "name": "otelcol/iisreceiver" + } + } + ] + } + ] +} diff --git a/receiver/iisreceiver/testdata/scraper/expected.json b/receiver/iisreceiver/testdata/scraper/expected.json new file mode 100644 index 000000000000..57c68c2c3d79 --- /dev/null +++ b/receiver/iisreceiver/testdata/scraper/expected.json @@ -0,0 +1,225 @@ +{ + "resourceMetrics": [ + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Number of active connections.", + "name": "iis.connection.active", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "1", + "startTimeUnixNano": "1649797402615187400", + "timeUnixNano": "1649797402615187400" + } + ] + }, + "unit": "{connections}" + }, + { + "description": "Number of connections established anonymously.", + "name": "iis.connection.anonymous", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "1", + "startTimeUnixNano": "1649797402615187400", + "timeUnixNano": "1649797402615187400" + } + ], + "isMonotonic": true + }, + "unit": "{connections}" + }, + { + "description": "Total number of attempts to connect to the server.", + "name": "iis.connection.attempt.count", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "1", + "startTimeUnixNano": "1649797402615187400", + "timeUnixNano": "1649797402615187400" + } + ], + "isMonotonic": true + }, + "unit": "{attempts}" + }, + { + "description": "Number of bytes blocked due to bandwidth throttling.", + "name": "iis.network.blocked", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "1", + "startTimeUnixNano": "1649797402615187400", + "timeUnixNano": "1649797402615187400" + } + ], + "isMonotonic": true + }, + "unit": "By" + }, + { + "description": "Number of transmitted files.", + "name": "iis.network.file.count", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "direction", + "value": { + "stringValue": "received" + } + } + ], + "startTimeUnixNano": "1649797402615187400", + "timeUnixNano": "1649797402615187400" + } + ], + "isMonotonic": true + }, + "unit": "{files}" + }, + { + "description": "Total amount of bytes sent and received.", + "name": "iis.network.io", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "direction", + "value": { + "stringValue": "sent" + } + } + ], + "startTimeUnixNano": "1649797402615187400", + "timeUnixNano": "1649797402615187400" + } + ], + "isMonotonic": true + }, + "unit": "By" + }, + { + "description": "Total number of requests of a given type.", + "name": "iis.request.count", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "request", + "value": { + "stringValue": "get" + } + } + ], + "startTimeUnixNano": "1649797402615187400", + "timeUnixNano": "1649797402615187400" + } + ], + "isMonotonic": true + }, + "unit": "{requests}" + }, + { + "description": "Age of oldest request in the queue.", + "gauge": { + "dataPoints": [ + { + "asInt": "1", + "startTimeUnixNano": "1649797402615187400", + "timeUnixNano": "1649797402615187400" + } + ] + }, + "name": "iis.request.queue.age.max", + "unit": "ms" + }, + { + "description": "Current number of requests in the queue.", + "name": "iis.request.queue.count", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "1", + "startTimeUnixNano": "1649797402615187400", + "timeUnixNano": "1649797402615187400" + } + ] + }, + "unit": "{requests}" + }, + { + "description": "Total number of requests rejected.", + "name": "iis.request.rejected", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "1", + "startTimeUnixNano": "1649797402615187400", + "timeUnixNano": "1649797402615187400" + } + ], + "isMonotonic": true + }, + "unit": "{requests}" + }, + { + "description": "Current number of active threads.", + "name": "iis.thread.active", + "sum": { + "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE", + "dataPoints": [ + { + "asInt": "1", + "startTimeUnixNano": "1649797402615187400", + "timeUnixNano": "1649797402615187400" + } + ] + }, + "unit": "{threads}" + }, + { + "description": "The amount of time the server has been up.", + "gauge": { + "dataPoints": [ + { + "asInt": "1", + "startTimeUnixNano": "1649797402615187400", + "timeUnixNano": "1649797402615187400" + } + ] + }, + "name": "iis.uptime", + "unit": "s" + } + ], + "scope": { + "name": "otelcol/iisreceiver" + } + } + ] + } + ] +} diff --git a/versions.yaml b/versions.yaml index afde76db274c..73d1f46cc6b5 100644 --- a/versions.yaml +++ b/versions.yaml @@ -150,6 +150,7 @@ module-sets: - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/googlecloudspannerreceiver - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/influxdbreceiver + - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/iisreceiver - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jmxreceiver - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/journaldreceiver