APM AspNet Core

Hello,

I have an AspNet Core application (2.2). I install APM server and add the APM nuget package on local machine and while the APM server is running logs are successfully sent to elastic cloud based cluster. How would this work if I deploy the app in an Web App Service in the cloud or a docker container for example - how do I go about the APM server ?

On the official APM page there is nothing about the .NET integration https://www.elastic.co/solutions/apm

I would expect something similar to the NodeJs integration.

Thanks,
Ross

Hey Ross,

Welcome here! It’s nice to see that you already use the .NET Agent.

Hosting the app in the cloud or in a docker container shouldn’t really change much on the setup. Your app must be able to talk to an APM Server - meaning what you configured in the ServerUrls setting should be available, but I think this works by default both on Azure App Services and also in docker. If not, all you need to do is that you enable that specific URL and port to HTTP.

You have two options:

  • You can still use Elastic Cloud. Probably this is the easiest, since you don’t have to change anything. You have to make sure that the the app from docker or from the App Service is able to talk to the Elastic APM Server, but that’s all.

  • You can of course also host your own APM Server - in this case you’ll also need Kibana and Elasticsearch, which again, you can either use directly from Elastic Cloud or you can host those yourself. If from some reason you are not able or you don’t want your app to talk to Elastic Cloud you can move the APM Server directly to the network where your application runs.

I hope this helps.

Greg

Hi Greg,

Thanks for the answer. Can you confirm that this is a correct appsettings.json template:

"ElasticApm": {
"LogLevel": "Debug",
"ServerUrls": "",
"SecretToken": "",
"ServiceName": ""
}

Is the ServiceUrls field a json array or a string with separated values ?

Regards,
Ross

@Ruslan_Filipov Yes, the appsettings.json looks valid. Here is a little bit of documentation on this topic.

You probably already do this, so just for the record: make sure you pass the IConfiguration instance to the app.UseElasticApm(Configuration).

Also, jfyi Debug will log a lot, the default is Error, or if you simply skip a setting in the json file then the agent will use the default value.

Regarding ServiceUrl: It's a comma separated string, but currently in the .NET Agent we only use the 1. value (the feature that'd use multiple servers is not yet implemented... we are in the alpha phase, so this is a missing part). So it'd be something like this "ServerUrls": "http://myapmserver:8200" in case you add more everything from after the 1. url would be ignored atm. (for the record: this will change in the future).

It appears that the problem might have been the nuget version. After updating to Elastic.Apm.All 0.0.2-alpha I can now successfully send data to the cloud based APM server.

I can confirm it works with docker images deployed in Kubernetes.

I can see that it logs the response headers. I was wondering if there is a way to see/log the response body as well ? It is something I might be interested to see for health probes send from the cluster.

R

Yes; that is a known limitation of the 1. alpha release - I did not realize that you tried and did not work.

The SecretToken setting is only part of the 2. preview release - so you have to be on at least 0.0.2.0-alpha (currently latest). This explains a lot :slight_smile:

To you question: the response body is not captured by auto-instrumentation and there is no way to turn that on currently. Unfortunately it's not even part of the data model we send to the server currently - we only have the request body.

With Agent.Tracer.CurrentTransaction you can get the current transaction and on this you can set the body: transaction.Context.Request.Body = //...body as string. But that's the request body and not the response body that you want. Another option is to use the Tags dictionary on the Transaction, you can put custom data there: transaction.Tags["foo"] = "bar";

Maybe that helps to capture at least part of what you need. The value you can put into the dictionary cannot be longer than 1024 char, otherwise it'll be trimmed.

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.