top of page
Search

Tracing in .NET Application

  • Writer: TechTutor
    TechTutor
  • Feb 12, 2024
  • 4 min read

System.Diagnostics in .NET is a namespace that provides classes allowing you to interact with system processes, event logs, and performance counters. It also includes tracing and debugging facilities. Tracing is a way to monitor the execution of an application while it is running. It is used to log information about the application's operation, which can be instrumental in diagnosing problems or understanding the application's behavior.


Key Components for Tracing in System.Diagnostics:

TraceSource: Provides a set of methods and properties that enable applications to trace the execution of code and associate each trace with a category.

TraceListener: Receives the output from the TraceSource and writes it to a specific medium, such as a file, the console, or the Windows Event Log.

TraceSwitch: Provides a mechanism to enable or disable tracing based on the current configuration and the importance of the trace messages.


Benefits of Using Tracing:

Debugging and Diagnostic: Tracing allows developers to monitor the flow of their application and diagnose issues by logging detailed information about the application's behavior at runtime. This is especially useful for debugging hard-to-replicate issues in production environments.


Performance Monitoring: By logging performance-related information, developers can identify bottlenecks and optimize the performance of their applications.


Audit and Security: Tracing can be used to log security-related events, providing an audit trail that can be analyzed for suspicious activity or to verify compliance with security policies.


Configuration-Based Logging: Tracing in .NET can be configured dynamically using configuration files (e.g., app.config or web.config). This means that the level of detail logged can be adjusted without needing to recompile the application, making it versatile for development, testing, and production environments.


Integration with Other Diagnostics Tools: The System.Diagnostics namespace is designed to work seamlessly with other diagnostics tools and services, making it a powerful component of the .NET ecosystem for application monitoring and analysis.


Use Case: Diagnosing SSL/TLS Errors When Calling an External API


Scenario:

Your .NET application makes a call to an external API over HTTPS. However, the call fails, and the application throws an SSL/TLS handshake error. This could be due to a variety of reasons such as mismatched SSL protocols between the client and server, expired certificates, or a failure to validate the server's SSL certificate.

Solution Using System.Diagnostics:

Enable Tracing in Your Application: First, enable tracing for System.Net and System.Net.Sockets to capture detailed information about the SSL/TLS handshake process. This can be done by adding configurations in your app.config or web.config file. Here's an example configuration snippet:

<system.diagnostics>
  <sources>
    <source name="System.Net" tracemode="protocolonly">
      <listeners>
        <add name="myListener"/>
      </listeners>
    </source>
    <source name="System.Net.Sockets">
      <listeners>
        <add name="myListener"/>
      </listeners>
    </source>
  </sources>
  <sharedListeners>
    <add name="myListener" 
         type="System.Diagnostics.TextWriterTraceListener" 
         initializeData="network.log"/>
  </sharedListeners>
  <trace autoflush="true"/>
</system.diagnostics>

Analyze the Trace Output: With tracing enabled, make the API call again. The System.Diagnostics namespace will log detailed information about the network communication, including the SSL/TLS handshake process, to the network.log file specified in the listener configuration.


Identify the Root Cause: By examining the trace output, you can identify specific details about the SSL/TLS error, such as:

  • Whether the client and server were able to agree on a protocol version.

  • If there was a problem with the server's certificate (e.g., validation failure, expired certificate).

  • Cipher suite mismatches.


Resolve the Issue: Once you have identified the root cause, you can take appropriate steps to resolve the issue, such as:

  • Updating the server's SSL certificate if it's expired.

  • Ensuring that both client and server support a common set of SSL/TLS protocols and cipher suites.

  • Configuring the .NET application to trust the server's SSL certificate, if it's self-signed or issued by a non-standard CA.


Benefits:

  • Troubleshooting Efficiency: Quickly identifies the point of failure in the SSL/TLS handshake process.

  • Security Compliance: Ensures that the communication between the client and the external API meets security standards.

  • Application Reliability: Helps maintain the reliability of your application by ensuring external API calls are successful


Enabling tracing in .net Core Applications


Program.cs

You can write logs to either file or to console. change the code baed on your requirments.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
using System.Net;

class Program
{
    static async Task Main(string[] args)
    {

        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug() // Capture detailed logs
                                  //.WriteTo.Console()
            .WriteTo.File("System.Net.trace.log", rollingInterval: RollingInterval.Day)
            .CreateLogger();

        // Set up dependency injection
        var serviceCollection = new ServiceCollection();
        ConfigureServices(serviceCollection);

        var serviceProvider = serviceCollection.BuildServiceProvider();

        // Get the logger instance from the service provider
        var logger = serviceProvider.GetRequiredService<ILogger<Program>>();

        // Example usage of logger
        logger.LogInformation("Starting application");


        using var listener = new HttpEventListener();
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

        using var client = new HttpClient();
        

        try
        {

            Console.WriteLine("Making HTTP request...");
            for (var i = 0; i < 1; i++)
            {
                var response = await client.GetAsync("https://example.com/api/");
                logger.LogInformation($"Response: {response.StatusCode}");
                Thread.Sleep(30000);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
            logger.LogInformation($"Error: {ex.Message}");
        }
    }

    private static void ConfigureServices(IServiceCollection services)
    {
        // Add logging
        services.AddLogging(builder =>
        {
            builder.ClearProviders(); // Clears default logging providers
            builder.AddSerilog(); // Use Serilog for logging
        });
    }
}

HttpEventListener.cs

using System.Diagnostics.Tracing;
using System.Net.Sockets;
using System.Text;
public class HttpEventListener : EventListener
{

    protected override void OnEventSourceCreated(EventSource eventSource)
    {
        // Here you filter the EventSources you're interested in.
        if (eventSource.Name.StartsWith("System.Net.Http"))
        {
            // Enable events with informational level or higher from System.Net.Http EventSource
            EnableEvents(eventSource, EventLevel.Informational);
        }
        // Attempt to enable network-related event sources
        // This is speculative, as explicit System.Net.Sockets events might not be available
        if (eventSource.Name.Contains("System.Net") || eventSource.Name.Contains("System.Net.Http"))
        {
            EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.All);
        }
    }

    protected override void OnEventWritten(EventWrittenEventArgs eventData)
    {
        //// Check if the payload is null and handle accordingly.
        //var payloadString = eventData.Payload != null ? string.Join(", ", eventData.Payload) : "null";

        //// Handle the event. For simplicity, we're just writing to the console.
        //Console.WriteLine($"Event: {eventData.EventName} Payload: {payloadString}");

        Console.WriteLine($"[{DateTime.Now}] Event: {eventData.EventName}");
        for (int i = 0; i < eventData.Payload?.Count; i++)
        {
            Console.WriteLine($"    Payload {i}: {eventData.Payload[i]}");
        }
    }
}

How can I verify if TLS 1.2 (any) is supported on a remote web server

To verify if TLS 1.2 (SSL/TLS 1.1/TLS 1.3) is supported on a remote web server using OpenSSL, you can use the s_client command. This command allows you to connect to a server using specified SSL/TLS protocol versions and cipher suites, enabling you to test the server's support for those protocols.


Here's a command that specifically checks for TLS 1.2 support:

openssl s_client -connect hostname:port -tls1_2

Replace hostname with the domain name or IP address of the web server you want to test, and port with the port number (typically 443 for HTTPS).


Additional Options

  • To get more detailed output, you can add the -debug or -msg option to the command.

  • If you're interested in checking support for other TLS versions (e.g., TLS 1.3 or TLS 1.1), you can replace -tls1_2 with -tls1_3 or -tls1_1 accordingly.



Reference

 
 
 

Kommentare

Mit 0 von 5 Sternen bewertet.
Noch keine Ratings

Rating hinzufügen

TechTutorTips.com


SUBSCRIBE 


Thanks for submitting!

© 2025 Powered and secured by Wix

bottom of page