Ao.Logging
Ao.Logging
The Ao.Logging
namespace contains classes that support the logging of data into text files. I have been using them in field test applications mostly for debugging purposes and logging status and diagnostic information from vehicle components.
Session
The Session
class represents a folder containing a set of log files. The SessionRoot
class represents a folder containing a set of sessions. It also provides a means to create new sessions.
var SR = new SessionRoot("C:\\logs");
var S = SR.CreateSession("first-session");
Console.WriteLine(S.Path);
C:\logs\first-session
Additionally, there is a parameter-less overload of the CreateSession()
method, that creates a folder name from the current timestamp. This is useful in order to enable the user to create several sessions subsequently in a field test, without the need to name each one explicitly.
var S = SR.CreateSession();
Console.WriteLine(S.Path);
C:\logs\2022-07-01-14-20-22
Log
The Log
class facilitates the logging and manages log files. Especially, it contains a simple mechanism to reduce the actual number of file accesses, as these can be a bottleneck for an application. The class’s constructor requires a path to a folder where to store all the log files, for which the Session
class can be used.
var L = new Log(S.Path);
The log must be started and stopped explicitly.
L.Start();
This is for two important reasons.
First, in common scenarios, data to be logged is arriving continuously, while logging that data may be required only for a couple of minutes. From a software engineering point of view, it is much easier to simply ignore incoming data that need not be logged, instead of shutting down the data source. This is, what the Log
object does, if it is not started.
Second, in some scenarios, it is desirable to simultaneously log data to different folders. A LogControl
object can be used for this purpose. Actually, such a control is used under the hood of every Log
object. It synchronizes logging with several logs in a thread-safe fashion.
var LC = new LogControl();
var L1 = new Log("folder1", LC);
var L2 = new Log("folder2", LC);
L1.Start();
Console.WriteLine(L1.Running);
Console.WriteLine(L2.Running);
True
True
Logging data is straightforward. The Log
class contains a single method, that adds a line to a file.
L.Add("file1.txt", "Line 1.");
L.Add("file1.txt", "Line 2.");
L.Add("file1.txt", "Line 3.");
L.Add("subfolder/data.csv", "2022-07-01-14-25-00;1.23");
L.Add("subfolder/data.csv", "2022-07-01-14-25-02;1.24");
L.Add("subfolder/data.csv", "2022-07-01-14-25-04;1.21");
The Log
class is not sealed. Hence, it can be subclassed in order to provide more convenient alternatives to the Add()
method. Another option is to define extension methods.
public static void AddTimestamp(this Log L, string fileName, DateTime t)
{
L.Add(fileName, t.ToString("yyyy-MM-dd-HH-mm-ss"));
}
L.AddTimestamp("timestamps.txt", DateTime.Now);
As mentioned above, the Log
class reduces the number of actual file accesses. That is, it keeps an added line in memory, instead of immediately updating the respective file. Only when a larger number of lines has been added, these will be bulk-added to the file. The threshold can be set for each Log
object individually and defaults to 10,000.
L.FileLineBufferSize = 2000;
Of course, all cached lines will be written to their respective files, when logging is stopped.
L.Stop();