# How to send error message to Elastic APM and show the error in Kibana tab

**URL:** https://discuss.elastic.co/t/how-to-send-error-message-to-elastic-apm-and-show-the-error-in-kibana-tab/329183
**Category:** APM
**Tags:** nodejs, aws-lambda
**Created:** [April 3, 2023, 8:54am UTC](https://discuss.elastic.co/t/how-to-send-error-message-to-elastic-apm-and-show-the-error-in-kibana-tab/329183 "2023-04-03T08:54:35Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![JasonREC](https://avatars.discourse-cdn.com/v4/letter/j/858c86/32.png) [@JasonREC](https://discuss.elastic.co/u/JasonREC)
#### Post date: [April 3, 2023, 8:54am UTC](https://discuss.elastic.co/t/how-to-send-error-message-to-elastic-apm-and-show-the-error-in-kibana-tab/329183/1 "2023-04-03T08:54:35Z")

</div>

I followed the set up of this page

> **[Monitoring AWS Lambda Node.js Functions | APM Node.js Agent Reference \[4.x\] |...](https://www.elastic.co/guide/en/apm/agent/nodejs/current/lambda.html)**

I am using the template.yml to set up my lambda function and Elastic APM

```auto
...
Resources:
  yourLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Environment:
          Variables:
            NODE_OPTIONS: -r elastic-apm-node/start
            ELASTIC_APM_LAMBDA_APM_SERVER: <YOUR-APM-SERVER-URL>
            ELASTIC_APM_SECRET_TOKEN: <YOUR-APM-SECRET-TOKEN>
            ELASTIC_APM_SEND_STRATEGY: background

```

According to the offical webpage it said,

> By default, the Node.js agent will watch for uncaught exceptions and send them to Elastic APM automatically. But in most cases, errors are not thrown but returned via a callback, caught by a promise, or simply manually created. Those errors will not automatically be sent to Elastic APM. To manually send an error to Elastic APM, simply call `apm.captureError()` with the error:

```auto
var err = new Error('Ups, something broke!') 

apm.captureError(err)

```

I am wonder if I have to npm install the 'elastic-apm-node' and import it into my code so as to manually send an error to Elastic APM, like **apm.captureError(err)**

```auto
import apm from 'elastic-apm-node'
 apm.start({
 
            serviceName: serviecName,

            secretToken: secretToken,

            serverUrl: serviceUrl,
        })
apm.captureError(err)

```

But I have already stated that **NODE\_OPTIONS: -r elastic-apm-node/start** in my template.yml, wouldn't it be started the elastic apm agent **twice!?**

Could anyone help?  
Thanks

---

<div class="post-metadata">

### Author: ![trentm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/trentm/32/77647_2.png) [@trentm](https://discuss.elastic.co/u/trentm)
#### Post date: [April 3, 2023, 5:20pm UTC](https://discuss.elastic.co/t/how-to-send-error-message-to-elastic-apm-and-show-the-error-in-kibana-tab/329183/2 "2023-04-03T17:20:00Z")

</div>

Hi @JasonREC. Thanks for the question.

You are correct that using `apm.start()` again would start the APM agent _twice_, which would break.

In your Lambda code you should be able to import the APM module and use it **without `.start()`ing it again**.

```js
import apm from 'elastic-apm-node'
apm.captureError(err)

```

That import should return the already-started APM agent singleton object.  
(Note that sometime there can be a gotcha here if _bundling_ is involved.)

---

<div class="post-metadata">

### Author: ![JasonREC](https://avatars.discourse-cdn.com/v4/letter/j/858c86/32.png) [@JasonREC](https://discuss.elastic.co/u/JasonREC)
#### Post date: [April 4, 2023, 2:06am UTC](https://discuss.elastic.co/t/how-to-send-error-message-to-elastic-apm-and-show-the-error-in-kibana-tab/329183/3 "2023-04-04T02:06:38Z")

</div>

Hi @trentm ,Thanks for the reply

I found out this would show an undefined agent somhow if I dont use agent start method twice.

Below is my lambda function entry point, I've already stated : **NODE\_OPTIONS**  
**-r elastic-apm-node/start** in my tamplate.yml, and I called the apm.isStated method, but it return undefined

```auto

import apm from 'elastic-apm-node'
import { Handler, SNSEvent } from "aws-lambda";
import Model from './Model';
import timer from './lib/timer';
import { run as runBackgroundTask } from './BackgroundTask';

export const handler: Handler<SNSEvent, string | void> = async (event) => {
    console.log(apm.isStarted(), 'check start or not ') // here prints undefined
    timer.reset();

    console.log('enter bg lambda function');
    const result = await Promise.all(event.Records
        .map(record => JSON.parse(record.Sns.Message) as Model.BackgroundTask)
        .map(runBackgroundTask));

    console.log('All task done', result);
    return "Success";

};

```

---

<div class="post-metadata">

### Author: ![trentm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/trentm/32/77647_2.png) [@trentm](https://discuss.elastic.co/u/trentm)
#### Post date: [April 4, 2023, 3:20am UTC](https://discuss.elastic.co/t/how-to-send-error-message-to-elastic-apm-and-show-the-error-in-kibana-tab/329183/4 "2023-04-04T03:20:51Z")

</div>

@JasonREC Hrm. That `undefined` result means that your `import apm from 'elastic-apm-node'` is creating a different APM `Agent` class instance from the one created by `NODE_OPTIONS=...`. They are meant to be the same singleton.

This is TypeScript code. Are you able to post the built JavaScript code that you are deploying? Perhaps it is emitting ESM code (using `import ...`) rather than CommonJS code (using `require`). If so, then you are liking hitting the APM agent's limitations with ES modules. See [Supported technologies | APM Node.js Agent Reference [3.x] | Elastic](https://www.elastic.co/guide/en/apm/agent/nodejs/current/supported-technologies.html#compatibility-esm) for some details.

---

<div class="post-metadata">

### Author: ![JasonREC](https://avatars.discourse-cdn.com/v4/letter/j/858c86/32.png) [@JasonREC](https://discuss.elastic.co/u/JasonREC)
#### Post date: [April 4, 2023, 4:17am UTC](https://discuss.elastic.co/t/how-to-send-error-message-to-elastic-apm-and-show-the-error-in-kibana-tab/329183/5 "2023-04-04T04:17:16Z")

</div>

Hi @trentm,

Appreciate for your quick reply.

I see your point. Currently, I am using template.yml MetaData property to do the build

> **[Building Node.js Lambda functions with esbuild - AWS Serverless Application...](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-build-typescript.html)**
>
> Use the sam build command to build an AWS SAM serverless application that uses TypeScript as a .zip file archive or a container image.

And, I just add one more line in template.yml to specify that I want it to help me compile Typescript to Javascript in Common JS. I think this may satisify that the elastic document points out

> The Elastic APM Node.js agent does _not yet support automatically instrumenting [ECMAScript module imports (ESM)](https://nodejs.org/api/esm.html#modules-ecmascript-modules)_ , i.e. modules that are loaded via `import ...` statements. It currently only instruments [CommonJS module imports](https://nodejs.org/api/modules.html#modules-commonjs-modules), i.e. modules loaded via `require(...)` .

> Metadata: # Manage esbuild properties  
> BuildMethod: esbuild  
> BuildProperties:  
> Format: cjs **\<------ I add this line**  
> Minify: true  
> Target: "es2020"  
> Sourcemap: true  
> EntryPoints:  
> - lambdaBackground.ts

But when I looked at the cloudwatch log, it still said apm agent is undfined when the request enter the lambda function.

And, if I run apm.captureError(new Error('test')), it will say agent has not started

 ![capture](https://us1.discourse-cdn.com/elastic/original/3X/2/c/2c151468b41a0b1437bd8d2a3b6f77ea48d2f5b9.png)

I wish I could post the built javascript code, but they all got minified, and it is almost unreadble.

---

<div class="post-metadata">

### Author: ![trentm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/trentm/32/77647_2.png) [@trentm](https://discuss.elastic.co/u/trentm)
#### Post date: [April 4, 2023, 7:03pm UTC](https://discuss.elastic.co/t/how-to-send-error-message-to-elastic-apm-and-show-the-error-in-kibana-tab/329183/6 "2023-04-04T19:03:44Z")

</div>

Oh, esbuild and bundling/minifying are involved. That will be an issue. See [Starting the agent | APM Node.js Agent Reference [4.x] | Elastic](https://www.elastic.co/guide/en/apm/agent/nodejs/current/starting-the-agent.html#start-bundlers) (and the "esbuild" section further down) for some details.

I don't have an answer that I know will work. I've opened [get working out of the box with AWS Lambda using esbuild: Agent singleton, esbuild format config, etc. · Issue #3244 · elastic/apm-agent-nodejs · GitHub](https://github.com/elastic/apm-agent-nodejs/issues/3244) to look into this when I am able.

A couple things you could try now as workarounds are points 2 and 3 on that issue:

> 1. Another workaround might be to specify that the `elastic-apm-node` module be in the esbuild `externals` -- as documented at [Starting the agent | APM Node.js Agent Reference [4.x] | Elastic](https://www.elastic.co/guide/en/apm/agent/nodejs/current/starting-the-agent.html#start-esbuild). Can this config be passed through via the SAM configuration? If so, we should document this example.
> 2. Another possible workaround might be to _not_ have `elastic-apm-node` listed in dependencies, but _still_ import it **via CommonJS `require`**. That might result in getting the `elastic-apm-node` module provided by the Elastic Lambda layer. This may require configuring a linter and/or esbuild to ignore the attempt to import a module that is not listed in "dependencies".

---

<div class="post-metadata">

### Author: ![JasonREC](https://avatars.discourse-cdn.com/v4/letter/j/858c86/32.png) [@JasonREC](https://discuss.elastic.co/u/JasonREC)
#### Post date: [April 5, 2023, 9:28am UTC](https://discuss.elastic.co/t/how-to-send-error-message-to-elastic-apm-and-show-the-error-in-kibana-tab/329183/7 "2023-04-05T09:28:35Z")

</div>

Hi, @trentm  
Thanks for helping me.  
I looked at the document you mentioned, it is very helpful to know so as to use **elastic apm node with ESbuild** , I have to mark the modules as external.

And, yes, I just noticed that in the AWS document (The intro of Building Node.js Lambda functions with esbuild that I mentioned earlier), it does have a field called **External** , which the usage is

> Specifies the list of packages to omit from the build.

I think I would love to give it a try and see if this can fix the problem. I will let you how it goes as soon as I try it.

Thanks

---

<div class="post-metadata">

### Author: ![JasonREC](https://avatars.discourse-cdn.com/v4/letter/j/858c86/32.png) [@JasonREC](https://discuss.elastic.co/u/JasonREC)
#### Post date: [April 11, 2023, 3:53am UTC](https://discuss.elastic.co/t/how-to-send-error-message-to-elastic-apm-and-show-the-error-in-kibana-tab/329183/8 "2023-04-11T03:53:20Z")

</div>

Hi @trentm,

Adding external does fix the undefined agent problem, and error message now can sucessfully send to Kibana tab. Appreciate for your help.

---

<div class="post-metadata">

### Author: ![trentm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/trentm/32/77647_2.png) [@trentm](https://discuss.elastic.co/u/trentm)
#### Post date: [April 11, 2023, 6:31pm UTC](https://discuss.elastic.co/t/how-to-send-error-message-to-elastic-apm-and-show-the-error-in-kibana-tab/329183/9 "2023-04-11T18:31:58Z")

</div>

@JasonREC Good to hear. Thanks for following up on this thread!

---

<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: [May 2, 2023, 2:32pm UTC](https://discuss.elastic.co/t/how-to-send-error-message-to-elastic-apm-and-show-the-error-in-kibana-tab/329183/10 "2023-05-02T14:32:25Z")

</div>

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