{"id":2488,"date":"2011-07-14T21:41:07","date_gmt":"2011-07-14T19:41:07","guid":{"rendered":"http:\/\/contoso.se\/blog\/?p=2488"},"modified":"2011-07-14T21:41:07","modified_gmt":"2011-07-14T19:41:07","slug":"building-a-log-for-your-runbooks","status":"publish","type":"post","link":"http:\/\/contoso.se\/blog\/?p=2488","title":{"rendered":"Building a log for your runbooks"},"content":{"rendered":"<p>The last week I have been working on a way to handle logs for multiple runbooks in Orchestrator. Opalis and Orchestrator will\u00c2\u00a0executes but\u00c2\u00a0as soon as they are done, they\u00c2\u00a0will drop everything, and will not &#8220;remember anything&#8221;. They only\u00c2\u00a0keeps\u00c2\u00a0data in memory during execution (and maybe in some logs). That is one of the reasons why it is important to log to a external system when working with Opalis or Orchestrator. You most likely want to store information in a external system so you can go back and review it later, for example what triggered the runbook to\u00c2\u00a0start,\u00c2\u00a0what files was it moving\u00c2\u00a0and with which parameters? Some scenarios can be\u00c2\u00a0solved\u00c2\u00a0by using Service Manager and change management. When someone submits a change, you will have all the information in the change request, that will trigger Orchestrator. But there will not always be a change request, you could then use for example a SQL database that each runbook writes to.\u00c2\u00a0In this blogpost I share some ideas around logging to a SQL database. I will use the Orchestrator beta build but most of this you can build exactly the same in Opalis.<\/p>\n<p>In this example I have\u00c2\u00a0a runbook that creates the database I will use to store logs. Of course you can create the database manually, but it is easy to keep it in a runbook, easy if you copy the runbook to a new environment. Then you know that the database will be setup the same every time. The &#8220;Create LOG Database&#8221; runbook looks like<\/p>\n<p><a href=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/20110708_Log07.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-medium wp-image-2507\" title=\"20110708_Log07\" src=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/20110708_Log07-300x171.jpg\" alt=\"\" width=\"300\" height=\"171\" srcset=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/20110708_Log07-300x171.jpg 300w, http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/20110708_Log07.jpg 464w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<ol>\n<li>&#8220;Create log database&#8221;, creates the log database. If it works there is a 10 sec delay on the link before tables are created. If it doesn&#8217;t work it will go to 4<img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-medium wp-image-2494\" title=\"20110708_Log03\" src=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/20110708_Log03-300x152.jpg\" alt=\"\" width=\"300\" height=\"152\" srcset=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/20110708_Log03-300x152.jpg 300w, http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/20110708_Log03.jpg 399w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/li>\n<li>&#8220;Create tables&#8221;, creates tables in the database. If it works it will move on to 5, else it will go to 3<\/li>\n<li>&#8220;Drop db&#8221;, deletes the database<\/li>\n<li>&#8220;Error Event&#8221;, writes a platform event saying that the database or tables could not be created<\/li>\n<li>&#8220;Get timestamp&#8221;, gets the current timestamp in a suitable format<\/li>\n<li>&#8220;Insert test event&#8221;, test insert a event in the database<\/li>\n<li>&#8220;Write Error Event&#8221;, if the test insert activity don\u00c2\u00b4t work a platform event is generated<br \/>\n<a href=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/20110708_Log11.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-medium wp-image-2511\" title=\"20110708_Log11\" src=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/20110708_Log11-300x106.jpg\" alt=\"\" width=\"300\" height=\"106\" srcset=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/20110708_Log11-300x106.jpg 300w, http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/20110708_Log11.jpg 585w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/li>\n<li>&#8220;Send OK event&#8221;, a platform event is generating saying the database has been created<\/li>\n<li>Get a timestamp in correct format. I notice when I was moving this runbook between environment that the default time stamp is different, so I use this activity to format the data format to yyyy-M-d h:m:s<\/li>\n<li>Insert a test event into the database<\/li>\n<li>Send a platform event saying the database is created<\/li>\n<\/ol>\n<p>After the database is created and is working we need to create the runbook that will add events to the database.\u00c2\u00a0 In the picture\u00c2\u00a0there is\u00c2\u00a0a example of a runbook that writes log data to the log database, the &#8220;write to log runbook&#8221;. When you trigger this runbook you need to send some parameters,<\/p>\n<ul>\n<li>Runbook, name of the runbook that trigger the log runbook<\/li>\n<li>Description, description of the event, for example &#8220;Service can\u00c2\u00b4t start&#8221;<\/li>\n<li>Runbook Process ID, the process ID of the runbook module<\/li>\n<li>Severity, how serious is the issue. Try to use a standard here, like INFORMATION, WARNING\u00c2\u00a0and CRITICAL<\/li>\n<\/ul>\n<p><a href=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/log03.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-medium wp-image-2514\" title=\"log03\" src=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/log03-300x145.jpg\" alt=\"\" width=\"300\" height=\"145\" srcset=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/log03-300x145.jpg 300w, http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/log03.jpg 937w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>If the severity is Critical there will be an alert generated in Operations Manager direct. Then the runbook\u00c2\u00a0creates a suitable time format. Next step is to insert the data into the database. As you can see in the picture below we insert all the data that was sent from the runbook that triggers this runbook.<\/p>\n<p><a href=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/log04.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-medium wp-image-2515\" title=\"log04\" src=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/log04-300x155.jpg\" alt=\"\" width=\"300\" height=\"155\" srcset=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/log04-300x155.jpg 300w, http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/log04.jpg 576w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>If the runbook cant insert event into the database an Operations Manager alert will be generated and also a platform event.\u00c2\u00a0So we have the database setup and we have a runbook that insert events into the database. How do we use all this? We use the Invoke Runbook activity! Below I have a runbook that loooks for new files in a folder and then copies them and moves them around. I have a number of Invoke Runbook activities that triggers the &#8220;write to log&#8221; runbook when there is something that needs to be in the log. As you can see in the image I forward data from this runbook to the &#8220;write in log&#8221; runbook, like the description and severity. This is the info that will be written in the database.<\/p>\n<p><a href=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/log05.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-medium wp-image-2516\" title=\"log05\" src=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/log05-300x163.jpg\" alt=\"\" width=\"300\" height=\"163\" srcset=\"http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/log05-300x163.jpg 300w, http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/log05-1024x557.jpg 1024w, http:\/\/contoso.se\/blog\/wp-content\/uploads\/2011\/07\/log05.jpg 1068w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Your runbooks will now write logs to a common database. You can review the database with any tool to see how everything has been working and if you need to review some parameter or some variable value, you can simple look in your database (presuppose that you wrote it there :)). If you want to change how to store logs you can change one place, the &#8220;write to log runbook&#8221;, and you don&#8217;t need to modify all your runbooks. If you want to trigger alerts or incidents you can also do that simple in the &#8220;write to log runbook&#8221; instead of modify all your runbooks. Remember that Opalis and Orchestrator &#8220;only&#8221; executes, you need to store your data somewhere else if you want to read it after the runbook\/policy is done.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The last week I have been working on a way to handle logs for multiple runbooks in Orchestrator. Opalis and Orchestrator will\u00c2\u00a0executes but\u00c2\u00a0as soon as they are done, they\u00c2\u00a0will drop everything, and will not &#8220;remember anything&#8221;. They only\u00c2\u00a0keeps\u00c2\u00a0data in memory during execution (and maybe in some logs). That is one of the reasons why it &hellip; <a href=\"http:\/\/contoso.se\/blog\/?p=2488\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[58,60],"tags":[],"_links":{"self":[{"href":"http:\/\/contoso.se\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2488"}],"collection":[{"href":"http:\/\/contoso.se\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/contoso.se\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/contoso.se\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/contoso.se\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2488"}],"version-history":[{"count":24,"href":"http:\/\/contoso.se\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2488\/revisions"}],"predecessor-version":[{"id":2522,"href":"http:\/\/contoso.se\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2488\/revisions\/2522"}],"wp:attachment":[{"href":"http:\/\/contoso.se\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2488"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/contoso.se\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2488"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/contoso.se\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2488"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}