In the past few days I have been working on validating the logging mechanics of an application we’re building at Info Support. One of the things I have to do is to assign event IDs to all the known error, warning and informational events in the application so we can capture those using Microsoft System Center Operations Manager.
A little bit of context
My job basically is to document all the signals (error events, info events, etc.) in Enterprise Architect and assign event IDs to them using a tagged property.
Next I have to make sure that our logging component writes the correct entries to the event log by attaching the documented event IDs to the correct logging statements in the code.
I’m using constants to identify the event IDs and use a small utility class to lookup the right resource in the resource file that contains the messages that go with each of the events.
You can imagine that documenting the events and applying them in code takes quite a lot of time.
There’s an app for that
Enterprise Architect luckily has a pretty neat repository format since it’s a (very cool) SQL server database which I can query to get the information I need. So I thought, what if I wrote a small utility that generates a class containing constants and a resource file from the events registered in a package in Enterprise Architect.
1: select t_objectproperties.Value as EventId,
2: t_object.Name as Name,
3: t_object.Note as Description
4: from t_objectproperties
5: join t_object on t_object.object_id = t_objectproperties.object_id and t_objectproperties.property = 'EventId'
6: join t_package on t_package.package_id = t_object.package_id and t_package.name = 'Events'
Getting the query to retrieve the right objects is pretty simple and generating the constants too. Generating resources however is a different story all together. Or so I thought …
1: using (ResXResourceWriter writer = new ResXResourceWriter(outputFileName))
2: {
3: foreach (var eventEntry in EventRepository.GetEvents().OrderBy(item => item.EventId))
4: {
5: string resourceName = String.Format(CultureInfo.InvariantCulture,
6: "Event{0}", eventEntry.EventId);
7:
8: ResXDataNode node = new ResXDataNode(resourceName, eventEntry.Description);
9: writer.AddResource(node);
10:
11: }
12:
13: writer.Generate();
14: writer.Close();
15: }
As it turns out there’s a little gem in the .NET Framework that allows one to generate resource files directly from code. Add all the resources you need, by creating new ResXDataNode instances and adding them to the resource writer. Once finished call Generate and you’re done.
Pretty cool ey ? Now to make a MSBuild task out of that so we can do it automatically in the nightly builds. Keeps the resources updated without me having to execute the utility manually.