gpt4 book ai didi

c# - 使用 Application Insights 的 Azure Function 中出现内存不足异常

转载 作者:行者123 更新时间:2023-12-02 08:17:41 25 4
gpt4 key购买 nike

我有一个队列触发的 azure 功能,用于发送电子邮件/文本。我使用应用程序洞察来跟踪自定义事件,以便我可以监控电子邮件、文本和错误的数量。创建 Telemetry Client 对象时有时会出现内存不足的异常。这是我的 TelemetryHandler.cs 类:

internal class TelemetryHandler : IDisposable
{
private const string EmailSentEvent = "Email Sent";
private const string EmailFailedEvent = "Email Failure";
private const string TextSentEvent = "Text Sent";
private const string ErrorEvent = "Error";
private readonly TelemetryClient telemetryClient;
private readonly TelemetryConfiguration telemetryConfiguration;
private readonly Dictionary<string, string> properties;
private readonly Dictionary<string, double> metrics;

public TelemetryHandler()
{
telemetryConfiguration = new(Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY"));
telemetryClient = new TelemetryClient(telemetryConfiguration);
metrics = new();
properties = new();
}

public void InitializeFromMessage(EmailTextMessage emailTextMessage)
{
properties.Add("Tenant ID", emailTextMessage.TenantID);
properties.Add("User", emailTextMessage.User);
properties.Add("Payload", emailTextMessage.Payload.ToString());
}

public void FinalizeSendEmailEvent(string messageID)
{
properties.Add("Postmark Message ID", messageID);
metrics.Add("Emails", 1);
telemetryClient.TrackEvent(EmailSentEvent, properties, metrics);
}

public void FinalizeSendTextEvent(string sid)
{
properties.Add("Twilio Message Sid", sid);
metrics.Add("Texts", 1);
telemetryClient.TrackEvent(TextSentEvent, properties, metrics);
}

public void FinalizeSendEmailFailure(string errorMessage)
{
properties.Add("Error Message", errorMessage);
metrics.Add("Failed", 1);
telemetryClient.TrackEvent(EmailFailedEvent, properties, metrics);
}

public void FinalizeErrorEvent(Exception ex)
{
StringBuilder message = new(ex.Message);
Exception exception = ex;
while(exception.InnerException != null)
{
message.Append($"{Environment.NewLine}{exception.InnerException.Message}");
exception = exception.InnerException;
}
properties.Add("Message", message.ToString());
properties.Add("Stack Trace", ex.StackTrace);
metrics.Add("Error", 1);
telemetryClient.TrackEvent(ErrorEvent, properties, metrics);
}

public void Dispose()
{
if(telemetryConfiguration != null)
telemetryConfiguration.Dispose();
}
}

知道什么可能导致内存不足异常以及如何修复吗?当队列中有大量消息等待(例如超过 15 条)时,会发生这种情况,但我已将批处理大小减少到 4。我无法从错误日志中获取堆栈跟踪,只能知道它发生在我的 TelemetryHandler 构造函数中。我也在函数末尾处理我的 TelemetryHandler 类(它处理 TelemtryConfiguration 对象)。如有任何帮助,我们将不胜感激。

最佳答案

我接受了使用 TelemetryHandler 类作为单例并使用 DI 将其作为参数传递的建议。这是该类的界面和更新版本:

internal interface ITelemetryHandler
{
void FinalizeSendEmailEvent(string tenantID, string user, EmailMessage emailMessage, string messageID);
void FinalizeSendEmailFailure(string tenantID, string user, EmailMessage emailMessage, string errorMessage);
void FinalizeSendTextEvent(string tenantID, string user, TextMessage textMessage, string sid);
void FinalizeErrorEvent(EmailTextMessage emailTextMessage, Exception ex);
}
internal class TelemetryHandler : ITelemetryHandler, IDisposable
{
private const string EmailSentEvent = "Email Sent";
private const string EmailFailedEvent = "Email Failure";
private const string TextSentEvent = "Text Sent";
private const string ErrorEvent = "Error";
private readonly TelemetryClient telemetryClient;
private readonly TelemetryConfiguration telemetryConfiguration;

public TelemetryHandler()
{
telemetryConfiguration = new(Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY"));
telemetryClient = new TelemetryClient(telemetryConfiguration);
}

public void FinalizeSendEmailEvent(string tenantID, string user, EmailMessage emailMessage, string messageID)
{
Dictionary<string, string> properties = new();
Dictionary<string, double> metrics = new();
properties.Add("Tenant ID", tenantID);
properties.Add("User", user);
properties.Add("Payload", JsonConvert.SerializeObject(emailMessage));
properties.Add("Postmark Message ID", messageID);
metrics.Add("Emails", 1);
telemetryClient.TrackEvent(EmailSentEvent, properties, metrics);
}

public void FinalizeSendTextEvent(string tenantID, string user, TextMessage textMessage, string sid)
{
Dictionary<string, string> properties = new();
Dictionary<string, double> metrics = new();
properties.Add("Tenant ID", tenantID);
properties.Add("User", user);
properties.Add("Payload", JsonConvert.SerializeObject(textMessage));
properties.Add("Twilio Message Sid", sid);
metrics.Add("Texts", 1);
telemetryClient.TrackEvent(TextSentEvent, properties, metrics);
}

public void FinalizeSendEmailFailure(string tenantID, string user, EmailMessage message, string errorMessage)
{
Dictionary<string, string> properties = new();
Dictionary<string, double> metrics = new();
properties.Add("Tenant ID", tenantID);
properties.Add("User", user);
properties.Add("Payload", message.ToString());
properties.Add("Error Message", errorMessage);
metrics.Add("Failed", 1);
telemetryClient.TrackEvent(EmailFailedEvent, properties, metrics);
}

public void FinalizeErrorEvent(EmailTextMessage emailTextMessage, Exception ex)
{
Dictionary<string, string> properties = new();
Dictionary<string, double> metrics = new();
if (emailTextMessage != null)
{
properties.Add("Tenant ID", emailTextMessage.TenantID);
properties.Add("User", emailTextMessage.User);
properties.Add("Payload", emailTextMessage.Payload.ToString());
}
StringBuilder message = new(ex.Message);
Exception exception = ex;
while (exception.InnerException != null)
{
message.Append($"{Environment.NewLine}{exception.InnerException.Message}");
exception = exception.InnerException;
}
properties.Add("Message", message.ToString());
properties.Add("Stack Trace", ex.StackTrace);
metrics.Add("Error", 1);
telemetryClient.TrackEvent(ErrorEvent, properties, metrics);
}

public void Dispose()
{
if (telemetryConfiguration != null)
telemetryConfiguration.Dispose();
}
}

以下是它如何用作单例:

[assembly: FunctionsStartup(typeof(FWT.EmailText.Startup))]

namespace FWT.EmailText;

class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton<ITelemetryHandler>((s) => {
return new TelemetryHandler();
});
}
}
class EmailTextHandler
{
private readonly ITelemetryHandler telemetryHandler;

public EmailTextHandler(ITelemetryHandler telemetryHandler)
{
this.telemetryHandler = telemetryHandler;
}

[FunctionName("EmailTextHandler")]
public async Task Run([QueueTrigger("%QueueName%", Connection = "QueueStorageAccount")] string queueMessage, ILogger log)
{
//Function code that accesses telemetryHandler
}
}

对于任何可能需要它的人,我使用本文在 azure 函数中设置了 singleton/DI:https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection

关于c# - 使用 Application Insights 的 Azure Function 中出现内存不足异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71875795/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com