You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Application Insights请求条目丢失:自定义维度数据超限排查

问题:Application Insights请求条目消失,因存储Base64图片分块到自定义维度?

我实现了一个中间件遥测处理器,用于在请求执行完成后,将响应体中的关键数据存入Application Insights的自定义维度字段,以便通过Grafana等第三方工具分析响应。

核心代码实现如下:

ResponseBodyHandler与TelemetryPropertyHandler

public class ResponseBodyHandler : IResponseBodyHandler
{
    private readonly ITelemetryPropertyHandler _telemetryPropertyHandler = new TelemetryPropertyHandler();
    
    public void TransformResponseBodyDataToTelemetryData(RequestTelemetry requestTelemetry, string responseBody)
    {
        SuccessResponse<List<Booking>> result = null;
        try
        {
            result = JsonConvert.DeserializeObject<SuccessResponse<List<Booking>>>(responseBody);
        }
        catch (Exception e)
        {
            Log.Error("Telemetry response handler, failure to deserialize response body: " + e.Message);
            return;
        }

        _telemetryPropertyHandler.CreateTelemetryProperties(requestTelemetry, result);
    }
}

public class TelemetryPropertyHandler : ITelemetryPropertyHandler
{
    private readonly ILabelHandler _labelHandler = new LabelHandler();
    public void CreateTelemetryProperties(RequestTelemetry requestTelemetry, SuccessResponse<List<Booking>> result)
    {
        Header bookingHeader = result?.SuccessObject?.FirstOrDefault()?.BookingHeader;
        requestTelemetry?.Properties.Add("ResponseClientId", "" + bookingHeader?.ConsigneeNumber);
        
        Line line = bookingHeader?.Lines.FirstOrDefault();
        requestTelemetry?.Properties.Add("ResponseProductId", "" + line?.PurchaseProductID);
        requestTelemetry?.Properties.Add("ResponseCarrierId", "" + line?.SubCarrierID);

        _labelHandler.HandleLabel(requestTelemetry, bookingHeader);
        
        requestTelemetry?.Properties.Add("ResponseBody", JsonConvert.SerializeObject(result));
    }
}

在_labelHandler.HandleLabel方法中,我提取了Base64编码的图片,将其按8192字符分块,以"Image index 0 .. N"为键添加到Properties中。调试时代码正常运行,但Application Insights中的整个请求条目消失,并非仅自定义维度缺失。我推测这是数据大小超限导致,但未找到相关限制文档。

当仅将图片截断为单个属性存储时,代码可正常工作,但此方式无法完整存储图片数据。相关代码如下:

LabelHandler与Base64Splitter

public class LabelHandler : ILabelHandler
{
    private readonly IBase64Splitter _base64Splitter = new Base64Splitter();
    
    public void HandleLabel(RequestTelemetry requestTelemetry, Header bookingHeader)
    {
        Label label = bookingHeader?.Labels.FirstOrDefault();
        IEnumerable<List<char>> splitBase64String = _base64Splitter.SplitList(label?.Base64.ToList());

        if (splitBase64String != null)
        {
            bool imageHandlingWorked = true;
            try
            {
                int index = 0;
                foreach (List<char> chunkOfImageString in splitBase64String)
                {
                    string dictionaryKey = $"Image index {index}";
                    string chunkData = new string(chunkOfImageString.ToArray());
                    requestTelemetry?.Properties.Add(dictionaryKey, chunkData);
                    index++;
                }
            }
            catch (Exception e)
            {
                imageHandlingWorked = false;
                Log.Error("Error trying to store label in chunks: " + e.Message);
            }
            
            if (imageHandlingWorked && label != null)
            {
                label.Base64 = "";
            }
        }
    }
}
public class Base64Splitter : IBase64Splitter
{
    private const int ChunkSize = 8192;

    public IEnumerable<List<T>> SplitList<T>(List<T> originalList)
    {
        for (var i = 0; i < originalList.Count; i += ChunkSize)
            yield return originalList.GetRange(i, Math.Min(ChunkSize, originalList.Count - i));
    }
}

请问我违反了什么规则?是否需要截断图片数据,或是存在其他问题?


回答

你遇到的问题是Application Insights的单条遥测数据大小限制导致的:

  1. 核心限制:Application Insights中每个遥测条目(比如RequestTelemetry)的总大小上限为64KB。这个大小包含遥测的所有字段:请求基本信息、自定义Properties、上下文数据等。当你把Base64图片分块存入Properties后,加上ResponseBody等其他属性,整个遥测的总大小超过了64KB,导致Application Insights直接丢弃了这条遥测,而不是仅忽略超限的属性。

  2. 单块截断能工作的原因:当你只存截断后的单块图片数据时,整个遥测的总大小控制在了64KB以内,所以能正常被接收和存储。

解决方案

方案1:截断图片数据(快速妥协)

如果必须在自定义维度中保留图片相关数据,可以只存储Base64字符串的前N个字符(比如前4KB),确保整个遥测的总大小不超过64KB。但这种方式无法保留完整图片,仅适合需要预览或标识的场景。

方案2:避免在自定义维度存储大文件(推荐)

Application Insights的自定义维度设计初衷是存储小体积的元数据(比如ID、状态码、简短标识),而非大二进制/Base64数据。正确的做法是:

  • 将Base64图片解码后存储到Blob存储;
  • 在RequestTelemetry的自定义维度中仅存储该Blob的访问URL或唯一标识;
  • 当Grafana需要查看图片时,通过这个URL去Blob存储中获取完整数据。

方案3:提前校验遥测大小

在添加属性前,手动计算当前RequestTelemetry的序列化大小,避免超限。可以通过将遥测序列化为JSON后计算字节数的方式判断,如果即将超过64KB,就跳过图片数据的存储。


内容的提问来源于stack exchange,提问作者Morten Bork

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 14:30:41