DEV Community

Jonathan Mourtada
Jonathan Mourtada

Posted on • Originally published at mourtada.se on

 

Create a simple azure function

In this post I’ll show you how to create a simple azure function which is triggered by a http call and logs the requests to an appendblob on azure blob storage.

Create a new project

First of all you will need to create a project. I just used the visual studio project template for azure functions(The Azure SDK is needed). Choose to create a Http trigger function and set the authorization level to anonymous

The code

Once created you will get a stub for a working http trigger function. Below is an example how to log the request to an appendblob.

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Azure.Storage.Blobs;
using System.Globalization;
using Azure.Storage.Blobs.Specialized;
using Azure.Storage.Blobs.Models;
using System.Text;
using Microsoft.Extensions.Primitives;
using System.Linq;

namespace MyAzureFunction
{
  public static class MyAzureFunction
    {
    [FunctionName("MyAzureFunction")]
    public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req,
    [Blob("my-blob-container")] BlobContainerClient container,
    ILogger log)
    {
      var culture = new CultureInfo("sv-SE");
      var clientIp = GetClientIp(req.Headers);

      var logStr = $"{DateTime.Now.ToString("T", culture)} {clientIp}\n";
      log.LogInformation(logStr);

      await container.CreateIfNotExistsAsync();
      var blobName = $"access_{DateTime.Now.ToString("d", culture).Replace("-", "")}.log";
      var appendBlob = container.GetAppendBlobClient(blobName);
      await appendBlob.CreateIfNotExistsAsync();
      await appendBlob.SetHttpHeadersAsync(new BlobHttpHeaders() { ContentType = "text/plain" });
      byte[] blockContent = Encoding.UTF8.GetBytes(logStr);
      using (var ms = new MemoryStream(blockContent))
      {
        await appendBlob.AppendBlockAsync(ms);
      }

      return new OkResult();
    }

    private static string GetClientIp(IHeaderDictionary headers)
    {
      headers.TryGetValue("X-Forwarded-For", out StringValues value);
      var clientIp = value.FirstOrDefault() ?? "missing-ip";
      return clientIp;
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

The first interesting part is the [Blob("my-blob-container")] BlobContainerClient container. This injects a BlobContainerClient that will be used with our interactions with the blob storage of our configured azure storage account.

It is important to use the new Azure.Storage.Blobs namespace. I had some troubles following old code examples that used deprecated namespaces and types. More information can be found here https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob-output?tabs=csharp#additional-types.

The function creates an appendblob for every new date and sets the content-type of the blob to text/plain. It then adds a row to the blob for every incoming http get request.

Top comments (0)

An Animated Guide to Node.js Event Loop

Node.js doesn’t stop from running other operations because of Libuv, a C++ library responsible for the event loop and asynchronously handling tasks such as network requests, DNS resolution, file system operations, data encryption, etc.

What happens under the hood when Node.js works on tasks such as database queries? We will explore it by following this piece of code step by step.