Skip to content

An ASP.NET Core app that continuously digest traces sent from HTTP(S) clients and creates csv files from them

License

Notifications You must be signed in to change notification settings

smourier/TracesToCsv

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TracesToCsv

An ASP.NET Core 10+ application that continuously ingests lightweight trace payloads sent over HTTP(S) and converts them into downloadable CSV files.

Features

  • Accepts traces via HTTPS PUT requests
  • Reads JSON trace payloads, converts them to CSV rows, and stores them in a server-side folder
  • Simple hierarchical categorization of traces using URL path segments
  • Minimal footprint: publish and run
  • No third-party dependencies
  • Supports per-trace dynamic key/value pairs mapped to expandable CSV columns

Use cases

  • Centralized collection of diagnostic or telemetry traces from diverse clients
  • Application troubleshooting by inspecting structured trace history
  • Offline analysis in spreadsheets or any CSV-compatible tooling

How to use

The app listens for HTTPS PUT requests on the configured port (default: https://localhost:7020).

Send trace data as JSON in the following shape:

{
    "timestamp": "2025-09-19T11:13:53.6160989+00:00", // required. client timestamp
    "level": "info",   // required. level of trace, can be "error" or 1, "warning" or 2, "info" or 3, "verbose" or 4
    "message": "blah", // optional. a message
    "values": {        // optional. a dictionary of values
        "some bool": true,
        "a value": 1234.5677,
        "dummy": "hello world",
        "etc.": "..."
    }
}

Getting an API Key

Generate a Guid to serve as the trace identifier (the "id"). This guid is yours and yours only. Visit
https://localhost:7020/traces/<id> (example: https://localhost:7020/traces/733eb60f2ef14444866093a64d6b8a41) and open Show Help.

Show Help

The displayed API Key (example: iElBVk8qlQd5h3nmXdbu8DNLGUH3AlJHHPAiNGb0eLvaM9Roxf7s556hUNzX4nk6) is what clients use to submit traces associated with that Guid.

Treat the Guid more carefully than the API Key: possession of the Guid allows browsing of the related CSV output. Avoid embedding the Guid directly in distributed binaries or sharing it publicly.

Server configuration

Configure a server-side password in appsettings.json:

{
  "Traces": {
    "Password": "put_your_password_here"
  }
}

This password is used to derive API Keys from their Guids. Changing it later invalidates previously issued API Keys, so pick a value early and keep it stable.

C# sample Code

var apiKey = "..."; // see above to get the key
    
var client = new HttpClient(new HttpClientHandler
{
    // optional, if your server certificate is not valid
    ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true,
})
{
    DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher,
    BaseAddress = new Uri("https://127.0.0.1:7020/Traces/")
};

var trace = new
{
    level = "info",
    timestamp = DateTimeOffset.UtcNow,
    message = "Hello World",
    values = new Dictionary<string, object>()
    {
        { "bool", true },
        { "single", 1234.5678f},
        { "double", 1234.5678},
        { "timespan", TimeSpan.FromDays(1234.5679)},
        { "decimal", 1234.5678m }
    }
};

var content = JsonContent.Create(trace);
var url = new Uri(apiKey, UriKind.Relative);
var response = await client.PutAsync(url, content);
if (!response.IsSuccessStatusCode)
{
    // dump error message on console
    var str = await response.Content.ReadAsStringAsync();
    Console.WriteLine(str);
    response.EnsureSuccessStatusCode();
}

Here is the result when connecting to the server:

CSV Traces

Categorization

You can categorize traces by appending path segments: https://localhost:7020/traces/<id>/cat/cat2. The server places the resulting CSV into a matching subdirectory structure.

Example client call:

var response = await client.PutAsync(url + "/cat/cat2", content);

Result: the UI understands cat and cat2 in url like nested "folders".

Categorization

About

An ASP.NET Core app that continuously digest traces sent from HTTP(S) clients and creates csv files from them

Topics

Resources

License

Stars

Watchers

Forks