Foundatio.MetricsNET 10.2.1 The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org.

Pluggable foundation blocks for building distributed apps.

Install-Package Foundatio.MetricsNET -Version 10.2.1
dotnet add package Foundatio.MetricsNET --version 10.2.1
<PackageReference Include="Foundatio.MetricsNET" Version="10.2.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Foundatio.MetricsNET --version 10.2.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Foundatio.MetricsNET, 10.2.1"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install Foundatio.MetricsNET as a Cake Addin
#addin nuget:?package=Foundatio.MetricsNET&version=10.2.1

// Install Foundatio.MetricsNET as a Cake Tool
#tool nuget:?package=Foundatio.MetricsNET&version=10.2.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

Foundatio

Build status NuGet Version feedz.io Discord

Pluggable foundation blocks for building loosely coupled distributed apps.

Includes implementations in Redis, Azure, AWS, RabbitMQ and in memory (for development).

Why Foundatio?

When building several big cloud applications we found a lack of great solutions (that's not to say there isn't solutions out there) for many key pieces to building scalable distributed applications while keeping the development experience simple. Here are a few examples of why we built and use Foundatio:

  • Wanted to build against abstract interfaces so that we could easily change implementations.
  • Wanted the blocks to be dependency injection friendly.
  • Caching: We were initially using an open source Redis cache client but then it turned into a commercial product with high licensing costs. Not only that, but there weren't any in memory implementations so every developer was required to set up and configure Redis.
  • Message Bus: We initially looked at NServiceBus (great product) but it had high licensing costs (they have to eat too) but was not OSS friendly. We also looked into MassTransit but found Azure support lacking and local set up a pain. We wanted a simple message bus that just worked locally or in the cloud.
  • Storage: We couldn't find any existing project that was decoupled and supported in memory, file storage or Azure Blob Storage.

To summarize, if you want pain free development and testing while allowing your app to scale, use Foundatio!

Implementations

Getting Started (Development)

Foundatio can be installed via the NuGet package manager. If you need help, please open an issue or join our Discord chat room. We’re always here to help if you have any questions!

This section is for development purposes only! If you are trying to use the Foundatio libraries, please get them from NuGet.

  1. You will need to have Visual Studio Code installed.
  2. Open the Foundatio.sln Visual Studio solution file.

Using Foundatio

The sections below contain a small subset of what's possible with Foundatio. We recommend taking a peek at the source code for more information. Please let us know if you have any questions or need assistance!

Caching

Caching allows you to store and access data lightning fast, saving you exspensive operations to create or get data. We provide four different cache implementations that derive from the ICacheClient interface:

  1. InMemoryCacheClient: An in memory cache client implementation. This cache implementation is only valid for the lifetime of the process. It's worth noting that the in memory cache client has the ability to cache the last X items via the MaxItems property. We use this in Exceptionless to only keep the last 250 resolved geoip results.
  2. HybridCacheClient: This cache implementation uses both an ICacheClient and the InMemoryCacheClient and uses an IMessageBus to keep the cache in sync across processes. This can lead to huge wins in performance as you are saving a serialization operation and a call to the remote cache if the item exists in the local cache.
  3. RedisCacheClient: A Redis cache client implementation.
  4. RedisHybridCacheClient: An implementation of HybridCacheClient that uses the RedisCacheClient as ICacheClient and the RedisMessageBus as IMessageBus.
  5. ScopedCacheClient: This cache implementation takes an instance of ICacheClient and a string scope. The scope is prefixed onto every cache key. This makes it really easy to scope all cache keys and remove them with ease.
Sample
using Foundatio.Caching;

ICacheClient cache = new InMemoryCacheClient();
await cache.SetAsync("test", 1);
var value = await cache.GetAsync<int>("test");

Queues

Queues offer First In, First Out (FIFO) message delivery. We provide four different queue implementations that derive from the IQueue interface:

  1. InMemoryQueue: An in memory queue implementation. This queue implementation is only valid for the lifetime of the process.
  2. RedisQueue: An Redis queue implementation.
  3. AzureServiceBusQueue: An Azure Service Bus Queue implementation.
  4. AzureStorageQueue: An Azure Storage Queue implementation.
  5. SQSQueue: An AWS SQS implementation.
Sample
using Foundatio.Queues;

IQueue<SimpleWorkItem> queue = new InMemoryQueue<SimpleWorkItem>();

await queue.EnqueueAsync(new SimpleWorkItem {
    Data = "Hello"
});

var workItem = await queue.DequeueAsync();

Locks

Locks ensure a resource is only accessed by one consumer at any given time. We provide two different locking implementations that derive from the ILockProvider interface:

  1. CacheLockProvider: A lock implementation that uses cache to communicate between processes.
  2. ThrottlingLockProvider: A lock implementation that only allows a certain amount of locks through. You could use this to throttle api calls to some external service and it will throttle them across all processes asking for that lock.
  3. ScopedLockProvider: This lock implementation takes an instance of ILockProvider and a string scope. The scope is prefixed onto every lock key. This makes it really easy to scope all locks and release them with ease.

It's worth noting that all lock providers take a ICacheClient. This allows you to ensure your code locks properly across machines.

Sample
using Foundatio.Lock;

ILockProvider locker = new CacheLockProvider(new InMemoryCacheClient(), new InMemoryMessageBus());
var testLock = await locker.AcquireAsync("test");
// ...
await testLock.ReleaseAsync();

ILockProvider throttledLocker = new ThrottlingLockProvider(new InMemoryCacheClient(), 1, TimeSpan.FromMinutes(1));
var throttledLock = await throttledLocker.AcquireAsync("test");
// ...
await throttledLock.ReleaseAsync();

Messaging

Allows you to publish and subscribe to messages flowing through your application. We provide four different message bus implementations that derive from the IMessageBus interface:

  1. InMemoryMessageBus: An in memory message bus implementation. This message bus implementation is only valid for the lifetime of the process.
  2. RedisMessageBus: A Redis message bus implementation.
  3. RabbitMQMessageBus: A RabbitMQ implementation.
  4. AzureServiceBusMessageBus: An Azure Service Bus implementation.
Sample
using Foundatio.Messaging;

IMessageBus messageBus = new InMemoryMessageBus();
await messageBus.SubscribeAsync<SimpleMessageA>(msg => {
  // Got message
});

await messageBus.PublishAsync(new SimpleMessageA { Data = "Hello" });

Jobs

Allows you to run a long running process (in process or out of process) without worrying about it being terminated prematurely. We provide three different ways of defining a job, based on your use case:

  1. Jobs: All jobs must derive from the IJob interface. We also have a JobBase base class you can derive from which provides a JobContext and logging. You can then run jobs by calling RunAsync() on the job or by creating a instance of the JobRunner class and calling one of the Run methods. The JobRunner can be used to easily run your jobs as Azure Web Jobs.
Sample
using Foundatio.Jobs;

public class HelloWorldJob : JobBase {
  public int RunCount { get; set; }

  protected override Task<JobResult> RunInternalAsync(JobContext context) {
     RunCount++;
     return Task.FromResult(JobResult.Success);
  }
}
var job = new HelloWorldJob();
await job.RunAsync(); // job.RunCount = 1;
await job.RunContinuousAsync(iterationLimit: 2); // job.RunCount = 3;
await job.RunContinuousAsync(cancellationToken: new CancellationTokenSource(10).Token); // job.RunCount > 10;
  1. Queue Processor Jobs: A queue processor job works great for working with jobs that will be driven from queued data. Queue Processor jobs must derive from QueueJobBase<T> class. You can then run jobs by calling RunAsync() on the job or passing it to the JobRunner class. The JobRunner can be used to easily run your jobs as Azure Web Jobs.
Sample
using Foundatio.Jobs;

public class HelloWorldQueueJob : QueueJobBase<HelloWorldQueueItem> {
  public int RunCount { get; set; }

  public HelloWorldQueueJob(IQueue<HelloWorldQueueItem> queue) : base(queue) {}

  protected override Task<JobResult> ProcessQueueEntryAsync(QueueEntryContext<HelloWorldQueueItem> context) {
     RunCount++;

     return Task.FromResult(JobResult.Success);
  }
}

public class HelloWorldQueueItem {
  public string Message { get; set; }
}
 // Register the queue for HelloWorldQueueItem.
container.AddSingleton<IQueue<HelloWorldQueueItem>>(s => new InMemoryQueue<HelloWorldQueueItem>());

// To trigger the job we need to queue the HelloWorldWorkItem message.
// This assumes that we injected an instance of IQueue<HelloWorldWorkItem> queue

IJob job = new HelloWorldQueueJob();
await job.RunAsync(); // job.RunCount = 0; The RunCount wasn't incremented because we didn't enqueue any data.

await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });
await job.RunAsync(); // job.RunCount = 1;

await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });
await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });
await job.RunUntilEmptyAsync(); // job.RunCount = 3;
  1. Work Item Jobs: A work item job will run in a job pool among other work item jobs. This type of job works great for things that don't happen often but should be in a job (Example: Deleting an entity that has many children.). It will be triggered when you publish a message on the message bus. The job must derive from the WorkItemHandlerBase class. You can then run all shared jobs via JobRunner class. The JobRunner can be used to easily run your jobs as Azure Web Jobs.
Sample
using System.Threading.Tasks;
using Foundatio.Jobs;

public class HelloWorldWorkItemHandler : WorkItemHandlerBase {
  public override async Task HandleItemAsync(WorkItemContext ctx) {
    var workItem = ctx.GetData<HelloWorldWorkItem>();

    // We can report the progress over the message bus easily.
    // To receive these messages just inject IMessageSubscriber
    // and Subscribe to messages of type WorkItemStatus
    await ctx.ReportProgressAsync(0, "Starting Hello World Job");
    await Task.Delay(TimeSpan.FromSeconds(2.5));
    await ctx.ReportProgressAsync(50, "Reading value");
    await Task.Delay(TimeSpan.FromSeconds(.5));
    await ctx.ReportProgressAsync(70, "Reading value");
    await Task.Delay(TimeSpan.FromSeconds(.5));
    await ctx.ReportProgressAsync(90, "Reading value.");
    await Task.Delay(TimeSpan.FromSeconds(.5));

    await ctx.ReportProgressAsync(100, workItem.Message);
  }
}

public class HelloWorldWorkItem {
  public string Message { get; set; }
}
// Register the shared job.
var handlers = new WorkItemHandlers();
handlers.Register<HelloWorldWorkItem, HelloWorldWorkItemHandler>();

// Register the handlers with dependency injection.
container.AddSingleton(handlers);

// Register the queue for WorkItemData.
container.AddSingleton<IQueue<WorkItemData>>(s => new InMemoryQueue<WorkItemData>());

// The job runner will automatically look for and run all registered WorkItemHandlers.
new JobRunner(container.GetRequiredService<WorkItemJob>(), instanceCount: 2).RunInBackground();
 // To trigger the job we need to queue the HelloWorldWorkItem message.
 // This assumes that we injected an instance of IQueue<WorkItemData> queue

 // NOTE: You may have noticed that HelloWorldWorkItem doesn't derive from WorkItemData.
 // Foundatio has an extension method that takes the model you post and serializes it to the
 // WorkItemData.Data property.
 await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });

File Storage

We provide different file storage implementations that derive from the IFileStorage interface:

  1. InMemoryFileStorage: An in memory file implementation. This file storage implementation is only valid for the lifetime of the process.
  2. FolderFileStorage: An file storage implementation that uses the hard drive for storage.
  3. AzureFileStorage: An Azure Blob storage implementation.
  4. S3FileStorage: An AWS S3 file storage implementation.
  5. RedisFileStorage: An Redis file storage implementation.
  6. MinioFileStorage An Minio file storage implementation.
  7. AliyunFileStorage: An Aliyun file storage implementation.
  8. SshNetFileStorage: An SFTP file storage implementation.

We recommend using all of the IFileStorage implementations as singletons.

Sample
using Foundatio.Storage;

IFileStorage storage = new InMemoryFileStorage();
await storage.SaveFileAsync("test.txt", "test");
string content = await storage.GetFileContentsAsync("test.txt")

Metrics

We provide five implementations that derive from the IMetricsClient interface:

  1. InMemoryMetricsClient: An in memory metrics implementation.
  2. RedisMetricsClient: An Redis metrics implementation.
  3. StatsDMetricsClient: An statsd metrics implementation.
  4. MetricsNETClient: An Metrics.NET implementation.
  5. AppMetricsClient: An AppMetrics implementation.
  6. CloudWatchMetricsClient: An AWS CloudWatch implementation.

We recommend using all of the IMetricsClient implementations as singletons.

Sample
IMetricsClient metrics = new InMemoryMetricsClient();
metrics.Counter("c1");
metrics.Gauge("g1", 2.534);
metrics.Timer("t1", 50788);

Sample Application

We have both slides and a sample application that shows off how to use Foundatio.

Thanks to all the people who have contributed

contributors

Foundatio

Build status NuGet Version feedz.io Discord

Pluggable foundation blocks for building loosely coupled distributed apps.

Includes implementations in Redis, Azure, AWS, RabbitMQ and in memory (for development).

Why Foundatio?

When building several big cloud applications we found a lack of great solutions (that's not to say there isn't solutions out there) for many key pieces to building scalable distributed applications while keeping the development experience simple. Here are a few examples of why we built and use Foundatio:

  • Wanted to build against abstract interfaces so that we could easily change implementations.
  • Wanted the blocks to be dependency injection friendly.
  • Caching: We were initially using an open source Redis cache client but then it turned into a commercial product with high licensing costs. Not only that, but there weren't any in memory implementations so every developer was required to set up and configure Redis.
  • Message Bus: We initially looked at NServiceBus (great product) but it had high licensing costs (they have to eat too) but was not OSS friendly. We also looked into MassTransit but found Azure support lacking and local set up a pain. We wanted a simple message bus that just worked locally or in the cloud.
  • Storage: We couldn't find any existing project that was decoupled and supported in memory, file storage or Azure Blob Storage.

To summarize, if you want pain free development and testing while allowing your app to scale, use Foundatio!

Implementations

Getting Started (Development)

Foundatio can be installed via the NuGet package manager. If you need help, please open an issue or join our Discord chat room. We’re always here to help if you have any questions!

This section is for development purposes only! If you are trying to use the Foundatio libraries, please get them from NuGet.

  1. You will need to have Visual Studio Code installed.
  2. Open the Foundatio.sln Visual Studio solution file.

Using Foundatio

The sections below contain a small subset of what's possible with Foundatio. We recommend taking a peek at the source code for more information. Please let us know if you have any questions or need assistance!

Caching

Caching allows you to store and access data lightning fast, saving you exspensive operations to create or get data. We provide four different cache implementations that derive from the ICacheClient interface:

  1. InMemoryCacheClient: An in memory cache client implementation. This cache implementation is only valid for the lifetime of the process. It's worth noting that the in memory cache client has the ability to cache the last X items via the MaxItems property. We use this in Exceptionless to only keep the last 250 resolved geoip results.
  2. HybridCacheClient: This cache implementation uses both an ICacheClient and the InMemoryCacheClient and uses an IMessageBus to keep the cache in sync across processes. This can lead to huge wins in performance as you are saving a serialization operation and a call to the remote cache if the item exists in the local cache.
  3. RedisCacheClient: A Redis cache client implementation.
  4. RedisHybridCacheClient: An implementation of HybridCacheClient that uses the RedisCacheClient as ICacheClient and the RedisMessageBus as IMessageBus.
  5. ScopedCacheClient: This cache implementation takes an instance of ICacheClient and a string scope. The scope is prefixed onto every cache key. This makes it really easy to scope all cache keys and remove them with ease.
Sample
using Foundatio.Caching;

ICacheClient cache = new InMemoryCacheClient();
await cache.SetAsync("test", 1);
var value = await cache.GetAsync<int>("test");

Queues

Queues offer First In, First Out (FIFO) message delivery. We provide four different queue implementations that derive from the IQueue interface:

  1. InMemoryQueue: An in memory queue implementation. This queue implementation is only valid for the lifetime of the process.
  2. RedisQueue: An Redis queue implementation.
  3. AzureServiceBusQueue: An Azure Service Bus Queue implementation.
  4. AzureStorageQueue: An Azure Storage Queue implementation.
  5. SQSQueue: An AWS SQS implementation.
Sample
using Foundatio.Queues;

IQueue<SimpleWorkItem> queue = new InMemoryQueue<SimpleWorkItem>();

await queue.EnqueueAsync(new SimpleWorkItem {
    Data = "Hello"
});

var workItem = await queue.DequeueAsync();

Locks

Locks ensure a resource is only accessed by one consumer at any given time. We provide two different locking implementations that derive from the ILockProvider interface:

  1. CacheLockProvider: A lock implementation that uses cache to communicate between processes.
  2. ThrottlingLockProvider: A lock implementation that only allows a certain amount of locks through. You could use this to throttle api calls to some external service and it will throttle them across all processes asking for that lock.
  3. ScopedLockProvider: This lock implementation takes an instance of ILockProvider and a string scope. The scope is prefixed onto every lock key. This makes it really easy to scope all locks and release them with ease.

It's worth noting that all lock providers take a ICacheClient. This allows you to ensure your code locks properly across machines.

Sample
using Foundatio.Lock;

ILockProvider locker = new CacheLockProvider(new InMemoryCacheClient(), new InMemoryMessageBus());
var testLock = await locker.AcquireAsync("test");
// ...
await testLock.ReleaseAsync();

ILockProvider throttledLocker = new ThrottlingLockProvider(new InMemoryCacheClient(), 1, TimeSpan.FromMinutes(1));
var throttledLock = await throttledLocker.AcquireAsync("test");
// ...
await throttledLock.ReleaseAsync();

Messaging

Allows you to publish and subscribe to messages flowing through your application. We provide four different message bus implementations that derive from the IMessageBus interface:

  1. InMemoryMessageBus: An in memory message bus implementation. This message bus implementation is only valid for the lifetime of the process.
  2. RedisMessageBus: A Redis message bus implementation.
  3. RabbitMQMessageBus: A RabbitMQ implementation.
  4. AzureServiceBusMessageBus: An Azure Service Bus implementation.
Sample
using Foundatio.Messaging;

IMessageBus messageBus = new InMemoryMessageBus();
await messageBus.SubscribeAsync<SimpleMessageA>(msg => {
  // Got message
});

await messageBus.PublishAsync(new SimpleMessageA { Data = "Hello" });

Jobs

Allows you to run a long running process (in process or out of process) without worrying about it being terminated prematurely. We provide three different ways of defining a job, based on your use case:

  1. Jobs: All jobs must derive from the IJob interface. We also have a JobBase base class you can derive from which provides a JobContext and logging. You can then run jobs by calling RunAsync() on the job or by creating a instance of the JobRunner class and calling one of the Run methods. The JobRunner can be used to easily run your jobs as Azure Web Jobs.
Sample
using Foundatio.Jobs;

public class HelloWorldJob : JobBase {
  public int RunCount { get; set; }

  protected override Task<JobResult> RunInternalAsync(JobContext context) {
     RunCount++;
     return Task.FromResult(JobResult.Success);
  }
}
var job = new HelloWorldJob();
await job.RunAsync(); // job.RunCount = 1;
await job.RunContinuousAsync(iterationLimit: 2); // job.RunCount = 3;
await job.RunContinuousAsync(cancellationToken: new CancellationTokenSource(10).Token); // job.RunCount > 10;
  1. Queue Processor Jobs: A queue processor job works great for working with jobs that will be driven from queued data. Queue Processor jobs must derive from QueueJobBase<T> class. You can then run jobs by calling RunAsync() on the job or passing it to the JobRunner class. The JobRunner can be used to easily run your jobs as Azure Web Jobs.
Sample
using Foundatio.Jobs;

public class HelloWorldQueueJob : QueueJobBase<HelloWorldQueueItem> {
  public int RunCount { get; set; }

  public HelloWorldQueueJob(IQueue<HelloWorldQueueItem> queue) : base(queue) {}

  protected override Task<JobResult> ProcessQueueEntryAsync(QueueEntryContext<HelloWorldQueueItem> context) {
     RunCount++;

     return Task.FromResult(JobResult.Success);
  }
}

public class HelloWorldQueueItem {
  public string Message { get; set; }
}
 // Register the queue for HelloWorldQueueItem.
container.AddSingleton<IQueue<HelloWorldQueueItem>>(s => new InMemoryQueue<HelloWorldQueueItem>());

// To trigger the job we need to queue the HelloWorldWorkItem message.
// This assumes that we injected an instance of IQueue<HelloWorldWorkItem> queue

IJob job = new HelloWorldQueueJob();
await job.RunAsync(); // job.RunCount = 0; The RunCount wasn't incremented because we didn't enqueue any data.

await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });
await job.RunAsync(); // job.RunCount = 1;

await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });
await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });
await job.RunUntilEmptyAsync(); // job.RunCount = 3;
  1. Work Item Jobs: A work item job will run in a job pool among other work item jobs. This type of job works great for things that don't happen often but should be in a job (Example: Deleting an entity that has many children.). It will be triggered when you publish a message on the message bus. The job must derive from the WorkItemHandlerBase class. You can then run all shared jobs via JobRunner class. The JobRunner can be used to easily run your jobs as Azure Web Jobs.
Sample
using System.Threading.Tasks;
using Foundatio.Jobs;

public class HelloWorldWorkItemHandler : WorkItemHandlerBase {
  public override async Task HandleItemAsync(WorkItemContext ctx) {
    var workItem = ctx.GetData<HelloWorldWorkItem>();

    // We can report the progress over the message bus easily.
    // To receive these messages just inject IMessageSubscriber
    // and Subscribe to messages of type WorkItemStatus
    await ctx.ReportProgressAsync(0, "Starting Hello World Job");
    await Task.Delay(TimeSpan.FromSeconds(2.5));
    await ctx.ReportProgressAsync(50, "Reading value");
    await Task.Delay(TimeSpan.FromSeconds(.5));
    await ctx.ReportProgressAsync(70, "Reading value");
    await Task.Delay(TimeSpan.FromSeconds(.5));
    await ctx.ReportProgressAsync(90, "Reading value.");
    await Task.Delay(TimeSpan.FromSeconds(.5));

    await ctx.ReportProgressAsync(100, workItem.Message);
  }
}

public class HelloWorldWorkItem {
  public string Message { get; set; }
}
// Register the shared job.
var handlers = new WorkItemHandlers();
handlers.Register<HelloWorldWorkItem, HelloWorldWorkItemHandler>();

// Register the handlers with dependency injection.
container.AddSingleton(handlers);

// Register the queue for WorkItemData.
container.AddSingleton<IQueue<WorkItemData>>(s => new InMemoryQueue<WorkItemData>());

// The job runner will automatically look for and run all registered WorkItemHandlers.
new JobRunner(container.GetRequiredService<WorkItemJob>(), instanceCount: 2).RunInBackground();
 // To trigger the job we need to queue the HelloWorldWorkItem message.
 // This assumes that we injected an instance of IQueue<WorkItemData> queue

 // NOTE: You may have noticed that HelloWorldWorkItem doesn't derive from WorkItemData.
 // Foundatio has an extension method that takes the model you post and serializes it to the
 // WorkItemData.Data property.
 await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });

File Storage

We provide different file storage implementations that derive from the IFileStorage interface:

  1. InMemoryFileStorage: An in memory file implementation. This file storage implementation is only valid for the lifetime of the process.
  2. FolderFileStorage: An file storage implementation that uses the hard drive for storage.
  3. AzureFileStorage: An Azure Blob storage implementation.
  4. S3FileStorage: An AWS S3 file storage implementation.
  5. RedisFileStorage: An Redis file storage implementation.
  6. MinioFileStorage An Minio file storage implementation.
  7. AliyunFileStorage: An Aliyun file storage implementation.
  8. SshNetFileStorage: An SFTP file storage implementation.

We recommend using all of the IFileStorage implementations as singletons.

Sample
using Foundatio.Storage;

IFileStorage storage = new InMemoryFileStorage();
await storage.SaveFileAsync("test.txt", "test");
string content = await storage.GetFileContentsAsync("test.txt")

Metrics

We provide five implementations that derive from the IMetricsClient interface:

  1. InMemoryMetricsClient: An in memory metrics implementation.
  2. RedisMetricsClient: An Redis metrics implementation.
  3. StatsDMetricsClient: An statsd metrics implementation.
  4. MetricsNETClient: An Metrics.NET implementation.
  5. AppMetricsClient: An AppMetrics implementation.
  6. CloudWatchMetricsClient: An AWS CloudWatch implementation.

We recommend using all of the IMetricsClient implementations as singletons.

Sample
IMetricsClient metrics = new InMemoryMetricsClient();
metrics.Counter("c1");
metrics.Gauge("g1", 2.534);
metrics.Timer("t1", 50788);

Sample Application

We have both slides and a sample application that shows off how to use Foundatio.

Thanks to all the people who have contributed

contributors

Release Notes

https://github.com/FoundatioFx/Foundatio/releases

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version History

Version Downloads Last updated
10.2.1 57 7/19/2021
10.2.0 59 7/8/2021
10.1.4 111 6/16/2021
10.1.3 77 4/23/2021
10.1.2 75 4/23/2021
10.1.1 85 4/15/2021
10.1.0 81 4/13/2021
10.0.2 118 1/20/2021
10.0.1 227 11/2/2020
10.0.0 285 9/16/2020
10.0.0-beta9 173 8/25/2020
10.0.0-beta8 174 8/3/2020
10.0.0-beta7 212 7/29/2020
10.0.0-beta6 215 7/7/2020
10.0.0-beta5 366 6/20/2020
10.0.0-beta3 180 6/14/2020
10.0.0-beta2 279 6/6/2020
10.0.0-beta10 194 9/15/2020
10.0.0-beta1 228 5/26/2020
10.0.0-alpha3 193 5/5/2020
10.0.0-alpha2 186 4/27/2020
10.0.0-alpha1 208 4/25/2020
9.1.1 582 4/28/2020
9.1.0 210 4/28/2020
9.0.0 248 1/16/2020
8.1.2126 297 8/30/2019
8.1.2123 263 8/27/2019
8.1.2120 267 8/27/2019
8.1.2115 270 8/27/2019
8.1.2109 267 8/26/2019
8.1.2058 303 5/14/2019
8.1.2027 330 4/16/2019
8.0.1965 328 2/24/2019
8.0.1948 318 2/22/2019
7.1.1845 418 11/3/2018
7.1.1841 428 11/3/2018
7.1.1837 405 11/1/2018
7.1.1833 431 11/1/2018
7.0.1831 401 11/1/2018
7.0.1818 414 10/30/2018
7.0.1738 456 9/7/2018
7.0.1706 567 5/9/2018
6.0.1586 590 11/30/2017
5.1.1562 553 10/30/2017
5.1.1521 544 9/27/2017
5.1.1515 529 9/26/2017
5.1.1501 558 9/14/2017
5.1.1498 541 8/28/2017
5.1.1492 578 8/28/2017
5.1.1490 552 8/16/2017
5.1.1474 580 8/1/2017
5.1.1470 563 7/31/2017
5.1.1457 596 6/23/2017
5.1.1448 579 5/5/2017
5.1.1443 590 5/5/2017
5.0.1336 586 3/14/2017
5.0.1334 579 3/13/2017
5.0.1331 587 3/12/2017
5.0.1329-pre 566 3/12/2017
5.0.1328-pre 550 3/12/2017
5.0.1327-pre 566 3/12/2017
5.0.1326-pre 584 3/12/2017
5.0.1324-pre 576 3/12/2017
4.3.1323-pre 576 3/11/2017
4.3.1317 615 2/23/2017
4.3.1316 600 2/22/2017
4.3.1315 608 2/22/2017
4.3.1314 626 2/20/2017
4.3.1312 601 2/20/2017
4.3.1311-pre 563 2/20/2017
4.3.1307 601 2/16/2017
4.3.1306 582 2/15/2017
4.3.1305 607 2/15/2017
4.3.1304-pre 562 2/15/2017
4.3.1303-pre 580 2/14/2017
4.3.1301 588 2/14/2017
4.3.1299 603 2/14/2017
4.3.1293 619 2/12/2017
4.3.1292 587 2/10/2017
4.3.1291 601 2/10/2017
4.3.1290 589 2/10/2017
4.3.1289 593 2/9/2017
4.3.1288 592 2/9/2017
4.3.1286 613 2/8/2017
4.3.1282 619 2/5/2017
4.3.1281 619 2/5/2017
4.3.1280 587 2/5/2017
4.3.1276-pre 577 2/5/2017
4.3.1177-pre 618 9/2/2016
4.3.1164-pre 583 8/21/2016
4.2.1205-pre 619 9/19/2016
4.2.1183 649 9/9/2016
4.2.1179 608 9/8/2016
4.2.1176 618 9/2/2016
4.2.1172 599 9/1/2016
4.2.1171-pre 593 9/1/2016
4.2.1169 610 8/22/2016
4.2.1167-pre 604 8/22/2016
4.2.1166-pre 585 8/22/2016
4.2.1161 612 8/10/2016
4.2.1156-pre 582 8/2/2016
4.2.1155 632 8/1/2016
4.2.1150 626 7/20/2016
4.2.1149-pre 577 7/19/2016
4.2.1148-pre 576 7/19/2016
4.2.1147-pre 598 7/19/2016
4.2.1146-pre 620 7/19/2016
4.2.1137 602 7/19/2016
4.2.1129-pre 594 7/19/2016
4.2.1128-pre 576 7/19/2016
4.2.1127-pre 604 7/19/2016
4.2.1126-pre 576 7/19/2016
4.2.1125-pre 586 7/19/2016
4.2.1123-pre 592 7/19/2016
4.2.1119-pre 578 7/18/2016
4.2.1113-pre 596 7/16/2016
4.2.1108-pre 595 7/15/2016
4.2.1107-pre 587 7/15/2016
4.2.1104-pre 744 7/13/2016
4.2.1099-pre 756 7/12/2016
4.2.1098-pre 741 7/12/2016
4.2.1093-pre 626 7/8/2016
4.2.1091-pre 634 7/8/2016
4.2.1090-pre 595 7/8/2016
4.2.1089-pre 606 7/7/2016
4.2.1087-pre 603 7/7/2016
4.2.1083-pre 614 7/6/2016
4.2.1082-pre 633 7/6/2016
4.2.1081-pre 622 7/6/2016
4.2.1079-pre 598 7/6/2016
4.2.1078-pre 602 7/6/2016
4.2.1073-pre 636 7/5/2016
4.2.1070-pre 622 7/5/2016
4.2.1069-pre 602 7/1/2016
4.2.1059-pre 601 7/1/2016
4.2.1046-pre 581 6/24/2016
4.2.1031-pre 606 6/24/2016
4.2.1028-pre 613 6/24/2016
4.2.1027-pre 617 6/24/2016
4.1.1009 652 6/15/2016
4.1.1002-pre 600 6/14/2016
4.1.995-pre 625 6/13/2016
4.1.989-pre 611 5/26/2016
4.1.983-pre 588 5/25/2016
4.1.982-pre 589 5/25/2016
4.1.978-pre 584 5/6/2016
4.1.977-pre 595 5/5/2016
4.1.975-pre 592 5/5/2016
4.0.958 611 5/1/2016
4.0.957 613 4/29/2016
4.0.956 643 4/29/2016
4.0.955 634 4/28/2016
4.0.941 623 4/27/2016
4.0.940 634 4/27/2016
4.0.925 630 4/27/2016
4.0.922 639 4/27/2016
4.0.909 638 4/20/2016
4.0.880 660 4/7/2016
4.0.869 650 3/30/2016
4.0.864 615 3/29/2016
4.0.861 651 3/29/2016
4.0.860 623 3/29/2016
4.0.857 614 3/29/2016
4.0.855 638 3/29/2016
4.0.846 624 3/22/2016
4.0.842 624 3/21/2016
4.0.836 619 3/18/2016
4.0.835 622 3/18/2016
4.0.834 637 3/17/2016
4.0.832 618 3/17/2016
4.0.831 599 3/16/2016
4.0.829 614 3/16/2016
4.0.828 644 3/15/2016
4.0.827 634 3/15/2016
4.0.826 628 3/15/2016
4.0.825 700 3/13/2016
4.0.821 618 3/11/2016
4.0.819 666 3/11/2016
4.0.818 618 3/11/2016
4.0.816 681 3/11/2016
4.0.815 704 3/11/2016
4.0.814 630 3/11/2016
4.0.813 707 3/10/2016
4.0.812 671 3/10/2016
4.0.811 683 3/10/2016
4.0.810 635 3/10/2016
4.0.809 630 3/10/2016
4.0.805 618 3/9/2016
4.0.797 632 3/9/2016
4.0.796 628 3/9/2016
4.0.794 624 3/9/2016
4.0.793 639 3/9/2016
4.0.792 637 3/8/2016
4.0.791 616 3/8/2016
4.0.790 621 3/8/2016
4.0.788 624 3/8/2016
4.0.774 634 3/2/2016
4.0.773 625 3/1/2016
4.0.772 654 3/1/2016
4.0.770 627 3/1/2016
4.0.769 633 3/1/2016
4.0.762 639 3/1/2016
4.0.761 624 3/1/2016
4.0.760 630 2/29/2016
4.0.759 635 2/29/2016
4.0.758 639 2/29/2016
4.0.757 615 2/29/2016
4.0.756 626 2/27/2016
4.0.755 621 2/27/2016
4.0.754 618 2/27/2016
4.0.753 638 2/27/2016
4.0.752 657 2/27/2016
4.0.750 604 2/27/2016
4.0.749 621 2/27/2016
4.0.747 631 2/26/2016
4.0.746 621 2/26/2016
4.0.744 635 2/26/2016
4.0.743 641 2/26/2016
4.0.742 647 2/26/2016
4.0.741 618 2/26/2016
4.0.739 622 2/25/2016
4.0.738 613 2/25/2016
4.0.734 622 2/25/2016
4.0.733-beta 578 2/25/2016
4.0.672 616 2/16/2016
4.0.669 605 2/11/2016
4.0.668 685 2/11/2016
3.0.654 627 2/10/2016
3.0.646 637 2/5/2016
3.0.645 625 2/5/2016
3.0.644 608 2/5/2016
3.0.639 625 2/3/2016
3.0.638 619 2/2/2016
3.0.637 631 2/1/2016
3.0.635 597 2/1/2016
3.0.633 613 1/27/2016
3.0.632 631 1/27/2016
3.0.629 632 1/18/2016
3.0.626 639 1/18/2016
3.0.625 633 1/18/2016
3.0.624 627 12/17/2015
3.0.623 669 12/9/2015
3.0.622 621 12/9/2015
3.0.621 634 12/9/2015
3.0.620 622 12/8/2015
3.0.613 630 12/4/2015
3.0.611 628 12/3/2015
3.0.610 648 11/30/2015
3.0.606 636 11/30/2015
3.0.605 628 11/25/2015
3.0.603 660 11/23/2015
3.0.601 639 11/23/2015
3.0.600 673 11/19/2015
3.0.599 647 11/19/2015
3.0.598 658 11/17/2015
3.0.592 659 11/12/2015
3.0.589 644 11/10/2015
3.0.588 653 11/10/2015
3.0.586 636 11/10/2015
3.0.584 655 11/10/2015
3.0.583 659 11/10/2015
3.0.581 643 11/6/2015
3.0.579 613 11/6/2015
3.0.576 649 11/5/2015
3.0.575 639 11/4/2015
3.0.574 660 11/4/2015
3.0.569 632 11/3/2015
3.0.568 645 11/3/2015
3.0.566 641 11/3/2015
3.0.545 654 10/28/2015
3.0.538 649 10/22/2015
3.0.537 651 10/21/2015
3.0.536 648 10/21/2015
3.0.534 640 10/21/2015
3.0.532 652 10/21/2015
3.0.531 638 10/21/2015
3.0.524 656 10/15/2015
3.0.523 662 10/10/2015
3.0.522 635 10/10/2015
3.0.520 631 10/9/2015
3.0.519 645 10/9/2015
3.0.518 642 10/9/2015
3.0.517 646 10/9/2015
3.0.516 655 10/7/2015
3.0.514 648 10/6/2015
3.0.513 658 10/6/2015
3.0.512 642 10/6/2015
3.0.509 661 10/1/2015
3.0.507 662 10/1/2015
3.0.505 655 9/30/2015
3.0.503 649 9/30/2015
3.0.502 635 9/30/2015
3.0.479 655 9/25/2015
3.0.476 646 9/24/2015
3.0.471 655 9/24/2015
3.0.470 642 9/24/2015
3.0.469 644 9/24/2015
3.0.468 645 9/24/2015
3.0.467 666 9/24/2015
3.0.465 661 9/24/2015
3.0.459 654 9/23/2015
3.0.456 663 9/23/2015
3.0.455 641 9/22/2015
3.0.454 670 9/19/2015
3.0.453 696 9/19/2015
3.0.452 654 9/18/2015
3.0.451 680 9/18/2015
3.0.450 657 9/18/2015
3.0.447 650 9/18/2015
2.0.378 664 9/5/2015
2.0.372 672 9/4/2015
2.0.370 675 9/4/2015
2.0.368 659 9/4/2015
2.0.365 661 9/3/2015
2.0.363 673 9/3/2015
2.0.361 648 9/3/2015
1.0.360 671 9/1/2015
1.0.359 655 9/1/2015
1.0.358 643 9/1/2015
1.0.356 656 8/31/2015
1.0.355 737 8/31/2015
1.0.354 647 8/29/2015
1.0.305 667 8/19/2015
1.0.299 631 8/8/2015
1.0.293 632 7/20/2015
1.0.292 630 7/20/2015
1.0.289 643 7/10/2015
1.0.288 630 7/10/2015
1.0.286 684 7/7/2015
1.0.285 655 7/7/2015
1.0.284 660 7/7/2015
1.0.282 656 7/6/2015
1.0.281 654 7/6/2015
1.0.279 669 7/6/2015
1.0.277 660 6/18/2015
1.0.276 638 6/8/2015
1.0.275 636 6/8/2015
1.0.274 638 6/8/2015
1.0.272 778 6/1/2015
1.0.269 669 5/25/2015
1.0.268 662 5/24/2015
1.0.266 684 5/24/2015
1.0.263 649 5/21/2015
1.0.258 646 5/19/2015
1.0.257 642 5/18/2015
1.0.256 702 5/17/2015
1.0.254 646 5/13/2015
1.0.253 668 5/13/2015
1.0.250 651 5/13/2015
1.0.249 671 5/12/2015
1.0.248 633 5/12/2015
1.0.245 648 5/12/2015
1.0.241 656 5/12/2015