Skip to content

[Heartbeat] Set HTTP user-agent in Heartbeat#14297

Merged
andrewvc merged 9 commits intoelastic:masterfrom
andrewvc:default-ua
Oct 31, 2019
Merged

[Heartbeat] Set HTTP user-agent in Heartbeat#14297
andrewvc merged 9 commits intoelastic:masterfrom
andrewvc:default-ua

Conversation

@andrewvc
Copy link
Copy Markdown
Contributor

@andrewvc andrewvc commented Oct 29, 2019

By default heartbeat uses the golang user agent, which is blacklisted by a number of services, including elastic.co. URLs like https://www.elastic.co/products/beats/heartbeat do not work with the
default go user agent due to such blacklists.

This changes the default user agent to be 'Elastic Heartbeat/VERSION (PLATFORM INFO)'

Resolves #10170 (comment)

@andrewvc andrewvc added enhancement Heartbeat Team:obs-ds-hosted-services Label for the Observability Hosted Services team labels Oct 29, 2019
@andrewvc andrewvc requested a review from ruflin October 29, 2019 00:42
@andrewvc andrewvc requested a review from a team as a code owner October 29, 2019 00:42
@andrewvc andrewvc self-assigned this Oct 29, 2019
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/uptime (:uptime)

@andrewvc andrewvc changed the title [Heartbeat] Set HTTP user-agent to 'elastic_heatbeat' [Heartbeat] Set HTTP user-agent to 'elastic_heartbeat' Oct 29, 2019
By default heartbeat uses the golang user agent, which is blacklisted
by a number of services, including elastic.co. URLs like
https://www.elastic.co/products/beats/heartbeat do not work with the
default go user agent due to such blacklists.

This changes the default user agent to be 'elastic_heartbeat'.

While the HTTP spec allows UAs to add version numbers to the end this PR
does not add the version number for two reasons:

1. Adding the version wouldn't practically be of use to anyone as one UA
version numbers for an uptime check aren't practically useful.
2. It would needlessly add complexity to this commit.

Resolves elastic#10170 (comment)
@andrewkroh
Copy link
Copy Markdown
Member

andrewkroh commented Oct 29, 2019

We set the User-Agent in Filebeat for the client that connects to Google Pub/Sub and in the client that connects to MISP. It would be good to align all of these to use the same exact format.

I recommend creating a util in libbeat to get the User-Agent string and make each of these use that.

func userAgent() string {
return fmt.Sprintf("Elastic Filebeat/%s (%s; %s; %s; %s)",
version.GetDefaultVersion(), runtime.GOOS, runtime.GOARCH,
version.Commit(), version.BuildTime())
}

@andrewvc
Copy link
Copy Markdown
Contributor Author

andrewvc commented Oct 29, 2019 via email

Copy link
Copy Markdown
Contributor

@ruflin ruflin left a comment

Choose a reason for hiding this comment

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

This is great, +1 on the util approach. Do you plan to handle it in this PR or a follow up?

Probably this info should also show up somewhere in the heartbeat docs ...

@andrewvc
Copy link
Copy Markdown
Contributor Author

@ruflin I'll do the util thing in this PR. ++ on adding docs.

@andrewvc
Copy link
Copy Markdown
Contributor Author

@ruflin @andrewkroh I've updated this PR to make a common helper function

Copy link
Copy Markdown
Member

@andrewkroh andrewkroh left a comment

Choose a reason for hiding this comment

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

"sync"
"time"

"github.com/elastic/beats/libbeat/common/useragent"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Move this down to the grouping of github.com/elastic imports.

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.

Fixed!

}

if enc != nil {
enc.AddHeaders(&request.Header)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

concerning the implementation, you might want to take a look at https://github.com/elastic/beats/blob/fleet/agent/kibana/round_trippers.go#L33-L52 and use http.Roundtripper interface.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

What's the advantage of adding it there vs. here? Seems like they're fairly equivalent in this case.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There are, but you make sure that all connection through the http client get the headers no matter what.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

But, you are right I am not familliar enough with hearthbeat client. so it might be equivalent in that case.

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 think in our case it's equivalent since this is the only entry point through to the client. I think I'll leave the code here so there's only one spot where header stuff happens, which at least to me, seems easier to maintain, but I agree with you, generally speaking if you share the HTTP client it should go in the round tripper.

@andrewvc andrewvc changed the title [Heartbeat] Set HTTP user-agent to 'elastic_heartbeat' [Heartbeat] Set HTTP user-agent in Heartbeat Oct 29, 2019
@andrewvc andrewvc added the Filebeat Filebeat label Oct 29, 2019
@andrewvc
Copy link
Copy Markdown
Contributor Author

@andrewkroh I've added it to the httpjson module as well.

@ruflin I think this is ready for a final review.

Copy link
Copy Markdown
Contributor

@ruflin ruflin left a comment

Choose a reason for hiding this comment

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

PR LGTM. I still think we should have this in our docs somewhere.

@andrewvc
Copy link
Copy Markdown
Contributor Author

@ruflin I just added the docs for this. If it's still good let me know with another LGTM.

*`method`*:: The HTTP method to use. Valid values are `"HEAD"`, `"GET"` and
`"POST"`.
*`headers`*:: A dictionary of additional HTTP headers to send.
*`headers`*:: A dictionary of additional HTTP headers to send. By default heartbeat
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: It would be nice to have a header example posted here. So if someone configures a tool where he needs to filter on the headers, he can just copy-paste it here (or at least have the pattern).

@ruflin
Copy link
Copy Markdown
Contributor

ruflin commented Oct 31, 2019

jenkins, test this

Copy link
Copy Markdown
Contributor

@ruflin ruflin left a comment

Choose a reason for hiding this comment

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

The code LGTM, but CI ...

"sync"
"time"

"github.com/elastic/beats/libbeat/common/useragent"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Guess what ;-)

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.

Argh, fixed :)

@andrewvc
Copy link
Copy Markdown
Contributor Author

Build failures unrelated

@andrewvc andrewvc merged commit 956f87c into elastic:master Oct 31, 2019
@andrewvc andrewvc deleted the default-ua branch October 31, 2019 17:40
andrewvc added a commit to andrewvc/beats that referenced this pull request Oct 31, 2019
By default heartbeat uses the golang user agent, which is blacklisted by a number of services, including elastic.co. URLs like https://www.elastic.co/products/beats/heartbeat do not work with the
default go user agent due to such blacklists.

This changes the default user agent to be 'Elastic Heartbeat/VERSION (PLATFORM INFO)'

Resolves elastic#10170 (comment)

(cherry picked from commit 956f87c)
@OrangeDog
Copy link
Copy Markdown

OrangeDog commented Nov 25, 2019

This change is probably incorrect.
Elastic Heartbeat/VERSION is two separate products: Elastic and Heartbeat/VERSION.
If the space separator was intentional, the primary identifier (Heartbeat) should still go first.

A better User-Agent would be something like Heartbeat/VERSION libbeat/VERSION Go-http-client/1.1

@andrewvc
Copy link
Copy Markdown
Contributor Author

Thanks @OrangeDog , I've opened an issue to track this here #14747

jorgemarey pushed a commit to jorgemarey/beats that referenced this pull request Jun 8, 2020
By default heartbeat uses the golang user agent, which is blacklisted by a number of services, including elastic.co. URLs like https://www.elastic.co/products/beats/heartbeat do not work with the
default go user agent due to such blacklists.

This changes the default user agent to be 'Elastic Heartbeat/VERSION (PLATFORM INFO)'

Resolves elastic#10170 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Heartbeat] HTTP request should include the beat name and the version as part of the user-agent.

6 participants