skip to Main Content

I’ve been having some issues with my Azure Function that monitors a blob storage. I’ve followed the tutorial here: https://learn.microsoft.com/en-us/azure/azure-functions/functions-event-grid-blob-trigger?pivots=programming-language-csharp

I have my Azure Function setup, my event grid webhook setup and my blob storage ready.
In application insights, I can see no errors for my app:
enter image description here

Then monitoring the event grid, I can see the uploads are triggered.
enter image description here

However, my Azure Function never triggers. I’m using the template code Visual Studio Code provides, the function also works fine when running locally.

Any suggestions on what I’m perhaps doing wrong, or someone that can point me in the right direction?

** UPDATE:

I’ve run the function locally too and set the webhook to route via ngrok. It runs as expected. So it does seem the issue seem to be the webhook receiving the information or the running of the Azure Function.

There is nothing or no errors on the logs at all. I’m not sure what else to do here. Any guidance on debugging would be appreciated.

My code looks as follows:

using System.IO;
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace initroot.io
{
    public class XXX
    {
        private readonly ILogger<XXX> _logger;

        public XXXX(ILogger<XXX> logger)
        {
            _logger = logger;
        }

        [Function(nameof(XXXX))]
        public async Task Run([BlobTrigger("XXXX/{name}", Source = BlobTriggerSource.EventGrid, Connection = "420bee_STORAGE")] Stream stream, string name)
        {
            using var blobStreamReader = new StreamReader(stream);
            var content = await blobStreamReader.ReadToEndAsync();
            _logger.LogInformation($"C# Blob Trigger (using Event Grid) processed blobn Name: {name} n Data: {content}");
        }
    }
}

When looking into the Azure Metric, I can see that each time I upload a new file, an instance is started for the Azure Function, indicating that the webhook is working. However, it seems the execution just never happens, or no output.

2

Answers


  1. Chosen as BEST ANSWER

    Just for anyone else that wants a full solution to read the blobs too. This is not using isolated runtimes.

    // Default URL for triggering event grid function in the local environment.
    // http://localhost:7071/runtime/webhooks/EventGrid?functionName={functionname}
    using System;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.EventGrid;
    using Microsoft.Extensions.Logging;
    using Azure.Messaging.EventGrid;
    using Azure.Storage.Blobs;
    using System.Threading.Tasks;
    using System.IO;
    using System.Text.Json;
    using Newtonsoft.Json.Linq;
    using Azure.Identity;
    using Azure.Storage.Blobs.Models;
    
    namespace XXX
    {
        public static class BlobEventTrigger
        {
            [FunctionName("BlobEventTrigger")]
            public static async Task RunAsync([EventGridTrigger]EventGridEvent eventGridEvent, ILogger log)
        {
                log.LogInformation($"Event Grid trigger function processed an event: {eventGridEvent.EventType}");
    
                if (eventGridEvent.EventType == "Microsoft.Storage.BlobCreated")
                {
                StorageBlobCreatedEventData createdEvent;
    
                if (eventGridEvent.Data is BinaryData binaryData)
                {
                    string jsonData = binaryData.ToString();
                    JObject jObject = JObject.Parse(jsonData);
                    createdEvent = jObject.ToObject<StorageBlobCreatedEventData>();
                }
                else
                {
                    throw new InvalidOperationException("Unexpected event data type");
                }
        
                log.LogInformation($"Blob: {createdEvent.Url}");
                log.LogInformation($"Api operation: {createdEvent.Api}");
     
    
                if (string.IsNullOrEmpty(createdEvent.Url))
                {
                    log.LogInformation($"Blob content: {createdEvent.Url}");
                    log.LogError("Event data or Blob URL is null or empty.");
                    return;
                }
    
                 var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
                {
                    ManagedIdentityClientId = "XXXXXXXX"
                });
    
                // Create a BlobClient from the blob URL
                BlobClient blobClient = new BlobClient(new Uri(createdEvent.Url),credential);
    
                try
                {
                    // Download the blob content
                    var response = await blobClient.DownloadAsync();
    
                    // Check if the blob exists and log its properties
                    BlobProperties properties = await blobClient.GetPropertiesAsync();
                    log.LogInformation($"Blob properties: {properties.BlobType}, {properties.ContentType}");
    
    
                    // Download the blob content
                    BlobDownloadInfo download = await blobClient.DownloadAsync();
                    using (StreamReader reader = new StreamReader(download.Content, true))
                    {
                        string content = await reader.ReadToEndAsync();
                        log.LogInformation($"Blob content: {content}");
                    }
                }
                catch (Exception ex)
                {
                    log.LogError($"Error reading blob: {ex.Message}");
                }
            }
        }
    }
    
        public class StorageBlobCreatedEventData
        {
            public string Api { get; set; }
            public string ClientRequestId { get; set; }
            public string RequestId { get; set; }
            public string ETag { get; set; }
            public string ContentType { get; set; }
            public int ContentLength { get; set; }
            public string BlobType { get; set; }
            public string Url { get; set; }
            public string Sequencer { get; set; }
            public StorageDiagnostics StorageDiagnostics { get; set; }
        }
    
        public class StorageDiagnostics
        {
            public string BatchId { get; set; }
        }
    }
    

  2. Initially, I was also getting same issue. In this case while adding the type of blob events in event grid subscription blob trigger is not available.

    For getting the same requirement I have created event grid trigger function with runtime stack .NET 8.0 isolated.

    Function code:

    using System;
    using Azure.Messaging.EventGrid;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Extensions.Logging;
    
    namespace Company.Function
    {
        public class EventGridTrigger1
        {
            private readonly ILogger<EventGridTrigger1> _logger;
    
            public EventGridTrigger1(ILogger<EventGridTrigger1> logger)
            {
                _logger = logger;
            }
    
            [Function(nameof(EventGridTrigger1))]
            public void Run([EventGridTrigger] EventGridEvent eventGridEvent)
            {
                _logger.LogInformation("Event type: {type}, Event subject: {subject}", eventGridEvent.EventType, eventGridEvent.Subject);
    
                // Optional: Deserialize event data if needed
                var data = eventGridEvent.Data.ToString();
                _logger.LogInformation($"Event Data: {data}");
            }
        }
    }
    
    

    I have deployed the function into azure portal successfully.

    enter image description here

    • I have configured the function endpoint in event grid subscription in storage events.

    enter image description here

    enter image description here

    When i uploaded or deleted the blobs in container function got triggered successfully. check below:

    Event grid output:

    enter image description here

    Function output:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search