使用Azure的Application Insights可以輕鬆監控自己系統的狀況和資訊外,另一個重要的部分,在於當發現問題時候,要能即時通知團隊,才能做即時的處理。雖然,Application Insights可以建立Alert Mail的機制,通知團隊問題發,但是,感覺還是味道還是差一點,況且有些問題可以需要透過討論後才有辦法解決
所以,來使用目前比較流行的『Slack』,作為團隊溝通協調的一個平台,且透過『Slack』也可以減少要開發手機Push Message機制的App,因為,Slack本身也具有Push Message了。
本身Application Insights並無直接跟Slack整合,而是透過Application Insights內的Webhook機制與其他平台進行整合,所以,我們必須先透過Logic App產生能符合Webhook規範的URL,因此,我們必須在Azure上建立一個Logic App
建立Azure Logic App 首先建立一個Logic App的服務
當它服務建立好後,一開始就是準備建立資訊流程,在Logic App動作行為是依賴流程去撰寫。在預設的官方Template並沒有符合我們需求,所以,這邊我們手動建立一個屬於自己的流程。在這個案例中,input來源是Application Insights,Output位置是Slack,再加上要把Application Insights提供資訊網址,用Google的短網址服務,將很長的網址縮短,所以,我們這邊會用到三個方塊組合流程,分別是
Request 
Http 
Slack 
 
後續就分別去設定這三個流程的內容就可以
設定Request 這方塊意義在於當Application Insights監測到異常時候,會透過Webhook通知,一旦Logic app的Request收到訊息,就會開始跑後續流程,在這裡的HTTP POST TO THIS URL ,等流程設定完儲存後才會出現,在REQUEST BODY JSON SCHEMA 內填入下面json資訊1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
  "$schema" : "http://json-schema.org/draft-04/schema#" ,
  "properties" : {
    "context" : {
      "properties" : {
        "name" : {
          "type" : "string" 
        },
        "portalLink" : {
          "type" : "string" 
        },
        "resourceName" : {
          "type" : "string" 
        }
      },
      "required" : [
        "name" ,
        "portalLink" ,
        "resourceName" 
      ],
      "type" : "object" 
    },
    "status" : {
      "type" : "string" 
    }
  },
  "required" : [
    "status" ,
    "context" 
  ],
  "type" : "object" 
}
設定Http 收到Request時,會把Application Insights的網址,透過Google服務將網址縮短,所以,是透過post方式把資訊傳送給Google Service,然後,我們再把接收到的短網址放到後續發送到Slack的資訊之一
1.HTTP  Method設定PostURI  設定填入Google短網址服務的URL1
https://www.googleapis.com/urlshortener/v1/url?key=AIzaSyBkT1BRbA-uULHz8HMUAi0ywJtpNLXHShI
3.Headers  設定要傳送訊息的型態,這邊設定為json1
2
3
{
 "Content-Type" : "application/json" 
 }
4.Body  則是設定原本Application Insights事件的長網址,傳送給Google服務,這邊可以透過紅色匡點選portalink ,就會自動把portalink資訊帶入
這一段在Logic App code view為1
2
3
4
5
6
7
8
9
10
11
12
13
14
"HTTP": {
    "inputs": {
        "body": {
            "longUrl": "@{triggerBody()['context']['portalLink']}"
        },
        "headers": {
            "Content-Type": "application/json"
        },
        "method": "POST",
        "uri": "https://www.googleapis.com/urlshortener/v1/url?key=AIzaSyBkT1BRbA-uULHz8HMUAi0ywJtpNLXHShI"
    },
    "runAfter": {},
    "type": "Http"
}
設定Slack 一開始必須先建立Slack連線資訊,點選Sign In會跳出登入畫面,這時候輸入團隊在Slack的名稱和帳號密碼,團隊Slack是XXX.slack.com,名稱就是XXX
輸入完後會跳出Microsoft Azure Logic Apps would like access to XXX訊息,這是讓Azure和Slack建立授權關係,基本上就是要按同意囉
然後,就要建立對應在Slack的相關設定
Channel_Name  就是設定你要發送到Slack Channel的名稱,格式因該是#XXXMessaage Text  就是設定想要在Slack Channel上顯示的資訊,設定後的資訊如下 
以上設定完成後,可以發現在Azure不僅僅多了一個Logic App外,也會多一個API COnnection
此外,在Request區塊中HTTP POST TO THIS URL也會自動有了URL,要把這組URL放到Application Insights Alert設定的Webhook,當要發送Alert時候,也會Application Insights也會透過Webhook把資訊傳給Logic App
在Logic App也可以看是否資訊有正常發送出去
如果發現有發生錯誤的地方,只要點選Faild的Event就可以看出是哪一段流程出問題
整個Logic App Code View1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
{
    "$schema" : "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#" ,
    "actions" : {
        "HTTP" : {
            "inputs" : {
                "body" : {
                    "longUrl" : "@{triggerBody()['context']['portalLink']}" 
                },
                "headers" : {
                    "Content-Type" : "application/json" 
                },
                "method" : "POST" ,
                "uri" : "https://www.googleapis.com/urlshortener/v1/url?key=AIzaSyBkT1BRbA-uULHz8HMUAi0ywJtpNLXHShI" 
            },
            "runAfter" : {},
            "type" : "Http" 
        },
        "Post_Message" : {
            "inputs" : {
                "host" : {
                    "api" : {
                        "runtimeUrl" : "XXXX" 
                    },
                    "connection" : {
                        "name" : "@parameters('$connections')['slack']['connectionId']" 
                    }
                },
                "method" : "post" ,
                "path" : "/chat.postMessage" ,
                "queries" : {
                    "channel" : "#alert\n" ,
                    "text" : "@{triggerBody()['context']['resourceName']} Alert\nAlert Name : @{triggerBody()['context']['name']}\nDescription:@{triggerBody()['context']['description']}\nInfo Link: @{body('Http')['id']} \n----------------------------------------\n@{triggerBody()}" ,
                    "username" : "Service" 
                }
            },
            "runAfter" : {
                "HTTP" : [
                    "Succeeded" 
                ]
            },
            "type" : "ApiConnection" 
        }
    },
    "contentVersion" : "1.0.0.0" ,
    "outputs" : {},
    "parameters" : {
        "$connections" : {
            "defaultValue" : {},
            "type" : "Object" 
        }
    },
    "triggers" : {
        "manual" : {
            "inputs" : {
                "schema" : {
                    "$schema" : "http://json-schema.org/draft-04/schema#" ,
                    "properties" : {
                        "context" : {
                            "properties" : {
                                "name" : {
                                    "type" : "string" 
                                },
                                "portalLink" : {
                                    "type" : "string" 
                                },
                                "resourceName" : {
                                    "type" : "string" 
                                }
                            },
                            "required" : [
                                "name" ,
                                "portalLink" ,
                                "resourceName" 
                            ],
                            "type" : "object" 
                        },
                        "status" : {
                            "type" : "string" 
                        }
                    },
                    "required" : [
                        "status" ,
                        "context" 
                    ],
                    "type" : "object" 
                }
            },
            "kind" : "Http" ,
            "type" : "Request" 
        }
    }
}