Bodoconsult.Core.App
Autor: Bodoconsult EDV-Dienstleistungen GmbH Robert Leisner
Nuget package
https://www.nuget.org/packages/Bodoconsult.Core.Charting/
Github repository
https://github.com/RobertLeisner/Bodoconsult.Core.App
About the library Bodoconsult.Core.App
What does the library
Bodoconsult.Core.App is a library with basic functionality for multilayered monolithic applications like database based client server apps. It delivers the following main functionality:
- Single-threaded high-performance logging for single-threaded or multi-threaded environments (IAppLoggerProxy / AppLoggerProxy )
- Basic watchdog implementation IWatchDog / WatchDog as replacement for timers for non-time critical tasks
- Infrastructure for handling event counts for application performance measurement (IAppEventSource / AppEventSource)
- Using PerformanceCounters to log application performance metrics (IPerformanceLogger / PerformanceLogger and IPerformanceLoggerManager / PerformanceLoggerManager)
How to use the library
The source code contains NUnit test classes the following source code is extracted from. The samples below show the most helpful use cases for the library.
IAppLoggerProxy / AppLoggerProxy
AppLoggerProxy is a high performance logger infrastructure for multithreaded and or multitasked apps. Log entries are stored to a intermediate queue and then processed on a single thread during app runtime using a IWatchdog implementation. This avoids file access errors resulting from different threads trying to access the destinantion log at the same time.
Using log4net as logger
If you want to use log4net for logging you can use the Log4NetLoggerFactory.
var logger = new AppLoggerProxy(new Log4NetLoggerFactory.());
_log.LogWarning("Hallo");
You can configure the logger with a log4net.config file in the project main folder. See log4net documentation for details.
Fake logger for unit tests
For unit tests you can use a fake implementation of a logger. It logs to the output window only.
var logger = new AppLoggerProxy(new FakeLoggerFactory());
_log.LogWarning("Hallo");
IWatchDog / WatchDog
WatchDog is a replacement for timers. Timers do have the potential issue with multiple runnings tasks if tasks may run longer than the timer interval. So if your timer task will potentially run longer then the timer interval you should think about using IWatchDog implementations.
The runner method is fired and processed until done. Then the watchdog waits for the delay interval until it restarts the runner method.
For time critical tasks WatchDog is not a good solution. If you have to ensure that your task is running i.e. every minute exactly, you better should use a Timer.
The runner method is running always on the same separated background thread.
WatchDogRunnerDelegate runner = Runner;
var w = new WatchDog(runner, delayTime);
w.StartWatchDog();
...
w.StopWatchDog();
/// <summary>
/// Runner method for the watchdog
/// </summary>
private void Runner()
{
// Do your tasks here
}
IAppEventSource / AppEventSource
Event counters are a platform independent feature of .NET to implement application performance measurement. For basic information on ecvent counters see Microsoft: basics on event counters.
The implementations of IAppEventSource like AppEventSource deliver basic infrastructure for adding event counters to an app as easily as possible.
To define event counters for your app implement one or more IEventSourceProvider based instances an load them into IAppEventSource implementations via IAppEventSource.AddProvider. Using multiple providers is recommend if your requires certain event counters only under certain circumstances.
As example see the implemtation of the BusinessTransactionEventSourceProvider:
/// <summary>
/// Provider for business transaction management relevante event counters
/// </summary>
public class BusinessTransactionEventSourceProvider: IEventSourceProvider
{
public const string BtmRunBusinessTransactionSuccess = "Btm.RunBusinessTransaction.Success";
public const string BtmRunBusinessTransactionDuration = "Btm.RunBusinessTransaction.Duration";
/// <summary>
/// Add <see cref="EventCounter"/> to the event source
/// </summary>
/// <param name="eventSource">Current event source</param>
public void AddEventCounters(AppApmEventSource eventSource)
{
CreateBtRunTransactionDurationEventCounter(eventSource);
}
private void CreateBtRunTransactionDurationEventCounter(AppApmEventSource eventSource)
{
var ec = new EventCounter(BtmRunBusinessTransactionDuration, eventSource);
ec.DisplayName = "Business transaction duration";
ec.DisplayUnits = "ms";
eventSource.EventCounters.Add(BtmRunBusinessTransactionDuration, ec);
}
/// <summary>
/// Add <see cref="IncrementingEventCounter"/> to the event source
/// </summary>
/// <param name="eventSource">Current event source</param>
public void AddIncrementingEventCounters(AppApmEventSource eventSource)
{
CreateRunBtSuccessIncrementEventCounter(eventSource);
}
private void CreateRunBtSuccessIncrementEventCounter(AppApmEventSource eventSource)
{
var ec = new IncrementingEventCounter(BtmRunBusinessTransactionSuccess, eventSource);
ec.DisplayName = "Business transaction running successfully";
ec.DisplayUnits = "runs";
eventSource.IncrementingEventCounters.Add(BtmRunBusinessTransactionSuccess, ec);
}
/// <summary>
/// Add e<see cref="PollingCounter"/> to the event source
/// </summary>
/// <param name="eventSource">Current event source</param>
public void AddPollingCounters(AppApmEventSource eventSource)
{
// Do nothing
}
/// <summary>
/// Add <see cref="IncrementingPollingCounter"/> to the event source
/// </summary>
/// <param name="eventSource">Current event source</param>
public void AddIncrementingPollingCounters(AppApmEventSource eventSource)
{
// Do nothing
}
}
IPerformanceLogger / PerformanceLogger
The IPerformanceLogger implementations read performance counters and provide them as formatted string. PerformanceLogger class read main event counters provided by .NET runtime.
// Arrange
var logger = new PerformanceLogger();
// Act
var s = logger.GetCountersAsString();
// Assert
Assert.IsFalse(string.IsNullOrEmpty(s));
Debug.Print(s);
IPerformanceLoggerManager / PerformanceLoggerManager
The IPerformanceLoggerManager implementations are intended to fetch performance counter data from IPerformanceLogger implementations in a scheduled manner and provide it as string to a delegate for further usage like logging.
var logger = new PerformanceLogger();
var manager = new PerformanceLoggerManager(logger)
{
StatusMessageDelegate = StatusMessageDelegate
};
Assert.IsNotNull(manager);
Assert.IsNotNull(manager.PerformanceLogger);
// Act
manager.StartLogging();
IBusinessTransactionManager / IBusinessTransactionManager
A business transaction is defined here as an external call for a certain functionality of an app by a UI client, webservice or any other client of the app. IBusinessTransactionManager is intended as central point for inbound business transactions for the app.
IBusinessTransactionManager delivers central features like logging and performance measurement for business transaction.
ToDo: add more information
IExceptionReplyBuilder / ExceptionReplyBuilder
ExceptionReplyBuilder delivers a central exception management to be used standalone or in conjunction with business transactions.
ToDo: add more information
About us
Bodoconsult http://www.bodoconsult.de is a Munich based software company from Germany.
Robert Leisner is senior software developer at Bodoconsult. See his profile on http://www.bodoconsult.de/Curriculum_vitae_Robert_Leisner.pdf.