Foundatio.MetricsNET 10.1.4

Pluggable foundation blocks for building distributed apps.

Install-Package Foundatio.MetricsNET -Version 10.1.4
dotnet add package Foundatio.MetricsNET --version 10.1.4
<PackageReference Include="Foundatio.MetricsNET" Version="10.1.4" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Foundatio.MetricsNET --version 10.1.4
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Foundatio.MetricsNET, 10.1.4"
#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.1.4

// Install Foundatio.MetricsNET as a Cake Tool
#tool nuget:?package=Foundatio.MetricsNET&version=10.1.4
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.1.4 50 6/16/2021
10.1.3 60 4/23/2021
10.1.2 59 4/23/2021
10.1.1 70 4/15/2021
10.1.0 69 4/13/2021
10.0.2 109 1/20/2021
10.0.1 219 11/2/2020
10.0.0 277 9/16/2020
10.0.0-beta9 170 8/25/2020
10.0.0-beta8 171 8/3/2020
10.0.0-beta7 208 7/29/2020
10.0.0-beta6 212 7/7/2020
10.0.0-beta5 363 6/20/2020
10.0.0-beta3 176 6/14/2020
10.0.0-beta2 276 6/6/2020
10.0.0-beta10 191 9/15/2020
10.0.0-beta1 225 5/26/2020
10.0.0-alpha3 189 5/5/2020
10.0.0-alpha2 180 4/27/2020
10.0.0-alpha1 203 4/25/2020
9.1.1 573 4/28/2020
9.1.0 202 4/28/2020
9.0.0 238 1/16/2020
8.1.2126 287 8/30/2019
8.1.2123 254 8/27/2019
8.1.2120 258 8/27/2019
8.1.2115 259 8/27/2019
8.1.2109 255 8/26/2019
8.1.2058 293 5/14/2019
8.1.2027 320 4/16/2019
8.0.1965 318 2/24/2019
8.0.1948 308 2/22/2019
7.1.1845 408 11/3/2018
7.1.1841 418 11/3/2018
7.1.1837 396 11/1/2018
7.1.1833 420 11/1/2018
7.0.1831 391 11/1/2018
7.0.1818 404 10/30/2018
7.0.1738 445 9/7/2018
7.0.1706 552 5/9/2018
6.0.1586 574 11/30/2017
5.1.1562 540 10/30/2017
5.1.1521 530 9/27/2017
5.1.1515 514 9/26/2017
5.1.1501 545 9/14/2017
5.1.1498 529 8/28/2017
5.1.1492 566 8/28/2017
5.1.1490 539 8/16/2017
5.1.1474 566 8/1/2017
5.1.1470 549 7/31/2017
5.1.1457 583 6/23/2017
5.1.1448 565 5/5/2017
5.1.1443 577 5/5/2017
5.0.1336 573 3/14/2017
5.0.1334 566 3/13/2017
5.0.1331 575 3/12/2017
5.0.1329-pre 557 3/12/2017
5.0.1328-pre 543 3/12/2017
5.0.1327-pre 559 3/12/2017
5.0.1326-pre 576 3/12/2017
5.0.1324-pre 567 3/12/2017
4.3.1323-pre 568 3/11/2017
4.3.1317 602 2/23/2017
4.3.1316 587 2/22/2017
4.3.1315 595 2/22/2017
4.3.1314 613 2/20/2017
4.3.1312 588 2/20/2017
4.3.1311-pre 555 2/20/2017
4.3.1307 589 2/16/2017
4.3.1306 568 2/15/2017
4.3.1305 594 2/15/2017
4.3.1304-pre 554 2/15/2017
4.3.1303-pre 572 2/14/2017
4.3.1301 575 2/14/2017
4.3.1299 590 2/14/2017
4.3.1293 606 2/12/2017
4.3.1292 574 2/10/2017
4.3.1291 589 2/10/2017
4.3.1290 575 2/10/2017
4.3.1289 580 2/9/2017
4.3.1288 578 2/9/2017
4.3.1286 599 2/8/2017
4.3.1282 606 2/5/2017
4.3.1281 605 2/5/2017
4.3.1280 573 2/5/2017
4.3.1276-pre 570 2/5/2017
4.3.1177-pre 608 9/2/2016
4.3.1164-pre 574 8/21/2016
4.2.1205-pre 611 9/19/2016
4.2.1183 635 9/9/2016
4.2.1179 593 9/8/2016
4.2.1176 604 9/2/2016
4.2.1172 584 9/1/2016
4.2.1171-pre 584 9/1/2016
4.2.1169 595 8/22/2016
4.2.1167-pre 595 8/22/2016
4.2.1166-pre 577 8/22/2016
4.2.1161 598 8/10/2016
4.2.1156-pre 572 8/2/2016
4.2.1155 616 8/1/2016
4.2.1150 613 7/20/2016
4.2.1149-pre 569 7/19/2016
4.2.1148-pre 568 7/19/2016
4.2.1147-pre 591 7/19/2016
4.2.1146-pre 613 7/19/2016
4.2.1137 590 7/19/2016
4.2.1129-pre 586 7/19/2016
4.2.1128-pre 568 7/19/2016
4.2.1127-pre 597 7/19/2016
4.2.1126-pre 569 7/19/2016
4.2.1125-pre 579 7/19/2016
4.2.1123-pre 583 7/19/2016
4.2.1119-pre 570 7/18/2016
4.2.1113-pre 588 7/16/2016
4.2.1108-pre 586 7/15/2016
4.2.1107-pre 578 7/15/2016
4.2.1104-pre 735 7/13/2016
4.2.1099-pre 747 7/12/2016
4.2.1098-pre 733 7/12/2016
4.2.1093-pre 618 7/8/2016
4.2.1091-pre 626 7/8/2016
4.2.1090-pre 588 7/8/2016
4.2.1089-pre 597 7/7/2016
4.2.1087-pre 593 7/7/2016
4.2.1083-pre 605 7/6/2016
4.2.1082-pre 625 7/6/2016
4.2.1081-pre 614 7/6/2016
4.2.1079-pre 590 7/6/2016
4.2.1078-pre 595 7/6/2016
4.2.1073-pre 628 7/5/2016
4.2.1070-pre 613 7/5/2016
4.2.1069-pre 594 7/1/2016
4.2.1059-pre 592 7/1/2016
4.2.1046-pre 574 6/24/2016
4.2.1031-pre 598 6/24/2016
4.2.1028-pre 605 6/24/2016
4.2.1027-pre 610 6/24/2016
4.1.1009 639 6/15/2016
4.1.1002-pre 590 6/14/2016
4.1.995-pre 617 6/13/2016
4.1.989-pre 603 5/26/2016
4.1.983-pre 580 5/25/2016
4.1.982-pre 581 5/25/2016
4.1.978-pre 575 5/6/2016
4.1.977-pre 586 5/5/2016
4.1.975-pre 584 5/5/2016
4.0.958 598 5/1/2016
4.0.957 598 4/29/2016
4.0.956 628 4/29/2016
4.0.955 619 4/28/2016
4.0.941 609 4/27/2016
4.0.940 620 4/27/2016
4.0.925 615 4/27/2016
4.0.922 625 4/27/2016
4.0.909 624 4/20/2016
4.0.880 647 4/7/2016
4.0.869 635 3/30/2016
4.0.864 601 3/29/2016
4.0.861 638 3/29/2016
4.0.860 608 3/29/2016
4.0.857 601 3/29/2016
4.0.855 624 3/29/2016
4.0.846 611 3/22/2016
4.0.842 611 3/21/2016
4.0.836 606 3/18/2016
4.0.835 607 3/18/2016
4.0.834 624 3/17/2016
4.0.832 603 3/17/2016
4.0.831 585 3/16/2016
4.0.829 600 3/16/2016
4.0.828 631 3/15/2016
4.0.827 621 3/15/2016
4.0.826 614 3/15/2016
4.0.825 686 3/13/2016
4.0.821 604 3/11/2016
4.0.819 651 3/11/2016
4.0.818 604 3/11/2016
4.0.816 665 3/11/2016
4.0.815 688 3/11/2016
4.0.814 616 3/11/2016
4.0.813 692 3/10/2016
4.0.812 656 3/10/2016
4.0.811 668 3/10/2016
4.0.810 620 3/10/2016
4.0.809 616 3/10/2016
4.0.805 604 3/9/2016
4.0.797 618 3/9/2016
4.0.796 614 3/9/2016
4.0.794 610 3/9/2016
4.0.793 625 3/9/2016
4.0.792 622 3/8/2016
4.0.791 603 3/8/2016
4.0.790 606 3/8/2016
4.0.788 610 3/8/2016
4.0.774 618 3/2/2016
4.0.773 610 3/1/2016
4.0.772 640 3/1/2016
4.0.770 613 3/1/2016
4.0.769 620 3/1/2016
4.0.762 626 3/1/2016
4.0.761 610 3/1/2016
4.0.760 617 2/29/2016
4.0.759 622 2/29/2016
4.0.758 625 2/29/2016
4.0.757 601 2/29/2016
4.0.756 613 2/27/2016
4.0.755 608 2/27/2016
4.0.754 604 2/27/2016
4.0.753 625 2/27/2016
4.0.752 643 2/27/2016
4.0.750 591 2/27/2016
4.0.749 606 2/27/2016
4.0.747 616 2/26/2016
4.0.746 608 2/26/2016
4.0.744 620 2/26/2016
4.0.743 628 2/26/2016
4.0.742 633 2/26/2016
4.0.741 604 2/26/2016
4.0.739 609 2/25/2016
4.0.738 598 2/25/2016
4.0.734 608 2/25/2016
4.0.733-beta 568 2/25/2016
4.0.672 604 2/16/2016
4.0.669 592 2/11/2016
4.0.668 669 2/11/2016
3.0.654 613 2/10/2016
3.0.646 623 2/5/2016
3.0.645 610 2/5/2016
3.0.644 595 2/5/2016
3.0.639 612 2/3/2016
3.0.638 606 2/2/2016
3.0.637 617 2/1/2016
3.0.635 584 2/1/2016
3.0.633 600 1/27/2016
3.0.632 617 1/27/2016
3.0.629 619 1/18/2016
3.0.626 626 1/18/2016
3.0.625 619 1/18/2016
3.0.624 612 12/17/2015
3.0.623 654 12/9/2015
3.0.622 605 12/9/2015
3.0.621 618 12/9/2015
3.0.620 607 12/8/2015
3.0.613 615 12/4/2015
3.0.611 612 12/3/2015
3.0.610 633 11/30/2015
3.0.606 621 11/30/2015
3.0.605 614 11/25/2015
3.0.603 645 11/23/2015
3.0.601 624 11/23/2015
3.0.600 658 11/19/2015
3.0.599 632 11/19/2015
3.0.598 642 11/17/2015
3.0.592 645 11/12/2015
3.0.589 630 11/10/2015
3.0.588 638 11/10/2015
3.0.586 621 11/10/2015
3.0.584 639 11/10/2015
3.0.583 643 11/10/2015
3.0.581 627 11/6/2015
3.0.579 596 11/6/2015
3.0.576 634 11/5/2015
3.0.575 623 11/4/2015
3.0.574 645 11/4/2015
3.0.569 616 11/3/2015
3.0.568 630 11/3/2015
3.0.566 626 11/3/2015
3.0.545 639 10/28/2015
3.0.538 633 10/22/2015
3.0.537 637 10/21/2015
3.0.536 634 10/21/2015
3.0.534 625 10/21/2015
3.0.532 637 10/21/2015
3.0.531 623 10/21/2015
3.0.524 641 10/15/2015
3.0.523 647 10/10/2015
3.0.522 621 10/10/2015
3.0.520 617 10/9/2015
3.0.519 629 10/9/2015
3.0.518 627 10/9/2015
3.0.517 632 10/9/2015
3.0.516 639 10/7/2015
3.0.514 633 10/6/2015
3.0.513 642 10/6/2015
3.0.512 627 10/6/2015
3.0.509 646 10/1/2015
3.0.507 646 10/1/2015
3.0.505 639 9/30/2015
3.0.503 634 9/30/2015
3.0.502 619 9/30/2015
3.0.479 640 9/25/2015
3.0.476 632 9/24/2015
3.0.471 639 9/24/2015
3.0.470 626 9/24/2015
3.0.469 629 9/24/2015
3.0.468 630 9/24/2015
3.0.467 652 9/24/2015
3.0.465 645 9/24/2015
3.0.459 639 9/23/2015
3.0.456 647 9/23/2015
3.0.455 626 9/22/2015
3.0.454 654 9/19/2015
3.0.453 682 9/19/2015
3.0.452 640 9/18/2015
3.0.451 665 9/18/2015
3.0.450 642 9/18/2015
3.0.447 636 9/18/2015
2.0.378 649 9/5/2015
2.0.372 658 9/4/2015
2.0.370 661 9/4/2015
2.0.368 644 9/4/2015
2.0.365 646 9/3/2015
2.0.363 659 9/3/2015
2.0.361 633 9/3/2015
1.0.360 656 9/1/2015
1.0.359 640 9/1/2015
1.0.358 628 9/1/2015
1.0.356 641 8/31/2015
1.0.355 722 8/31/2015
1.0.354 633 8/29/2015
1.0.305 652 8/19/2015
1.0.299 615 8/8/2015
1.0.293 616 7/20/2015
1.0.292 615 7/20/2015
1.0.289 627 7/10/2015
1.0.288 615 7/10/2015
1.0.286 668 7/7/2015
1.0.285 640 7/7/2015
1.0.284 644 7/7/2015
1.0.282 641 7/6/2015
1.0.281 639 7/6/2015
1.0.279 653 7/6/2015
1.0.277 645 6/18/2015
1.0.276 623 6/8/2015
1.0.275 620 6/8/2015
1.0.274 622 6/8/2015
1.0.272 759 6/1/2015
1.0.269 654 5/25/2015
1.0.268 646 5/24/2015
1.0.266 668 5/24/2015
1.0.263 633 5/21/2015
1.0.258 629 5/19/2015
1.0.257 625 5/18/2015
1.0.256 683 5/17/2015
1.0.254 631 5/13/2015
1.0.253 652 5/13/2015
1.0.250 634 5/13/2015
1.0.249 653 5/12/2015
1.0.248 615 5/12/2015
1.0.245 632 5/12/2015
1.0.241 638 5/12/2015