Skip to content

feat: Add Cloud Run Output Plugin & Update to Wavefront Serializer#10210

Closed
crflanigan wants to merge 20 commits intoinfluxdata:masterfrom
homedepot:master
Closed

feat: Add Cloud Run Output Plugin & Update to Wavefront Serializer#10210
crflanigan wants to merge 20 commits intoinfluxdata:masterfrom
homedepot:master

Conversation

@crflanigan
Copy link
Copy Markdown
Contributor

Required for all PRs:

resolves #7913

Added an output plugin for Google Cloud Run which implements the OAuth 2.0 protocol enabling the Telegraf agent to send encrypted metric payloads into a time series metrics proxy running in GCP.

Additionally, customers using the Wavefront serializer who don't wish to have their metric prefixes modified may configure their output plugin in the same way as the Wavefront Output Plugin.

This is accomplished by adding the convert_paths = false boolean option to the output section of their conf file.

Example prefix before getting processed by the Wavefront serializer:
prod.prefix_name.metric_name

Existing behavior:
prefix.name.metric.name

New behavior with convert_paths = false option:
prod.prefix_name.metric_name

@telegraf-tiger
Copy link
Copy Markdown
Contributor

telegraf-tiger bot commented Dec 2, 2021

Thanks so much for the pull request!
🤝 ✒️ Just a reminder that the CLA has not yet been signed, and we'll need it before merging. Please sign the CLA when you get a chance, then post a comment here saying !signed-cla

@telegraf-tiger telegraf-tiger bot added the feat Improvement on an existing feature such as adding a new setting/mode to an existing plugin label Dec 2, 2021
@crflanigan
Copy link
Copy Markdown
Contributor Author

@zachmares

@telegraf-tiger
Copy link
Copy Markdown
Contributor

telegraf-tiger bot commented Dec 2, 2021

Thanks so much for the pull request!
🤝 ✒️ Just a reminder that the CLA has not yet been signed, and we'll need it before merging. Please sign the CLA when you get a chance, then post a comment here saying !signed-cla

@crflanigan
Copy link
Copy Markdown
Contributor Author

!signed-cla

@telegraf-tiger
Copy link
Copy Markdown
Contributor

telegraf-tiger bot commented Dec 2, 2021

☺️ This pull request doesn't significantly change the Telegraf binary size (less than 1%)

📦 Looks like new artifacts were built from this PR.

Expand this list to get them here ! 🐯

Artifact URLs

DEB RPM TAR GZ ZIP
amd64.deb aarch64.rpm darwin_amd64.tar.gz windows_amd64.zip
arm64.deb armel.rpm freebsd_amd64.tar.gz windows_i386.zip
armel.deb armv6hl.rpm freebsd_armv7.tar.gz
armhf.deb i386.rpm freebsd_i386.tar.gz
i386.deb ppc64le.rpm linux_amd64.tar.gz
mips.deb s390x.rpm linux_arm64.tar.gz
mipsel.deb x86_64.rpm linux_armel.tar.gz
ppc64el.deb linux_armhf.tar.gz
s390x.deb linux_i386.tar.gz
linux_mips.tar.gz
linux_mipsel.tar.gz
linux_ppc64le.tar.gz
linux_s390x.tar.gz
static_linux_amd64.tar.gz

Copy link
Copy Markdown
Member

@srebhan srebhan left a comment

Choose a reason for hiding this comment

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

@crflanigan thank you very much for this cool contribution! The linter found some issues and I also have some comments in the code. The most severe ones are

  1. Please split this PR into one for the Wavefront part and one for the CloudRun part. You probably best move the Wavefront part to a new PR and remove it from this one. Please remember to adapt the PR title and description accordingly. Feel free to assign (or mention) me in the newly created PR so I can give it a review.
  2. Almost half of the PR goes to common/gcp dealing with the authentication. I wonder why you can't use the existing oauth2 library. Is there a reason? If you really can't use any external lib, my impression is that common/gcp should be a library outside of Telegraf as it is in no way specific to this project.
  3. Please check the linter warnings and errors.

Looking forward to the next round and your comments!

Comment on lines -577 to -583
// Skip inputs that are registered twice for backward compatibility
if pname == "cisco_telemetry_gnmi" {
continue
}
if pname == "KNXListener" {
continue
}
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.

Why do you remove those?


require github.com/libp2p/go-reuseport v0.1.0
require (
github.com/golang-jwt/jwt v3.2.2+incompatible
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.

Would it be possible to use github.com/golang-jwt/jwt/v4 which we already carry as a dependency instead of v3?

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.

Let me check, thank you!

@@ -0,0 +1,118 @@
package gcp
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.

Why do you put this in common? The only user currently AFAICS is cloutrun, so it belongs there. If you plan to add more users later we can still move the files...

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.

Sure, would you suggest (if we keep this package) we keep this code alongside the cloudrun package code?

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.

Kind of. First of all, please check carefully if using golang.org/x/oauth2/google is an option instead of really having this code. Second, I tend to making the code in this package an external packages that does not live in telegraf. However, if you have good reasons why option one and two cannot be pursued we should move it to the cloudrun plugin directory.

return "", fmt.Errorf("could not parse service account JSON: %v", err)
}

signedJWT, err := generateSignedJWT(conf, audience, 120)
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.

Is that expiry time the only valid value? Maybe you should allow to provide the expiry time as a parameter.

Comment on lines +49 to +50
func generateSignedJWT(conf *jwt.Config, audience string, expiryLength int64) (string, error) {
now := time.Now().Unix()
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.

To be honest I would feel a bit better to get the expiry time as a time.Duration...

Suggested change
func generateSignedJWT(conf *jwt.Config, audience string, expiryLength int64) (string, error) {
now := time.Now().Unix()
func generateSignedJWT(conf *jwt.Config, audience string, expiryLength time.Duration) (string, error) {
now := time.Now().Unix()
expiry := now.Add(expiryLength)

Comment on lines +161 to +162
req.Header.Set("Content-Type", defaultContentType)
req.Header.Set("Accept", defaultAccept)
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.

Please directly set the values here instead of using default... constants as this is the only user and you directly can see what is set instead of navigating the whole file.

Comment on lines +166 to +168
if strings.ToLower(k) == "host" {
req.Host = v
}
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.

Do you mean to continue here as otherwise host is set twice once in req.Host and another time as req.Header...

}

if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf("when writing to [%s] received status code: %d", cr.URL, resp.StatusCode)
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.

Suggested change
return fmt.Errorf("when writing to [%s] received status code: %d", cr.URL, resp.StatusCode)
return fmt.Errorf("when writing to %q received status code: %d", cr.URL, resp.StatusCode)

PrometheusStringAsLabel bool `toml:"prometheus_string_as_label"`

// Convert "_" in paths to "." for Wavefront
WavefrontConvertPaths bool `toml:"convert_paths"`
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.

With this change you will break all existing wavefront users as suddenly (when using their old config) their paths change without further notice on updateing telegraf. This cannot happen. Please invert that setting such that by default (i.e. not set by the user) the paths are converted as before.

A natural alternative would be wavefront_keep_path or wavefront_disable_path_conversion.

}

s := WavefrontSerializer{}
s := WavefrontSerializer{ConvertPaths: true}
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.

That's exactly the point mentioned above. All current users would need to do the same in their config. Please keep existing tests unchanged to ensure backward compatibility!

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.

Good point!
Let me fix that.

@srebhan srebhan self-assigned this Dec 6, 2021
@crflanigan
Copy link
Copy Markdown
Contributor Author

Going to close this as suggested by @srebhan and open two pull requests, one for the update to the Wavefront serializer and one for the Cloud Run code.

@crflanigan crflanigan closed this Dec 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat Improvement on an existing feature such as adding a new setting/mode to an existing plugin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Output plugin that supports sending metrics into Google CloudRun

3 participants