Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Cloud Foundry metrics receiver #1 - config, factory, docs #4626

Merged
merged 9 commits into from
Sep 21, 2021

Conversation

agoallikmaa
Copy link
Contributor

@agoallikmaa agoallikmaa commented Aug 16, 2021

Description: Adds a Cloud Foundry metric receiver which reads metrics from Cloud Foundry Reverse Log Proxy Gateway. More details available in the README.md. make gotidy seems to have made plenty of subtle changes to go.sum files, not sure if this is normal. This PR contains the overall structure, documentation, implementation for config and factory, but does NOT contain the implementation of the receiver and does not enable the component, as that will come in separate PRs later.

Link to tracking Issue: #5320

Testing: Unit tests. Manual testing was performed against Tanzu Application Service (TAS) versions 2.7, 2.8 and 2.11. Considered adding an integration test with mocked HTTP servers acting as endpoints where the HTTP server would provide a constant response (prerecorded from the real TAS traffic), but not sure if mocks would make more sense.

Documentation: README.md and doc.go for the new receiver module were added.

@bogdandrutu
Copy link
Member

@agoallikmaa
Copy link
Contributor Author

Updated current PR to be the first stage PR of adding a new component by removing concrete implementation of everything except factory and config, and removing from components.go.

@agoallikmaa agoallikmaa changed the title Cloud Foundry metrics receiver Cloud Foundry metrics receiver - config, factory, docs Aug 23, 2021
@agoallikmaa agoallikmaa changed the title Cloud Foundry metrics receiver - config, factory, docs Cloud Foundry metrics receiver #1 - config, factory, docs Aug 23, 2021
@bogdandrutu
Copy link
Member

Please identify couple of people who will maintain this component and add them to the CODEOWNERS

@github-actions
Copy link
Contributor

github-actions bot commented Sep 7, 2021

This PR was marked stale due to lack of activity. It will be closed in 7 days.

@github-actions github-actions bot added the Stale label Sep 7, 2021
@agoallikmaa
Copy link
Contributor Author

Code owners present, rebased.

@github-actions github-actions bot removed the Stale label Sep 8, 2021
@github-actions
Copy link
Contributor

This PR was marked stale due to lack of activity. It will be closed in 7 days.

@github-actions github-actions bot added the Stale label Sep 15, 2021
Copy link
Member

@pellared pellared left a comment

Choose a reason for hiding this comment

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

Nice job. I added some minor comments which should be easy to address.

Can you edit the description of this PR to define what this PR contains?

Can you please create an issue e.g. named Cloud Foundry metrics receiver? We could use it and use it to track the cloudfoundryreceiver implementation status. From https://github.com/open-telemetry/opentelemetry-collector/blob/main/CONTRIBUTING.md#before-you-start:

If you would like to work on something that is not listed as an issue [...], then create an issue and describe your proposal. It is best to do this in advance so that maintainers can decide if the proposal is a good fit for this repository. This will help avoid situations when you spend significant time on something that maintainers may decide this repo is not the right place for.

Comment on lines 23 to 35
## Configuration

The receiver takes the following configuration options:
* `rlp_gateway_url` - URL of the RLP gateway, required, typically `https://log-stream.<cf-system-domain>`
* `rlp_gateway_skip_tls_verify` - whether to skip TLS verify for the RLP Gateway endpoint, default `false`
* `rlp_gateway_shard_id` - metrics are load balanced among receivers that use the same shard ID, therefore this must
only be set if there are multiple receivers which must both receive all the metrics instead of them being balanced
between them. Default value is `opentelemetry`
* `uaa_url` - URL of the UAA provider, required, typically `https://uaa.<cf-system-domain>`
* `uaa_skip_tls_verify` - whether to skip TLS verify for the UAA endpoint, default `false`
* `uaa_username` - name of the UAA user (required grant types/authorities described above)
* `uaa_username` - password of the UAA user
* `http_timeout` - HTTP socket timeout used for RLP Gateway, default `10s`
Copy link
Member

Choose a reason for hiding this comment

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

Can you format it to make it more readable? It should be easy to find if an option is required and what is its default value.

E.g. https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/filelogreceiver#configuration

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Member

Choose a reason for hiding this comment

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

please resolve

Comment on lines 14 to 15
The following is an example sequence of commands to create the UAA user using the `uaac` command line utility:
* `uaac target https://uaa.<cf-system-domain>`
Copy link
Member

Choose a reason for hiding this comment

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

nit: markdownlint wants to have a blank line between a paragraph and a list

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Member

Choose a reason for hiding this comment

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

nit: the same comment applies to other places in the README.md


_, err := url.Parse(value)
if err != nil {
return fmt.Errorf("failed to parse %s value %s as url: %v", name, value, err)
Copy link
Member

Choose a reason for hiding this comment

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

There is no need to pass the value. See https://play.golang.org/p/XcW50z01QNf

Suggested change
return fmt.Errorf("failed to parse %s value %s as url: %v", name, value, err)
return fmt.Errorf("parse %s as URL: %v", name, err)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Member

Choose a reason for hiding this comment

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

please resolve


func TestLoadConfig(t *testing.T) {
factories, err := componenttest.NopFactories()
assert.Nil(t, err)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
assert.Nil(t, err)
require.NoError(t, err)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Member

Choose a reason for hiding this comment

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

please resolve

"go.opentelemetry.io/collector/config/configtest"
)

func TestLoadConfig(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

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

I suggest adding a TODO for the next PR: add negative tests e.g. in TestFailedLoadConfig

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Member

Choose a reason for hiding this comment

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

please resolve

require.NoError(t, err)
require.NotNil(t, cfg)

assert.Equal(t, len(cfg.Receivers), 2)
Copy link
Member

Choose a reason for hiding this comment

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

How about changing this line to:

Suggested change
assert.Equal(t, len(cfg.Receivers), 2)
require.Len(t, cfg.Receivers, 2)

so that it does not panic later if the length would be 0 or 1?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Member

Choose a reason for hiding this comment

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

please resolve

assert.Equal(t, len(cfg.Receivers), 2)

r0 := cfg.Receivers[config.NewID(typeStr)]
assert.Equal(t, r0, factory.CreateDefaultConfig())
Copy link
Member

Choose a reason for hiding this comment

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

Expected is first, actual is second.

Suggested change
assert.Equal(t, r0, factory.CreateDefaultConfig())
assert.Equal(t, factory.CreateDefaultConfig(), r0)

See: https://pkg.go.dev/github.com/stretchr/testify@v1.7.0/assert#Equal

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Member

Choose a reason for hiding this comment

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

please resolve

Comment on lines 46 to 57
assert.Equal(t, r1,
&Config{
ReceiverSettings: config.NewReceiverSettings(config.NewIDWithName(typeStr, "one")),
RLPGatewayURL: "https://log-stream.sys.example.internal",
RLPGatewaySkipTLSVerify: true,
RLPGatewayShardID: "otel-test",
UAAUrl: "https://uaa.sys.example.internal",
UAASkipTLSVerify: true,
UAAUsername: "admin",
UAAPassword: "test",
HTTPTimeout: time.Second * 20,
})
Copy link
Member

Choose a reason for hiding this comment

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

Expected is first, actual is second.

See: https://pkg.go.dev/github.com/stretchr/testify@v1.7.0/assert#Equal

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Member

Choose a reason for hiding this comment

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

please resolve

func TestCreateDefaultConfig(t *testing.T) {
factory := NewFactory()
cfg := factory.CreateDefaultConfig()
assert.NotNil(t, cfg, "failed to create default config")
Copy link
Member

Choose a reason for hiding this comment

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

Should it not be require? Does the next line make any sense if this one fails?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Member

Choose a reason for hiding this comment

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

please resolve

@pellared
Copy link
Member

pellared commented Sep 20, 2021

Considered adding an integration test with mocked HTTP servers acting as endpoints where the HTTP server would provide a constant response (prerecorded from the real TAS traffic), but not sure if mocks would make more sense.

For me, it makes a lot of sense, because:

  1. testing with TAS is very time-consuming and this may extremely help during refactoring;
  2. better to have a test with prerecorded traffic than no test;
  3. not everyone has access to TAS.

@github-actions github-actions bot removed the Stale label Sep 21, 2021
@agoallikmaa
Copy link
Contributor Author

Can you edit the description of this PR to define what this PR contains?

Added an additional sentence to description that explains what this PR includes and what it does not.

Can you please create an issue e.g. named Cloud Foundry metrics receiver? We could use it and use it to track the cloudfoundryreceiver implementation status. From https://github.com/open-telemetry/opentelemetry-collector/blob/main/CONTRIBUTING.md#before-you-start:

Issue created, edited PR description to link to the issue.

Copy link
Member

@pellared pellared left a comment

Choose a reason for hiding this comment

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

LGTM

### Attributes

All the metrics have the following attributes:
* `origin` - origin name as documented by Cloud Foundry
Copy link
Member

Choose a reason for hiding this comment

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

Is origin both an attribute and also prepended to the metric name? (I don't know if this is desirable or no, just double checking that the docs are correct).

* `origin` - origin name as documented by Cloud Foundry
* `source` - for applications, the GUID of the application, otherwise equal to `origin`

For CF/TAS deployed in BOSH, the following attributes are also present, using their canonical BOSH meanings:
Copy link
Member

Choose a reason for hiding this comment

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

Nit: it may be useful to link abbreviations to their definitions somewhere. I don't know what TAS or BOSH and being able to quickly find out can help maintaining the component in the future.

RLPGatewaySkipTLSVerify bool `mapstructure:"rlp_gateway_skip_tls_verify"`
RLPGatewayShardID string `mapstructure:"rlp_gateway_shard_id"`
UAAUrl string `mapstructure:"uaa_url"`
UAASkipTLSVerify bool `mapstructure:"uaa_skip_tls_verify"`
Copy link
Member

Choose a reason for hiding this comment

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

Consider using the generic TLSClientSetting (if this receiver is capable of supporting the settings). Otherwise it would be still good to use the same names for settings (e.g. insecure_skip_verify).

Comment on lines +29 to +31
RLPGatewayURL string `mapstructure:"rlp_gateway_url"`
RLPGatewaySkipTLSVerify bool `mapstructure:"rlp_gateway_skip_tls_verify"`
RLPGatewayShardID string `mapstructure:"rlp_gateway_shard_id"`
Copy link
Member

Choose a reason for hiding this comment

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

Would it be nicer to make rtl a section with subkeys?

Comment on lines +32 to +35
UAAUrl string `mapstructure:"uaa_url"`
UAASkipTLSVerify bool `mapstructure:"uaa_skip_tls_verify"`
UAAUsername string `mapstructure:"uaa_username"`
UAAPassword string `mapstructure:"uaa_password"`
Copy link
Member

Choose a reason for hiding this comment

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

Would it be nicer to make uaa a section with subkeys?

UAASkipTLSVerify bool `mapstructure:"uaa_skip_tls_verify"`
UAAUsername string `mapstructure:"uaa_username"`
UAAPassword string `mapstructure:"uaa_password"`
HTTPTimeout time.Duration `mapstructure:"http_timeout"`
Copy link
Member

Choose a reason for hiding this comment

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

Consider using HTTPClientSettings which already includes timeout setting.

@tigrannajaryan
Copy link
Member

I am going to merge this now since the component is not enabled yet. Please address the comments I left in the future PRs.

@tigrannajaryan tigrannajaryan merged commit ceec9c7 into open-telemetry:main Sep 21, 2021
tigrannajaryan pushed a commit that referenced this pull request Nov 19, 2021
Adds implementation to the Cloud Foundry receiver skeleton merged in #4626 .

**Link to tracking Issue:** #5320

**Testing:** Some implementation parts have been unit tested, the rest will be added as integration tests, in a separate PR which tests against a local HTTP server which will respond with prerecorded responses (recorded from running it against Tanzu Application Service).

**Documentation:** Configuration was updated in documentation to reflect using `HTTPClientSettings` instead of custom fields.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants