MetricFlow 0.1.2

dotnet add package MetricFlow --version 0.1.2
                    
NuGet\Install-Package MetricFlow -Version 0.1.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MetricFlow" Version="0.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MetricFlow" Version="0.1.2" />
                    
Directory.Packages.props
<PackageReference Include="MetricFlow" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MetricFlow --version 0.1.2
                    
#r "nuget: MetricFlow, 0.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MetricFlow@0.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MetricFlow&version=0.1.2
                    
Install as a Cake Addin
#tool nuget:?package=MetricFlow&version=0.1.2
                    
Install as a Cake Tool

MetricFlow .NET Client Library

A lightweight, allocation-conscious .NET client for sending metrics to the MetricFlow service.

Targets:

  • netstandard2.0 (broad compatibility)
  • net8.0 (optimized modern runtime)

Runtime goals: low allocation, simple API, AOT + trimming friendly.


Table of Contents

  1. Installation
  2. Quick Start
  3. API Overview
  4. Usage Patterns
  5. Dependency Injection
  6. Error Handling & Resilience
  7. Performance Notes
  8. AOT / Trimming Considerations
  9. Metric Naming & Semantics
  10. Self-Hosting / Local Development
  11. Thread Safety
  12. Roadmap
  13. Contributing
  14. Versioning & Packing
  15. FAQ
  16. License

1. Installation

Pending publication to NuGet. Once published:

dotnet add package MetricFlow

Or via PackageReference:

<PackageReference Include="MetricFlow" Version="x.y.z" />

2. Quick Start

using MetricFlow;

using var client = new MetricFlowClient(
    apiKey: "YOUR_API_KEY",              // Optional for local / self-host
    endpointUrl: "https://metricflow.co/" // Optional (default shown)
);

// Counter (increment by 1)
await client.SendCounterAsync("orders.processed");

// Counter (custom increment)
await client.SendCounterAsync("orders.processed", value: 5);

// Gauge (instantaneous value)
await client.SendValueAsync("queue.depth", 42.7m);

3. API Overview

public interface IMetricFlowClient : IDisposable
{
    Task SendCounterAsync(string name, long value = 1, CancellationToken cancellationToken = default);
    Task SendValueAsync(string name, decimal value, CancellationToken cancellationToken = default);
}

Both members throw ArgumentException if name is null/empty/whitespace.


4. Usage Patterns

Recommended:

  • Reuse a single MetricFlowClient (or register it as a singleton via DI).
  • Prefer async calls; they return after the HTTP post completes.
  • For non-critical paths, consider wrapping in a best-effort fire-and-forget strategy if latency sensitive.

Bulk: A public batching API is not yet exposed (roadmap). For now, call per metric.


5. Dependency Injection

// Program.cs / Startup equivalent
services.AddSingleton<IMetricFlowClient>(sp => new MetricFlowClient(
    apiKey: configuration["MetricFlow:ApiKey"],
    endpointUrl: configuration["MetricFlow:Endpoint"] ?? "https://metricflow.co/"));

Consume:

public class OrderProcessor
{
    private readonly IMetricFlowClient _metrics;
    public OrderProcessor(IMetricFlowClient metrics) => _metrics = metrics;

    public async Task ProcessAsync()
    {
        // work ...
        await _metrics.SendCounterAsync("orders.processed");
    }
}

6. Error Handling & Resilience

MetricFlowClient calls HttpClient.PostAsync then EnsureSuccessStatusCode(). Failures raise HttpRequestException (or derived exceptions). Guidance:

  • Treat metric submission as non-critical (log + continue) unless auditing is required.
  • Wrap calls in try/catch:
try { await _metrics.SendCounterAsync("orders.processed"); }
catch (HttpRequestException ex) { _logger.LogWarning(ex, "Metric submission failed"); }
  • External resilience (e.g. Polly) can be added at call sites if retries or circuit breaking are desired.

7. Performance Notes

  • Source-generated System.Text.Json context (no reflection at runtime).
  • Minimal object allocation per call (single DTO batch + serialization buffer).
  • HttpClient reuse prevents socket exhaustion.

8. AOT / Trimming Considerations

Project is analyzer-enabled for AOT/trimming on applicable TFMs.

  • Avoid adding reflection heavy patterns without updating the JSON context.
  • Current DTOs are internal and included in the source-gen context.

9. Metric Naming & Semantics

Suggested naming convention: resource.action.dimension (dot-separated, lowercase). Examples:

  • orders.processed
  • queue.depth
  • user.signup.success

Types:

  • Counter: Monotonically increasing occurrence count. Server may aggregate.
  • Gauge (Value): Instantaneous numeric reading at capture time.

Payload shape sent (example):

{
  "data": [
    { "metric": "orders.processed", "count": 5, "t": 1730000000 },
    { "metric": "queue.depth", "value": 42.7, "t": 1730000001 }
  ]
}

t = Unix epoch seconds (UTC) assigned client-side.


10. Self-Hosting / Local Development

var client = new MetricFlowClient(
    apiKey: "dev-key",          // optional for local
    endpointUrl: "https://localhost:5001/" // ensure trailing slash or it is added
);

If using self-signed certs, trust locally or disable certificate validation ONLY in controlled dev scenarios.


11. Thread Safety

All public methods are safe for concurrent invocation. Internal mutable state is limited to the HttpClient instance.


12. Roadmap

Planned / Proposed:

  • Public batching API (multi-metric send)
  • Buffered writer with periodic flush
  • Retry / backoff policy hooks
  • Tags / dimensional metrics
  • Structured diagnostic logging callbacks
  • OpenTelemetry bridge adapter

Open an issue to influence prioritization.


13. Contributing

  1. Fork
  2. Create a feature branch
  3. Implement changes + (future) tests
  4. Run: dotnet build (ensure no warnings)
  5. Submit PR with clear description

Coding guidelines:

  • Keep API surface minimal and clear
  • Avoid unnecessary allocations
  • Maintain netstandard2.0 compatibility where feasible

14. Versioning & Packing

Uses [MinVer] with v tag prefix for semantic version inference.

Tag example:

git tag v0.2.0

Build & pack:

dotnet pack src/MetricFlow/MetricFlow.csproj -c Release -p:GeneratePackageOnBuild=true

Resulting .nupkg includes this README (see <PackageReadmeFile> in csproj).


15. FAQ

Q: Why no batching method yet?
A: Simplicity first; batching will be added with configurable flush semantics.

Q: Are metrics lost on failure?
A: Currently yes; no internal buffering or retry. Add external retries if critical.

Q: Can I send negative counters?
A: Counters conceptually increment; use gauge/value for arbitrary deltas.

Q: High-frequency metrics?
A: Consider upcoming batching or aggregate locally before sending.


16. License

MIT. See root LICENSE file.


Feedback / questions: open an issue at https://github.com/kfrancis/metric-flow/issues

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.2 185 9/23/2025
0.1.1 320 9/19/2025
0.1.0 301 9/19/2025