-
Notifications
You must be signed in to change notification settings - Fork 34
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
Refactor alerting package #49
Conversation
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, but please look at my comments.
I was hoping this was done per package as opposed to in one go so that can we have isolated, bike shedable conversations (as this is a good time to bike shed).
"github.com/grafana/alerting/receivers/wecom" | ||
) | ||
|
||
var receiverFactories = map[string]func(receivers.FactoryConfig) (NotificationChannel, 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.
NotificationChannel
is a legacy Grafana concept, is it possible to get rid of it? I'm fine with this part of the separate PR as this PR is already kind of hard to review as it is right now.
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.
It's just a composition of two interfaces. I think we can but not in this PR. We need to move code that builds integrations from Grafana first.
notify.ResolvedSender | ||
} | ||
|
||
func Factory(receiverType string) (func(receivers.FactoryConfig) (NotificationChannel, error), bool) { |
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.
Do these functions warrant tests?
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.
It probably does but this code is mostly moved as is from Grafana where it did not have the tests either. I am not sure what we can test here. Probably that all receivers are covered. Each receiver is covered by its own tests.
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'd test what happens when a receiver exists and when it does not.
@@ -0,0 +1,98 @@ | |||
package notify |
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 gotta admit, I'm not a fan of this pattern at all. I spent a big portion of my career writing this type of code in ruby and 10 years later I continue to find this hard to read/understand.
The layer of abstraction for the sake of saving an initialisation of an error seems too much.
That being said, I consider this a nit - if you all agree this is OK feel free to ignore my comment.
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.
Not sure to which line of code you refer to. Do you mean wrap
function? If yes, I am not a fan of it either, this was made as a workaround for providing a validation of the configuration prior to saving it to the database.
Currently, there is a similar factory method for each receiver and it looks exactly the same. I just made it DRY-er.
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.
Not sure to which line of code you refer to
The whole design within this file. It's called factory
so given I cannot comment on files I tend to typically pick the first line of the file when referring to the whole file.
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.
Ah, definitely, I think we should change it to the way it is implemented in Alertmanager!
receivers/line/config.go
Outdated
Description string `json:"description,omitempty" yaml:"description,omitempty"` | ||
} | ||
|
||
func BuildConfig(fc receivers.FactoryConfig) (*Config, 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.
nit: This is validating the configuration but it's called BuildConfig
in all receivers - this feels misleading, I understand that this "technically" returning a configuration because it's doing the marshalling but the common pattern I see in most cases is to simply execute the unmarshall call inline and call Validate()
on top of the built object.
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 do not have a strong opinion on this name. BuildConfig and Validate have pros and cons. Ideally, that should be boiled down to custom marshaller implementation for each struct but for now, decryption functionality does not let us do that (I have a ddoc for that).
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 renamed BuildConfig to ValidateConfig.
I tried to do so by package but when I touched something it just affected all other files. So, I decided to do it in kinda one change. I did not touch |
) | ||
|
||
type AlertmanagerConfig struct { | ||
*NotificationChannelConfig | ||
type Config struct { |
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.
The package-per-receiver is an amazing change 👍
// Notifier sends alert notifications to the alert manager | ||
type Notifier struct { |
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 called the package receivers
but generalized all the notifier types Notifier
- WDYT on aligning this? I.e. calling the package two layers up notifiers
or calling these structs Receiver
?
Do "notifier" and "receiver" always mean the same thing in our context?
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.
The reason I chose package receivers
and struct name Notifier
is that:
- we have
notify
package, and havingnotifiers
would look awkward. If we want to rename to notifiers then probably we need to renamenotify
package. - Notifier implements upstream's interface Notifier that has method Notify. Receiver in Alertmanager terminology is a set of Integrations, where each Integration wraps a Notifier.
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
Co-authored-by: gotjosh <josue.abreu@gmail.com>
1. All code moved from alerting sub-package to root. This removes the duplicated path component, e.g "github.com/grafana/alerting/alerting/models" turns to "github.com/grafana/alerting/models" 2. Refactored channels package. - Package renamed to `receivers` - All receivers are moved into their own sub-packages - Logging interface is moved to `logging` package in the root - Code for working with images is moved to `images` package in the root - Templates, structs and functions to work with them are moved to `templates` package in the root 3. All receivers are renamed to Notifier. So reference to receivers will look like `email.Notifier` and the constructor is `email.New` 4. Removed a factory function *Factory that wrapped New function with a `ReceiverInitError` and replaced by a generic function in the Factory. 5. Copied receivers factory from Grafana. Co-authored-by: gotjosh <josue.abreu@gmail.com>
receivers
logging
package in the rootimages
package in the roottemplates
package in the rootemail.Notifier
and constructor isemail.New
ReceiverInitError
and replaced by a generic function in the Factory.Fixes #46