Programmatically create APM objects and configuration (w/ APM Explorer sample app)
I have been speaking to multiple customers, and a lot of them had the same feedback: “the APM template/wizard is great, BUT what if I want to automate enablement of monitoring when I provision new applications, without using the UI ?”. The request seems fair, but our extensibility/programmability story for APM currently doesn’t easily allow that.
The APM template, like all templates, generates a management pack (or adds “stuff” to an existing management pack). Many other templates actually create classes/discoveries/rules/monitors… but APM provides a lot of settings which are really peculiar to its functionality, and don’t easily fit into the “standard” management packs/discoveries/rules/monitors pattern. What the APM template does is really to capture INTENT, and use that information to generate the right configuration on the agent.
Sure, it still creates an MP, and it does create an object (<EntityType>) for the “application group” you are defining, within that MP. If you are wondering what an “application group” is, you might want to refer to this previous post of mine that explains more at a high level what objects are created by APM first: http://blogs.technet.com/b/momteam/archive/2012/01/14/apm-object-model.aspx then come back here.
It also creates a discovery for the application group. What the APM discovery has that is really special, is its data source configuration, which features a “special sauce” you can see below (from an exported MP in my demo environment):
Is XML the one I see within the <AppChunk1> tag? It surely is, encoded XML, nested within the “outer” Management Pack’s XML… but XML nonetheless. For the non-programmers here, those > and < are encoded versions of open and closed tags: “>” and “<”. It gets encoded this way in order to have XML within other XML… that is because technically, the whole AppChunk1 is just a string – that is right: the MP Schema has NOT been extended to support special APM “stuff” – it all is just a string that gets used by a data source module as configuration. This configuration happens to be quite complex, but the MP will validate and import even if you write something incorrect in this string. BUT then the discovery module will choke on this input and fail (and raise an alert on the management server). Since “normally” the MP gets only written by our official UI/Template, then this is not an issue because we guarantee we will write it correctly (if not, we likely have a bug somewhere).
But this is the reason why it isn’t supported to edit it outside of the template: because it is a non-trivial exercise, and it is easy to get it wrong without having a public schema to validate against. Also, since the AppChunk1 module configuration is not in the MP Schema, a future version of the module and template might change the way this piece of XML looks like.
So, with the warning that all that I am going to write starting now is TOTALLY UNSUPPORTED, I will show you how to look at what the template builds, and try to replicate it. I won’t use any “insider knowledge” nor code officially released by Microsoft nor part of any product: I will just guide you thru looking at the XML output and try to make sense out of it. When I did this myself, I came up with some SAMPLE CODE which I will provide, which can generate the same XML.
Sounds easy enough, so let’s take a look at this <AppChunk1> and look at it once you add some carriage returns to make it more readable:
I highlighted a few different blocks in it:
- some global settings about the application group (name, environment tag, a unique GUID)
- server-side monitoring settings (global)
- client-side monitoring settings (global)
- application-component-specific configuration (which application components to enable for monitoring for – this is essentially the list of “application components” within the “application group” (again, refer to this blog post for the object model and terminology)
Most of the settings are self-explanatory, when you look at them… you will recognize they are all the same things that you configured in the template: namespaces, thresholds, etc…
So with this knowledge, what does it take to create the same XML?
It takes some code, of course. Some sample code is what I am going to provide in this post, linked below: I built a small sample application to demonstrate this. It is built with Visual Studio 2010 and compiled to run against .NET Framework 4.x. The sample application will let you connect to a management server (I only tested it against SC 2012 SP1) and will list all he applications you have (that have been discovered) and will show whether they are already enabled for monitoring, in which MP, and some of the settings applied to them. Please note that this is just an EXAMPLE, so it has not gone thru full testing and there is no guarantee that it will keep working with future updates. It also doesn’t understand nor show things like group scoping of the template, nor if the same application has been configured more than once in multiple templates, etc – in fact it might even be broken in some of those scenarios, as I have not done extensive testing!
To be totally fair and give due credit, this first part of the application got started by my friend Eric, when he was trying to figure out which applications he had configured and which ones he was still missing. So the first part of the code, which enumerates your endpoints, is actually coming from him. I eventually ended up writing a SQL query and SSRS report for THAT scenario (see here http://blogs.technet.com/b/momteam/archive/2012/08/22/apm-configured-endpoint-report.aspx ) but then re-used the GUI for this “configuration” experiment, instead.
So back to configuration, the GUI is only meant to be a quick way to multi-select various “application components” from your inventory, and quickly create an MP to monitor them with APM:
This brings up a form with the same basic settings in the template (note not ALL the settings available in the template have been implemented in my sample!)
When you click OK, a management pack will be written to disk (in the same folder where you launched the EXE from).
This is a totally “importable” MP that should be working and creating all the right things that the template would have created, at least for the server-side settings.
The tool isn’t extremely useful as-is (because you still have to go thru a UI, after all! – and if you have to use a UI, you might just as well use the official one that ships with the product!)… but that is not the point! The main goal is to show that it is possible to create the right XML thru custom code, to automate provisioning of APM monitoring for your apps. I built a UI on it to let you validate how it works. But eventually, if you want to automate enablement of monitoring for your own apps, you will only really care about the “APMMPGenerator” class, which is the one that does the “dirty” work of creating the MP!
As I wrote earlier, I didn’t use any insider knowledge, and this code is absolutely NOT the same code as to what is used within the product itself – it just happens to produce the same XML fragment as output. To further prove that this could be done by anyone, I purposely kept the code NOT elegant: by this I mean that I didn’t treat XML as such nor used classes in the framework to deal with XML like a true programmer would have done, no schema validation, nothing of that sort! Instead, I hacked together the required XML by using quick and dirty STRING manipulation and token replacement. While most real programmers will be probably thinking this code should be posted on TheDailyWTF, I stand behind my choice, and I believe many IT Pro’s and operations manager administrator that don’t write code every day will actually appreciate it and find it more readable, and probably easier to port to PowerShell, Perl, or their favorite scripting language. APMMPGenerator is the main class in this sample code that is relevant to learn how to write the required pieces of the MP:
This class and its methods are heavily commented ‘step by step’, and it will show how you can generate the XML for a management packs to be used with SCOM to enable APM.
Writing XML for management packs thru code (and concatenating strings) is in my opinion a very powerful technique that I have also used in the past to build other MPs that were “repetitive” (i.e. needed to contain many “similar” groups, rules, monitors, etc), and should allow people to more easily port it to other languages (i.e. PowerShell, for automation, sounds like a good choice…).
Gotcha’s / Disclaimer
- Client-side monitoring settings cannot be created by just writing XML “offline” and “outside” of an OpsMgr Management Group, because the real APM template creates a binary RunAs Account that is used as an encryption key to secure the browser-to-server communication (so that random attackers cannot just feed bad data to the CSM Collector endpoint, but they need to be valid/real browsers doing that). This is something that has to call the SDK on the management server, to see if such an account already exists or not, etc… it gets a lot trickier and it is simply not possible, with the current design to create such part of the MP “offline” just by crafting XML. This said, once the MP is imported, you can go and EDIT it again in the template, add client-side monitoring, apply/save, and the right things should happen there and then.
- The tool’s code does NOT create a FOLDER and VIEWs for the monitored applications. I left that as an exercise for the reader. if you look at the views that the template creates, there really isn’t anything too special about them – they are just standard views, like those in any other MP. Hence I didn’t spend time there… there are examples on how to add views here http://msdn.microsoft.com/en-us/library/bb437626.aspx and here http://msdn.microsoft.com/en-us/library/bb960509.aspx (among other places…). Like the above, editing the template after the fact should add the views at that point, when saving.
- Other than the above “AppChunk1”, there are a few more things that the class creates but I didn’t describe: things like references to other MPs, display strings, and info required to make the “template instance” appear in the “Authoring” pane of the console, so it can be further edited later on. I am not describing those since they are all “standard” Management Packs elements… documentation on MSDN, like for the views, above.
- All of this (tool, sample code, post) is TOTALLY NOT SUPPORTED. I repeat it: NOT SUPPORTED. I am not encouraging anybody to use this! The only supported way to do this stuff is to use the Template, which is what has been written by professional developers and tested. What I did here is to put myself in the customers’ shoes, look at what the template builds, and tried to replicate it. I didn’t use any “insider knowledge” nor code owned by Microsoft to do this – I did what anyone of you could have done: observe the MP, and try to build one that looks the same. Call it reverse engineering, if you wish. Anyway, since some people have expressed the need to automate enablement of monitoring… this is the only way I can think of enabling that with the current product. I know. There are plenty of smart people in the OpsMgr community, who don’t' get scared about creating custom solutions on top of the platform. This is a post for them.
- All of the above is not supported. No, really. Just in case you missed it. If you really want to use it, please evaluate in your test environment first! As expected, this solution is provided AS-IS, with no warranties and confers no rights. Future versions of this tool may be created based on time and requests.