Skip to content
This repository was archived by the owner on Aug 30, 2019. It is now read-only.

writer: allow writing to multiple endpoints.#496

Closed
gbbr wants to merge 8 commits into
masterfrom
gbbr/multiwriter
Closed

writer: allow writing to multiple endpoints.#496
gbbr wants to merge 8 commits into
masterfrom
gbbr/multiwriter

Conversation

@gbbr

@gbbr gbbr commented Oct 17, 2018

Copy link
Copy Markdown
Contributor

Description

This change adds a new set of options to the apm_config sub-section of the config file, enabling the possibility of forwarding data (traces, stats & services) to additional endpoints besides the main one.

Example configuration:

apm_config:
  ...
  # The trace agent will also forward traces, stats and services to these endpoints,
  # besides the main endpoint.
  additional_endpoints:
    # Simply specify the list of URLs to forward to along with one or more API keys
    # to use for that URL.
    https://trace.agent.datadoghq.eu:
    - 1234abcd
    - 4567efghi
    https://trace.agent.other-endpoint.com:
    - 890jkl

References

@gbbr gbbr added this to the next milestone Oct 17, 2018
@gbbr
gbbr force-pushed the gbbr/multiwriter branch 2 times, most recently from 7e8cf03 to e11686c Compare October 17, 2018 13:49
@gbbr

This comment has been minimized.

@olivielpeau

This comment has been minimized.

@gbbr
gbbr force-pushed the gbbr/multiwriter branch 8 times, most recently from 1e49d6e to f7b442a Compare October 18, 2018 10:02
@gbbr
gbbr requested review from AlexJF and palazzem October 18, 2018 10:03
@gbbr

This comment has been minimized.

@gbbr gbbr modified the milestones: next, 6.7.0 Oct 18, 2018
@gbbr

gbbr commented Oct 18, 2018

Copy link
Copy Markdown
Contributor Author

@AlexJF @palazzem ready for review

Comment thread config/agent.go Outdated
APIEndpoint string
APIKey string `json:"-"` // never publish this
APIEnabled bool
APIEndpoint string

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Maybe I should merge these two into one:

    Endpoints []*Endpoint

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Agree, don't see the point of treating main vs additional differently and if we need to we can just ensure the main is the first in this endpoints list.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Doing it in the scope of this PR, separate commit.

@AlexJF AlexJF left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Partial review, I'll look at the remaining files after lunch 👨‍🍳

Comment thread cmd/trace-agent/main.go
Comment thread config/agent.go Outdated
APIEndpoint string
APIKey string `json:"-"` // never publish this
APIEnabled bool
APIEndpoint string

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Agree, don't see the point of treating main vs additional differently and if we need to we can just ensure the main is the first in this endpoints list.

Comment thread config/merge_yaml.go
Comment thread writer/datadog_endpoint.go Outdated
apiKey := e.APIKey
if apiKey == "" {
// if this endpoint doesn't have its own API key, try the main one.
apiKey = conf.APIKey

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I wouldn't even allow this to occur. Looking at the infra PR, they dedupe endpoints missing apikey already at the config: https://github.com/DataDog/datadog-agent/pull/352/files#diff-091ace02b49a46f55f2586cfec89a160R95

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fair enough, removed it entirely. I've modified the config to ignore endpoints without API keys; but I think deduping is a bit overkill unless I'm missing some aspect.

Comment thread writer/datadog_endpoint.go Outdated
// newClient returns a http.Client configured with the Agent options.
func newClient(conf *config.AgentConfig, noProxy bool) *http.Client {
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: conf.SkipSSLValidation},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We've had some issues with some other code that was using custom transports. We should probably include all settings set in DefaultTransport as well otherwise most timeouts will be zeroed out and we'll wait for much longer than we should when network issues happen.

https://golang.org/src/net/http/transport.go (line 42). I'm fine with this going to another PR but we should track this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're very right here, this was indeed an oversight. Great catch! I've copied the http.DefaultTransport except the Proxy: http.ProxyFromEnvironment part which I assume was likely also an oversight on our behalf. We can ponder whether to introduce that back in a separate topic. I'm afraid not to cause any backwards breaking changes because of introducing it.

Comment thread writer/multi_writer.go Outdated
if len(endpoints) == 1 {
return NewCustomQueuablePayloadSender(endpoints[0], cfg)
}
var senders []PayloadSender

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Minor nit, we can already allocate enough space for len(endpoints).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Definitely.

Comment thread writer/multi_writer.go Outdated
func newMultiSender(cfg config.QueuablePayloadSenderConf) func([]Endpoint) PayloadSender {
return func(endpoints []Endpoint) PayloadSender {
if len(endpoints) == 1 {
return NewCustomQueuablePayloadSender(endpoints[0], cfg)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nice shortcut here, saving a bunch of overhead if not needed 👍

Comment thread writer/multi_writer.go Outdated

// newMultiSender returns a new factory to generate PayloadSenders capable of forwarding
// payloads to multiple endpoints.
func newMultiSender(cfg config.QueuablePayloadSenderConf) func([]Endpoint) PayloadSender {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The name here threw me off initially and breaks expectations imo.

Can we have a newMultiSender(cfg, []Endpoint) and turn this into

newMultiSenderFactory(cfg) func([]Endpoint) {
   return func (endpoints) PayloadSender {
      return newMultiSender(cfg, endpoints);
  }
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I like it. Done.

Comment thread writer/service_writer_test.go
Comment thread writer/trace_writer.go

@gbbr gbbr left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Great review and I agree with all your points. Submitted a new commit addressing all comments, except the merging of APIEndpoint and AdditionalEndpoints into one, which will follow in this very PR in an upcoming commit (tomorrow).

Comment thread config/agent.go Outdated
APIEndpoint string
APIKey string `json:"-"` // never publish this
APIEnabled bool
APIEndpoint string

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Doing it in the scope of this PR, separate commit.

Comment thread writer/datadog_endpoint.go Outdated
apiKey := e.APIKey
if apiKey == "" {
// if this endpoint doesn't have its own API key, try the main one.
apiKey = conf.APIKey

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fair enough, removed it entirely. I've modified the config to ignore endpoints without API keys; but I think deduping is a bit overkill unless I'm missing some aspect.

Comment thread writer/datadog_endpoint.go Outdated
// newClient returns a http.Client configured with the Agent options.
func newClient(conf *config.AgentConfig, noProxy bool) *http.Client {
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: conf.SkipSSLValidation},

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're very right here, this was indeed an oversight. Great catch! I've copied the http.DefaultTransport except the Proxy: http.ProxyFromEnvironment part which I assume was likely also an oversight on our behalf. We can ponder whether to introduce that back in a separate topic. I'm afraid not to cause any backwards breaking changes because of introducing it.

Comment thread writer/multi_writer.go Outdated

// newMultiSender returns a new factory to generate PayloadSenders capable of forwarding
// payloads to multiple endpoints.
func newMultiSender(cfg config.QueuablePayloadSenderConf) func([]Endpoint) PayloadSender {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I like it. Done.

Comment thread writer/multi_writer.go Outdated
if len(endpoints) == 1 {
return NewCustomQueuablePayloadSender(endpoints[0], cfg)
}
var senders []PayloadSender

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Definitely.

Comment thread writer/trace_writer.go
@gbbr
gbbr force-pushed the gbbr/multiwriter branch from 3e24e1b to 07e2808 Compare October 18, 2018 15:12
Comment thread config/agent.go Outdated
Comment thread writer/trace_writer.go
@gbbr
gbbr force-pushed the gbbr/multiwriter branch from 07e2808 to 65c92e4 Compare October 19, 2018 07:46
@gbbr
gbbr force-pushed the gbbr/multiwriter branch 2 times, most recently from 36ea26c to 5317672 Compare October 19, 2018 09:13
@gbbr
gbbr force-pushed the gbbr/multiwriter branch from 5317672 to e573587 Compare October 19, 2018 09:21
@gbbr

gbbr commented Oct 19, 2018

Copy link
Copy Markdown
Contributor Author

@AlexJF merged all endpoints in the latest commit. Tested manually with app too, seems to work fine. PTAL when you get a chance.

Comment thread config/merge_env.go
@gbbr

gbbr commented Oct 19, 2018

Copy link
Copy Markdown
Contributor Author

@AlexJF good catch, changed in next commit.

@AlexJF AlexJF left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Looks good from my side! If everything works in practice lets ship it! 🚢

@gbbr

gbbr commented Oct 22, 2018

Copy link
Copy Markdown
Contributor Author

Seems Github is buggy. Kept getting errors from using the "Squash & Merge" button and PR is still open even though it was merged twice (see master commits)

@gbbr gbbr closed this Oct 22, 2018
@gbbr

gbbr commented Oct 22, 2018

Copy link
Copy Markdown
Contributor Author

Seems Github is buggy. Kept getting errors from using the "Squash & Merge" button and PR is still open even though it was merged twice (see master commits)

@gbbr
gbbr deleted the gbbr/multiwriter branch October 22, 2018 08:12
@gbbr

gbbr commented Oct 22, 2018

Copy link
Copy Markdown
Contributor Author

Seems Github is buggy. Kept getting errors from using the "Squash & Merge" button and PR is still open even though it was merged twice (see master commits)

raphaelgavache pushed a commit that referenced this pull request Oct 24, 2018
* writer: add support for multiple endpoints
* writer: add host information to stats
* statsd: ensure all stats get version tag
* writer: remove statsClient field from BaseWriter
raphaelgavache pushed a commit that referenced this pull request Oct 24, 2018
* writer: add support for multiple endpoints
* writer: add host information to stats
* statsd: ensure all stats get version tag
* writer: remove statsClient field from BaseWriter
* all: merge APIEndpoint into Endpoints
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants