在 Application Insights SDK 中篩選及前置處理遙測

您可以撰寫程式碼來篩選、修改或擴充遙測,再從 SDK 傳送。 此處理包含從標準遙測模組傳送的資料,例如 HTTP 要求集合和相依性集合。

  • 篩選 可以藉由實 ITelemetryProcessor 作 ,在從 SDK 傳送遙測之前修改或捨棄遙測。 例如,您可以藉由排除來自機器人的要求來減少遙測量。 與取樣不同,您可以完全控制傳送或捨棄的內容,但會影響以匯總記錄為基礎的任何計量。 視您捨棄專案的方式而定,您可能也會失去在相關專案之間巡覽的能力。

  • 藉由實作 ITelemetryInitializer ,將屬性 新增或修改至從您的應用程式傳送的任何遙測。 例如,您可以新增匯出值或版本號碼,以篩選入口網站中的資料。

  • 取樣 可減少遙測量,而不會影響您的統計資料。 它會將相關的資料點保持在一起,以便在診斷問題時在資料點之間巡覽。 在入口網站中,總計數會相乘以補償取樣。

注意

SDK API 可用來傳送自訂事件和計量。

在開始之前:

篩選

這項技術可讓您直接控制遙測資料流程中包含或排除的內容。 篩選可用來將遙測專案從傳送至 Application Insights。 您可以使用篩選搭配取樣,或個別使用。

若要篩選遙測,您可以撰寫遙測處理器,並將它註冊到 TelemetryConfiguration 。 所有遙測都會通過您的處理器。 您可以選擇從資料流程卸載它,或將它提供給鏈結中的下一個處理器。 包含來自標準模組的遙測,例如 HTTP 要求收集器和相依性收集器,以及您自己追蹤的遙測。 例如,您可以篩選出有關機器人要求或成功相依性呼叫的遙測。

警告

使用處理器篩選從 SDK 傳送的遙測,可能會扭曲您在入口網站中看到的統計資料,並難以追蹤相關專案。

相反地,請考慮使用 取樣

建立遙測處理器

C#

  1. 若要建立篩選,請實作 ITelemetryProcessor

    遙測處理器會建構一個處理鏈結。 當您具現化遙測處理器時,系統會提供鏈結中下一個處理器的參考。 當遙測資料點傳遞至進程方法時,它會執行其工作,然後呼叫鏈結中的下一個遙測處理器(或未呼叫)。

    using Microsoft.ApplicationInsights.Channel;
    using Microsoft.ApplicationInsights.Extensibility;
    using Microsoft.ApplicationInsights.DataContracts;
    
    public class SuccessfulDependencyFilter : ITelemetryProcessor
    {
        private ITelemetryProcessor Next { get; set; }
    
        // next will point to the next TelemetryProcessor in the chain.
        public SuccessfulDependencyFilter(ITelemetryProcessor next)
        {
            this.Next = next;
        }
    
        public void Process(ITelemetry item)
        {
            // To filter out an item, return without calling the next processor.
            if (!OKtoSend(item)) { return; }
    
            this.Next.Process(item);
        }
    
        // Example: replace with your own criteria.
        private bool OKtoSend (ITelemetry item)
        {
            var dependency = item as DependencyTelemetry;
            if (dependency == null) return true;
    
            return dependency.Success != true;
        }
    }
    
  2. 新增處理器。

ASP.NET 應用程式

在 ApplicationInsights.config 中插入此程式碼片段:

<TelemetryProcessors>
  <Add Type="WebApplication9.SuccessfulDependencyFilter, WebApplication9">
     <!-- Set public property -->
     <MyParamFromConfigFile>2-beta</MyParamFromConfigFile>
  </Add>
</TelemetryProcessors>

您可以在 類別中提供公用具名屬性,以傳遞 .config 檔案中的字串值。

警告

請小心將 .config 檔案中的類型名稱和任何屬性名稱與程式碼中的類別和屬性名稱相符。 如果 .config 檔案參考不存在的類型或屬性,SDK 可能會以無訊息方式無法傳送任何遙測。

或者,您可以在程式碼中初始化篩選。 在適當的初始化類別中,例如,中的 Global.asax.cs AppStart,將您的處理器插入鏈結中:

var builder = TelemetryConfiguration.Active.DefaultTelemetrySink.TelemetryProcessorChainBuilder;
builder.Use((next) => new SuccessfulDependencyFilter(next));

// If you have more processors:
builder.Use((next) => new AnotherProcessor(next));

builder.Build();

在此點之後建立的遙測用戶端將會使用您的處理器。

ASP.NET Core/Worker 服務應用程式

注意

使用 或 TelemetryConfiguration.Active 新增 ApplicationInsights.config 處理器不適用於 ASP.NET Core 應用程式,或者如果您使用 Microsoft.ApplicationInsights.WorkerService SDK。

針對使用 ASP.NET Core WorkerService 所撰寫的應用程式,新增遙測處理器是使用 AddApplicationInsightsTelemetryProcessor 上的 IServiceCollection 擴充方法完成,如下所示。 這個方法會在 類別 Startup.cs 的 方法中 ConfigureServices 呼叫。

    public void ConfigureServices(IServiceCollection services)
    {
        // ...
        services.AddApplicationInsightsTelemetry();
        services.AddApplicationInsightsTelemetryProcessor<SuccessfulDependencyFilter>();

        // If you have more processors:
        services.AddApplicationInsightsTelemetryProcessor<AnotherProcessor>();
    }

若要註冊 ASP.NET Core 中需要參數的遙測處理器,請建立實作 ITelemetryProcessorFactory 的自訂類別。 在 Create 方法中使用 所需的參數呼叫建構函式,然後使用 AddSingleton < ITelemetryProcessorFactory、MyTelemetryProcessorFactory > ()

範例篩選

綜合要求

篩選出 Bot 和 Web 測試。 雖然計量總管可讓您選擇篩選出綜合來源,但此選項可藉由篩選 SDK 本身來減少流量和擷取大小。

public void Process(ITelemetry item)
{
  if (!string.IsNullOrEmpty(item.Context.Operation.SyntheticSource)) {return;}

  // Send everything else:
  this.Next.Process(item);
}

驗證失敗

篩選出具有 「401」 回應的要求。

public void Process(ITelemetry item)
{
    var request = item as RequestTelemetry;

    if (request != null &&
    request.ResponseCode.Equals("401", StringComparison.OrdinalIgnoreCase))
    {
        // To filter out an item, return without calling the next processor.
        return;
    }

    // Send everything else
    this.Next.Process(item);
}

篩選掉快速遠端相依性呼叫

如果您想要只診斷速度緩慢的呼叫,請篩選掉快速呼叫。

注意

此篩選會扭曲您在入口網站上看到的統計資料。

public void Process(ITelemetry item)
{
    var request = item as DependencyTelemetry;

    if (request != null && request.Duration.TotalMilliseconds < 100)
    {
        return;
    }
    this.Next.Process(item);
}

診斷相依性問題

此部落格 描述透過自動將一般 Ping 傳送至相依性來診斷相依性問題的專案。

Java

若要深入瞭解遙測處理器及其在 JAVA 中的實作,請參閱 JAVA 遙測處理器檔

JavaScript Web 應用程式

使用 ITelemetryInitializer 進行篩選

  1. 建立遙測初始化運算式回呼函式。 回呼函式會採用 ITelemetryItem 做為參數,這是正在處理的事件。 從這個回呼傳 false 回會導致要篩選掉的遙測專案。

    var filteringFunction = (envelope) => {
      if (envelope.data.someField === 'tobefilteredout') {
          return false;
      }
    
      return true;
    };
    
  2. 新增遙測初始化運算式回呼:

    appInsights.addTelemetryInitializer(filteringFunction);
    

新增/修改屬性:ITelemetryInitializer

使用遙測初始化運算式以其他資訊擴充遙測,或覆寫標準遙測模組所設定的遙測屬性。

例如,Web 套件的 Application Insights 會收集 HTTP 要求的相關遙測。 根據預設,它會將回應碼 > =400 的任何要求標示為失敗。 但是,如果您想要將 400 視為成功,您可以提供遙測初始化運算式來設定成功屬性。

如果您提供遙測初始化運算式,每當呼叫任何 Track*() 方法時,就會呼叫它。 此初始化運算式包含 Track() 標準遙測模組所呼叫的方法。 依照慣例,這些模組不會設定初始化運算式已設定的任何屬性。 呼叫遙測處理器之前,會先呼叫遙測初始化運算式。 因此,處理器可以看到初始化運算式所完成的任何擴充。

定義初始化運算式

C#

using System;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;

namespace MvcWebRole.Telemetry
{
  /*
   * Custom TelemetryInitializer that overrides the default SDK
   * behavior of treating response codes >= 400 as failed requests
   *
   */
  public class MyTelemetryInitializer : ITelemetryInitializer
  {
    public void Initialize(ITelemetry telemetry)
    {
        var requestTelemetry = telemetry as RequestTelemetry;
        // Is this a TrackRequest() ?
        if (requestTelemetry == null) return;
        int code;
        bool parsed = Int32.TryParse(requestTelemetry.ResponseCode, out code);
        if (!parsed) return;
        if (code >= 400 && code < 500)
        {
            // If we set the Success property, the SDK won't change it:
            requestTelemetry.Success = true;

            // Allow us to filter these requests in the portal:
            requestTelemetry.Properties["Overridden400s"] = "true";
        }
        // else leave the SDK to set the Success property
    }
  }
}

ASP.NET 應用程式:載入初始化運算式

在 ApplicationInsights.config 中:

<ApplicationInsights>
  <TelemetryInitializers>
    <!-- Fully qualified type name, assembly name: -->
    <Add Type="MvcWebRole.Telemetry.MyTelemetryInitializer, MvcWebRole"/>
    ...
  </TelemetryInitializers>
</ApplicationInsights>

或者,您可以在程式碼中具現化初始化運算式,例如 Global.aspx.cs:

protected void Application_Start()
{
    // ...
    TelemetryConfiguration.Active.TelemetryInitializers.Add(new MyTelemetryInitializer());
}

如需此範例的詳細資訊 ,請參閱此範例

ASP.NET Core/Worker 服務應用程式:載入初始化運算式

注意

使用 或 TelemetryConfiguration.Active 新增 ApplicationInsights.config 初始化運算式對 ASP.NET Core 應用程式無效,或者如果您使用 Microsoft.ApplicationInsights.WorkerService SDK。

對於使用 ASP.NET Core WorkerService 撰寫的應用程式,新增遙測初始化運算式是藉由將它新增至相依性插入容器來完成,如下所示。 在 方法中 Startup.ConfigureServices 完成此步驟。

 using Microsoft.ApplicationInsights.Extensibility;
 using CustomInitializer.Telemetry;
 public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<ITelemetryInitializer, MyTelemetryInitializer>();
}

JavaScript 遙測初始化運算式

視需要插入 JavaScript 遙測初始化運算式。 如需 Application Insights JavaScript SDK 遙測初始化運算式的詳細資訊,請參閱 遙測初始化運算式

在 JavaScript (Web) SDK 載入器腳本組態 新增 onInit 回呼函式,以插入遙測初始化運算式:

<script type="text/javascript">
!(function (cfg){function e(){cfg.onInit&&cfg.onInit(i)}var S,u,D,t,n,i,C=window,x=document,w=C.location,I="script",b="ingestionendpoint",E="disableExceptionTracking",A="ai.device.";"instrumentationKey"[S="toLowerCase"](),u="crossOrigin",D="POST",t="appInsightsSDK",n=cfg.name||"appInsights",(cfg.name||C[t])&&(C[t]=n),i=C[n]||function(l){var d=!1,g=!1,f={initialize:!0,queue:[],sv:"7",version:2,config:l};function m(e,t){var n={},i="Browser";function a(e){e=""+e;return 1===e.length?"0"+e:e}return n[A+"id"]=i[S](),n[A+"type"]=i,n["ai.operation.name"]=w&&w.pathname||"_unknown_",n["ai.internal.sdkVersion"]="javascript:snippet_"+(f.sv||f.version),{time:(i=new Date).getUTCFullYear()+"-"+a(1+i.getUTCMonth())+"-"+a(i.getUTCDate())+"T"+a(i.getUTCHours())+":"+a(i.getUTCMinutes())+":"+a(i.getUTCSeconds())+"."+(i.getUTCMilliseconds()/1e3).toFixed(3).slice(2,5)+"Z",iKey:e,name:"Microsoft.ApplicationInsights."+e.replace(/-/g,"")+"."+t,sampleRate:100,tags:n,data:{baseData:{ver:2}},ver:4,seq:"1",aiDataContract:undefined}}var h=-1,v=0,y=["js.monitor.azure.com","js.cdn.applicationinsights.io","js.cdn.monitor.azure.com","js0.cdn.applicationinsights.io","js0.cdn.monitor.azure.com","js2.cdn.applicationinsights.io","js2.cdn.monitor.azure.com","az416426.vo.msecnd.net"],k=l.url||cfg.src;if(k){if((n=navigator)&&(~(n=(n.userAgent||"").toLowerCase()).indexOf("msie")||~n.indexOf("trident/"))&&~k.indexOf("ai.3")&&(k=k.replace(/(\/)(ai\.3\.)([^\d]*)$/,function(e,t,n){return t+"ai.2"+n})),!1!==cfg.cr)for(var e=0;e<y.length;e++)if(0<k.indexOf(y[e])){h=e;break}var i=function(e){var a,t,n,i,o,r,s,c,p,u;f.queue=[],g||(0<=h&&v+1<y.length?(a=(h+v+1)%y.length,T(k.replace(/^(.*\/\/)([\w\.]*)(\/.*)$/,function(e,t,n,i){return t+y[a]+i})),v+=1):(d=g=!0,o=k,c=(p=function(){var e,t={},n=l.connectionString;if(n)for(var i=n.split(";"),a=0;a<i.length;a++){var o=i[a].split("=");2===o.length&&(t[o[0][S]()]=o[1])}return t[b]||(e=(n=t.endpointsuffix)?t.location:null,t[b]="https://"+(e?e+".":"")+"dc."+(n||"services.visualstudio.com")),t}()).instrumentationkey||l.instrumentationKey||"",p=(p=p[b])?p+"/v2/track":l.endpointUrl,(u=[]).push((t="SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)",n=o,r=p,(s=(i=m(c,"Exception")).data).baseType="ExceptionData",s.baseData.exceptions=[{typeName:"SDKLoadFailed",message:t.replace(/\./g,"-"),hasFullStack:!1,stack:t+"\nSnippet failed to load ["+n+"] -- Telemetry is disabled\nHelp Link: https://go.microsoft.com/fwlink/?linkid=2128109\nHost: "+(w&&w.pathname||"_unknown_")+"\nEndpoint: "+r,parsedStack:[]}],i)),u.push((s=o,t=p,(r=(n=m(c,"Message")).data).baseType="MessageData",(i=r.baseData).message='AI (Internal): 99 message:"'+("SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details) ("+s+")").replace(/\"/g,"")+'"',i.properties={endpoint:t},n)),o=u,c=p,JSON&&((r=C.fetch)&&!cfg.useXhr?r(c,{method:D,body:JSON.stringify(o),mode:"cors"}):XMLHttpRequest&&((s=new XMLHttpRequest).open(D,c),s.setRequestHeader("Content-type","application/json"),s.send(JSON.stringify(o))))))},a=function(e,t){g||setTimeout(function(){!t&&f.core||i()},500),d=!1},T=function(e){var n=x.createElement(I),e=(n.src=e,cfg[u]);return!e&&""!==e||"undefined"==n[u]||(n[u]=e),n.onload=a,n.onerror=i,n.onreadystatechange=function(e,t){"loaded"!==n.readyState&&"complete"!==n.readyState||a(0,t)},cfg.ld&&cfg.ld<0?x.getElementsByTagName("head")[0].appendChild(n):setTimeout(function(){x.getElementsByTagName(I)[0].parentNode.appendChild(n)},cfg.ld||0),n};T(k)}try{f.cookie=x.cookie}catch(p){}function t(e){for(;e.length;)!function(t){f[t]=function(){var e=arguments;d||f.queue.push(function(){f[t].apply(f,e)})}}(e.pop())}var r,s,n="track",o="TrackPage",c="TrackEvent",n=(t([n+"Event",n+"PageView",n+"Exception",n+"Trace",n+"DependencyData",n+"Metric",n+"PageViewPerformance","start"+o,"stop"+o,"start"+c,"stop"+c,"addTelemetryInitializer","setAuthenticatedUserContext","clearAuthenticatedUserContext","flush"]),f.SeverityLevel={Verbose:0,Information:1,Warning:2,Error:3,Critical:4},(l.extensionConfig||{}).ApplicationInsightsAnalytics||{});return!0!==l[E]&&!0!==n[E]&&(t(["_"+(r="onerror")]),s=C[r],C[r]=function(e,t,n,i,a){var o=s&&s(e,t,n,i,a);return!0!==o&&f["_"+r]({message:e,url:t,lineNumber:n,columnNumber:i,error:a,evt:C.event}),o},l.autoExceptionInstrumented=!0),f}(cfg.cfg),(C[n]=i).queue&&0===i.queue.length?(i.queue.push(e),i.trackPageView({})):e();})({
src: "https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js",
crossOrigin: "anonymous",
onInit: function (sdk) {
  sdk.addTelemetryInitializer(function (envelope) {
    envelope.data = envelope.data || {};
    envelope.data.someField = 'This item passed through my telemetry initializer';
  });
}, // Once the application insights instance has loaded and initialized this method will be called
cfg: { // Application Insights Configuration
    connectionString: "YOUR_CONNECTION_STRING"
}});
</script>

如需遙測專案上可用之非自訂屬性的摘要,請參閱 Application Insights 匯出資料模型

您可以視需要新增多個初始化運算式。 系統會依新增的順序呼叫它們。

OpenCensus Python 遙測處理器

OpenCensus Python 中的遙測處理器只是呼叫以在匯出遙測之前處理遙測的回呼函式。 回呼函式必須接受 信封 資料類型做為其參數。 若要從匯出中篩選出遙測,請確定回呼函式會傳 False 回 。 您可以在 GitHub 上的信封中看到 Azure 監視器資料類型的 架構。

注意

您可以藉由變更 欄位中的屬性 tags 來修改。 cloud_RoleNameai.cloud.role

def callback_function(envelope):
    envelope.tags['ai.cloud.role'] = 'new_role_name'
# Example for log exporter
import logging

from opencensus.ext.azure.log_exporter import AzureLogHandler

logger = logging.getLogger(__name__)

# Callback function to append '_hello' to each log message telemetry
def callback_function(envelope):
    envelope.data.baseData.message += '_hello'
    return True

handler = AzureLogHandler(connection_string='InstrumentationKey=<your-instrumentation_key-here>')
handler.add_telemetry_processor(callback_function)
logger.addHandler(handler)
logger.warning('Hello, World!')
# Example for trace exporter
import requests

from opencensus.ext.azure.trace_exporter import AzureExporter
from opencensus.trace import config_integration
from opencensus.trace.samplers import ProbabilitySampler
from opencensus.trace.tracer import Tracer

config_integration.trace_integrations(['requests'])

# Callback function to add os_type: linux to span properties
def callback_function(envelope):
    envelope.data.baseData.properties['os_type'] = 'linux'
    return True

exporter = AzureExporter(
    connection_string='InstrumentationKey=<your-instrumentation-key-here>'
)
exporter.add_telemetry_processor(callback_function)
tracer = Tracer(exporter=exporter, sampler=ProbabilitySampler(1.0))
with tracer.span(name='parent'):
response = requests.get(url='https://www.wikipedia.org/wiki/Rabbit')
# Example for metrics exporter
import time

from opencensus.ext.azure import metrics_exporter
from opencensus.stats import aggregation as aggregation_module
from opencensus.stats import measure as measure_module
from opencensus.stats import stats as stats_module
from opencensus.stats import view as view_module
from opencensus.tags import tag_map as tag_map_module

stats = stats_module.stats
view_manager = stats.view_manager
stats_recorder = stats.stats_recorder

CARROTS_MEASURE = measure_module.MeasureInt("carrots",
                                            "number of carrots",
                                            "carrots")
CARROTS_VIEW = view_module.View("carrots_view",
                                "number of carrots",
                                [],
                                CARROTS_MEASURE,
                                aggregation_module.CountAggregation())

# Callback function to only export the metric if value is greater than 0
def callback_function(envelope):
    return envelope.data.baseData.metrics[0].value > 0

def main():
    # Enable metrics
    # Set the interval in seconds in which you want to send metrics
    exporter = metrics_exporter.new_metrics_exporter(connection_string='InstrumentationKey=<your-instrumentation-key-here>')
    exporter.add_telemetry_processor(callback_function)
    view_manager.register_exporter(exporter)

    view_manager.register_view(CARROTS_VIEW)
    mmap = stats_recorder.new_measurement_map()
    tmap = tag_map_module.TagMap()

    mmap.measure_int_put(CARROTS_MEASURE, 1000)
    mmap.record(tmap)
    # Default export interval is every 15.0s
    # Your application should run for at least this amount
    # of time so the exporter will meet this interval
    # Sleep can fulfill this
    time.sleep(60)

    print("Done recording metrics")

if __name__ == "__main__":
    main()

您可以視需要新增多個處理器。 系統會依新增的順序呼叫它們。 如果一個處理器擲回例外狀況,則不會影響下列處理器。

範例 TelemetryInitializers

新增自訂屬性

下列範例初始化運算式會將自訂屬性新增至每個追蹤的遙測。

public void Initialize(ITelemetry item)
{
  var itemProperties = item as ISupportProperties;
  if(itemProperties != null && !itemProperties.Properties.ContainsKey("customProp"))
    {
        itemProperties.Properties["customProp"] = "customValue";
    }
}

新增雲端角色名稱

下列範例初始化運算式會將雲端角色名稱設定為每個追蹤的遙測。

public void Initialize(ITelemetry telemetry)
{
    if (string.IsNullOrEmpty(telemetry.Context.Cloud.RoleName))
    {
        telemetry.Context.Cloud.RoleName = "MyCloudRoleName";
    }
}

控制用於地理位置對應的用戶端 IP 位址

下列範例初始化運算式會在遙測擷取期間,設定將用於地理位置對應的用戶端 IP,而不是用戶端通訊端 IP 位址。

public void Initialize(ITelemetry telemetry)
{
    var request = telemetry as RequestTelemetry;
    if (request == null) return true;
    request.Context.Location.Ip = "{client ip address}"; // Could utilize System.Web.HttpContext.Current.Request.UserHostAddress;   
    return true;
}

ITelemetryProcessor 和 ITelemetryInitializer

遙測處理器與遙測初始化運算式之間的差異為何?

  • 您可以使用這些重迭的方式進行一些重迭。 這兩者都可以用來新增或修改遙測的屬性,不過我們建議您針對該目的使用初始化運算式。
  • 遙測初始化運算式一律會在遙測處理器之前執行。
  • 遙測初始化運算式可以多次呼叫。 依照慣例,它們不會設定任何已經設定的屬性。
  • 遙測處理器可讓您完全取代或捨棄遙測專案。
  • 所有已註冊的遙測初始化運算式都會針對每個遙測專案呼叫。 對於遙測處理器,SDK 保證會呼叫第一個遙測處理器。 上述遙測處理器是否決定呼叫其餘處理器。
  • 使用遙測初始化運算式,以更多屬性擴充遙測,或覆寫現有的遙測。 使用遙測處理器來篩選出遙測。

注意

JavaScript 只有遙測初始化運算式,可以使用 ITelemetryInitializer 來篩選掉事件

針對 ApplicationInsights.config 進行疑難排解

  • 確認完整類型名稱和元件名稱正確無誤。
  • 確認 applicationinsights.config 檔案位於您的輸出目錄中,並包含任何最近的變更。

Azure 監視器遙測資料類型參考

參考文件

SDK 程式碼

下一步