@@ -9,127 +9,131 @@ import (
99 "github.com/slack-go/slack"
1010 "net/http"
1111 url2 "net/url"
12+ "path"
1213 "strconv"
1314 "strings"
1415 "time"
1516)
1617
17- func genGrafanaRenderUrl (dash string , panel string , org string , host string ) string {
18+ func genGrafanaRenderUrl (grafanaUrl string , grafanaTZ string , org string , dash string , panel string ) ( string , error ) {
1819
19- const unixMinute = 1000 * 60
20- const unixSec = 1000
20+ const fromShift = - time . Hour
21+ const toShift = - time . Second * 10
2122 const imageWidth = "999"
2223 const imageHeight = "333"
23- const timeZone = "Europe/Moscow"
2424 const urlPath = "/render/d-solo/"
25- const urlScheme = "https"
26-
27- url := ""
28-
29- if u , err := url2 .Parse ("" ); err == nil {
30- u .Scheme = urlScheme
31- u .Host = host
32- u .Path = urlPath + dash + "/"
33- q := u .Query ()
34- q .Set ("orgId" , org )
35- q .Set ("from" , strconv .FormatInt (time .Now ().UnixMilli ()- (unixMinute * 60 ), 10 ))
36- q .Set ("to" , strconv .FormatInt (time .Now ().UnixMilli ()- (unixSec * 10 ), 10 ))
37- q .Set ("panelId" , panel )
38- q .Set ("width" , imageWidth )
39- q .Set ("height" , imageHeight )
40- q .Set ("tz" , timeZone )
41- u .RawQuery = q .Encode ()
42- url = u .String ()
25+
26+ if grafanaUrl == "" {
27+ return "" , fmt .Errorf ("grafanaUrl is empty" )
4328 }
44- return url
29+
30+ u , err := url2 .Parse (grafanaUrl )
31+ if err != nil {
32+ return "" , err
33+ }
34+
35+ u .Path = path .Join (u .Path , urlPath , dash )
36+ q := u .Query ()
37+ q .Set ("orgId" , org )
38+ q .Set ("from" , strconv .Itoa (int (time .Now ().Add (fromShift ).UnixMilli ())))
39+ q .Set ("to" , strconv .Itoa (int (time .Now ().Add (toShift ).UnixMilli ())))
40+ q .Set ("panelId" , panel )
41+ q .Set ("width" , imageWidth )
42+ q .Set ("height" , imageHeight )
43+ q .Set ("tz" , grafanaTZ )
44+ u .RawQuery = q .Encode ()
45+ return u .String (), nil
46+
4547}
46- func genGrafanaUrl (dash string , panel string , org string , host string ) string {
4748
48- const urlScheme = "https"
49+ func genGrafanaUrl ( grafanaUrl string , org string , dash string , panel string ) ( string , error ) {
4950
50- DashUrl := ""
51+ if grafanaUrl == "" {
52+ return "" , fmt .Errorf ("grafanaUrl is empty" )
53+ }
5154
52- if u , err := url2 .Parse ("" ); err == nil {
53- u .Scheme = urlScheme
54- u .Host = host
55- u .Path = "d/" + dash
56- q := u .Query ()
57- q .Set ("orgId" , org )
58- if panel != "" {
59- q .Set ("viewPanel" , panel )
60- }
61- u .RawQuery = q .Encode ()
62- DashUrl = u .String ()
55+ u , err := url2 .Parse (grafanaUrl )
56+ if err != nil {
57+ return "" , err
6358 }
64- return DashUrl
59+
60+ u .Path = path .Join (u .Path , "/d/" + dash )
61+ q := u .Query ()
62+ q .Set ("orgId" , org )
63+ if panel != "" {
64+ q .Set ("viewPanel" , panel )
65+ }
66+ u .RawQuery = q .Encode ()
67+ return u .String (), nil
6568}
66- func urlMerger ( kUrl string , pUrl string ) string {
67- imageLink := ""
68- key := ""
69- if u , err := url2 . Parse ( kUrl ); err = = nil {
70- key = u . Path
69+
70+ func urlMerger ( publicUrl string , privateUrl string ) ( string , error ) {
71+ u , err := url2 . Parse ( publicUrl )
72+ if err ! = nil {
73+ return "" , err
7174 }
7275
73- trunc := []rune (key )
74- key = string (trunc [len (trunc )- 10 :])
76+ trunc := []rune (u . Path )
77+ key : = string (trunc [len (trunc )- 10 :])
7578
76- if u2 , err := url2 .Parse (pUrl ); err == nil {
77- q := u2 .Query ()
78- q .Set ("pub_secret" , key )
79- u2 .RawQuery = q .Encode ()
80- imageLink = u2 .String ()
79+ u , err = url2 .Parse (privateUrl )
80+ if err != nil {
81+ return "" , err
8182 }
82- return imageLink
83- }
83+ q := u .Query ()
84+ q .Set ("pub_secret" , key )
85+ u .RawQuery = q .Encode ()
8486
85- func getUploadedImageUrl (url string , token config.Secret , grafanaToken config.Secret ) string {
87+ return u .String (), nil
88+ }
8689
90+ func getUploadedImageUrl (url string , token config.Secret , grafanaToken config.Secret ) (string , error ) {
91+ const imageExtension = "jpg"
8792 client := & http.Client {}
8893 req , err := http .NewRequest ("GET" , url , nil )
94+ if err != nil {
95+ return "" , err
96+ }
8997 req .Header .Set ("Authorization" , "Bearer " + string (grafanaToken ))
90- response , err := client .Do (req )
91-
92- defer response .Body .Close ()
9398
99+ response , err := client .Do (req )
94100 if err != nil {
95- fmt .Printf ("invalid req: %v\n " , err )
96- return ""
101+ return "" , err
97102 }
103+ defer response .Body .Close ()
98104
99- if response .StatusCode != 200 {
100- fmt .Printf ("received non 200 response code, code: %v\n " , response .StatusCode )
101- return ""
105+ if response .StatusCode != http .StatusOK {
106+ return "" , fmt .Errorf ("request status code %d != %d" , response .StatusCode , http .StatusOK )
102107 }
103108
104- uuid := uuid .NewV4 ()
105- fileName := strings .Replace (uuid .String (), "-" , "" , - 1 )
109+ fileName := fmt .Sprintf ("%s.%s" , strings .Replace (uuid .NewV4 ().String (), "-" , "" , - 1 ), imageExtension )
106110 api := slack .New (string (token ))
107111 params := slack.FileUploadParameters {
108112 Reader : response .Body ,
109113 Filetype : "jpg" ,
110- Filename : fileName + ".jpg" ,
114+ Filename : fileName ,
111115 }
112- image , err := api .UploadFile (params )
113116
117+ image , err := api .UploadFile (params )
114118 if err != nil {
115- fmt .Printf ("UPLOAD ERROR. Name: %s\n " , image .Name )
116- return ""
119+ return "" , fmt .Errorf ("upload error, image: %s, error: %w" , image .Name , err )
117120 }
118- sharedUrl , _ , _ , err := api .ShareFilePublicURL (image .ID )
119121
122+ sharedUrl , _ , _ , err := api .ShareFilePublicURL (image .ID )
120123 if err != nil {
121- fmt .Printf ("SharedError :%v\n " , sharedUrl )
122- return ""
124+ return "" , fmt .Errorf ("share error: %w" , err )
123125 }
124126
125- imageUrl := urlMerger (sharedUrl .PermalinkPublic , sharedUrl .URLPrivate )
127+ imageUrl , err := urlMerger (sharedUrl .PermalinkPublic , sharedUrl .URLPrivate )
128+ if err != nil {
129+ return "" , fmt .Errorf ("url merge error: %w" , err )
130+ }
126131
127- return imageUrl
132+ return imageUrl , nil
128133
129134}
130135
131136func (n * Notifier ) formatGrafanaMessage (data * template.Data ) slack.Blocks {
132-
133137 dashboardUid := ""
134138 panelId := ""
135139 orgId := ""
@@ -159,7 +163,6 @@ func (n *Notifier) formatGrafanaMessage(data *template.Data) slack.Blocks {
159163 }
160164 for _ , v := range alert .Annotations .SortedPairs () {
161165 switch v .Name {
162-
163166 case "__dashboardUid__" :
164167 dashboardUid = v .Value
165168 case "__panelId__" :
@@ -179,11 +182,6 @@ func (n *Notifier) formatGrafanaMessage(data *template.Data) slack.Blocks {
179182 firing = UniqStr (firing )
180183 envs = UniqStr (envs )
181184
182- grafanaDashUrl := genGrafanaUrl (dashboardUid , "" , orgId , n .conf .GrafanaHost )
183- grafanaPanelUrl := genGrafanaUrl (dashboardUid , panelId , orgId , n .conf .GrafanaHost )
184- grafanaImageUrl := genGrafanaRenderUrl (dashboardUid , panelId , orgId , n .conf .GrafanaHost )
185- slackImageUrl := getUploadedImageUrl (grafanaImageUrl , n .conf .UserToken , n .conf .GrafanaToken )
186-
187185 {
188186 url := ""
189187 if urlParsed , err := url2 .Parse (data .ExternalURL ); err == nil {
@@ -219,8 +217,8 @@ func (n *Notifier) formatGrafanaMessage(data *template.Data) slack.Blocks {
219217 fields = append (fields , & Field {Type : slack .MarkdownType , Text : fmt .Sprintf ("*Severety: %s*" , strings .ToUpper (strings .Join (severity , ", " )))})
220218
221219 //Buttons
222- if grafanaPanelUrl != "" {
223- fields = append (fields , & Field {Type : slack .MarkdownType , Text : fmt .Sprintf ("*<%s|:chart_with_upwards_trend:Panel>*" , grafanaPanelUrl )})
220+ if url , err := genGrafanaUrl ( n . conf . GrafanaUrl , orgId , dashboardUid , panelId ); err == nil {
221+ fields = append (fields , & Field {Type : slack .MarkdownType , Text : fmt .Sprintf ("*<%s|:chart_with_upwards_trend:Panel>*" , url )})
224222 } else {
225223 fields = append (fields , & Field {Type : slack .MarkdownType , Text : fmt .Sprintf (":chart_with_upwards_trend:~Panel~" )})
226224 }
@@ -230,8 +228,8 @@ func (n *Notifier) formatGrafanaMessage(data *template.Data) slack.Blocks {
230228 } else {
231229 fields = append (fields , & Field {Type : slack .MarkdownType , Text : fmt .Sprintf ("*<%s|:no_bell:Silence>*" , url )})
232230 }
233- if grafanaDashUrl != "" {
234- fields = append (fields , & Field {Type : slack .MarkdownType , Text : fmt .Sprintf ("*<%s|:dashboard:Dash>*" , grafanaDashUrl )})
231+ if url , err := genGrafanaUrl ( n . conf . GrafanaUrl , orgId , dashboardUid , "" ); err == nil {
232+ fields = append (fields , & Field {Type : slack .MarkdownType , Text : fmt .Sprintf ("*<%s|:dashboard:Dash>*" , url )})
235233 } else {
236234 fields = append (fields , & Field {Type : slack .MarkdownType , Text : fmt .Sprintf (":dashboard:~Dash~" )})
237235 }
@@ -261,8 +259,10 @@ func (n *Notifier) formatGrafanaMessage(data *template.Data) slack.Blocks {
261259 }
262260
263261 //GrafanaImage
264- if slackImageUrl != "" {
265- blocks = append (blocks , Block {Type : slack .MBTImage , ImageURL : slackImageUrl , AltText : "inspiration" })
262+ if imageUrl , err := genGrafanaRenderUrl (n .conf .GrafanaUrl , n .conf .GrafanaTZ , orgId , dashboardUid , panelId ); err == nil {
263+ if slackImageUrl , err := getUploadedImageUrl (imageUrl , n .conf .UserToken , n .conf .GrafanaToken ); err == nil {
264+ blocks = append (blocks , Block {Type : slack .MBTImage , ImageURL : slackImageUrl , AltText : "inspiration" })
265+ }
266266 }
267267
268268 //Summary and description
0 commit comments