-
Notifications
You must be signed in to change notification settings - Fork 1
.NET Logging Done Right: An Opinionated Approach Using Serilog
Pritesh Patel edited this page Aug 15, 2019
·
2 revisions
-
Logging of consistent data
-
Keep business logic clear of logging
-
Include logging in applications developed from a variety of languages ...
-
Analyse logging using SQL-based querying and gain out of the box insights from Kibana dashboard
- Good logging for rapid troubleshooting, feature usage analysis and performance monitoring to profile well and badly performing features
- Types of log entries: feature usage, performance entries, error details, diagnostic/debug entries (used for ad-hoc debugging entries at run-time)
- Information to log: where from? product, layer, location, hostname; who? user (role, permissions), customer (the customer logged in or represented); what else? time spent, parameters, browser
- Serilog - structured data logging; lots of sinks (a place to which logs can be written - text files, sql/nosql, splunk/seq); 6 log levels
- Leveraging Serilog - one logger per type - usage, performance, errors, diagnostics; different sinks based on type; easier consumption by developers, levels still available if needed
- Demo - add Serilog, create a class with 4 loggers, add a class to define info to be logged, add a special class to track performance, verify with a console app
- Create library project in solution
- Include Serilog and Serilog.Sinks.File nuget packages in project
- Create a class to define the data being logged based on the Information to log defined in previous section
- Create a class that defines methods for each of the 4 loggers (inc. conditional diagnostics logging based on config key in web/app.config). Set log level for each logger as required.
- add a separate PeformanceTracker class with private fields StopWatch and the log data definition class
- define constructor that calls
_sw = StopWatch.StartNew(), accepts data to populate the data class definition and adds a 'Started' key with a datetime stamp value to the log data's Additionalnfo object dictionary - a second constructor overload calls the first constructor and any items in the additional object dictionary parameters to AdditionalInfo
- add a Stop() method that calls
_sw.Stop()and sets the log data definition's ElapsedMilliseconds field with _sw.ElapsedMilliseconds before writing the performance log using the logger class created in the previous section
- Add a console app project to try out new logging framework
- Add all types of logging types
- Use global exception handlers - keep the business logic code clean
- Add additional exception handlers where they can add logic to provide improved behaviour when an exception occurs or to add more information for logging (e.g. parameter values for stored procs)
- Calling the stored proc using ADO.NET, Dapper and Entity Framework with a string parameter value that is too long for the db field will raise exceptions in all three instances which can be handled and logged using the existing logging framework. However the exception in each case does not contain the actual stored proc parameter values - this will be changed next.
- Log.Data project added
...
...
- Implications/Considerations: logging is done vai API call which timestamp - caller or API? security for calls - use CORS or bearer token? also works for Xamarin/Mobile, non .NET applications
- Types of Log Entries: JavaScript usage, performance, error, diagnostic ad-hoc logging when mixed with server-side apps (as server-side logging will already be logging some areas of the system)
- Information to Log: JavaScript Where From? Product = ToDo, Layer = JsClient, Location = window.location, Hostname = N/A * Who is in play? User = Logged in What else? Time spent, Parameters
- For calling code to see error response in a 500 response, add response header
Access-Control-Allow-Origin