Creating a web service health check with Jenkins pipeline and Mattermost notification
In this post, a simple health checker for one microservice will be created using theJenkins pipeline.
Prerequisites:
- Mattermost Notification Plugin
- cURL or similar
- Jenkins
1. 1 Configure Mattermost Config
https://docs.mattermost.com/developer/webhooks-incoming.html
2. 2 Create Job
Create a new job with type “Pipeline” in Jenkins.
3. 3 Add Build Trigger
This job will be executed every 30 minutes.
4. 4 Add Pipeline script
The 1st stage will connect to our keycloak server to get the access token, you can change it to any authentication server.
The second stage will use the access_token from the 1st stage and tries to call the web service.
If http response code is 200, the job will send a mattermost infor message; If code is not 200, the job wil send a mattermost warning message. And meanwhile, will send a warning email to the operation team.
The post action (failure ) will catch the stage failure, when it executes error function like this: error(“notify token retrieving error”)
5. Full script:
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 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 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
pipeline { agent any environment { stageName = "Service Name " ppcUrl = "https://test.com/api/servicename" keycloakUrl = "https://keycloak.test.com/auth/realms/realm_name/protocol/openid-connect/token" ACCESS_TOKEN = "" httpStatus = "" httpResponse = "" } stages { stage ('Get Service keycloak token') { steps { script { final def (String response, int code) = sh(script: "curl --insecure -s -w '\\n%{response_code}' \ --location --request POST $keycloakUrl \ --header 'Authorization: Basic d2ViX2FwcDp3ZWJfYXBw' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=password' \ --data-urlencode 'username=user' \ --data-urlencode 'password=passwprd' \ --data-urlencode 'scope=realm_nameprofile email' \ ", returnStdout: true) .trim() .tokenize("\n") echo "HTTP response status code: $code" if (code == 200) { def jsonObj = readJSON text: response ACCESS_TOKEN = jsonObj['access_token'] if (ACCESS_TOKEN == "") { httpStatus = "403" error("notify token retrieving error") } } } } } stage ('Check Service Health') { steps { script { httpStatus = sh(script: "curl --insecure -w '%{http_code}' $ppcUrl -o /dev/null \ --header 'Accept: application/json' \ --header 'Authorization: Bearer ${ACCESS_TOKEN}' \ ", returnStdout: true) if (httpStatus != "200" && httpStatus != "201" ) { echo "Service error with status code = ${httpStatus} when calling ${ppcUrl}" error("notify error") } else { echo "Service OK with status: ${httpStatus}" } } } } } // Finishing Up Actions post { success { script { notifySucc(stageName, httpStatus) } } failure { script { notifyError(stageName, httpStatus) } } unstable { mattermostSend channel: "#mattermost_channel_id", color: "warning", message: ":warning: $stageName health checking is aborted. | ${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)" } fixed { mattermostSend channel: "#mattermost_channel_id", color: "good", message: ":white_check_mark: $stageName is returning to health. | ${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)" } } } def notifySucc(String stageName = '', String httpStatus = '') { def message = ":smiley: $stageName is working. | ${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)" echo(message) mattermostSend channel: "#mattermost_channel_id", color: "good", message: message } def notifyError(String stageName = '', String httpStatus = '') { def message if (httpStatus == "401") { message = ":sweat: $stageName unauthorized ($httpStatus), please update token and session. | ${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)" } else if (httpStatus == "403") { message = ":dizzy_face: $stageName can not get token from Keycloak ($httpStatus), please update token and session. | ${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)" } else{ message = ":rage: $stageName is down with status: $httpStatus | ${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)" } echo(message) mattermostSend channel: "#mattermost_channel_id", color: "danger", message: message emailext ( subject: message, to: "youremail@test.com;someone@test.com;", body: """<p>$stageName Health Check Failed: '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p> <p>Check console output at "<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>"</p>""" //,recipientProviders: [[$class: 'DevelopersRecipientProvider']] ) } |
6. Last Result
Reference:
Creating a simple health check with Jenkins pipelines and Slack notification
https://www.jenkins.io/blog/2016/07/18/pipeline-notifications/