Friday, 29 November 2019

AWS Logging with Elastic Search and Kibana with C#

ELK is very famous for logging functionality. Here is the implementation of ELK (Elastic search + Logstash + Kibana) with .Net framework. I have used serilog with Elastic search instead of logstash, which is widely used in .Net.

Step 1: Create Elastic Search Domain. Follow bellow link.
https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-gsg-create-domain.html

Step 2: Open Visual Studio and create new console application in .Net Core.

Step 3: Open NuGet management console and install below packages:

    - Serilog.Sinks.Elasticsearch
    - Elasticsearch.Net.aws
    - Elasticsearch.Net

Step 4: In StartUp() register serilog that sink with Elastic serach.

Log.Logger= new LoggerConfiguration()
               .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("YourElasticEndPoint")))
               {
                   ModifyConnectionSettings = conn =>
                   {
                       var httpConnection = new AwsHttpConnection("YourAWSRegion");
                       var pool = new SingleNodeConnectionPool(new Uri("YourElasticEndPoint"));
                       var conf = new ConnectionConfiguration(pool, httpConnection);
                       return conf;
                   },
                   IndexFormat="YourIndexName-{0:MM-yyyy}"
               })
            .CreateLogger();

You can specify AWS Credentials in httpConnection object.

Step 5: Start using Serilogs. Log your events as below.

Log.Information("Event Occured!");
Log.Error(ex,"Error Occured");//ex is exception object
You can log complete object as well.

var auditlog = new AuditLog()
               {
                   FirstName = "Priyanka",
                   LastName = "Shah",             
                   FieldName = "AppintmentConfirmationWriteBackStatus",
                   PreviousValue = "true",
                   NewValue = "false",
                   LogDate = DateTime.Now
               };
Log.Information("{@auditlog}", auditlog);
Step 6: Check your logs in Kibana. Open Kibana dashboard. Create your Index as below.

Step 7: Click on Discover, apply your filters and see the logs.



Friday, 1 November 2019

AWS Lambda Prewarm



Lambdas can stay in RAM for 15mins. After that the request will be served from cold start stage. To avoid this latency, we need to keep lambdas alive. This concept is called as “Prewarming”. Certain containers will always ready to serve the request.
I have implemented Prewarming through cloud watch events. To do so, follow the steps as below.

Step 1: Create a rule in cloud watch. Set Schedule which will trigger lambda every 15mins.


Step 2: Add target to lambda function. Give the name of your lambda function “Pwa-prewarmmer-stage”. This lambda function takes two input parameters: number of containers to be created and whether to prewarm stage or production’s lambda.




This prewarming of lambda will invoke all other lambda’s and create containers for the same. This can be cross checked in cloud watch logs as below.



Code of Prewarm Lambda

[LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
        public async Task<string> FunctionHandlerAsync(JObject input,
            ILambdaContext lambdaContext)
        {
            int num=Convert.ToInt16( input["NumberofContainer"]);
            bool isProd=Convert.ToBoolean( input["isProd"]);
            try
            {
                Console.WriteLine("Prewarmer Start");
                for (int i = 1; i <= num; i++)
                {
                    using (AmazonLambdaClient client = new AmazonLambdaClient())
                    {
                        JObject ob = new JObject { { "Resource""WarmingLambda" }, { "Body", i.ToString() } };
                        var request = new InvokeRequest
                        {
                            FunctionName = isProd? "Pwa-lead" : "Pwa-lead-stage",
                            InvocationType = InvocationType.Event,
                            Payload = ob.ToString()
                        };
                        var response = await client.InvokeAsync(request);
                       
                    }
                }
                return "Lead prewarmer done";
            }
            catch (Exception ex)
            {
                return ex.Message + ex.StackTrace;
            }
        }
    }

Publish Lambda from Visual Studio



Here are the steps to publish .Net project as lambda in AWS from visual studio.

Step 1: Edit .csproj file and add below line of code.

<PropertyGroup>
    <AWSProjectType>Lambda</AWSProjectType>
  </PropertyGroup>

Step 2: Add Lambda function handler that will be init for API Gateway request.

public class LambdaFunction : APIGatewayProxyFunction
    {
        protected override void Init(IWebHostBuilder builder)
        {
            builder.UseContentRoot(Directory.GetCurrentDirectory())
                   .UseStartup<Startup>()
                   .UseLambdaServer();
        }
    }

Step 3: Add aws-lambda-tools-defaults.json file that will be used to store the publish settings.


Step 4: Finally, Publish Lambda to AWS from Visual Studio, by right click project and “Publish to AWS Lambda”. A wizard will open as shown below.




Settings to be configured in the above wizard

· Define environment variables (Staging or Production). Based on this variable, appsettings file will be executed.
·   Give PWA_Lambda_access IAM role to lambda function.
·   For .Net application Minimum RAM size is required 256MB.
·   All the lambda must be in VPC with proper security group to communicate with other assets.
·   Lambda stays warm for 15mins which are deployed in VPC. The idle lambda will be disposed after 15 mins and new request will be served from cold start.

With this Lambdas will be published on AWS.


Thursday, 31 October 2019

AWS API Gateway configuration


Here are the steps to configure API Gateway for integrated website.

Step 1: Create Rest API shown as below.



Step 2: Create resource as “proxy’.


Step 3: Create method as “Any” type

The method type is “Any”, so all the functions behind the Lambda either get or post will work within API. The invocation of the lambda function is dynamic. Define stage variable in place of lambda function name.



On click of Save, AWS will ask to add permission to Lambda function that can be executable by API gateway. Replace the value of ${stageVariables.functionname} to the lambda function name. Execute below command to CLI.
aws lambda add-permission  --function-name "arn:aws:lambda:ap-south-1:518955882229:function:${stageVariables.functionname}"  --source-arn "arn:aws:execute-api:ap-south-1:518955882229:u5ismynmx3/*/*/*"  --principal apigateway.amazonaws.com  --statement-id c7210776-beb6-4aad-bcfa-fdb20972f52f  --action lambda:InvokeFunction

Step 4: Deploy API

Create stages of API gateway like Stage and Prod.



 

Step 5: Assign lambda function to variable

Select the created stage. In stage variables, add new stage variable with name “functionname” and value “your lambda function”.

Step 6: Create custom domain for your API. (To be done by cloud team)

Step 7: Configure cloud watch Logs and alarms. Add newly created API to cloud watch dashboard (To be done by cloud team).