Skip to content

Commit

Permalink
[receiver/couchdb] Initialize component (#6815)
Browse files Browse the repository at this point in the history
* establish couchdb codebase

* add in pr feedback

* clean up names/format

* fix linting ci

* add couchdbreceiver to verisons

* remove host validation

* fix nit

* Update receiver/couchdbreceiver/README.md

Co-authored-by: Daniel Jaglowski <dan.jaglowski@bluemedora.com>

* add check for default endpoint on CreateDefaultConfig

* add missing receivers in versions

Co-authored-by: Daniel Jaglowski <dan.jaglowski@bluemedora.com>
  • Loading branch information
JonathanWamsley and djaglowski authored Dec 16, 2021
1 parent 9f23e98 commit 0a0e7e9
Show file tree
Hide file tree
Showing 15 changed files with 1,336 additions and 5 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ receiver/awsxrayreceiver/ @open-telemetry/collector-c
receiver/carbonreceiver/ @open-telemetry/collector-contrib-approvers @pjanotti
receiver/cloudfoundryreceiver/ @open-telemetry/collector-contrib-approvers @agoallikmaa @pellared
receiver/collectdreceiver/ @open-telemetry/collector-contrib-approvers @owais
receiver/couchdbreceiver/ @open-telemetry/collector-contrib-approvers @djaglowski
receiver/dockerstatsreceiver/ @open-telemetry/collector-contrib-approvers @rmfitzpatrick
receiver/dotnetdiagnosticsreceiver/ @open-telemetry/collector-contrib-approvers @pmcollins @davmason
receiver/filelogreceiver/ @open-telemetry/collector-contrib-approvers @djaglowski
Expand Down
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,10 @@ updates:
directory: "/receiver/collectdreceiver"
schedule:
interval: "weekly"
- package-ecosystem: "gomod"
directory: "/receiver/couchdbreceiver"
schedule:
interval: "weekly"
- package-ecosystem: "gomod"
directory: "/receiver/dockerstatsreceiver"
schedule:
Expand Down
1 change: 1 addition & 0 deletions receiver/couchdbreceiver/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../../Makefile.Common
42 changes: 42 additions & 0 deletions receiver/couchdbreceiver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# CouchDB Receiver

This receiver fetches stats from a couchdb server using the `/_node/{node-name}/_stats/couchdb` [endpoint](https://docs.couchdb.org/en/latest/api/server/common.html#node-node-name-stats).

Supported pipeline types: `metrics`

> :construction: This receiver is in **BETA**. Configuration fields and metric data model are subject to change.
## Prerequisites

This receiver supports Couchdb versions `2.3+` and `3.1+`.

## Configuration

The following settings are required:
- `username`
- `password`

The following settings are optional:
- `endpoint` (default: `http://localhost:5984`): The URL of the couchdb endpoint

- `all_nodes` (default: false): When `all_nodes` is false, this receiver collects a single node stats with {node-name} replaced with _local. When `all_nodes` is true, then this receiver fetches all known connected nodes using the `/_membership` [endpoint](docs.couchdb.org/en/stable/cluster/nodes.html#node-management) to then collect stats for each {node-name} found.

- `collection_interval` (default = `10s`): This receiver collects metrics on an interval. This value must be a string readable by Golang's [time.ParseDuration](https://pkg.go.dev/time#ParseDuration). Valid time units are `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`.

### Example Configuration

```yaml
receivers:
couchdb:
endpoint: http://localhost:5984
username: otelu
password: $COUCHDB_PASSWORD
all_nodes: false
collection_interval: 10s
```
The full list of settings exposed for this receiver are documented [here](./config.go) with detailed sample configurations [here](./testdata/config.yaml). TLS config is documented further under the [opentelemetry collector's configtls package](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/configtls/README.md).
## Metrics
Details about the metrics produced by this receiver can be found in [metadata.yaml](./metadata.yaml)
62 changes: 62 additions & 0 deletions receiver/couchdbreceiver/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// 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 couchdbreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/couchdbreceiver"

import (
"errors"
"fmt"
"net/url"

"go.opentelemetry.io/collector/config/confighttp"
"go.opentelemetry.io/collector/receiver/scraperhelper"
"go.uber.org/multierr"
)

const defaultEndpoint = "http://localhost:5984"

var (
// Errors for missing required config fields.
errMissingUsername = errors.New(`no "username" specified in config`)
errMissingPassword = errors.New(`no "password" specified in config`)

// Errors for invalid url components in the endpoint.
errInvalidEndpoint = errors.New(`"endpoint" %q must be in the form of <scheme>://<hostname>:<port>`)
)

// Config defines the configuration for the various elements of the receiver agent.
type Config struct {
scraperhelper.ScraperControllerSettings `mapstructure:",squash"`
confighttp.HTTPClientSettings `mapstructure:",squash"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
AllNodes bool `mapstructure:"all_nodes"`
}

// Validate validates missing and invalid configuration fields.
func (cfg *Config) Validate() error {
var err error
if cfg.Username == "" {
err = multierr.Append(err, errMissingUsername)
}
if cfg.Password == "" {
err = multierr.Append(err, errMissingPassword)
}

_, parseErr := url.Parse(cfg.Endpoint)
if parseErr != nil {
err = multierr.Append(err, fmt.Errorf(errInvalidEndpoint.Error(), parseErr))
}
return err
}
100 changes: 100 additions & 0 deletions receiver/couchdbreceiver/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// 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 couchdbreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/couchdbreceiver"

import (
"fmt"
"testing"

"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/config/confighttp"
"go.uber.org/multierr"
)

func TestValidate(t *testing.T) {
testCases := []struct {
desc string
cfg *Config
expectedErr error
}{
{
desc: "missing username, password and invalid endpoint",
cfg: &Config{
HTTPClientSettings: confighttp.HTTPClientSettings{
Endpoint: "http://localhost :5984",
},
},
expectedErr: multierr.Combine(
errMissingUsername,
errMissingPassword,
fmt.Errorf(errInvalidEndpoint.Error(), "parse \"http://localhost :5984\": invalid character \" \" in host name"),
),
},
{
desc: "missing password and invalid endpoint",
cfg: &Config{
HTTPClientSettings: confighttp.HTTPClientSettings{
Endpoint: "http://localhost :5984",
},
Username: "otelu",
},
expectedErr: multierr.Combine(
errMissingPassword,
fmt.Errorf(errInvalidEndpoint.Error(), "parse \"http://localhost :5984\": invalid character \" \" in host name"),
),
},
{
desc: "missing username and invalid endpoint",
cfg: &Config{
HTTPClientSettings: confighttp.HTTPClientSettings{
Endpoint: "http://localhost :5984",
},
Password: "otelp",
},
expectedErr: multierr.Combine(
errMissingUsername,
fmt.Errorf(errInvalidEndpoint.Error(), "parse \"http://localhost :5984\": invalid character \" \" in host name"),
),
},
{
desc: "invalid endpoint",
cfg: &Config{
Username: "otel",
Password: "otel",
HTTPClientSettings: confighttp.HTTPClientSettings{
Endpoint: "http://localhost :5984",
},
},
expectedErr: fmt.Errorf(errInvalidEndpoint.Error(), "parse \"http://localhost :5984\": invalid character \" \" in host name"),
},
{
desc: "no error",
cfg: &Config{
Username: "otel",
Password: "otel",
HTTPClientSettings: confighttp.HTTPClientSettings{
Endpoint: "http://localhost:5984",
},
},
expectedErr: nil,
},
}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
actualErr := tc.cfg.Validate()
require.Equal(t, tc.expectedErr, actualErr)
})
}
}
15 changes: 15 additions & 0 deletions receiver/couchdbreceiver/documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[comment]: <> (Code generated by mdatagen. DO NOT EDIT.)

# couchdbreceiver

## Metrics

These are the metrics available for this scraper.

| Name | Description | Unit | Type | Attributes |
| ---- | ----------- | ---- | ---- | ---------- |

## Attributes

| Name | Description |
| ---- | ----------- |
63 changes: 63 additions & 0 deletions receiver/couchdbreceiver/factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// 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 couchdbreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/couchdbreceiver"

//go:generate mdatagen metadata.yaml

import (
"context"
"time"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/config/confighttp"
"go.opentelemetry.io/collector/config/configtls"
"go.opentelemetry.io/collector/consumer"
"go.opentelemetry.io/collector/receiver/receiverhelper"
"go.opentelemetry.io/collector/receiver/scraperhelper"
)

const (
typeStr = "couchdb"
)

func NewFactory() component.ReceiverFactory {
return receiverhelper.NewFactory(
typeStr,
createDefaultConfig,
receiverhelper.WithMetrics(createMetricsReceiver))
}

func createDefaultConfig() config.Receiver {
return &Config{
ScraperControllerSettings: scraperhelper.ScraperControllerSettings{
ReceiverSettings: config.NewReceiverSettings(config.NewComponentID(typeStr)),
CollectionInterval: 10 * time.Second,
},
HTTPClientSettings: confighttp.HTTPClientSettings{
TLSSetting: configtls.TLSClientSetting{
Insecure: false,
InsecureSkipVerify: true,
},
Endpoint: defaultEndpoint,
Timeout: 10 * time.Second,
},
AllNodes: false,
}
}

func createMetricsReceiver(_ context.Context, params component.ReceiverCreateSettings, rConf config.Receiver, consumer consumer.Metrics) (component.MetricsReceiver, error) {
return nil, nil
}
65 changes: 65 additions & 0 deletions receiver/couchdbreceiver/factory_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// 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 couchdbreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/couchdbreceiver"

import (
"context"
"testing"
"time"

"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/config/confighttp"
"go.opentelemetry.io/collector/consumer/consumertest"
"go.opentelemetry.io/collector/receiver/scraperhelper"
)

func TestType(t *testing.T) {
factory := NewFactory()
ft := factory.Type()
require.EqualValues(t, "couchdb", ft)
}

func TestValidConfig(t *testing.T) {
factory := NewFactory()
cfg := factory.CreateDefaultConfig().(*Config)
cfg.Username = "otel"
cfg.Password = "otel"

require.EqualValues(t, defaultEndpoint, cfg.Endpoint)
require.NoError(t, cfg.Validate())
}

func TestCreateMetricsReceiver(t *testing.T) {
factory := NewFactory()
_, err := factory.CreateMetricsReceiver(
context.Background(),
component.ReceiverCreateSettings{},
&Config{
ScraperControllerSettings: scraperhelper.ScraperControllerSettings{
ReceiverSettings: config.NewReceiverSettings(config.NewComponentID("couchdb")),
CollectionInterval: 10 * time.Second,
},
HTTPClientSettings: confighttp.HTTPClientSettings{
Endpoint: "http://localhost:5984",
},
Username: "otel",
Password: "otel",
},
consumertest.NewNop(),
)
require.NoError(t, err)
}
Loading

0 comments on commit 0a0e7e9

Please sign in to comment.