Card image cap

Integrating ASP.NET Core API Logs to Amazon CloudWatch via ILogger

ASP.NET Core AWS  • Posted 7 months ago

In a previous article, we have looked at how we can configure our ASP.NET API to push generated logs onto Azure Application Insights for deeper processing and insights. By making use of the native ILogger interface which comes packed with the dotnet core SDK we can achieve complete abstraction of application and trace logging, while making a choice where the generated logs can be maintained.

In this article, let's look at how we can achieve the same with yet another popular cloud provider; aka the Amazon Cloud Services. We shall use the AWS CloudWatch, which is a comprehensive logging and analytics setup for storing, processing and analyzing what happens in an application deployed under Amazon EC2 or Elastic Beanstalk instance. CloudWatch also provides tools and API support for further exporting and processing in a customized way.

Read: Integrating ASP.NET Core API Logs to Azure Application Insights via ILogger


Integrating AWS SDK for programmatically utilizing features such as CloudWatch, S3 or other services involves installing the SDK for respective services. In this case, we shall integrate our exsiting ReadersAPI to an AWS CloudWatch instance (or implicitly create one if not exists) in three steps.

  1. Install AWS CloudWatch SDK:

In the first step, we shall include the AWS SDK which shall provide us tools for including cloudwatch support in our ASP.NET Core application. For this we shall install by the below command:

> dotnet add package AWS.Logger.AspNetCore --Version 2.2.0

or within the .csproj file add as a new Item,

    <PackageReference Include="AWS.Logger.AspNetCore" Version="2.2.0" />

Once this is done, we can use these tools in our cause; which is basically a few changes in the Startup.cs !

  1. Configure Logging Middleware:

This step is almost similar to what we have done to integrate Application Insights; we would need to hookup the AWS Cloudwatch instance onto the ILogging middleware, provided by the dotnet core SDK so that whatever logs are generated via ILogger shall also be pushed onto CloudWatch; treating it as a LogProvider.

namespace ReadersApi
    public class Startup
        public Startup(IConfiguration configuration)
            Configuration = configuration;

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
            services.AddLogging(config =>

the method config.AddAWSProvider() comes out from the included assembly AWS.Logger.AspNetCore; which is added as a part of LoggerExtensions from the namespace Mircosoft.Extensions.Logging. Wondering how do we supply the necessary configuration about the targeted CloudWatch instance? the method call, Configuration.GetAWSLoggingConfigSection() which we're passing as a parameter returns a ConfigurationSection from the appsettings.json file; which we shall add in the next step.

  1. Supplying Configuration via appsettings.json

In this we shall provide information to the AWS Logger Provider about what CloudWatch instance it needs to connect to for pushing the logs and the levels of logging. This is supplied via the Logging section in the appsettings.json file, which we shall modify as below:

  "Logging": {
    "Region": "us-west-2",
    "LogGroup": "ReadersApi.Logging",
    "IncludeLogLevel": true,
    "IncludeCategory": true,
    "IncludeNewline": true,
    "IncludeException": true,
    "IncludeEventId": false,
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"

When you look at it, we provide the details about in which region the Log shall be (created and) connected, and what is the name of the "LogGroup" - the term used by AWS to represent an individual grouping for an application related logs generated. The others are flags to represent what needs to be logged and what shouldn't be (pretty much similar for all log providers).

Once we are done with these steps, when we deploy our application under an EC2 instance or an Elastic Beanstalk environment; we can be able to view the traces and informations generated by our application under the LogGroup "ReadersApi.Logging" for the Region "us-west-2" or "Oregon" (which we can change on the top right of the AWS Management Console).

There are only two cases when this setup works:

  1. when we run locally via Visual Studio with AWS Toolkit available and Signed in
  2. when the application runs in an EC2 instance with necessary IAM role permissions provided for the profile the EC2 instance bears. Only under these two scenarios we can be able to view logs under CloudWatch.


Because unlike the Application Insights we saw earlier which runs merely on an Instrumentation Key, the AWS provides a higher level of security and developer complexity for its services by checking on the IAM profile that the instance runs. Generally AWS checks for any available user profile in the environment under .aws\credentials file. This is a shared credentials file created when one signs into AWS Toolkit within Visual Studio using one's credentials. Similarly this file will also be available under the same path in the deployed EC2 instance. Hence this is mandatory for the CloudWatch to work.

Keeping these prerequisites aside, when everything is in place as expected from above; we can see our logs under the CloudWatch portal as below:


This way, we can integrate our application logs in an ASP.NET Core application via ILogger onto a CloudWatch instance.

Enjoying my posts?
You can now show me your support! 😊

What is the difference between Run() and Use() methods in IApplicationBuilder?

* Use() method: Used to create a simple middleware which can be "chained" to other functions over the pipeline. Takes two arguments: RequestDelegate ...

What is the difference between Response.Redirect() and Server.Transfer() ?

* Response.Redirect() redirects browser to another page, history is updated, trip back to client where browser loads the new page. * Server.Transfer( ...

How do you handle errors Globally in ASP.NET Core?

We can make use of the built-in UseExceptionHandler() middleware for catching Global Errors in ASP.NET Core. ``` app.UseExceptionHandler(err => ...

How do you design a strongly-typed class for a configuration?

To create a strongly-typed class for binding to a configuration section: * The property names and their types match the key names and their value t ...

How can you bind a configuration section to an object?

A Configuration section can be bound to a strictly-typed class object in two ways: * use Configuration.Bind() by passing the configuration section to ...

We use cookies to provide you with a great user experience, analyze traffic and serve targeted promotions.   Learn More   Accept