APM Error gets user context but Transaction does not

ELK 6.5, APM 6.6 Windows

We are seeing the user context logged with errors but not with transactions - see the following NodeJS ExpressJS application:

var apm = require('elastic-apm-node').start({serviceName: 'expresstest', serverUrl: 'http://xxxx:8200'});
apm.setUserContext({id: 1, username: 'jack'});
apm.captureError(new Error('Something is down!'));
var trans = apm.startTransaction("foo", "bar");
trans.setTag("type", "test");
trans.result="success";
trans.end();

The result is

  • An error event with the user jack
  • A transaction event with no user

I would expect apm.setUserContext to set the user context "globally" i.e. for all future transactions - must it really be set for each transaction?

{
  "transaction": {
    "id": "1b23b8ad1e160c73",
    "trace_id": "bfaa68b17cc403a681ede938e89bd132",
    "name": "foo",
    "type": "bar",
    "duration": 6.442,
    "timestamp": 1551267487527078,
    "result": "success",
    "sampled": true,
    "context": {
      "user": {
        
      },
      "tags": {
        "type": "test"
      },
      "custom": {
        
      }
    },
    "span_count": {
      "started": 0
    }
  }
}
{
  "error": {
    "exception": {
      "message": "booga is down!",
      "type": "Error",
      "stacktrace": [
        ...
      ],
      "handled": true
    },
    "culprit": "Object.<anonymous> (index.js)",
    "id": "c069bc3de7a8de735fdb2f866dda2804",
    "timestamp": 1551267487518000,
    "context": {
      "user": {
        
      },
      "tags": {
        
      },
      "custom": {
        
      }
    }
  }
}

TL;DR: You have to set the current user after each transaction have started, else it will be ignored. Or you can use a filter.

So called "global" tags, user content and custom context are not supported by the Node.js agent - neither for transactions or errors. You did mention that the error event got the user "jack", but according to the document you included it doesn't, which is also what I'd expect.

There is a possible workaround though: You can add a filter, which you can use to add the global data to all transactions and errors:

apm.addErrorFilter(globalUser)
apm.addTransactionFilter(globalUser)

function globalUser (payload) {
  payload.context.user = { id: 1, username: 'jack' }
  return payload // remember to return the modified payload
}

You can read more about filters here: https://www.elastic.co/guide/en/apm/agent/nodejs/current/agent-api.html#apm-add-filter

Can I ask what your use-case for having a global user is?

My bad! I flew over the error JSON and saw my username in there and assumed it was passing the user through. Turns out, it was just the lines of code (pre_context) surrounding the error call which I cut from my snippet. Doh!

You are right, there is probably no reason to set the user globally. I naively assumed setUserContext was part of the initialisation boilerplate of my app and not a way to enrich the current event or transaction.

Cheers!

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