Chronolap.Extensions.Logging
1.2.0
dotnet add package Chronolap.Extensions.Logging --version 1.2.0
NuGet\Install-Package Chronolap.Extensions.Logging -Version 1.2.0
<PackageReference Include="Chronolap.Extensions.Logging" Version="1.2.0" />
<PackageVersion Include="Chronolap.Extensions.Logging" Version="1.2.0" />
<PackageReference Include="Chronolap.Extensions.Logging" />
paket add Chronolap.Extensions.Logging --version 1.2.0
#r "nuget: Chronolap.Extensions.Logging, 1.2.0"
#:package Chronolap.Extensions.Logging@1.2.0
#addin nuget:?package=Chronolap.Extensions.Logging&version=1.2.0
#tool nuget:?package=Chronolap.Extensions.Logging&version=1.2.0
Chronolap
Advanced stopwatch library with lap tracking support for .NET developers.
Supported Frameworks
Features
- Lap tracking with configurable maximum lap count
- Measurement time recording (synchronous and asynchronous)
- Return value support in measurement methods
- Exception handling support (measurements are recorded even when exceptions occur)
- Pause / Resume functionality
- Advanced statistics (Min, Max, Mean, Median, Standard Deviation, Variance, Percentiles)
- Fastest/Slowest lap detection
- ILogger logging support
- OpenTelemetry Activity integration
- Configurable minimum lap count for statistics
- Cached total lap time calculation for optimal performance
Installation
Install via NuGet:
dotnet add package Chronolap
Usage
Basic Usage
using Chronolap;
using System;
using System.Threading;
class Program
{
static void Main()
{
var timer = new ChronolapTimer();
timer.Start();
Thread.Sleep(100);
timer.Lap("First lap");
Thread.Sleep(200);
timer.Lap("Second lap");
timer.Stop();
foreach (var lap in timer.Laps)
{
Console.WriteLine(lap);
}
}
}
Measurement with Return Values
var timer = new ChronolapTimer();
timer.Start();
// Measure and get return value
int result = timer.MeasureExecutionTime(() => CalculateValue(), "Calculation");
Console.WriteLine($"Result: {result}");
// Async measurement with return value
var data = await timer.MeasureExecutionTimeAsync(async () =>
{
return await FetchDataAsync();
}, "DataFetch");
Exception Handling
var timer = new ChronolapTimer();
timer.Start();
// Lap is recorded even if exception occurs
try
{
timer.MeasureExecutionTimeWithExceptionHandling(() =>
{
RiskyOperation();
}, "RiskyOperation");
}
catch (Exception ex)
{
// Lap was still recorded
Console.WriteLine($"Operation failed but timing was recorded");
}
// With return value
int? result = null;
try
{
result = timer.MeasureExecutionTimeWithExceptionHandling(() =>
{
return RiskyOperationWithReturn();
}, "RiskyOperation");
}
finally
{
// Timing is always recorded
}
Advanced Statistics
var timer = new ChronolapTimer();
timer.Start();
// Record multiple laps
for (int i = 0; i < 50; i++)
{
Thread.Sleep(10 + i);
timer.Lap($"Lap{i}");
}
// Calculate statistics
var min = timer.CalculateLapStatistic(LapStatisticsType.Min);
var max = timer.CalculateLapStatistic(LapStatisticsType.Max);
var mean = timer.CalculateLapStatistic(LapStatisticsType.ArithmeticMean);
var median = timer.CalculateLapStatistic(LapStatisticsType.Median);
var stdDev = timer.CalculateLapStatistic(LapStatisticsType.StandardDeviation);
var variance = timer.CalculateLapStatistic(LapStatisticsType.Variance);
// Calculate percentiles
var p50 = timer.CalculatePercentile(50); // Median
var p95 = timer.CalculatePercentile(95); // 95th percentile
var p99 = timer.CalculatePercentile(99); // 99th percentile
// Find fastest and slowest laps
var fastest = timer.GetFastestLap();
var slowest = timer.GetSlowestLap();
Console.WriteLine($"Fastest: {fastest?.Name} ({fastest?.Duration.TotalMilliseconds} ms)");
Console.WriteLine($"Slowest: {slowest?.Name} ({slowest?.Duration.TotalMilliseconds} ms)");
Configuration
// Configure maximum lap count and minimum lap count for statistics
var timer = new ChronolapTimer(
maxLapCount: 5000,
minimumLapCountForStatistics: 50
);
// Or change minimum lap count at runtime
timer.MinimumLapCountForStatistics = 100;
// Access configuration
Console.WriteLine($"Max Lap Count: {timer.MaxLapCount}");
Console.WriteLine($"Min Lap Count for Stats: {timer.MinimumLapCountForStatistics}");
Pause and Resume
var timer = new ChronolapTimer();
timer.Start();
Thread.Sleep(100);
timer.Lap("Before pause");
timer.Pause();
// Timer is paused, elapsed time won't increase
Thread.Sleep(1000); // This won't be counted
timer.Resume();
Thread.Sleep(200);
timer.Lap("After resume");
timer.Stop();
OpenTelemetry Activity Extensions Usage
You can easily integrate Chronolap lap timings with OpenTelemetry Activity by using the provided extension methods. These allow you to add lap duration tags directly to your active tracing activities.
Example
using System.Diagnostics;
using Chronolap;
using Chronolap.OpenTelemetry;
var activitySource = new ActivitySource("MyCompany.MyProduct.MyLibrary");
var timer = new ChronolapTimer();
using (var activity = activitySource.StartActivity("ExampleOperation"))
{
timer.Start();
// Perform some operations
// ...
timer.Lap("Initialization");
// Lap after initialization
timer.Lap("Processing");
// Lap after processing
timer.Stop();
// Add last lap duration as tag
activity.Lap("Processing", timer);
// Or export all lap durations as tags at once
activity.ExportAllLaps(timer);
}
Contributing
Contributions are welcome! Please open issues or pull requests.
What's New
v1.2.0 - Advanced Statistics, Performance Improvements & New Features
New Statistics Features:
- Min, Max, Variance statistics support
- Percentile calculation (P50, P95, P99, etc.)
- GetFastestLap() and GetSlowestLap() methods
- Configurable minimum lap count for statistics
Performance Improvements:
- Cached TotalLapTime calculation (O(1) instead of O(n))
- Configurable maximum lap count
New Measurement Features:
- Return value support in measurement methods
- Exception handling support (measurements recorded even when exceptions occur)
- Both synchronous and asynchronous variants
Configuration:
- MaxLapCount constructor parameter
- MinimumLapCountForStatistics property
ILogger Integration:
- Chronolap can now log lap results directly through ILogger
- Batch Logging: All laps can be logged at once in a clean format
- Customizable Formatting: Use the default format or provide your own custom formatter
- Log Level Support: Log laps at Debug, Information, Warning, or any other log level
Example - Logging Extension
var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
var logger = loggerFactory.CreateLogger<Program>();
var chrono = new ChronolapTimer();
chrono.Start();
Thread.Sleep(500);
chrono.Lap("First operation");
Thread.Sleep(700);
chrono.Lap("Second operation");
chrono.Stop();
logger.LogLaps(chrono, LogLevel.Information);
Output will looks like this;
info: Program[0]
Chronolap Results:
Lap 1: 00:00:00.5000000
Lap 2: 00:00:01.2000000
Support
If you find this project useful, consider supporting me:
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Chronolap (>= 1.2.0)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.6)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.