kyletaylored.Datadog.Metrics
0.1.3
dotnet add package kyletaylored.Datadog.Metrics --version 0.1.3
NuGet\Install-Package kyletaylored.Datadog.Metrics -Version 0.1.3
<PackageReference Include="kyletaylored.Datadog.Metrics" Version="0.1.3" />
<PackageVersion Include="kyletaylored.Datadog.Metrics" Version="0.1.3" />
<PackageReference Include="kyletaylored.Datadog.Metrics" />
paket add kyletaylored.Datadog.Metrics --version 0.1.3
#r "nuget: kyletaylored.Datadog.Metrics, 0.1.3"
#:package kyletaylored.Datadog.Metrics@0.1.3
#addin nuget:?package=kyletaylored.Datadog.Metrics&version=0.1.3
#tool nuget:?package=kyletaylored.Datadog.Metrics&version=0.1.3
Datadog.Metrics
A .NET library for buffered metrics reporting to Datadog HTTP API with System.Diagnostics.Metrics integration.
Note: This is a community-maintained .NET port of node-datadog-metrics. Published as
kyletaylored.Datadog.Metricsuntil official Datadog support.
Features
- Buffered metrics aggregation - Metrics are buffered and flushed at regular intervals
- Multiple metric types - Gauge, Counter, Histogram, and Distribution support
- Client-side aggregation - Histograms compute percentiles locally to reduce API calls
- Server-side aggregation - Distributions send raw values for server-side calculation
- Tag sorting - Consistent buffer keys regardless of tag order
- Retry logic - Exponential backoff for transient failures
- Dual API support - Uses Datadog API v2 for regular metrics, v1 for distributions
- System.Diagnostics.Metrics integration - Automatically captures standard .NET metrics
- ASP.NET Core integration - Easy setup with dependency injection
- Multi-framework support - Targets .NET 10.0, 9.0, 8.0, 6.0, and .NET Standard 2.0
Installation
dotnet add package kyletaylored.Datadog.Metrics
Or via Package Manager Console:
Install-Package kyletaylored.Datadog.Metrics
Namespace remains Datadog.Metrics - no code changes needed if/when an official package is released.
Quick Start
1. Basic Usage with Dependency Injection
using Datadog.Metrics.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Register Datadog metrics
builder.Services.AddDatadogMetrics(options =>
{
options.ApiKey = "your-api-key";
options.Site = "datadoghq.com";
options.Prefix = "myapp.";
options.DefaultTags = new[] { "env:production", "service:api" };
options.FlushIntervalSeconds = 10;
});
var app = builder.Build();
// Inject and use DatadogMetricsLogger
app.MapGet("/", (DatadogMetricsLogger metrics) =>
{
metrics.Counter("requests", 1, new[] { "endpoint:/" });
metrics.Gauge("active_connections", 42);
return "Hello World!";
});
app.Run();
2. With System.Diagnostics.Metrics Integration
// Enable automatic capture of System.Diagnostics.Metrics
builder.Services.AddDatadogMetricsWithDiagnostics(options =>
{
options.ApiKey = "your-api-key";
options.Site = "datadoghq.com";
});
// Now any code using System.Diagnostics.Metrics will automatically send to Datadog
var meter = new Meter("MyApp");
var counter = meter.CreateCounter<int>("requests");
counter.Add(1, new KeyValuePair<string, object?>("endpoint", "/api"));
Metric Types
Gauge
Records a point-in-time value. Latest value wins.
metrics.Gauge("temperature", 72.5, new[] { "location:office" });
Counter
Accumulates values over time.
metrics.Counter("errors", 1, new[] { "type:validation" });
metrics.Increment("requests"); // Shorthand for Counter(..., 1)
Histogram
Client-side aggregation with configurable percentiles.
metrics.Histogram("response_time", 145.2, new[] { "endpoint:/api" });
// Custom histogram options
var options = new HistogramOptions
{
Aggregates = new[] { HistogramAggregate.Min, HistogramAggregate.Max, HistogramAggregate.Avg, HistogramAggregate.P95 },
Percentiles = new[] { 0.95, 0.99 }
};
metrics.Histogram("latency", 250, null, null, options);
Distribution
Server-side aggregation. Sends all raw values to Datadog.
metrics.Distribution("request_size", 1024, new[] { "method:POST" });
Configuration Options
services.AddDatadogMetrics(options =>
{
// Required
options.ApiKey = "your-api-key";
// Optional (with defaults)
options.Site = "datadoghq.com"; // or "datadoghq.eu", "us3.datadoghq.com", etc.
options.Host = Environment.MachineName; // Hostname for metrics
options.Prefix = null; // Prefix for all metric names
options.DefaultTags = Array.Empty<string>(); // Applied to all metrics
// Flush settings
options.FlushIntervalSeconds = 10; // How often to send metrics
options.MaxBufferSize = 1000; // Warning threshold for buffer size
// HTTP settings
options.HttpTimeoutSeconds = 10;
options.MaxRetries = 3;
options.RetryBackoffSeconds = 1; // Exponential backoff base
// Histogram defaults
options.Histogram = new HistogramOptions
{
Aggregates = new[] { HistogramAggregate.Max, HistogramAggregate.Median, HistogramAggregate.Avg, HistogramAggregate.Count },
Percentiles = new[] { 0.95 }
};
});
Architecture
Component Overview
- DatadogMetricsLogger - Main API for recording metrics
- MetricsAggregator - Buffers and aggregates metrics by unique key+tags combination
- DatadogReporter - Background service that flushes metrics at regular intervals
- HttpApi - Handles communication with Datadog API (v1 and v2) with retry logic
- DatadogMeterListener - Integrates with System.Diagnostics.Metrics
- Metric Types - GaugeMetric, CounterMetric, HistogramMetric, DistributionMetric
Buffer Key Generation
Metrics with the same name and tags (regardless of order) share the same buffer entry:
// These create the SAME buffer entry
metrics.Gauge("cpu", 50, new[] { "host:web1", "region:us-east" });
metrics.Gauge("cpu", 55, new[] { "region:us-east", "host:web1" });
// Result: Single gauge with value 55 (latest wins)
API Routing
- Regular metrics (Gauge, Counter, Histogram) →
/api/v2/series - Distributions →
/api/v1/distribution_points
Testing
dotnet test
Current test coverage includes:
- Buffer key generation with tag sorting
- Metric type behaviors (gauge, counter, histogram)
- Default tags and prefixes
- Aggregator flush behavior
Advanced Usage
Manual Flush
Metrics are automatically flushed at regular intervals, but you can force a flush:
var flushedMetrics = metrics.Flush();
Custom Tags Per Metric
metrics.Counter("api.requests", 1, new[] { "endpoint:/users", "method:GET", "status:200" });
Histogram Percentiles
Configure which percentiles to calculate:
services.AddDatadogMetrics(options =>
{
options.Histogram.Percentiles = new[] { 0.50, 0.75, 0.95, 0.99 };
options.Histogram.Aggregates = new[]
{
HistogramAggregate.Min,
HistogramAggregate.Max,
HistogramAggregate.Avg,
HistogramAggregate.Count
};
});
Development
Quick Start for Contributors
# Clone the repository
git clone https://github.com/kyletaylored/datadog-metrics-dotnet.git
cd datadog-metrics-dotnet
# Initialize development environment
make init
# Build the solution
make build
# Run tests
make test
# Run the sample app (requires DD_API_KEY env var)
export DD_API_KEY=your-api-key
make run-sample
Available Make Commands
make help # Show all available commands
make build # Build the solution
make test # Run all tests
make test-watch # Run tests in watch mode
make pack # Create NuGet package
make format # Format code
make lint # Run code analysis
make run-sample # Run sample application
make clean # Clean build artifacts
make ci # Run full CI pipeline locally
Project Structure
datadog-metrics-dotnet/
├── .github/ # GitHub Actions workflows and issue templates
├── samples/ # Sample applications
│ └── Datadog.Metrics.Sample/
├── src/ # Main library source
│ └── Datadog.Metrics/
│ ├── Configuration/ # Configuration models
│ ├── Core/ # Aggregation logic
│ ├── Extensions/ # DI extensions
│ ├── Integration/ # System.Diagnostics.Metrics
│ ├── Metrics/ # Metric implementations
│ └── Transport/ # HTTP API client
├── tests/ # Unit tests
│ └── Datadog.Metrics.Tests/
├── .editorconfig # Code style configuration
├── .gitignore # Git ignore rules
├── .gitattributes # Git line ending settings
├── Makefile # Development automation
├── CONTRIBUTING.md # Contribution guidelines
└── README.md # This file
License
MIT - See LICENSE for details
Contributing
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
Quick Contribution Checklist
- Fork the repository
- Create a feature branch
- Write tests for your changes
- Ensure all tests pass:
make test - Format your code:
make format - Update documentation as needed
- Submit a pull request
CI/CD
The project uses GitHub Actions for continuous integration:
CI Pipeline (
.github/workflows/ci.yml)- Runs on: push to main/develop, pull requests
- Matrix testing across: Ubuntu, Windows, macOS
- Tests on: .NET 6.0 and .NET 8.0
- Includes code formatting and quality checks
Publish Pipeline (
.github/workflows/publish.yml)- Triggered by: GitHub releases
- Automatically builds and publishes to NuGet.org
Support
- Documentation: samples/Datadog.Metrics.Sample/README.md
- Bug Reports: GitHub Issues
- Feature Requests: GitHub Issues
- Discussions: GitHub Discussions
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. 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 is compatible. 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 is compatible. 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. |
-
.NETStandard 2.0
- Microsoft.Extensions.Hosting.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
- System.Diagnostics.DiagnosticSource (>= 8.0.0)
- System.Text.Json (>= 8.0.5)
- System.Threading.Channels (>= 8.0.0)
-
net10.0
- Microsoft.Extensions.Hosting.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
-
net6.0
- Microsoft.Extensions.Hosting.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
- System.Diagnostics.DiagnosticSource (>= 8.0.0)
- System.Text.Json (>= 8.0.5)
-
net8.0
- Microsoft.Extensions.Hosting.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
-
net9.0
- Microsoft.Extensions.Hosting.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.