Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
8df558de
Commit
8df558de
authored
Jul 25, 2016
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(notifications): refactoring notification handling
parent
14eba30f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
111 additions
and
152 deletions
+111
-152
pkg/services/alerting/interfaces.go
+1
-0
pkg/services/alerting/notifier.go
+108
-149
public/app/features/alerting/alert_log_ctrl.ts
+1
-1
public/app/features/alerting/alerts_ctrl.ts
+1
-2
No files found.
pkg/services/alerting/interfaces.go
View file @
8df558de
...
...
@@ -17,6 +17,7 @@ type Scheduler interface {
type
Notifier
interface
{
Notify
(
alertResult
*
AlertResultContext
)
GetType
()
string
}
type
AlertCondition
interface
{
...
...
pkg/services/alerting/notifier.go
View file @
8df558de
package
alerting
import
(
"errors"
"fmt"
"log"
"strconv"
"strings"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/log"
m
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting"
)
type
NotifierImpl
struct
{
log
log
.
Logger
getNotifications
func
(
orgId
int64
,
notificationGroups
[]
int64
)
[]
*
Notification
type
RootNotifier
struct
{
NotifierBase
log
log
.
Logger
}
func
NewNotifier
()
*
NotifierImpl
{
log
:=
log
.
New
(
"alerting.notifier"
)
return
&
NotifierImpl
{
log
:
log
,
getNotifications
:
buildGetNotifiers
(
log
),
func
NewRootNotifier
()
*
RootNotifier
{
return
&
RootNotifier
{
log
:
log
.
New
(
"alerting.notifier"
),
}
}
func
(
n
*
NotifierImpl
)
Notify
(
alertResult
*
AlertResultContext
)
{
notifiers
:=
n
.
getNotifications
(
alertResult
.
Rule
.
OrgId
,
alertResult
.
Rule
.
Notifications
)
func
(
n
*
RootNotifier
)
Notify
(
context
*
AlertResultContext
)
{
notifiers
,
err
:=
n
.
getNotifiers
(
context
.
Rule
.
OrgId
,
context
.
Rule
.
Notifications
)
if
err
!=
nil
{
n
.
log
.
Error
(
"Failed to read notifications"
,
"error"
,
err
)
return
}
for
_
,
notifier
:=
range
notifiers
{
n
.
log
.
Info
(
"Sending notification"
,
"
state"
,
alertResult
.
State
,
"type"
,
notifier
.
Type
)
go
notifier
.
Notif
ierr
.
Dispatch
(
alertResul
t
)
n
.
log
.
Info
(
"Sending notification"
,
"
firing"
,
context
.
Firing
,
"type"
,
notifier
.
GetType
()
)
go
notifier
.
Notif
y
(
contex
t
)
}
}
type
Notification
struct
{
Name
string
Type
string
SendWarning
bool
SendCritical
bool
Notifierr
NotificationDispatcher
}
type
EmailNotifier
struct
{
To
string
log
log
.
Logger
}
func
(
this
*
EmailNotifier
)
Dispatch
(
alertResult
*
AlertResult
)
{
this
.
log
.
Info
(
"Sending email"
)
grafanaUrl
:=
fmt
.
Sprintf
(
"%s:%s"
,
setting
.
HttpAddr
,
setting
.
HttpPort
)
if
setting
.
AppSubUrl
!=
""
{
grafanaUrl
+=
"/"
+
setting
.
AppSubUrl
}
query
:=
&
m
.
GetDashboardsQuery
{
DashboardIds
:
[]
int64
{
alertResult
.
AlertJob
.
Rule
.
DashboardId
},
}
func
(
n
*
RootNotifier
)
getNotifiers
(
orgId
int64
,
notificationIds
[]
int64
)
([]
Notifier
,
error
)
{
query
:=
&
m
.
GetAlertNotificationsQuery
{
OrgId
:
orgId
,
Ids
:
notificationIds
}
if
err
:=
bus
.
Dispatch
(
query
);
err
!=
nil
{
this
.
log
.
Error
(
"Failed to load dashboard"
,
"error"
,
err
)
return
}
if
len
(
query
.
Result
)
!=
1
{
this
.
log
.
Error
(
"Can only support one dashboard"
,
"result"
,
len
(
query
.
Result
))
return
return
nil
,
err
}
dashboard
:=
query
.
Result
[
0
]
panelId
:=
strconv
.
Itoa
(
int
(
alertResult
.
AlertJob
.
Rule
.
PanelId
))
//TODO: get from alertrule and transforms to seconds
from
:=
"1466169458375"
to
:=
"1466171258375"
renderUrl
:=
fmt
.
Sprintf
(
"%s/render/dashboard-solo/db/%s?from=%s&to=%s&panelId=%s&width=1000&height=500"
,
grafanaUrl
,
dashboard
.
Slug
,
from
,
to
,
panelId
)
cmd
:=
&
m
.
SendEmailCommand
{
Data
:
map
[
string
]
interface
{}{
"Name"
:
"Name"
,
"State"
:
alertResult
.
State
,
"Description"
:
alertResult
.
Description
,
"TriggeredAlerts"
:
alertResult
.
TriggeredAlerts
,
"DashboardLink"
:
grafanaUrl
+
"/dashboard/db/"
+
dashboard
.
Slug
,
"AlertPageUrl"
:
grafanaUrl
+
"/alerting"
,
"DashboardImage"
:
renderUrl
,
},
To
:
[]
string
{
this
.
To
},
Template
:
"alert_notification.html"
,
var
result
[]
Notifier
for
_
,
notification
:=
range
query
.
Result
{
if
not
,
err
:=
NewNotificationFromDBModel
(
notification
);
err
!=
nil
{
return
nil
,
err
}
else
{
result
=
append
(
result
,
not
)
}
}
err
:=
bus
.
Dispatch
(
cmd
)
if
err
!=
nil
{
this
.
log
.
Error
(
"Could not send alert notification as email"
,
"error"
,
err
)
}
return
result
,
nil
}
type
WebhookNotifier
struct
{
Url
string
User
string
Password
string
log
log
.
Logger
type
NotifierBase
struct
{
Name
string
Type
string
}
func
(
this
*
WebhookNotifier
)
Dispatch
(
alertResult
*
AlertResultContext
)
{
this
.
log
.
Info
(
"Sending webhook"
)
bodyJSON
:=
simplejson
.
New
()
bodyJSON
.
Set
(
"name"
,
alertResult
.
AlertJob
.
Rule
.
Name
)
bodyJSON
.
Set
(
"state"
,
alertResult
.
State
)
bodyJSON
.
Set
(
"trigged"
,
alertResult
.
TriggeredAlerts
)
body
,
_
:=
bodyJSON
.
MarshalJSON
()
cmd
:=
&
m
.
SendWebhook
{
Url
:
this
.
Url
,
User
:
this
.
User
,
Password
:
this
.
Password
,
Body
:
string
(
body
),
}
bus
.
Dispatch
(
cmd
)
func
(
n
*
NotifierBase
)
GetType
()
string
{
return
n
.
Type
}
type
NotificationDispatcher
interface
{
Dispatch
(
alertResult
*
AlertResult
)
type
EmailNotifier
struct
{
NotifierBase
Addresses
[]
string
log
log
.
Logger
}
func
buildGetNotifiers
(
log
log
.
Logger
)
func
(
orgId
int64
,
notificationGroups
[]
int64
)
[]
*
Notification
{
return
func
(
orgId
int64
,
notificationGroups
[]
int64
)
[]
*
Notification
{
query
:=
&
m
.
GetAlertNotificationQuery
{
OrgID
:
orgId
,
Ids
:
notificationGroups
,
IncludeAlwaysExecute
:
true
,
}
err
:=
bus
.
Dispatch
(
query
)
if
err
!=
nil
{
log
.
Error
(
"Failed to read notifications"
,
"error"
,
err
)
}
func
(
this
*
EmailNotifier
)
Notify
(
context
*
AlertResultContext
)
{
this
.
log
.
Info
(
"Sending alert notification to %v"
,
this
.
Addresses
)
var
result
[]
*
Notification
for
_
,
notification
:=
range
query
.
Result
{
not
,
err
:=
NewNotificationFromDBModel
(
notification
)
if
err
==
nil
{
result
=
append
(
result
,
not
)
}
else
{
log
.
Error
(
"Failed to read notification model"
,
"error"
,
err
)
}
}
return
result
slugQuery
:=
&
m
.
GetDashboardSlugByIdQuery
{
Id
:
context
.
Rule
.
DashboardId
}
if
err
:=
bus
.
Dispatch
(
slugQuery
);
err
!=
nil
{
this
.
log
.
Error
(
"Failed to load dashboard"
,
"error"
,
err
)
return
}
}
dashboardSlug
:=
slugQuery
.
Result
func
NewNotificationFromDBModel
(
model
*
m
.
AlertNotification
)
(
*
Notification
,
error
)
{
notifier
,
err
:=
createNotifier
(
model
.
Type
,
model
.
Settings
)
cmd
:=
&
m
.
SendEmailCommand
{
Data
:
map
[
string
]
interface
{}{
"RuleName"
:
context
.
Rule
.
Name
,
"Severity"
:
context
.
Rule
.
Severity
,
"RuleLink"
:
setting
.
ToAbsUrl
(
"dashboard/db/"
+
dashboardSlug
),
},
To
:
this
.
Addresses
,
Template
:
"alert_notification.html"
,
}
err
:=
bus
.
Dispatch
(
cmd
)
if
err
!=
nil
{
return
nil
,
err
this
.
log
.
Error
(
"Failed tosend alert notification email"
,
"error"
,
err
)
}
return
&
Notification
{
Name
:
model
.
Name
,
Type
:
model
.
Type
,
Notifierr
:
notifier
,
SendCritical
:
model
.
Settings
.
Get
(
"sendCrit"
)
.
MustBool
(),
SendWarning
:
model
.
Settings
.
Get
(
"sendWarn"
)
.
MustBool
(),
},
nil
}
var
createNotifier
=
func
(
notificationType
string
,
settings
*
simplejson
.
Json
)
(
NotificationDispatcher
,
error
)
{
if
notificationType
==
"email"
{
to
:=
settings
.
Get
(
"to"
)
.
MustString
()
if
to
==
""
{
return
nil
,
fmt
.
Errorf
(
"Could not find to propertie in settings"
)
// type WebhookNotifier struct {
// Url string
// User string
// Password string
// log log.Logger
// }
//
// func (this *WebhookNotifier) Dispatch(context *AlertResultContext) {
// this.log.Info("Sending webhook")
//
// bodyJSON := simplejson.New()
// bodyJSON.Set("name", context.AlertJob.Rule.Name)
// bodyJSON.Set("state", context.State)
// bodyJSON.Set("trigged", context.TriggeredAlerts)
//
// body, _ := bodyJSON.MarshalJSON()
//
// cmd := &m.SendWebhook{
// Url: this.Url,
// User: this.User,
// Password: this.Password,
// Body: string(body),
// }
//
// bus.Dispatch(cmd)
// }
func
NewNotificationFromDBModel
(
model
*
m
.
AlertNotification
)
(
Notifier
,
error
)
{
if
model
.
Type
==
"email"
{
addressesString
:=
model
.
Settings
.
Get
(
"addresses"
)
.
MustString
()
if
addressesString
==
""
{
return
nil
,
fmt
.
Errorf
(
"Could not find addresses in settings"
)
}
return
&
EmailNotifier
{
To
:
to
,
log
:
log
.
New
(
"alerting.notification.email"
),
NotifierBase
:
NotifierBase
{
Name
:
model
.
Name
,
Type
:
model
.
Type
,
},
Addresses
:
strings
.
Split
(
addressesString
,
"
\n
"
),
log
:
log
.
New
(
"alerting.notification.email"
),
},
nil
}
url
:=
settings
.
Get
(
"url"
)
.
MustString
()
if
url
==
""
{
return
nil
,
fmt
.
Errorf
(
"Could not find url propertie in settings"
)
}
return
&
WebhookNotifier
{
Url
:
url
,
User
:
settings
.
Get
(
"user"
)
.
MustString
(),
Password
:
settings
.
Get
(
"password"
)
.
MustString
(),
log
:
log
.
New
(
"alerting.notification.webhook"
),
},
nil
return
nil
,
errors
.
New
(
"Unsupported notification type"
)
// url := settings.Get("url").MustString()
// if url == "" {
// return nil, fmt.Errorf("Could not find url propertie in settings")
// }
//
// return &WebhookNotifier{
// Url: url,
// User: settings.Get("user").MustString(),
// Password: settings.Get("password").MustString(),
// log: log.New("alerting.notification.webhook"),
// }, nil
}
public/app/features/alerting/alert_log_ctrl.ts
View file @
8df558de
...
...
@@ -22,7 +22,7 @@ export class AlertLogCtrl {
loadAlertLogs
(
alertId
:
number
)
{
this
.
backendSrv
.
get
(
`/api/alerts/
${
alertId
}
/states`
).
then
(
result
=>
{
this
.
alertLogs
=
_
.
map
(
result
,
log
=>
{
log
.
iconCss
=
alertDef
.
get
CssForState
(
log
.
state
);
log
.
iconCss
=
alertDef
.
get
SeverityIconClass
(
log
.
severity
);
log
.
humanTime
=
moment
(
log
.
created
).
format
(
"YYYY-MM-DD HH:mm:ss"
);
return
log
;
});
...
...
public/app/features/alerting/alerts_ctrl.ts
View file @
8df558de
...
...
@@ -49,8 +49,7 @@ export class AlertListCtrl {
this
.
backendSrv
.
get
(
'/api/alerts'
,
params
).
then
(
result
=>
{
this
.
alerts
=
_
.
map
(
result
,
alert
=>
{
alert
.
severityClass
=
alertDef
.
getSeverityClass
(
alert
.
severity
);
alert
.
stateClass
=
alertDef
.
getStateClass
(
alert
.
state
);
alert
.
severityClass
=
alertDef
.
getSeverityIconClass
(
alert
.
severity
);
return
alert
;
});
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment