I am developing a complex distributed service that performs an iterative synchronization process. It synchronizes every 10 seconds of a business entity in different information systems. One iteration consists of a bunch of third-party calls to retrieve the current state of business objects (the number of customers, products, certain customer and product data, etc.), query the local database, and then get the differences between them and smooth synchronization of this difference.
There are different types of iterations. They are fast (only changes in the set of objects) and slow iterations (full data validation). Fast every 10 seconds, and slow once a day.
So how can I log these processes using NLog? I use SQLite to store data. But I'm stuck in the design of the database for magazines.
So, I want to register the flow of each iteration: 1. Request the current state of objects for servicing 3d parties 2. Request a local database for the current state of objects 3. Get a list of differences 4. Call an external service to transfer insufficient data 5. Update the local database to obtain insufficient data.
But there are so many kinds of information to write, so I can’t just put it in one TEXT field.
I am currently using this structure for logs:
CREATE TABLE [Log] ( [id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [ts] TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, [iteration_id] varchar, [request_response_pair] varchar, [type] VARCHAR NOT NULL, [level] TEXT NOT NULL, [server_id] VARCHAR, [server_alias] VARCHAR, [description] TEXT, [error] Text);
Thus, each request and response of the service is placed in description and request_response_pair is the key that associates each response with each request.
Here is my NLog configurator:
<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" internalLogFile="D:\nlog.txt" internalLogLevel="Trace"> <targets> <target name="Database" xsi:type="Database" keepConnection="false" useTransactions="false" dbProvider="System.Data.SQLite.SQLiteConnection, System.Data.SQLite, Version=1.0.82.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" connectionString="Data Source=${basedir}\SyncLog.db;Version=3;" commandText="INSERT into Log(iteration_id, request_response_pair, type, level, server_id, server_alias, description, error) values(@Iteration_id, @Request_response_pair, @Type, @Loglevel, @server_id, @server_alias, @Description, @Error)"> <parameter name="@Type" layout="${message}"/> <parameter name="@Loglevel" layout="${level:uppercase=true}"/> <parameter name="@Request_response_pair" layout="${event-context:item=request_response_pair}"/> <parameter name="@Iteration_id" layout="${event-context:item=iteration_id}"/> <parameter name="@server_id" layout="${event-context:item=server_id}"/> <parameter name="@server_alias" layout="${event-context:item=server_alias}"/> <parameter name="@Description" layout="${event-context:item=description}"/> <parameter name="@Error" layout="${event-context:item=error}"/> </target> </targets> <rules> <logger name="*" minlevel="Trace" writeTo="Database" /> </rules> </nlog>
This is how I write:
namespace NLog { public static class LoggerExtensions { public static void InfoEx(this Logger l, string message, Dictionary<string, object> contextParams) { LogEventInfo eventInfo = new LogEventInfo(LogLevel.Info, "", message); foreach (KeyValuePair<string, object> kvp in contextParams) { eventInfo.Properties.Add(kvp.Key, kvp.Value); } l.Log(eventInfo); } public static void InfoEx(this Logger l, string message, string server_id, string server_alias, Dictionary<string, object> contextParams = null) { Dictionary<string, object> p = new Dictionary<string, object>(); p.Add("server_id", server_id); p.Add("server_alias", server_alias); if (contextParams != null) { foreach (KeyValuePair<string, object> kvp in contextParams) { p.Add(kvp.Key, kvp.Value); } } l.InfoEx(message, p); } } }
I know about logging levels, but I need all these detailed logs, so I am logging it as information. I cannot find any tutorial on how to write these complex, structured journals. Only simple dumb magazines.