Click here to Skip to main content
15,348,645 members

Dominic Burford - Professional Profile


Follow on Twitter LinkedIn      Blog RSS
I am a professional software engineer and technical architect with over twenty years commercial development experience with a strong focus on the design and development of web and mobile applications.

I have experience of architecting scalable, distributed, high volume web applications that are accessible from multiple devices due to their responsive web design, including architecting enterprise service-oriented solutions. I have also developed enterprise mobile applications using Xamarin and Telerik Platform.

I have extensive experience using .NET, ASP.NET, Windows and Web Services, WCF, SQL Server, LINQ and other Microsoft technologies. I am also familiar with HTML, Bootstrap, Javascript (inc. JQuery and Node.js), CSS, XML, JSON, Apache Cordova, KendoUI and many other web and mobile related technologies.

I am enthusiastic about Continuous Integration, Continuous Delivery and Application Life-cycle Management having configured such environments using CruiseControl.NET, TeamCity and Team Foundation Services. I enjoy working in Agile and Test Driven Development (TDD) environments.

Outside of work I have two beautiful daughters. I am also an avid cyclist who enjoys reading, listening to music and travelling.



Weekly Data. Recent events may not appear immediately. For information on Reputation please see the FAQ.


Members need to achieve at least one of the given member levels in the given reputation categories in order to perform a given action. For example, to store personal files in your account area you will need to achieve Platinum level in either the Author or Authority category. The "If Owner" column means that owners of an item automatically have the privilege. The member types column lists member types who gain the privilege regardless of their reputation level.

ActionAuthorAuthorityDebatorEditorEnquirerOrganiserParticipantIf OwnerMember Types
Have no restrictions on voting frequencysilversilversilversilver
Bypass spam checks when posting contentsilversilversilversilversilversilvergoldSubEditor, Mentor, Protector, Editor
Store personal files in your account areaplatinumplatinumSubEditor, Editor
Have live hyperlinks in your profilebronzebronzebronzebronzebronzebronzesilverSubEditor, Protector, Editor
Have the ability to include a biography in your profilebronzebronzebronzebronzebronzebronzesilverSubEditor, Protector, Editor
Edit a Question in Q&AsilversilversilversilverYesSubEditor, Protector, Editor
Edit an Answer in Q&AsilversilversilversilverYesSubEditor, Protector, Editor
Delete a Question in Q&AYesSubEditor, Protector, Editor
Delete an Answer in Q&AYesSubEditor, Protector, Editor
Report an ArticlesilversilversilversilverSubEditor, Mentor, Protector, Editor
Approve/Disapprove a pending ArticlegoldgoldgoldgoldSubEditor, Mentor, Protector, Editor
Edit other members' articlesSubEditor, Protector, Editor
Create an article without requiring moderationplatinumSubEditor, Mentor, Protector, Editor
Approve/Disapprove a pending QuestionProtector
Approve/Disapprove a pending AnswerProtector
Report a forum messagesilversilverbronzeProtector, Editor
Approve/Disapprove a pending Forum MessageProtector
Have the ability to send direct emails to members in the forumsProtector
Create a new tagsilversilversilversilver
Modify a tagsilversilversilversilver

Actions with a green tick can be performed by this member.

GeneralBlog updates Pin
Dominic Burford13-May-21 1:37
professionalDominic Burford13-May-21 1:37 
GeneralPublishing events into an ASP.NET Core webhook with Octopus Pin
Dominic Burford13-May-21 1:33
professionalDominic Burford13-May-21 1:33 
GeneralA quick update Pin
Dominic Burford2-Nov-20 8:33
professionalDominic Burford2-Nov-20 8:33 
GeneralHow do you know when it's time to move on? Pin
Dominic Burford19-Aug-20 0:19
professionalDominic Burford19-Aug-20 0:19 
GeneralInitial thoughts on deploying with Octopus Pin
Dominic Burford17-Aug-20 4:25
professionalDominic Burford17-Aug-20 4:25 
GeneralWhat makes for a good DevOps process? Pin
Dominic Burford5-Aug-20 23:00
professionalDominic Burford5-Aug-20 23:00 
GeneralExecuting async code from non async code Pin
Dominic Burford19-Jul-20 23:21
professionalDominic Burford19-Jul-20 23:21 
GeneralPassing dynamic queries between client and backend server Pin
Dominic Burford29-Jun-20 4:55
professionalDominic Burford29-Jun-20 4:55 
GeneralManaging your Azure resources using Powershell scripting Pin
Dominic Burford13-Mar-20 6:42
professionalDominic Burford13-Mar-20 6:42 
GeneralIntroduction to Azure Cognitive Search Pin
Dominic Burford28-Feb-20 5:39
professionalDominic Burford28-Feb-20 5:39 
GeneralUpdating the version number in your .NET build pipeline Pin
Dominic Burford24-Feb-20 5:33
professionalDominic Burford24-Feb-20 5:33 
GeneralFinding a solution to an Azure web app deployment problem Pin
Dominic Burford23-Jan-20 23:51
professionalDominic Burford23-Jan-20 23:51 
GeneralStructured Logging Pin
Dominic Burford24-Dec-19 1:28
professionalDominic Burford24-Dec-19 1:28 
When I first began writing the ASP.NET WebAPI services for our vehicle telemetry tracking, it was a small project with only a few controllers. The log data that was generated was small in volume and I would query the logs with relative ease. Fast forward to today (over 3 years later), and the ASP.NET WebAPI project now contains services that are consumed by our mobile app, web apps, licence and MOT checking apps etc. Basically, the project has grown substantially since I first created it.

At the time that I first wrote the ASP.NET WebAPI services, I investigated many of the logging frameworks that were targeted for the the .NET Framework at the time. I looked at Log4Net, NLog and Elmah. They all looked feature rich and customisable, but in the end I rolled my own logging framework. My requirements at the time were quite simple as were the sizes of the log data that would be generated. So I rolled a simple logging framework that would meet my requirements.

The log data that is generated today can get very large, and querying it can be time consuming. A single build can load 10k rows of log data. We have console apps, mobile apps and web apps all running on a daily basis that also contribute to the volume of log data that is generated. It is not uncommon to have 100s of thousands of log entries created each day. Trying to diagnose a problem with so much data to query is not always a simple task. This is where structured logging comes into play.

What is structured logging?

Log data is often comprised of log messages. These log messages are unstructured strings of text. Diagnosing an error entails searching through these text strings looking for the information that we need.

Typical log messages might look something like this.
INFORMATION - 2019-12-24 - This is a log message
ERROR - 2019-12-24 - Something went wrong
INFORMATION - 2019-12-24 - This is another log message
Such unstructured data makes it difficult to query for useful information. As a developer it would be really helpful to be able to query and filter your log data. For example to query log data by a specific date, customer, log entry type etc. The goal behind structured logging is to solve this problem. The aim of structured logging is to bring structure to unstructured data to allow it be usefully queried and filtered to find the information you need in a timely manner. For log data to be queried and filtered requires the data to be mapped into a format that allows this e.g. XML and JSON would be ideal candidates.

What was clear was that my initial logging framework was no longer fit for purpose. The volumes of log data being created each day were getting increasingly larger, and I was no longer able to query the data in a sensible and timely manner. That's when I came across the notion of structured logging. After much reading around and looking at other frameworks that supported this, I decided that I would update my own logging framework rather than employ one of the .NET logging frameworks (again). Although the frameworks mentioned earlier all now provide support for structured logging, SeriLog seems to be the preferred choice due it having provided support from the very beginning (whereas the others have provided support after the fact). The reason for updating my own logging framework rather than using one of the 3rd party ones was that I had already invested a lot of time and effort into my own framework, and it would probably be more straight forward to update what was already there than to start again with a new logging framework.

How have I implemented structured logging?

I have added a new column to my log table. Previously my log table consisted of a log message column that would contain text strings (as in the examples given previously). All the key information would be contained within the log message as in the following example.
INFORMATION - 2019-12-24 - User Joe has logged onto the system
The user name 'Joe' is what I would be looking for in the log message. As can be seen it is part of the log message itself. With structured logging all such information is now stored in JSON (other formats are available). My log table is composed of the following columns - with the Properties column storing the structured logging data in JSON format.

2019-12-24 10:45

User has logged onto the system

{ "username": "Joe" }
N.B. one added benefit of rolling my own logging framework is that I can implement as many log types (the column LogTypes in the above example) as I need (I currently have ERROR, INFORMATION, EXCEPTION, DEBUG). I have a .config setting that allows me to switch the DEBUG log data on or off. Currently I have this set to ON for my unit test projects and OFF for production.

The biggest challenge was not so much updating my logging framework to implement structured logging, but to update all the areas of the code where I am sending output to the log (which is everywhere). I am still currently in the process of doing this.

The signature for my log message method looks like this.
protected void LogMessage(string message, LogLevelTypes loglevel, Dictionary<string, string> properties = null)
  //write the log entry to the log table
The LogLevelTypes is an enum containing the values ERROR, EXCEPTION, INFORMATION and DEBUG. The structured log data is passed to my method as a Dictionary of key-value pairs. The Dictionary is then serialised before being sent to the log table.

With your log data now stored in a structured format, you are able to utilise one of the many different tools that are available for viewing structured logging data e.g. Prefix from Stackify[^]

I haven't yet got round to investigating any of the tools available for viewing structured data, but when I do I will be sure to write an article about it on here. Until then, have a Merry Christmas and a Happy New Year.
"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult." - C.A.R. Hoare

Home | LinkedIn | Google+ | Twitter

GeneralEnabling TLS 1.2 on your .NET application Pin
Dominic Burford11-Dec-19 23:11
professionalDominic Burford11-Dec-19 23:11 
GeneralThe new version of the app is (almost) ready for release Pin
Dominic Burford7-Nov-19 23:28
professionalDominic Burford7-Nov-19 23:28 
GeneralChunking your lists into multiple smaller lists Pin
Dominic Burford11-Sep-19 3:40
professionalDominic Burford11-Sep-19 3:40 
GeneralWriting flexible filters for your data using Predicates Pin
Dominic Burford16-Jul-19 6:11
professionalDominic Burford16-Jul-19 6:11 
GeneralRe: Writing flexible filters for your data using Predicates Pin
Slacker00716-Jul-19 22:09
professionalSlacker00716-Jul-19 22:09 
GeneralRe: Writing flexible filters for your data using Predicates Pin
Dominic Burford17-Jul-19 1:17
professionalDominic Burford17-Jul-19 1:17 
GeneralBlocking Asynchronous Code Pin
Dominic Burford4-Jul-19 22:11
professionalDominic Burford4-Jul-19 22:11 
GeneralDesigning and implementing flexible RESTful services Pin
Dominic Burford14-Jun-19 0:50
professionalDominic Burford14-Jun-19 0:50 
GeneralWriting asynchronous code with .NET Pin
Dominic Burford10-Jun-19 3:34
professionalDominic Burford10-Jun-19 3:34 
GeneralWeird Minification Behaviour in ASP.NET Core Pin
Dominic Burford28-May-19 3:54
professionalDominic Burford28-May-19 3:54 
GeneralThe Importance of Structure and Dilligence Pin
Dominic Burford24-May-19 6:14
professionalDominic Burford24-May-19 6:14 
GeneralWhen should you rewrite that legacy application? Pin
Dominic Burford22-May-19 0:03
professionalDominic Burford22-May-19 0:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.