Home » Opalis » Building a log for your runbooks


Welcome to contoso.se! My name is Anders Bengtsson and this is my blog about Azure infrastructure and system management. I am a senior engineer in the FastTrack for Azure team, part of Azure Engineering, at Microsoft.  Contoso.se has two main purposes, first as a platform to share information with the community and the second as a notebook for myself.

Everything you read here is my own personal opinion and any code is provided "AS-IS" with no warranties.

Anders Bengtsson

MVP awarded 2007,2008,2009,2010

My Books
Service Manager Unleashed
Service Manager Unleashed
Orchestrator Unleashed
Orchestrator 2012 Unleashed
Inside the Microsoft Operations Management Suite

Building a log for your runbooks

The last week I have been working on a way to handle logs for multiple runbooks in Orchestrator. Opalis and Orchestrator will executes but as soon as they are done, they will drop everything, and will not “remember anything”. They only keeps data 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 start, what files was it moving and with which parameters? Some scenarios can be solved by 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. In 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.

In this example I have a 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 “Create LOG Database” runbook looks like

  1. “Create log database”, creates the log database. If it works there is a 10 sec delay on the link before tables are created. If it doesn’t work it will go to 4
  2. “Create tables”, creates tables in the database. If it works it will move on to 5, else it will go to 3
  3. “Drop db”, deletes the database
  4. “Error Event”, writes a platform event saying that the database or tables could not be created
  5. “Get timestamp”, gets the current timestamp in a suitable format
  6. “Insert test event”, test insert a event in the database
  7. “Write Error Event”, if the test insert activity don´t work a platform event is generated
  8. “Send OK event”, a platform event is generating saying the database has been created
  9. 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
  10. Insert a test event into the database
  11. Send a platform event saying the database is created

After the database is created and is working we need to create the runbook that will add events to the database.  In the picture there is a example of a runbook that writes log data to the log database, the “write to log runbook”. When you trigger this runbook you need to send some parameters,

  • Runbook, name of the runbook that trigger the log runbook
  • Description, description of the event, for example “Service can´t start”
  • Runbook Process ID, the process ID of the runbook module
  • Severity, how serious is the issue. Try to use a standard here, like INFORMATION, WARNING and CRITICAL

If the severity is Critical there will be an alert generated in Operations Manager direct. Then the runbook creates 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.

If the runbook cant insert event into the database an Operations Manager alert will be generated and also a platform event. So 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 “write to log” 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 “write in log” runbook, like the description and severity. This is the info that will be written in the database.

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 “write to log runbook”, and you don’t need to modify all your runbooks. If you want to trigger alerts or incidents you can also do that simple in the “write to log runbook” instead of modify all your runbooks. Remember that Opalis and Orchestrator “only” executes, you need to store your data somewhere else if you want to read it after the runbook/policy is done.


  1. Do you have run book to start and shutdown Oracle Databases?

  2. Could you post the events for create DB and create log tables? Or better yet a link to the runbook?


  3. hello, I’m designing and brainstorming about logging for my runbooks. I was also considering logging this to a SQL database. However, I do have a question about your solution. How do you know which instance of the runbook reported this error. For example if a runbook is run 10 times a day and only one fails I want to see all the logging for that runbook.

    The error message is easily to get, due to the severity collumn. However I do not know which information events belong to the error event. This even gets more difficult if job concurency is higher than 1.

    My solution was to log the instance ID of the running runbook to the database. However this is not a common published data variable.

    Do you have a solution for my problem/challenge?

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.