# APM rest api

**URL:** <https://discuss.elastic.co/t/apm-rest-api/218986>\
**Category:** APM\
**Tags:** dotnet, server\
**Created:** [February 12, 2020, 1:18pm UTC](https://discuss.elastic.co/t/apm-rest-api/218986 "2020-02-12T13:18:31Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![spark](https://avatars.discourse-cdn.com/v4/letter/s/4da419/32.png) [@spark](https://discuss.elastic.co/u/spark)\
**Post date:** [February 12, 2020, 1:18pm UTC](https://discuss.elastic.co/t/apm-rest-api/218986/1 "2020-02-12T13:18:31Z")

</div>

Hey,

I'm using Kibana, ElasticSearch and APM in version 7.5.1 (fresh install).

I now want to use Application Performance Monitoring in my application, which is written in c++.  
Since Elastic does not have an C++ APM Agent, I thought utilizing the REST API.

For simplicity I first want to test the REST API with Visual Studio Code with Plugin `REST Client`.  
So currently I am sending a POST request to the endpoint `http://xxx:5601/intake/v2/events` (where xxx is the Elastic APM-Server) as described in [https://www.elastic.co/guide/en/apm/server/current/events-api.html](https://www.elastic.co/guide/en/apm/server/current/events-api.html).  
In the header I currently just have

```
content-type: application/json

```

And the body of this REST request is taken 1:1 from [https://www.elastic.co/guide/en/apm/server/current/intake-api.html](https://www.elastic.co/guide/en/apm/server/current/intake-api.html).

However after firing that REST request I get the following response:

```
HTTP/1.1 404 Not Found
kbn-name: kibana
kbn-xpack-sig: 98ef0b80a56156b387f246997c215417
content-type: application/json; charset=utf-8
cache-control: no-cache
content-length: 60
Date: Wed, 12 Feb 2020 12:48:33 GMT
Connection: close

{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Not Found"
}

```

Where did I go wrong/what did I forget?

Thank you very much in advance.

---

<div class="post-metadata">

**Author:** ![felixbarny](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/felixbarny/32/27341_2.png) [@felixbarny](https://discuss.elastic.co/u/felixbarny)\
**Post date:** [February 12, 2020, 1:21pm UTC](https://discuss.elastic.co/t/apm-rest-api/218986/2 "2020-02-12T13:21:24Z")

</div>

Seems you are sending the request to Kibana as opposed to the APM Server

---

<div class="post-metadata">

**Author:** ![spark](https://avatars.discourse-cdn.com/v4/letter/s/4da419/32.png) [@spark](https://discuss.elastic.co/u/spark)\
**Post date:** [February 12, 2020, 1:22pm UTC](https://discuss.elastic.co/t/apm-rest-api/218986/3 "2020-02-12T13:22:58Z")

</div>

What would be the right endpoint?  
I also tried `http://vm-es7-apm:5601/intake/v2/rum/events`, but I get the same response there.

---

<div class="post-metadata">

**Author:** ![felixbarny](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/felixbarny/32/27341_2.png) [@felixbarny](https://discuss.elastic.co/u/felixbarny)\
**Post date:** [February 12, 2020, 2:49pm UTC](https://discuss.elastic.co/t/apm-rest-api/218986/4 "2020-02-12T14:49:52Z")

</div>

The port of APM Server is usually 8200

---

<div class="post-metadata">

**Author:** ![spark](https://avatars.discourse-cdn.com/v4/letter/s/4da419/32.png) [@spark](https://discuss.elastic.co/u/spark)\
**Post date:** [February 14, 2020, 12:02pm UTC](https://discuss.elastic.co/t/apm-rest-api/218986/5 "2020-02-14T12:02:11Z")

</div>

I changed my approach.  
Instead of logging via C++, I will redirect my output to C#.

I installed `Elastic.Apm` nuget package.  
And wrote a function to test APM functionality.

```auto
Environment.SetEnvironmentVariable("ELASTIC_APM_SERVER_URLS", "http://xxx:8200");
Environment.SetEnvironmentVariable("ELASTIC_APM_SERVICE_NAME", "Your Service Name");

var transaction = Elastic.Apm.Agent.Tracer.StartTransaction("Transaction Name", ApiConstants.TypeRequest);
var span = transaction.StartSpan("Span Name", ApiConstants.TypeExternal, ApiConstants.ActionQuery);
Thread.Sleep(200);
span.End();
transaction.End();

```

On the [ASP.NET](http://ASP.NET) project everything works fine with above URL and I can see logs in Kibana.  
However executing above in a .NET class library there is no log in Kibana.

Intercepting the connection with Fiddler, I can see that there is an outgoing connection with the Request Header containing `GET /config/v1/agents?service.name=Your+Service+Name HTTP/1.1` and the Response Header reads `HTTP/1.1 403 Forbidden`.

What am I doing wrong here?

---

<div class="post-metadata">

**Author:** ![simitt](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/simitt/32/106406_2.png) [@simitt](https://discuss.elastic.co/u/simitt)\
**Post date:** [February 17, 2020, 9:00am UTC](https://discuss.elastic.co/t/apm-rest-api/218986/6 "2020-02-17T09:00:07Z")

</div>

The APM Server exposes an endpoint for APM agents to [query for configuration changes](https://www.elastic.co/guide/en/apm/server/7.6/agent-configuration-api.html). This endpoint is disabled by default, in which case you see above mentioned `403` response. It can be enabled by configuring `apm-server.kibana.*` accordingly in the APM Server.  
APM agents do not rely on this configuration endpoint though, so this should not be the reason for agents not sending data to the APM Server.

---

<div class="post-metadata">

**Author:** ![GregKalapos](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/gregkalapos/32/37205_2.png) [@GregKalapos](https://discuss.elastic.co/u/GregKalapos)\
**Post date:** [February 17, 2020, 9:13am UTC](https://discuss.elastic.co/t/apm-rest-api/218986/7 "2020-02-17T09:13:05Z")

</div>

Hi @spark,

as @simitt says that HTTP GET for the config can be ignored for your specific problem.

It should not matter where you put that code, it should also work with a class library, so unfortunately I don't see anything in your post that'd cause a problem here.

Maybe 1 idea: the agent does not stop the process from being terminated, so make sure the agent has enough time to send the data before the process is terminated - so if it's a console app, maybe put a thread sleep before the main method.

Otherwise - I assume this is some sample project - if you can share it with us somehow (just upload it to somewhere...) I'd be happy to take a look at it.

---

<div class="post-metadata">

**Author:** ![spark](https://avatars.discourse-cdn.com/v4/letter/s/4da419/32.png) [@spark](https://discuss.elastic.co/u/spark)\
**Post date:** [February 17, 2020, 10:50am UTC](https://discuss.elastic.co/t/apm-rest-api/218986/8 "2020-02-17T10:50:00Z")

</div>

@simitt, @GregKalapos Thank you very much for your answers.

@simitt I checked the file `apm-server\apm-server.yml`.  
There was only one entry active so far: Under node `apm-server` the entry `host: "10.54.149.154:8200"`, so now I enabled under node `kibana` the entry `enabled: true` and restarted both, the service `elasticsearch-apm` and `elasticsearch-kibana`.  
However with no change.

@GregKalapos What would be the preferred file hoster/storage? I created a new blank project `Console App (.NET Framework)` and `.NET Framework 4.6.1` in Visual Studio 2017 (before it was a class library).  
Then I added the library `Elastic.Apm` version 1.3.0 via nuget.  
The only file `program.cs` in the project looks as follows:

```auto
using Elastic.Apm.Api;
using System;
using System.Diagnostics;
using System.Threading;

namespace ElatsticAPM
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread.Sleep(500);

            ApmTest_ManualTest();

            Thread.Sleep(15000);
            Console.Read();
        }

        private static void ApmTest_ManualTest()
        {
            Thread.Sleep(500);

            Debug.WriteLine("Test ApmTest_ManualTest Start");

            string ElasticApmServerUrl = "http://10.54.149.154:8200";
            Environment.SetEnvironmentVariable("ELASTIC_APM_SERVER_URLS", ElasticApmServerUrl);
            Environment.SetEnvironmentVariable("ELASTIC_APM_SERVICE_NAME", "Your Service Name");
            Environment.SetEnvironmentVariable("ELASTIC_APM_LOG_LEVEL", "trace");

            var transaction = Elastic.Apm.Agent.Tracer.StartTransaction("Transaction Name", ApiConstants.TypeRequest);
            var span = transaction.StartSpan("Span Name", ApiConstants.TypeExternal, ApiConstants.ActionQuery);
            Thread.Sleep(200);
            span.End();
            transaction.End();

            Debug.WriteLine("Test ApmTest_ManualTest Output ends here 12574");

            Thread.Sleep(500);
        }
    }
}

```

and in the Console window I get the following output: [https://pastebin.com/SfEkjP92](https://pastebin.com/SfEkjP92)

---

<div class="post-metadata">

**Author:** ![simitt](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/simitt/32/106406_2.png) [@simitt](https://discuss.elastic.co/u/simitt)\
**Post date:** [February 17, 2020, 11:51am UTC](https://discuss.elastic.co/t/apm-rest-api/218986/9 "2020-02-17T11:51:21Z")

</div>

Did you ensure the APM Server can actually reach Kibana? You should find more details about that in the APM Server logs. Only setting `apm-server.kibana.enabled: true` might not be enough if any of the other default values do not fit your setup, eg the `host`. Please see the list of related [config options](https://www.elastic.co/guide/en/apm/server/7.6/setup-kibana-endpoint.html).

---

<div class="post-metadata">

**Author:** ![GregKalapos](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/gregkalapos/32/37205_2.png) [@GregKalapos](https://discuss.elastic.co/u/GregKalapos)\
**Post date:** [February 17, 2020, 11:57am UTC](https://discuss.elastic.co/t/apm-rest-api/218986/10 "2020-02-17T11:57:17Z")

</div>

Thanks for the info @spark, if you only have the 1 `.cs` file, then it's already enough for me, otherwise you can just put stuff on GitHub.

Regarding the sample you pasted and the logs:

From what I see in the logs, everything look ok from the agent's perspective:

```auto
[2020-02-17 11:27:22.193 +01:00][Debug] - {PayloadSenderV2} Sent items to server:
    Span{Id: 4d7c0b6f28272e93, TransactionId: bfd788c9f223a829, ParentId: bfd788c9f223a829, TraceId: e2c11b2fb42e135ca0847845a2059950, Name: Span Name, Type: external, IsSampled: True},
    Transaction{Id: bfd788c9f223a829, TraceId: e2c11b2fb42e135ca0847845a2059950, ParentId: null, Name: Transaction Name, Type: request, IsSampled: True}

```

This line tells that the agent successfully sent data (and specifically 1 transaction with name `"Transaction Name"` you capture in the sample code) to the APM Server. Are you totally sure this transaction is not captured? Is there maybe anything in the server logs?

---

<div class="post-metadata">

**Author:** ![spark](https://avatars.discourse-cdn.com/v4/letter/s/4da419/32.png) [@spark](https://discuss.elastic.co/u/spark)\
**Post date:** [February 17, 2020, 12:31pm UTC](https://discuss.elastic.co/t/apm-rest-api/218986/11 "2020-02-17T12:31:01Z")

</div>

@simitt Your hint helped to the solution.  
After editing node `kibana`, entry `host` to the IP (in my case `10.54.149.154:5601`), I was able to create a connection.

Thank you very much for helping me!

Now there is only one detail question: In the code you can see that I set environmental variables like `ELASTIC_APM_SERVER_URLS` and `ELASTIC_APM_SERVICE_NAME`.  
In an [ASP.NET](http://ASP.NET) project I would set these values in an `AppsSettings.config` file.  
Is is possible to set these variables on another way in an console/class library project?

---

<div class="post-metadata">

**Author:** ![GregKalapos](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/gregkalapos/32/37205_2.png) [@GregKalapos](https://discuss.elastic.co/u/GregKalapos)\
**Post date:** [February 17, 2020, 12:37pm UTC](https://discuss.elastic.co/t/apm-rest-api/218986/12 "2020-02-17T12:37:43Z")

</div>

> [@spark](#):
>
> Now there is only one detail question: In the code you can see that I set environmental variables like `ELASTIC_APM_SERVER_URLS` and `ELASTIC_APM_SERVICE_NAME` .  
> In an [ASP.NET](http://ASP.NET) project I would set these values in an `AppsSettings.config` file.  
> Is is possible to set these variables on another way in an console/class library project?

This depends on how the agent will be started - if the class library is in an [ASP.NET](http://ASP.NET) Classic application and you use [the IIS module](https://www.elastic.co/guide/en/apm/agent/dotnet/current/setup.html#setup-asp-net), then it'll pick up the configs from `web.config` as described [here](https://www.elastic.co/guide/en/apm/agent/dotnet/current/configuration-on-asp-net.html) - same for [ASP.NET](http://ASP.NET) Core and `appsettings.json`.

But if you let's say embed the class library into a .NET Framework console application, then in that case the agent will only read environment variables - even if you manually parse an `ApSettings.config` file - there would be a way to pass the config to the agent - we can discuss that, but that'll need some coding on your side.

I guess the [ASP.NET](http://ASP.NET) + web.config will cover your scenario, but I'm not sure - if not, and using environment variables are too bad, let's follow up.

---

<div class="post-metadata">

**Author:** ![spark](https://avatars.discourse-cdn.com/v4/letter/s/4da419/32.png) [@spark](https://discuss.elastic.co/u/spark)\
**Post date:** [February 17, 2020, 1:09pm UTC](https://discuss.elastic.co/t/apm-rest-api/218986/13 "2020-02-17T13:09:07Z")

</div>

@GregKalapos unfortunately I have the case without the [ASP.NET](http://ASP.NET) application.  
I only have a .NET Framework class library that will be called via RPC by c++ code of my application.

How would the coding you proposed look like?

---

<div class="post-metadata">

**Author:** ![GregKalapos](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/gregkalapos/32/37205_2.png) [@GregKalapos](https://discuss.elastic.co/u/GregKalapos)\
**Post date:** [February 17, 2020, 1:58pm UTC](https://discuss.elastic.co/t/apm-rest-api/218986/14 "2020-02-17T13:58:34Z")

</div>

> [@spark](#):
>
> @GregKalapos unfortunately I have the case without the [ASP.NET](http://ASP.NET) application.  
> I only have a .NET Framework class library that will be called via RPC by c++ code of my application.
> 
> How would the coding you proposed look like?

Oh, I see. Ok, so in this case the only way to configure the agent is to use environment variables. All you need to do is to make sure that the environment variables are set and visible to the process that hosts the .NET Agent - like on windows just use `set ELASTIC_APM_SERVER_URLS=yourserver` and so on. By default the agent will always try to read configs from environment variables.

---

<div class="post-metadata">

**Author:** ![GregKalapos](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/gregkalapos/32/37205_2.png) [@GregKalapos](https://discuss.elastic.co/u/GregKalapos)\
**Post date:** [February 17, 2020, 2:10pm UTC](https://discuss.elastic.co/t/apm-rest-api/218986/15 "2020-02-17T14:10:25Z")

</div>

Well, what I said above isn't really the full story - you can still read configs through `Appsettings.config`- I added a sample here.

```auto
using Elastic.Apm;
using Elastic.Apm.Config;
using Elastic.Apm.Helpers;
using Elastic.Apm.Logging;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConfigSample
{
	class Program
	{
		static void Main(string[] args)
		{
			Agent.Setup(new AgentComponents(configurationReader: new CustomConfig()));

			//after this the agent will use the configs from your CustomConfig
		}
	}

	class CustomConfig : IConfigurationReader
	{

		public IReadOnlyList<Uri> ServerUrls
		{
			get
			{
				var serverUrl = ConfigurationManager.AppSettings["ServerUrls"];
				var serverUri = new Uri(serverUrl);
				return new List<Uri> { serverUri };
			}

		}

		//implement all other properties
	}
}

```

App.Config:

```auto
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
	<appSettings>
		<add key="ServerUrls" value="http://localhost:8200" />
	</appSettings>
</configuration>

```

You'll also need to reference the `System.Configuration.dll` in order to use `ConfigurationManager`.

We are not very happy with the `IConfigurationReader` because you need to implement all the settings that the agent can read (A help for this could be to look at [the docs](https://www.elastic.co/guide/en/apm/agent/dotnet/current/config-all-options-summary.html) about the config settings), so, yeah, this is something we think about improving somehow.

Nevertheless I'd say setting the environment variables for the given process is in general in my opinion the easiest.

---

<div class="post-metadata">

**Author:** ![spark](https://avatars.discourse-cdn.com/v4/letter/s/4da419/32.png) [@spark](https://discuss.elastic.co/u/spark)\
**Post date:** [February 17, 2020, 2:46pm UTC](https://discuss.elastic.co/t/apm-rest-api/218986/16 "2020-02-17T14:46:03Z")

</div>

Thank you very much, I'll give it a try.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [March 9, 2020, 10:46am UTC](https://discuss.elastic.co/t/apm-rest-api/218986/17 "2020-03-09T10:46:04Z")

</div>

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