-
Notifications
You must be signed in to change notification settings - Fork 43
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
Replace notify.Factory with a build function that accepts typed configuration #63
Conversation
95dc30b
to
4684ec2
Compare
4684ec2
to
bc56f06
Compare
@@ -1,6 +1,6 @@ | |||
package logging | |||
|
|||
type LoggerFactory func(ctx ...interface{}) Logger | |||
type LoggerFactory func(loggerName string, ctx ...interface{}) Logger |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this makes it clear that first element is always logger name whereas the remaining go to context (that's how it is implemented in Grafana)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this change, but wouldn't it mean that we'll be using a different interface than the one defined in Grafana's infra
package? In order to use the logger, we would have to add this string as the first item in the ctx
slice.
I don't think it's a big deal, just want to make sure we're aware of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regularly, in the logging context is a slice of tuples. go-kit adds {Missing} if slice size is odd. However, In Grafana logger assumes that the first element is not a tuple's label but a logger name and automatically adds the logger
label. However, this package can (and will) use a different logger implementation but usages of this interface still assume that the first element of the context is a logger. This change makes this interface more explicit.
I like this change, but wouldn't it mean that we'll be using a different interface than the one defined in Grafana's infra package?
There is no interface for New
method in infra. What I do here is basically define it.
notify/factory.go
Outdated
} | ||
createIntegration(idx, cfg, func(logger logging.Logger) notificationChannel { | ||
return f(logger, w) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these to anonymous methods help reduce duplicated code below.
// GetDecryptedValueFn is a function that returns the decrypted value of | ||
// the given key. If the key is not present, then it returns the fallback value. | ||
type GetDecryptedValueFn func(ctx context.Context, sjd map[string][]byte, key string, fallback string) string | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is moved from the receivers package because it is not used there anymore.
c6f6f90
to
dbee25f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of passing explicit values to the factory function instead of a FactoryConfig
struct.
I requested a few comments to be added, but apart from that I think it's good to go!
@@ -1,6 +1,6 @@ | |||
package logging | |||
|
|||
type LoggerFactory func(ctx ...interface{}) Logger | |||
type LoggerFactory func(loggerName string, ctx ...interface{}) Logger |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this change, but wouldn't it mean that we'll be using a different interface than the one defined in Grafana's infra
package? In order to use the logger, we would have to add this string as the first item in the ctx
slice.
I don't think it's a big deal, just want to make sure we're aware of this.
Co-authored-by: Santiago <[email protected]>
Co-authored-by: Santiago <[email protected]>
Co-authored-by: Santiago <[email protected]>
Co-authored-by: Santiago <[email protected]>
Co-authored-by: Santiago <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Base: receivers.NewBase(meta), | ||
tmpl: template, | ||
log: logger, | ||
ns: sender, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This is called sender but the variable is installed called ns - this comment applies to all the others that use the webhook sender.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will address it in a follow up PR as this rename will cause changes in other places.
settings: settings, | ||
logger: fc.Logger, | ||
}, nil | ||
Base: receivers.NewBase(meta), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we filed #70 due to some problems we saw while reviewing this.
// It returns a slice of Integration objects, one for each notification channel, along with any errors that occurred. | ||
func BuildReceiverIntegrations( | ||
receiver GrafanaReceiverConfig, | ||
tmpl *template.Template, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tmpl *template.Template, | |
tmpl *alerting.Template, |
you need the local types otherwise you'll import the alertmanage directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will address it in a follow-up PR as it touches many lines.
newWebhookSender func(n receivers.Metadata) (receivers.WebhookSender, error), | ||
newEmailSender func(n receivers.Metadata) (receivers.EmailSender, error), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these functions should use primitives, such as:
func(ctx context.Context, client *http.Client, url string, body io.Reader) (*http.Response, error)
Instead of whatever interface was defined by Grafana with the WebhookSender
and the EmailSender
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of my previous comments have been addressed 👍
Based on changes made in #61 and #62.
This PR introduces a factory function
notify.BuildReceiverIntegrations
that accepts parsed receiver configuration and creates Integrations.Now, this looks pretty much closer to how upstream Alertmanager creates integrations.
Some notable changes:
notify
package where it is used only once, which will make it simpler to delete in future.NotificationSender
there are two interfaces WebhookSender and EmailSender. In vanilla Alertmanager they are different for each notifier (actually, each notifier creates one by itself). Therefore, instead of accepting a single instance of sendersBuildReceiverIntegrations
now accepts factory functions, which can return an error. For example, lin in upstream Alertmanager https://github.com/prometheus/alertmanager/blob/41eb1213bb1c7ce0aa9e6464e297976d9c81cfe5/notify/webhook/webhook.go#L46