У меня возникли проблемы с функцией Azure, которая отслеживает хранилище BLOB-объектов. Я следил за руководством здесь: https://learn.microsoft.com/en-us/azure/azure-functions/functions-event-grid-blob-trigger?pivots=programming-language-csharp
У меня есть настройка функции Azure, настройка веб-перехватчика сетки событий и хранилище BLOB-объектов. В аналитике приложений я не вижу ошибок для своего приложения:
Затем, просматривая сетку событий, я вижу, что загрузка запускается.
Однако моя функция Azure никогда не срабатывает. Я использую код шаблона, предоставляемый Visual Studio Code, функция также отлично работает при локальном запуске.
Есть какие-нибудь предложения о том, что я, возможно, делаю неправильно, или кто-то, кто может указать мне правильное направление?
** ОБНОВЛЯТЬ:
Я также запустил эту функцию локально и настроил веб-перехватчик на маршрутизацию через ngrok. Он работает так, как ожидалось. Таким образом, похоже, что проблема заключается в том, что веб-перехватчик получает информацию или запускает функцию Azure.
В логах вообще нет ошибок или ничего нет. Я не знаю, что еще здесь делать. Любые рекомендации по отладке будут оценены по достоинству.
Мой код выглядит следующим образом:
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 blob\n Name: {name} \n Data: {content}");
}
}
}
Просматривая метрику Azure, я вижу, что каждый раз, когда я загружаю новый файл, запускается экземпляр функции Azure, что указывает на то, что веб-перехватчик работает. Однако, похоже, что выполнение никогда не происходит или нет вывода.


Первоначально у меня тоже возникла такая же проблема. В этом случае при добавлении типа событий BLOB-объекта в подписку на сетку событий триггер BLOB-объекта недоступен.
Для выполнения того же требования я создал функцию триггера сетки событий с изолированным стеком времени выполнения .NET 8.0.
Код функции:
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}");
}
}
}
Я успешно развернул эту функцию на портале Azure.

storage events.

Когда я загрузил или удалил капли в функции контейнера, они успешно сработали. проверьте ниже:
Вывод сетки событий:

Выход функции:

Просто для тех, кому нужно полное решение, можно также читать капли. Это не использование изолированных сред выполнения.
// 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; }
}
}
Спасибо, это работает. Хотелось бы знать, почему оригинальное руководство, которое они предоставляют, не работает. Теперь я подумаю, как оттуда получить доступ к каплям.