In my opinion, a large part of being a good developer is ensuring the applications you build are maintainable and easy to debug both during development and after deployment. This becomes even more important if you work in the enterprise with plethora of complicated interdependent systems deployed regularly and the army of people constantly making changes to it; In such environments tasks such as maintaining, troubleshooting and monitoring the system is of tremendous value.

Unless all you build are HelloWorld applications which never get deployed anywhere you almost certainly have come across cases where either you or your support team have had to figure out:

  • What is causing that OutOfMemory exception?
  • Why is there such a performance degradation after the last release?
  • Why is the DLL I have referenced not doing what it is supposed to?
  • What system is my app running in?
  • What arguments the app has started with?
  • What version of JSON.NET is the app using?

Over the years I have found myself and my colleagues spending precious time trying to deal with finding the answers to such questions over and over again particularly at times where there are production issues and downtime could cost the business a lot of money. So today I have decided to share with you a helper class I built a while back which can help answer such questions more proactively. The idea is to log the report generated by this class at the start of your application and if required on demand or at certain intervals.

The class is very simple to use and currently supports Windows, Linux and OSX:

DiagnosticReport report = DiagnosticReport.Generate();
Console.WriteLine(report.ToString());

Which then generates a report that looks like:

/
|Diagnostic Report generated at: 13-11-2017 18:14:41.174 (+00:00) in: 849.7042 milliseconds.
|
|System|..................................................................
|
|    . OS - Name         : Microsoft Windows 10.0.14393
|    . OS - Type         : Windows (Server)
|    . OS - 64Bit        : True
|    . CLR Runtime       : .NET Framework 4.7.2110.0
|    . Machine Name      : MyServer.
|    . FQDN              : MyServer
|    . User              : MyServer\admin
|    . CPU               : Intel(R) Xeon(R) CPU E5-2673 v3 @ 2.40GHz
|    . CPU Core Count    : 2
|    . Installed RAM     : 16GB
|    . System Directory  : C:\Windows\system32
|    . Current Directory : C:\Users\admin\SampleApp
|    . Runtime Directory : C:\Windows\Microsoft.NET\Framework64\v4.0.30319\
|    . Uptime            : 20Day 12Hour 00Min 08Sec
|
|Process|......................................................................................................
|
|    . Id                  : 348
|    . Name                : LINQPad.UserQuery
|    . Started             : 13-11-2017 18:13:18.161 (+00:00)
|    . Loaded In           : 00:01:23.1225614
|    . Interactive         : True
|    . Optimized           : True
|    . 64Bit Process       : True
|    . Server GC           : True
|    . Large Address Aware : True
|    . WorkingSet          : 42MB
|    . Threads             : 88
|    . IO Threads          : 24 <-> 1,000
|    . Worker Threads      : 24 <-> 32,767
|    . File Version        : 1.0.0.0
|    . Product Version     : 1.0.0.0
|    . Language            : Language Neutral
|    . Copyright           : Copyright © Nima Ara 2017
|    . Original File Name  : LINQPad.UserQuery.exe
|    . File Name           : C:\Users\admin\AppData\Local\LINQPad\ProcessServer5AnyCPUB\LINQPad.UserQuery.exe
|    . Module Name         : LINQPad.UserQuery.exe
|    . Module File Name    : C:\Users\admin\AppData\Local\LINQPad\ProcessServer5AnyCPUB\LINQPad.UserQuery.exe
|    . Product Name        : A Sample Query
|    . CommandLine         : C:\Users\admin\AppData\Local\LINQPad\ProcessServer5AnyCPUB\LINQPad.UserQuery.exe
|                            C:/Program Files/LINQPad5/LINQPad.EXE
|                            C:/Program Files/LINQPad5/
|                            C:/Program Files/LINQPad5/LINQPad.config
|                            LINQPad.ivddgmnj.Server.2
|                            ivddgmnj
|                            4328
|                            True
|
|Drives|.......................................................................................
|
|     -----------------------------------------------------------------------------------------
|    | Name | Type      | Format | Label             | Capacity(GB) | Free(GB) | Available(GB) |
|    |------|-----------|--------|-------------------|--------------|----------|---------------|
|    | A:\  | Removable |        |                   | 0            | 0        | 0             |
|    | C:\  | Fixed     | NTFS   |                   | 127          | 108      | 108           |
|    | D:\  | Fixed     | NTFS   | Temporary Storage | 14           | 13       | 13            |
|    | E:\  | CDRom     |        |                   | 0            | 0        | 0             |
|     -----------------------------------------------------------------------------------------
|
|Assemblies|........................................................................................................................................
|
|    001| Name      : mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscorlib.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/mscorlib.dll
|
|    002| Name      : System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
|
|    003| Name      : System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
|
|    004| Name      : System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
|
|    005| Name      : System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
|
|    006| Name      : System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
|
|    007| Name      : System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
|
|    008| Name      : System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml.Linq\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.Linq.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml.Linq/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.Linq.dll
|
|    009| Name      : System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Data.Linq\v4.0_4.0.0.0__b77a5c561934e089\System.Data.Linq.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Data.Linq/v4.0_4.0.0.0__b77a5c561934e089/System.Data.Linq.dll
|
|    010| Name      : System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_64\System.Data\v4.0_4.0.0.0__b77a5c561934e089\System.Data.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_64/System.Data/v4.0_4.0.0.0__b77a5c561934e089/System.Data.dll
|
|    011| Name      : Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
|       . GAC       : True
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.CSharp\v4.0_4.0.0.0__b03f5f7f11d50a3a\Microsoft.CSharp.dll
|       . CodeBase  : file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/Microsoft.CSharp/v4.0_4.0.0.0__b03f5f7f11d50a3a/Microsoft.CSharp.dll
|
|    012| Name      : LINQPad, Version=1.0.0.0, Culture=neutral, PublicKeyToken=21353812cd2a2db5
|       . GAC       : False
|       . 64Bit     : True
|       . Optimized : False
|       . Framework : .NETFramework,Version=v4.5.2
|       . Location  : C:\Program Files\LINQPad5\LINQPad.exe
|       . CodeBase  : file:///C:/Program Files/LINQPad5/LINQPad.EXE
|
|    013| Name      : LINQPad.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=21353812cd2a2db5
|       . GAC       : False
|       . 64Bit     : True
|       . Optimized : False
|       . Framework : .NETFramework,Version=v4.5.2
|       . Location  :
|       . CodeBase  : file:///C:/Program Files/LINQPad5/LINQPad.exe
|
|    014| Name      : query_viulpd, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|       . GAC       : False
|       . 64Bit     : True
|       . Optimized : False
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Users\admin\AppData\Local\Temp\2\LINQPad5\_tqnmweww\query_viulpd.dll
|       . CodeBase  : file:///C:/Users/admin/AppData/Local/Temp/2/LINQPad5/_tqnmweww/query_viulpd.dll
|
|    015| Name      : Easy.Common, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|       . GAC       : False
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NETFramework,Version=v4.5
|       . Location  : C:\Users\admin\AppData\Local\Temp\2\LINQPad5\_tqnmweww\shadow_ebuhxn\easy.common.dll
|       . CodeBase  : file:///C:/Users/admin/AppData/Local/Temp/2/LINQPad5/_tqnmweww/shadow_ebuhxn/easy.common.dll
|
|    016| Name      : System.Runtime.InteropServices.RuntimeInformation, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
|       . GAC       : False
|       . 64Bit     : True
|       . Optimized : True
|       . Framework : .NET 2, 3 or 3.5
|       . Location  : C:\Users\admin\AppData\Local\Temp\2\LINQPad5\netstandard2\System.Runtime.InteropServices.RuntimeInformation.dll
|       . CodeBase  : file:///C:/Users/admin/AppData/Local/Temp/2/LINQPad5/netstandard2/System.Runtime.InteropServices.RuntimeInformation.dll
|
|Environment-Variables|..................................................................................................................................................................................................
|
|    001. ALLUSERSPROFILE           : C:\ProgramData
|    002. APPDATA                   : C:\Users\admin\AppData\Roaming
|    003. CLIENTNAME                : SomeClient
|    004. CommonProgramFiles        : C:\Program Files\Common Files
|    005. CommonProgramFiles(x86)   : C:\Program Files (x86)\Common Files
|    006. CommonProgramW6432        : C:\Program Files\Common Files
|    007. COMPUTERNAME              : MyServer
|    008. ComSpec                   : C:\Windows\system32\cmd.exe
|    009. HOMEDRIVE                 : C:
|    010. HOMEPATH                  : \Users\admin
|    011. LOCALAPPDATA              : C:\Users\admin\AppData\Local
|    012. LOGONSERVER               : \\MyServer
|    013. NUMBER_OF_PROCESSORS      : 2
|    014. OS                        : Windows_NT
|    015. Path                      : C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\LINQPad5;C:\Users\admin\AppData\Local\Microsoft\WindowsApps;
|    016. PATHEXT                   : .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
|    017. PROCESSOR_ARCHITECTURE    : AMD64
|    018. PROCESSOR_IDENTIFIER      : Intel64 Family 6 Model 63 Stepping 2, GenuineIntel
|    019. PROCESSOR_LEVEL           : 6
|    020. PROCESSOR_REVISION        : 3f02
|    021. ProgramData               : C:\ProgramData
|    022. ProgramFiles              : C:\Program Files
|    023. ProgramFiles(x86)         : C:\Program Files (x86)
|    024. ProgramW6432              : C:\Program Files
|    025. PSModulePath              : C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules;C:\Program Files\Microsoft Monitoring Agent\Agent\PowerShell\
|    026. PUBLIC                    : C:\Users\Public
|    027. SESSIONNAME               : RDP-Tcp#58
|    028. SystemDrive               : C:
|    029. SystemRoot                : C:\Windows
|    030. TEMP                      : C:\Users\admin\AppData\Local\Temp\2
|    031. TMP                       : C:\Users\admin\AppData\Local\Temp\2
|    032. USERDOMAIN                : MyServer
|    033. USERDOMAIN_ROAMINGPROFILE : MyServer
|    034. USERNAME                  : admin
|    035. USERPROFILE               : C:\Users\admin
|    036. windir                    : C:\Windows
|
|Networks|.....................................................................
|
|    . Windows IP Configuration
|      -------------------------
|      | Host               : MyServer
|      | Domain             :
|      | DHCP Scope         :
|      | Node Type          : Hybrid
|      | Is WINS Proxy      : False
|
|    . Microsoft Hyper-V Network Adapter #2
|      -------------------------------------
|      | Name               : Ethernet 2
|      | MAC                : 00:0D:3B:A3:D6:AC
|      | Type               : Ethernet
|      | Status             : Up
|      | Supports Multicast : True
|      | Is Receive Only    : False
|      | Speed              : 10,000 Mbit/s
|      | IP Addresses       : [1.2.3.4]
|
|    . Software Loopback Interface 1
|      ------------------------------
|      | Name               : Loopback Pseudo-Interface 1
|      | MAC                :
|      | Type               : Loopback
|      | Status             : Up
|      | Supports Multicast : True
|      | Is Receive Only    : False
|      | Speed              : 1,073 Mbit/s
|
|    . Microsoft ISATAP Adapter #2
|      ----------------------------
|      | Name               : isatap.MyServer.a8.internal.cloudapp.net
|      | MAC                : 00:00:00:00:00:00:00:E0
|      | Type               : Tunnel
|      | Status             : Down
|      | Supports Multicast : False
|      | Is Receive Only    : False
|      | Speed              : 0 Mbit/s
|
|    . Teredo Tunneling Pseudo-Interface
|      ----------------------------------
|      | Name               : Teredo Tunneling Pseudo-Interface
|      | MAC                : 00:00:00:00:00:00:00:E0
|      | Type               : Tunnel
|      | Status             : Up
|      | Supports Multicast : False
|      | Is Receive Only    : False
|      | Speed              : 0 Mbit/s
|
\

What does it produce?

The above report was generated in about 849 milliseconds on its first run and contains various information that are relevant to your application. This information has been categorised into six main sections which you can find in more detail at the bottom of this article but here’s an overview:

  1. System
  2. Process
  3. Drives
  4. Assemblies
  5. Environment Variables
  6. Networking

If you are not interested in generating the full report, you have the option to only generate a specific section:

DiagnosticReport drivesReport = DiagnosticReport.Generate(DiagnosticReportType.Drives);

or combine multiple sections:

DiagnosticReport drivesAndNetworkingReport = DiagnosticReport.Generate(
    DiagnosticReportType.Drives | DiagnosticReportType.Networking);

or only exclude a specific section:

DiagnosticReport partialReport = DiagnosticReport.Generate(
       DiagnosticReportType.Full &~ DiagnosticReportType.EnvironmentVariables);

It is as simple as that!

Where do I find it?

You can see the source of the class in DiagnosticReport and can start generating your own reports by referencing the Easy.Common NuGet package from your .NET or .NET Core app.

What information is covered?

System

Contains information relating to the system under which the application is running:

  • Name of the operating system
  • Type of the operating system e.g Windows, Linux or OSX
  • Flag indicating whether the operating system is 64-bit capable
  • Version of the CLR
  • machine name
  • Fully Qualified Domain Name (FQDN)
  • User under which the process is running
  • Processor name
  • Number of processor cores including HyperThreading
  • Number of installed RAM
  • Location of the System directory
  • Location of the current directory the application is running
  • Location where the CLR is installed
  • Duration the system has been up

Process

Contains information relating to the current process:

  • Process ID (PID)
  • Process name
  • Time at which the process was started
  • Time taken for the process to be loaded
  • Flag indicating whether the process is running in User Interactive mode (This will be false for a Windows Service or a service such as IIS that runs without a UI)
  • Flag indicating whether the application has been compiled in Release mode
  • Flag indicating whether the process is 64-bit
  • Flag indicating whether the GC mode is Server
  • Flag indicating whether the process is Large Address Aware
  • Current value of Working Set memory (RAM) in use by the process. This value includes both Shared and Private memory
  • Number of threads owned by the process
  • Minimum and maximum number of IO Completion Port threads
  • Minimum and maximum number of Thread Pool Worker threads
  • File version of the process
  • Version of the product the process is distributed with
  • Default language for the process
  • Copyright notices that apply to the process
  • Name of the file the process was created as
  • File name representing the process
  • Name of the process module
  • File representing the process module
  • Name of the product the process is distributed with
  • CommandLine including any arguments passed into the process

Drives

Contains information relating to the system drives including fixed as well as removable ones:

  • Name of the drive
  • Type of the drive e.g. Fixed, CDRom etc.
  • Format of the drive e.g. NTFS
  • Label of the drive
  • Capacity of the drive
  • Total amount of free space available on the drive (not just what is available to the current user)
  • Amount of free space available on the drive (this value takes into account disk quotas)

Assemblies

Contains information relating to the assemblies which have been loaded by the process:

  • Full name of the assembly
  • Flag indicating whether the assembly has been loaded from the GAC
  • Flag indicating whether the assembly is 64-bit
  • Flag indicating whether the assembly has been compiled in Release mode
  • framework for which the assembly has been compiled
  • Location from which the assembly has been loaded from
  • Path to the location where the assembly was found. (If the assembly was downloaded from the web, this value may start with HTTP)

Environment Variables

Contains the name and value of the environment variables available to the process.

Networking

Contains information relating to the networking infrastructure available to the process:

  • Windows IP Configuration including:

    • Host name
    • DNS details
  • Adapter information:

    • Name & description
    • Status
    • Speed
    • Physical address (MAC)
    • IP addresses
    • DHCP details

Enjoy!


<
Previous Post
Practical Parallelization in C# with MapReduce, ProducerConsumer and ActorModel
>
Next Post
Counting Lines of a Text File in C#, the Smart Way