ApplicationInsights-dotnet
ApplicationInsights-dotnet copied to clipboard
How to specify Proxy Settings
We were trying out Application Insights at work and we are not getting any telemetry in the Azure portal other than Page Views. We are pretty sure it is related to our Corporate proxy (it has caused us high levels of pain in the past).
How can I specify the proxy settings? The default proxy will not cut it for us. We have to specify url, port, username and password for our proxy.
For our .NET Core we have to set it to the HttpClientHandler like this:
var httpClientHandler = new HttpClientHandler {
Proxy = new MyProxy(), //our implementation of IWebProxy
};
I couldn't find the code in this repo in charge of sending the telemetry but if you are using HttpClient then it would be something similar.
Note that we are planning to use Application Insights in house, not in Azure, so we have the proxy restriction in all our environments.
Transmission is handled by the base SDK. Which specific class depends on whether you are using the InMemoryChannel or the ServerTelemetryChannel.
Thanks for pointing me in the right direction. I'm using the ServerTelemetryChannel. Looks like the issue is in this line.
Ideally, I would like to be able to provide Application Insights with an HttpClient
to use or at least be able to participate in the creation of the HttpClient
so I can set the Proxy of the HttpClientHandler
.
Should I move this issue to the ApplicationInsights-dotnet repo?
@epignosisx Yes, please feel free to move it there, and if you want to submit a pull request that would be awesome!
@dnduffy | @epignosisx
What is the status of this issue? Is there a new code that can handle proxy configurations? We are also governed by a proxy, though we use .NET 4.5 and then it seems like CreateRequest (https://github.com/Microsoft/ApplicationInsights-dotnet/blob/develop/src/Core/Managed/Shared/Channel/Transmission.cs#L374) is used today.
If no one had the opportunity to do something, can/should I make the changes and add a pull request?
In order to simplify, there should be something like:
if (this.UseProxy)
{
request.Proxy = new WebProxy (this.ProxyAddress, this.ProxyBypassOnLocal);
}
@crippe Are you able to get the channel from dependency injection and modify it? If not then please feel free to submit a pull request in that repo and we'll plan to take it in the next version.
Hi @dnduffy, any update on this issue? Is not it still possible to handle proxy configuration? We are governed by a proxy too. We are using the ServerTelemetryChannel.
Shortly after my comment, it was decided centrally to use technology other than Application Insights. I'm sorry for the decision, but I could not do anything about it. Therefore, I did not make a request.
Hi, any update on this issue. Seems that the milestone is moved forward continuously...
Since HttpClient uses system proxy, I think it's possible to use a tool like cntlm to store the proxy credentials and configure a system proxy without a username/password.
Any update on this issue, or an alternative example to use AI with a proxy on-prem?
@wernerbarnard If you are configuring a system wide proxy, then SDK would just pick it up. If you'd like to configure proxy settings to applicationinsights channel - that is not supported today. I'll tag this as an enhancement.
I too am hitting this issue using AI on .Net Core behind proxy. Im not convinced that HttpClient in .NET Core does use the system proxy either so need to be able to set the proxy explicitly on AI to resolve.
@davebally Please run the following in a .NET Core Console app, and check if it respects system proxy. If it does, then it'll print the AppId for the given ikey.
class Program
{
static void Main(string[] args)
{
HttpClient client = new HttpClient();
var res = client.GetStringAsync("https://dc.services.visualstudio.com/api/profiles/your_instrumentationkey/appId").Result;
Console.WriteLine(res);
}
}
@cijothomas Thanks, i retract that statement. Looks like all is well, i can see the call coming through in fiddler without an explicit proxy being set.
@cijothomas Unfortunately, this doesn't seem to work in all cases.
Running this code in our corporate environment raises a 407 error.
In our case, to make this pass, we have to define a HttpHandler
, value the Proxy
and UseProxy
properties, and build the HttpClient
from it. From a dev environment standpoint, that relies on running a local cntlm proxy, and configuring the Proxy
property so that it points to it.
Teaching AppInsights to accept a HttpHandler
would be very helpful for us.
@nulltoken Yes we are tracking this as an enhancement - to modify to accept httpclient settings.
@cijothomas Can you confirm that the HttpClient that is returned by default from IHttpClientFactory should be using the proxy ? When i set the proxy with the below code i see the call come through in fiddler, if i dont , i dont
Thanks.
in startup ....
services.AddHttpClient("external", c => { c.DefaultRequestHeaders.CacheControl = GetCacheControlHeader(); })
.ConfigureHttpMessageHandlerBuilder(c => c.PrimaryHandler = GetHttpClientHandler(true));
private static HttpClientHandler GetHttpClientHandler(bool isExternal = false)
{
var handler = new HttpClientHandler
{
AutomaticDecompression = System.Net.DecompressionMethods.GZip,
SslProtocols = SslProtocols.Tls12,
ClientCertificateOptions = ClientCertificateOption.Manual
};
if (isExternal)
{
var proxy = GetConfigProperty("Config", "Proxy", "Uri");
if (!string.IsNullOrEmpty(proxy.Value))
{
handler.Proxy = new WebProxy()
{
Address = new Uri(proxy.Value)
};
}
}
else {
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
}
return handler;
}
@davebally Sorry, i dont have any expertise in that area :( Its best to ask this in HttpClient github repo.
@davebally - for me running inside docker with HTTP_PROXY and HTTPS_PROXY set as env variables, new HttpClient
did NOT respect the proxy (default settings - not using your sample), but a HttpClient created from IHttpClientFactory
did.
This is not planned for the next release 2.8.
Is it planned at all? Having exactly the same problem here...
It is, and tagged with Future milestone. This means its not likely to land in next 2 stable releases. Please upvote the issues here so we promote items from Future to nearer milestones.
The following worked for us. Run it in the StartUp of your application:
private static void ConfigureProxyForApplicationInsightsHack(IWebProxy proxy)
{
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(Transmission).TypeHandle);
var field = typeof(Transmission).GetField("client", BindingFlags.Static | BindingFlags.NonPublic);
field.SetValue(null, new HttpClient(new HttpClientHandler { Proxy = proxy, UseProxy = true }));
}
@mvdburght thanks for sharing. The enhancement we are tracking here is to allow users to supply HttpClient for the channel/transmission.
I was getting a 407 Proxy Authorisation Required
type message. (which by the way I had to use WireShark to discover) I got it to work using @mvdburght 's workaround. My code is using a console app so I have this at the start of my main
method:
var proxy = Settings.GetSection("Proxy").Get<WebProxy>();
if (!string.IsNullOrWhiteSpace(proxy.Address.ToString()))
{
var handler = new HttpClientHandler
{
Proxy = proxy
};
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(Transmission).TypeHandle);
var field = typeof(Transmission).GetField("client", BindingFlags.Static | BindingFlags.NonPublic);
field.SetValue(null, new HttpClient(handler));
}
and in my config:
"Proxy": {
"Address": "http://[Url]:[Port]",
"UseDefaultCredentials": true
},
Hope that helps someone. Would be good to have an official way of doing it.
Hi guys.
We're using App Insights in our .NET Core services and these services are running on premises in an Azure Service Fabric backend cluster. This cluster does not have internet/azure direct access.
Right now we're doing a bunch of infrastructure "hacks" using Squid in intercept mode and DNS configs so that the App Insights requests can get to Azure, without affecting the service. It works but it's ugly and it's having unintended consequences, because of the way it's set up.
It would be much easier to be able to specify a proxy exclusive to the App Insights telemetry, without changing the rest of the service.
Do you think we could use @mvdburght suggestion in this scenario?
Instead of reflection, can't you set the default proxy globally for the app via
System.Net.WebRequest.DefaultWebProxy
?
i.e.
using System.Net;
...
// in Startup
WebRequest.DefaultWebProxy = new WebProxy(proxyUri);
Or do you want to set the value differently for App Insights?
Oh, sorry; that doesn't work for HttpClient.
In .NET Core 3.0 and 3.1, there's an HttpClient.DefaultProxy
static property:
https://docs.microsoft.com/dotnet/api/system.net.http.httpclient.defaultproxy
Or do you want to set the value differently for App Insights?
This. Do you think it's possible?
Hello.
Can someone please confirm if it's possible to specify a proxy only/different for App Insights using the @mvdburght suggestion?