Tag Archives: QuickMon - Page 3

Mail Aggregator Service

One problem with creating very useful apps sometimes is that you end up making more work or trouble for yourself 🙂 My QuickMon tool has been created to help me monitor some services and ‘stuff’ which alerts me if things go pear shape… That is all good and wonderful until you (me) realize I’m beginning to ‘spam’ myself with too many messages (since I’m using smtp alerts…). Now they are all ‘valid’ alert messages and I still need to be aware of them but at some point there are just too many individual messages flying around. QuickMon alerts are quite configurable and if you want to some suppression is possible but managing this is almost a job on its own since things change with time, conditions change etc. etc. etc.

So I started thinking (an act that in itself could be dangerous at times) about how to solve the problem by grouping messages before they get sent. QuickMon itself raise alerts and immediately send them off – fire and forget style. Sure, I can build a new notifier that tries to do some batching (not sure how I can do that yet) or modify the QuickMon service itself to ‘hold on’ to alerts for time periods but that won’t be a generic solution any more. A better solution is to build a separate ‘generic’ solution that can also be used from QuickMon plus any other apps I might still create that need smtp messages to be sent out automatically (system level stuff).

This is where the idea of the MailAggregator service started. In itself it is a very simple thing – it runs, periodically checking for all messages from some ‘source’ that need to be send to the same destination, groups them as one message and sends it. The ‘source’ could be a database table or directory with files (or possibly any other place that can store a bunch of messages that can be retrieved at one time. For my own proof of concept I created a simple working example that checks for text files in a directory, use the content as the message content, group/append it, send it and then either deletes or renames the original files.

I decided to make the service a bit more dynamic in that you can add aggregators – implementing a standard interface so adding new aggregator source types in the future would be easy (like Text file and Sql table I already mentioned). Also, the service can run multiple aggregators (of the same or different types) at the same time – each serviced on its own thread (I just love threading but yeh, you have to be careful!). As with QuickMon each instance (or host as I termed it here) can have its own separate config.

So the end result of this little experiment is a working (or should I say workable) example that can already (with some electronic duck tape) be used with QuickMon alerts.

Basic architecture overview

  • MailAggregatorService

The main component of this little project is again a simple ‘Windows Service’. The service on its own is actually very simple – really just a shell that contains the aggregator hosts which calls the aggregator  libraries. A host instance gets created for every config entry (in an array) as specified in the config file.

This service also contains my code for self registration (to install it with the -install command line)

  • MailAggregatorHost

The MailAggregatorHost (class) is the container that holds the ‘aggregator source type library’. Because each source type implements a standard interface the host does not know or care which specific aggregator it is dealing with. The host is the entity that runs in a permanent loop calling the GetMessages() method of the aggregator, sends the smtp messages and then waits until the next iteration.

  • IMailAggregatorSource

Each mail aggregator source library implements the IMailAggregatorSource interface for a particular resource type a.k.a. like Text files, Sql table or whatever. The interface itself is fairly simple and has the following members:

    • event AggregatorError
    • string GetConfigIdentifierType() – will be use later to dynamically load source types
    • bool SetConfig(string config) – configure the source type with specified config
    • List<MailAggregatedMessage> GetMessages() – get the messages dub…
    • string LastError { get;set;} – not used yet but one day….
  • MailAggregatedMessage
This is just a container to hold and pass the aggregated messages from the source type to the host.
  • MailAggregatorFFSource
This is the first example implementation of the IMailAggregatorSource interface that check for plain text files (txt or anything you specify in the config) and groups them for messages. This implementation optionally checks for lines starting with ‘TO:’ and ‘SUBJECT:’. It is possible to specify default values that will be used if these lines are not available. The rest of the file is taken as the ‘body’ of the message.
By default it only groups ‘messages’ by the ‘TO’ address but you can also specify that the subject (plus TO address) will be used for the grouping. Grouped messages simple get appended.
A maximum messages size can be specified so that when a grouped set of ‘messages’ exceed the specified size a new MailAggregatedMessage instance will be created.
Once all the reading and grouping of messages have been done the processed files get either deleted or renamed as per config. When using the renaming option there is another choice – if the renamed file already exists it can either be overwritten or appended. ‘Done’ files are renamed to the original file name plus ‘.done‘.

Example source code

If you like to play with the source code yourself you need VS2010 – it requires .Net 4 (client framework)

MailAggregator

QuickMon 2.5.4

The first update to one of my tool projects on CodePlex is a QuickMon release. It is actually a very small change – bug fix of a silly little UI bug.

Hopefully I’ll have some time this year to improve the tool further – there are several ideas in the pipeline…

Event log notifier for QuickMon

I’ve eventually added an Event log notifier for QuickMon. It is actually really simple and does a basic job of logging alerts to the event log. It could be useful for those users that might not have a full SQL server database to log alerts to.

Some features:

* It use the alert level for the event log entry ‘type’ – like warning or error.
* You can log events to the local and remote event logs – but remember the permissions!
* The event source can be customized – including 2 macros for specifying the collector name or type.

Have fun monitoring!

QuickMon 2.5.2

Sometimes keeping track of version numbers is a job all on its own. I released an update to QuickMon to include the syntax highlighting component I found on Code Project (‘Fast Colored TextBox’ from Pavel Torgashov) for the manual xml editing and SQLQuery collector editing. After some initial issues with the control due to a bug in the .Net framework (Regex classes with Compiled option on x64) it is now working nicely.

Happy monitoring

Syntax high-lighting

I came across a cool control for syntax high-lighting based on a language (programming languages like C#, TSql etc.) created by  Pavel Torgashov. It provides a customizable way to configure syntax high-lighting based on configuration and you can even provide custom high-lighting based on a simple xml file.

I plan on using it in the QuickMon SQL Query collector’s editor so it  is easier to edit tsql statements. Seeing your code (sql) in different colors make it easier to spot editing problems and also to get a picture of what/where you are doing stuff. Of course, this control is not a compiler so it doesn’t actually do syntax or error checking but it helps with spotting problems if there are simple ones.

 

QuickMon 2.5

I recently made a big update to QuickMon. Since the start of version 2 I added the the concept of registering ‘agents’ in a separate ‘Agent Registration List’ file. The idea was that this could be reusable and allow more flexibility. But like some good ideas it was just too much for what the whole tool was intended for.

So I decided to simplify the whole way ‘agents’ are used in the application. From version 2.5 a ‘Monitor Pack’ will simply have a property that stores the path (a single path) where all agent assemblies/dll’s are stored. When opening a monitor pack to edit the default path will simple be the installation directory for the whole tool – which also contains all the agents anyway. This still allows you to make a copy of only some or even different version agents to another directory it you like. The default scenario however will be the simplest so that most users won’t even have to worry about possible complex things around this issue.

Then I added another thing. When launching a detail view of an agent’s state the window title will also display the collector name. This helps to identify which window is which if you have multiple similar windows open.

One negative point of all this is that it breaks compatibility with any previous version assemblies – since the some core interface changes were required. The new version editor can happily open previous version monitor pack files and save them in the new version format. The opposite is not possible though…

Anyway, happy monitoring

Another QuickMon update

Just a quick note to mention that I’ll be adding an Event Log collector soon to QuickMon. Although you can use EventScavenger combined with the SQL Query collector it might be a bit of an overkill for some people that just want to quickly add an alert based on some Event Log entries.

The focus for this collector in simplicity and it is not optimized to scan millions of Event Log entries each time it polls.

QuickMon Version 2.3 and Installers

I’ve now updated the QuickMon installers to include some ‘new’ functionality that allows you to choose to install the Windows service as part of the MSI installation.

There are still a few possible quirks – like what happens when you choose not to install the service initially (and do it manually afterwards) or when uninstalling the MSI (without removing the service manually) and then installing a new version ‘and then ‘choosing to install the service. In that case you get an error message that the service is already installed (duh as if you don’t know), the MSI Installer fails and rolls back completely. The solution (one of them) is to simply install the MSI and not choose to install/register the service in Service Manager.

Installers

I’ve learned a whole bunch of new ‘things’ about the standard VS installer during all of this. Mostly how limited the build-in Installer technology is but also some tweaks you can do to still (despite) get something good out of it.

Here is a few tips I came across:

1. When you add a ‘Checkboxes’ custom dialog to the ‘User Interface’ of the installer and want to use the checkbox value as a condition in one of the Custom Action it must look like this e.g: ‘CHKINSTALLSERVICE=1’  (without the quotes). I tried all kind of weird combinations like =”True”, =”1″ etc. that didn’t work…

2. You can have the MSI Installer call the ‘Installer’ classes housed inside your service project (and automatically install it) by adding a ‘Custom Action’ – ‘Install’ action. The default for it is to look for any installer classes inside the assembly. Similarly you can add the same for ‘Uninstall’ but this requires that the service has actually been installed (which is a problem for me since the user can choose not to install it at all)

3. Adding the “-install” and “-uninstall” parameters is nice and all but please remember to run it under an Administrator account (elevated) otherwise it simply fails with an “Access is denied” error. If you understand why then it seems obvious but for people that do not know about this it could be a pain (the error message does not tell you why ‘Access is denied…’)

4. The whole ‘backwards compatibility ID generation thing still baffles me. Upgraded projects (from VS2008 to VS2010) does not show it and the default on VS2010 is false. If not set it seems each time you install a newer version any copy of your shortcuts (like pinned to the taskbar) becomes ‘invalid. This is really a big pain (yes, it is probably easy enough to just unpin/pin again to fix it…)

5. The whole ‘Target platform’ thing is a mess – especially when the solution is under source control. Why do you have to check out the whole project just to change the Target platform setting to rebuild the MSI installer? Why is there not an option to build ‘both’ x86 and x64 at the same time (separate directories or something)?

6. Yes, using a better Installer tool like Wix will probably help… still need to learn how to use it. Anyone have some good tutorials somewhere? 🙂