How to trace Socket Events using Elastic APM Tool

Kibana version:
7.5.2
Elasticsearch version:
7.5.2
APM Server version:
7.5.2
Kibana 7.5.2

APM Agent language and version:

elastic-apm-node : 3.6.1

How do we capture the socket events?

I am using TypeScript version (3.9.6) for writing this functionality.

I tried to work around using custom Transaction to this way.

     apm.startTransaction("Socket Unknown", "request", "socket.io");
      

This call is always throwing me error :frowning:

TypeError: apm.startTransaction is not a function
    at /Users/sreedhar/projects/ABC/Example/build/index.js:71:9
    at Layer.handle [as handle_request] (/Users/sreedhar/projects/ABC/Example/node_modules/express/lib/router/layer.js:95:5)

    at next (/Users/sreedhar/projects/ABC/Example/node_modules/express/lib/router/

my sample code for health check:

import * as apm from 'elastic-apm-node/start'
const app = new ExampleServer().getApp();  // express app

app.use(bodyParser.json());

app.get("/health", (request , response) => {
    apm.startTransaction("Health Test");
    response.statusCode = 200;
    response.statusMessage = "OK";
    response.send(
        {
            "Health" : "OK",
            "ServiceName" : "VideoCallService"
        }
    )
});
  "dependencies": {
    "@sentry/integrations": "5.19.1",
    "@sentry/node": "5.19.1",
    "@types/node": "^14.0.23",
    "@types/socket.io": "^2.1.8",
    "cors": "^2.8.5",
    "dotenv": "^8.2.0",
    "elastic-apm-node": "^3.6.1",
    "express": "^4.17.1",
    "nodemon": "^2.0.4",
    "rimraf": "^3.0.2",
    "socket.io": "^2.3.0"
  },
  "devDependencies": {
    "@danmasta/mocha-sonar": "0.0.6",
    "@types/cors": "^2.8.6",
    "codecov": "^3.7.0",
    "cypress-multi-reporters": "^1.4.0",
    "mocha": "^8.0.1",
    "mocha-junit-reporter": "^2.0.0",
    "nyc": "^15.1.0",
    "tslib": "^2.0.0",
    "typescript": "^3.9.6",
    "ts-node": "^8.10.2",
    "supertest": "latest"
  }
}

All the settings are loaded with environment variables.

Hi @sreedharbukya,

Possible reason for that would be TypeScript is compiling the modules in a way that breaks the exported functions of the APM Node.js module. Could you share your tsconfig.json, that would help isolate the issue.

Thanks,
Vignesh

Here is tsconfig.json

{
  "compilerOptions": {
   "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    "lib": ["es6"],                           /* Specify library files to be included in the compilation. */
    "allowJs": true,                          /* Allow javascript files to be compiled. */
    "outDir": "build",                        /* Redirect output structure to the directory. */
    "rootDir": "src",                         /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    "strict": true,                           /* Enable all strict type-checking options. */
    "noImplicitAny": true,                    /* Raise error on expressions and declarations with an implied 'any' type. */
    "strictPropertyInitialization": false,  /* Enable strict checking of property initialization in classes. */
    "esModuleInterop": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    "resolveJsonModule": true,                /* Include modules imported with '.json' extension */
    "skipLibCheck": true,                     /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true,  /* Disallow inconsistently-cased references to the same file. */
    "baseUrl": "./",
    "paths": {
      "tslib" : ["node_modules/tslib/tslib.d.ts"]
   }
  },
 "exclude": [
  "node_modules",
  "test"
 ]
}

tsconfig.production.json

{
  "extends": "./tsconfig",
  "compilerOptions": {
    "sourceMap": true,
    "inlineSources": true,
    "sourceRoot": "/",
    "noEmitHelpers": true,
    "importHelpers": true
  }
}

APM Node.js module uses the ES6 default exports to export the agent interface. Since the code is importing all the named module exports through import * as apm it wont be able to find the correct export.

You have to change the code in either of the following ways

import apm from 'elastic-apm-node' 

apm.startTransaction

// OR

import * as apm from 'elastic-apm-node'

apm.default.startTransaction // default exports

Let us know if it helps.

Thanks,
Vignesh

Thanks @vigneshh, It did worked but in the following statement

 apm.startTransaction('SocketIO Unknown', 'request', 'socket.io');

But fails in following statement

 apm.startTransaction('SocketIO Unknown', 'request', 'socket.io',  {
                    childOf: apm.currentTraceparent
                });

Second line of code throws the same Error which is reported above.

Apologies for the delay,

You have to use the elastic-apm-node-opentracing package to use the Opentracing bridge.

Thanks,
Vignesh

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