.NET Logging Done Right: An Opinionated Approach Using Serilog - p-patel/software-engineer-knowledge-base GitHub Wiki
Goals of Good Logging / Intro to Serilog
Define Goals and Objectives, Introduce Serilog, Outline Course
-
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
Write a Global Logger as a Serilog Wrapper
- 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 the Global Logger
- 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 Performance Tracker
- 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
Logging with a Console App
- Add a console app project to try out new logging framework
- Add all types of logging types
Discussion: Exception Handling and Data Access
- 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)
Data Access Before Custom Exception Handling
- 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.
Creating an ADO.NET Stored Procedure Wrapper
- Log.Data project added
Global Logging: ASP.NET MVC and Web Forms
...
Global Logging: ASP.NET WebAPI
...
Global Logging: JavaScript/TypeScript
Introduction and Approach
- 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
Introducing a JavaScript Page on a MVC Website
Implementing a Logging API
- For calling code to see error response in a 500 response, add response header
Access-Control-Allow-Origin