Filtrera och förbearbeta telemetri i Application Insights SDK
Du kan skriva kod för att filtrera, ändra eller utöka telemetrin innan den skickas från SDK:t. Bearbetningen innehåller data som skickas från standardtelemetrimodulerna, till exempel INSAMLING av HTTP-begäranden och beroendeinsamling.
Filtrering kan ändra eller ta bort telemetri innan den skickas från SDK:t genom att implementera
ITelemetryProcessor
. Du kan till exempel minska mängden telemetri genom att exkludera begäranden från robotar. Till skillnad från sampling har du fullständig kontroll över vad som skickas eller tas bort, men det påverkar alla mått som baseras på aggregerade loggar. Beroende på hur du tar bort objekt kan du också förlora möjligheten att navigera mellan relaterade objekt.Lägg till eller ändra egenskaper i telemetri som skickas från din app genom att implementera en
ITelemetryInitializer
. Du kan till exempel lägga till beräknade värden eller versionsnummer för att filtrera data i portalen.Sampling minskar mängden telemetri utan att påverka din statistik. Den håller ihop relaterade datapunkter så att du kan navigera mellan dem när du diagnostiserar ett problem. I portalen multipliceras det totala antalet för att kompensera för samplingen.
Kommentar
SDK-API:et används för att skicka anpassade händelser och mått.
Förutsättningar
Installera lämplig SDK för ditt program: ASP.NET, ASP.NET Core, Icke-HTTP/Worker för .NET/.NET Core eller JavaScript.
Filtrering
Den här tekniken ger dig direkt kontroll över vad som ingår eller undantas från telemetriströmmen. Filtrering kan användas för att ta bort telemetriobjekt från att skickas till Application Insights. Du kan använda filtrering med sampling eller separat.
Om du vill filtrera telemetri skriver du en telemetriprocessor och registrerar den med TelemetryConfiguration
. All telemetri går igenom processorn. Du kan välja att släppa den från strömmen eller ge den till nästa processor i kedjan. Telemetri från standardmodulerna, till exempel HTTP-begärandeinsamlaren och beroendeinsamlaren, och telemetri som du spårade själv ingår. Du kan till exempel filtrera bort telemetri om begäranden från robotar eller lyckade beroendeanrop.
Varning
Om du filtrerar telemetrin som skickas från SDK:t med hjälp av processorer kan du förvränga den statistik som visas i portalen och göra det svårt att följa relaterade objekt.
Överväg i stället att använda sampling.
.NET-program
Implementera
ITelemetryProcessor
.Telemetriprocessorer skapar en bearbetningskedja. När du instansierar en telemetriprocessor får du en referens till nästa processor i kedjan. När en telemetridatapunkt skickas till processmetoden utför den sitt arbete och anropar sedan (eller anropar inte) nästa telemetriprocessor i kedjan.
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; } }
Lägg till processorn.
Infoga det här kodfragmentet i ApplicationInsights.config:
<TelemetryProcessors> <Add Type="WebApplication9.SuccessfulDependencyFilter, WebApplication9"> <!-- Set public property --> <MyParamFromConfigFile>2-beta</MyParamFromConfigFile> </Add> </TelemetryProcessors>
Du kan skicka strängvärden från .config-filen genom att ange offentliga namngivna egenskaper i klassen.
Varning
Var noga med att matcha typnamnet och eventuella egenskapsnamn i .config-filen med klass- och egenskapsnamnen i koden. Om .config-filen refererar till en icke-existerande typ eller egenskap kan SDK:t i tysthet misslyckas med att skicka telemetri.
Du kan också initiera filtret i koden. I en lämplig initieringsklass, till exempel AppStart i
Global.asax.cs
, infogar du processorn i kedjan: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();
Telemetriklienter som skapats efter den här punkten använder dina processorer.
Exempelfilter
Syntetiska begäranden
Filtrera bort robotar och webbtester. Även om Metrics Explorer ger dig möjlighet att filtrera bort syntetiska källor, minskar det här alternativet trafik- och inmatningsstorleken genom att filtrera dem i själva SDK:t.
public void Process(ITelemetry item)
{
if (!string.IsNullOrEmpty(item.Context.Operation.SyntheticSource)) {return;}
// Send everything else:
this.Next.Process(item);
}
Autentiseringen misslyckades
Filtrera bort begäranden med svaret "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);
}
Filtrera bort snabba fjärrberoendeanrop
Om du bara vill diagnostisera anrop som är långsamma filtrerar du bort de snabba.
Kommentar
Den här filtreringen förvränger den statistik som visas på portalen.
public void Process(ITelemetry item)
{
var request = item as DependencyTelemetry;
if (request != null && request.Duration.TotalMilliseconds < 100)
{
return;
}
this.Next.Process(item);
}
Diagnostisera beroendeproblem
Den här bloggen beskriver ett projekt för att diagnostisera beroendeproblem genom att automatiskt skicka regelbundna pingar till beroenden.
Java-program
Mer information om telemetriprocessorer och deras implementering i Java finns i dokumentationen för Java-telemetriprocessorer.
JavaScript-webbprogram
Du kan filtrera telemetri från JavaScript-webbprogram med hjälp av ITelemetryInitializer.
Skapa en telemetriinitieringsåteranropsfunktion. Återanropsfunktionen tar
ITelemetryItem
som en parameter, vilket är den händelse som bearbetas. Om du returnerarfalse
från det här återanropet kommer telemetriobjektet att filtreras bort.var filteringFunction = (envelope) => { if (envelope.data.someField === 'tobefilteredout') { return false; } return true; };
Lägg till telemetriinitierarens motringning:
appInsights.addTelemetryInitializer(filteringFunction);
Lägg till/ändra egenskaper: ITelemetryInitializer
Använd telemetriinitierare för att utöka telemetri med ytterligare information eller för att åsidosätta telemetriegenskaper som anges av standardtelemetrimodulerna.
Application Insights för ett webbpaket samlar till exempel in telemetri om HTTP-begäranden. Som standard flaggas alla begäranden med svarskoden >=400 som misslyckade. Om du i stället vill behandla 400 som en lyckad initiering kan du ange en telemetriinitierare som anger den lyckade egenskapen.
Om du anger en telemetriinitierare anropas den när någon av Metoderna Track*() anropas. Den här initiatorn innehåller Track()
metoder som anropas av standardtelemetrimodulerna. Enligt konventionen anger dessa moduler inte någon egenskap som redan har angetts av en initiator. Telemetriinitierare anropas innan telemetriprocessorer anropas, så alla berikanden som görs av initiatorer är synliga för processorer.
.NET-program
Definiera initieraren
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 } } }
Läs in initieraren
I ApplicationInsights.config:
<ApplicationInsights> <TelemetryInitializers> <!-- Fully qualified type name, assembly name: --> <Add Type="MvcWebRole.Telemetry.MyTelemetryInitializer, MvcWebRole"/> ... </TelemetryInitializers> </ApplicationInsights>
Du kan också instansiera initiatorn i kod, till exempel i Global.aspx.cs:
protected void Application_Start() { // ... TelemetryConfiguration.Active.TelemetryInitializers.Add(new MyTelemetryInitializer()); }
Se mer av det här exemplet.
JavaScript-telemetriinitierare
Infoga en JavaScript-telemetriinitierare om det behövs. Mer information om telemetriinitieringarna för Application Insights JavaScript SDK finns i Telemetriinitierare.
Infoga en telemetriinitierare genom att lägga till funktionen onInit-återanrop i JavaScript-SDK-inläsningsskriptkonfigurationen (Web):
<script type="text/javascript">
!(function (cfg){function e(){cfg.onInit&&cfg.onInit(n)}var x,w,D,t,E,n,C=window,O=document,b=C.location,q="script",I="ingestionendpoint",L="disableExceptionTracking",j="ai.device.";"instrumentationKey"[x="toLowerCase"](),w="crossOrigin",D="POST",t="appInsightsSDK",E=cfg.name||"appInsights",(cfg.name||C[t])&&(C[t]=E),n=C[E]||function(g){var f=!1,m=!1,h={initialize:!0,queue:[],sv:"8",version:2,config:g};function v(e,t){var n={},i="Browser";function a(e){e=""+e;return 1===e.length?"0"+e:e}return n[j+"id"]=i[x](),n[j+"type"]=i,n["ai.operation.name"]=b&&b.pathname||"_unknown_",n["ai.internal.sdkVersion"]="javascript:snippet_"+(h.sv||h.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:undefined,seq:"1",aiDataContract:undefined}}var n,i,t,a,y=-1,T=0,S=["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"],o=g.url||cfg.src,r=function(){return s(o,null)};function s(d,t){if((n=navigator)&&(~(n=(n.userAgent||"").toLowerCase()).indexOf("msie")||~n.indexOf("trident/"))&&~d.indexOf("ai.3")&&(d=d.replace(/(\/)(ai\.3\.)([^\d]*)$/,function(e,t,n){return t+"ai.2"+n})),!1!==cfg.cr)for(var e=0;e<S.length;e++)if(0<d.indexOf(S[e])){y=e;break}var n,i=function(e){var a,t,n,i,o,r,s,c,u,l;h.queue=[],m||(0<=y&&T+1<S.length?(a=(y+T+1)%S.length,p(d.replace(/^(.*\/\/)([\w\.]*)(\/.*)$/,function(e,t,n,i){return t+S[a]+i})),T+=1):(f=m=!0,s=d,!0!==cfg.dle&&(c=(t=function(){var e,t={},n=g.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][x]()]=o[1])}return t[I]||(e=(n=t.endpointsuffix)?t.location:null,t[I]="https://"+(e?e+".":"")+"dc."+(n||"services.visualstudio.com")),t}()).instrumentationkey||g.instrumentationKey||"",t=(t=(t=t[I])&&"/"===t.slice(-1)?t.slice(0,-1):t)?t+"/v2/track":g.endpointUrl,t=g.userOverrideEndpointUrl||t,(n=[]).push((i="SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)",o=s,u=t,(l=(r=v(c,"Exception")).data).baseType="ExceptionData",l.baseData.exceptions=[{typeName:"SDKLoadFailed",message:i.replace(/\./g,"-"),hasFullStack:!1,stack:i+"\nSnippet failed to load ["+o+"] -- Telemetry is disabled\nHelp Link: https://go.microsoft.com/fwlink/?linkid=2128109\nHost: "+(b&&b.pathname||"_unknown_")+"\nEndpoint: "+u,parsedStack:[]}],r)),n.push((l=s,i=t,(u=(o=v(c,"Message")).data).baseType="MessageData",(r=u.baseData).message='AI (Internal): 99 message:"'+("SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details) ("+l+")").replace(/\"/g,"")+'"',r.properties={endpoint:i},o)),s=n,c=t,JSON&&((u=C.fetch)&&!cfg.useXhr?u(c,{method:D,body:JSON.stringify(s),mode:"cors"}):XMLHttpRequest&&((l=new XMLHttpRequest).open(D,c),l.setRequestHeader("Content-type","application/json"),l.send(JSON.stringify(s)))))))},a=function(e,t){m||setTimeout(function(){!t&&h.core||i()},500),f=!1},p=function(e){var n=O.createElement(q),e=(n.src=e,t&&(n.integrity=t),n.setAttribute("data-ai-name",E),cfg[w]);return!e&&""!==e||"undefined"==n[w]||(n[w]=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?O.getElementsByTagName("head")[0].appendChild(n):setTimeout(function(){O.getElementsByTagName(q)[0].parentNode.appendChild(n)},cfg.ld||0),n};p(d)}cfg.sri&&(n=o.match(/^((http[s]?:\/\/.*\/)\w+(\.\d+){1,5})\.(([\w]+\.){0,2}js)$/))&&6===n.length?(d="".concat(n[1],".integrity.json"),i="@".concat(n[4]),l=window.fetch,t=function(e){if(!e.ext||!e.ext[i]||!e.ext[i].file)throw Error("Error Loading JSON response");var t=e.ext[i].integrity||null;s(o=n[2]+e.ext[i].file,t)},l&&!cfg.useXhr?l(d,{method:"GET",mode:"cors"}).then(function(e){return e.json()["catch"](function(){return{}})}).then(t)["catch"](r):XMLHttpRequest&&((a=new XMLHttpRequest).open("GET",d),a.onreadystatechange=function(){if(a.readyState===XMLHttpRequest.DONE)if(200===a.status)try{t(JSON.parse(a.responseText))}catch(e){r()}else r()},a.send())):o&&r();try{h.cookie=O.cookie}catch(k){}function e(e){for(;e.length;)!function(t){h[t]=function(){var e=arguments;f||h.queue.push(function(){h[t].apply(h,e)})}}(e.pop())}var c,u,l="track",d="TrackPage",p="TrackEvent",l=(e([l+"Event",l+"PageView",l+"Exception",l+"Trace",l+"DependencyData",l+"Metric",l+"PageViewPerformance","start"+d,"stop"+d,"start"+p,"stop"+p,"addTelemetryInitializer","setAuthenticatedUserContext","clearAuthenticatedUserContext","flush"]),h.SeverityLevel={Verbose:0,Information:1,Warning:2,Error:3,Critical:4},(g.extensionConfig||{}).ApplicationInsightsAnalytics||{});return!0!==g[L]&&!0!==l[L]&&(e(["_"+(c="onerror")]),u=C[c],C[c]=function(e,t,n,i,a){var o=u&&u(e,t,n,i,a);return!0!==o&&h["_"+c]({message:e,url:t,lineNumber:n,columnNumber:i,error:a,evt:C.event}),o},g.autoExceptionInstrumented=!0),h}(cfg.cfg),(C[E]=n).queue&&0===n.queue.length?(n.queue.push(e),n.trackPageView({})):e();})({
src: "https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js",
crossOrigin: "anonymous", // When supplied this will add the provided value as the cross origin attribute on the script tag
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
// sri: false, // Custom optional value to specify whether fetching the snippet from integrity file and do integrity check
cfg: { // Application Insights Configuration
connectionString: "YOUR_CONNECTION_STRING"
}});
</script>
En sammanfattning av de icke-anpassade egenskaper som är tillgängliga för telemetriobjektet finns i Application Insights Exportera datamodell.
Du kan lägga till så många initierare som du vill. De anropas i den ordning de läggs till.
OpenCensus Python-telemetriprocessorer
Telemetriprocessorer i OpenCensus Python är helt enkelt återanropsfunktioner som anropas för att bearbeta telemetri innan de exporteras. Återanropsfunktionen måste acceptera en kuvertdatatyp som parameter. Om du vill filtrera bort telemetri från att exporteras kontrollerar du att återanropsfunktionen returnerar False
. Du kan se schemat för Azure Monitor-datatyper i kuverten på GitHub.
Kommentar
Du kan ändra cloud_RoleName
genom att ai.cloud.role
ändra attributet i fältet tags
.
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()
Du kan lägga till så många processorer som du vill. De anropas i den ordning de läggs till. Om en processor utlöser ett undantag påverkar det inte följande processorer.
Exempel på TelemetryInitializers
Lägga till en anpassad egenskap
Följande exempelinitierare lägger till en anpassad egenskap för varje spårad telemetri.
public void Initialize(ITelemetry item)
{
var itemProperties = item as ISupportProperties;
if(itemProperties != null && !itemProperties.Properties.ContainsKey("customProp"))
{
itemProperties.Properties["customProp"] = "customValue";
}
}
Lägga till ett molnrollnamn
Följande exempelinitierare anger namnet på molnrollen till varje spårad telemetri.
public void Initialize(ITelemetry telemetry)
{
if (string.IsNullOrEmpty(telemetry.Context.Cloud.RoleName))
{
telemetry.Context.Cloud.RoleName = "MyCloudRoleName";
}
}
Kontrollera klientens IP-adress som används för geoplatsmappningar
Följande exempelinitierare anger klientens IP-adress, som används för geoplatsmappning, i stället för IP-adressen för klient socket, under telemetriinmatning.
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 och ITelemetryInitializer
Vad är skillnaden mellan telemetriprocessorer och telemetriinitierare?
- Det finns vissa överlappningar i vad du kan göra med dem. Båda kan användas för att lägga till eller ändra egenskaper för telemetri, men vi rekommenderar att du använder initierare för detta ändamål.
- Telemetriinitierare körs alltid före telemetriprocessorer.
- Telemetriinitierare kan anropas mer än en gång. Enligt konventionen anger de inte någon egenskap som redan har angetts.
- Med telemetriprocessorer kan du helt ersätta eller ta bort ett telemetriobjekt.
- Alla registrerade telemetriinitierare anropas för varje telemetriobjekt. För telemetriprocessorer garanterar SDK att den första telemetriprocessorn anropas. Om resten av processorerna anropas eller inte bestäms av de föregående telemetriprocessorerna.
- Använd telemetriinitierare för att utöka telemetri med fler egenskaper eller åsidosätta en befintlig. Använd en telemetriprocessor för att filtrera bort telemetri.
Kommentar
JavaScript har bara telemetriinitierare som kan filtrera bort händelser med hjälp av ITelemetryInitializer
Felsöka ApplicationInsights.config
- Kontrollera att det fullständigt kvalificerade typnamnet och sammansättningsnamnet är korrekta.
- Bekräfta att filen applicationinsights.config finns i utdatakatalogen och innehåller de senaste ändringarna.