elastic / apm-agent-nodejs

https://www.elastic.co/guide/en/apm/agent/nodejs/current/index.html
BSD 2-Clause "Simplified" License
582 stars 224 forks source link

Simple support for instrumenting incoming WebSockets #195

Open watson opened 6 years ago

watson commented 6 years ago

Today incoming WebSocket connections are not instrumented as we don't know how to group events on the socket into meaningful Transactions.

Normally we refer users to manually instrument the WebSockets using custom transactions, but it would be really nice if we could provide a better out-of-the-box experience.

If it makes the task easier, we could consider limiting this support to Socket.IO, as that library have higher level concepts that translate better to Transactions.

watson commented 6 years ago

For reference see related issue: #195

william1888 commented 6 years ago

Would it be possible to instrument socket.io server the same way that you instrument express for example?

watson commented 6 years ago

Yes that was my idea

Qard commented 6 years ago

Could possibly wrap the ack callback in socket.io. https://github.com/socketio/socket.io/blob/7e35f901b8b60605b6cde94467033921ab582fc5/docs/API.md#socketoneventname-callback

nuragic commented 4 years ago

Hi @watson,

Do you think it would be possible to integrate apm right now with an app that's using this lib (both client and server)? https://github.com/apollographql/subscriptions-transport-ws

We are already starting the transactions from the onOperation and ending from onOperationComplete, but that's on the server; we would like them to start from the client instead...

Thanks!

watson commented 4 years ago

@nuragic I think the Get started with a custom Node.js stack guide is what you're looking for. This describes how to instrument an unsupported framework.

nuragic commented 4 years ago

@watson Hey thanks for answering, really appreciated! However I can't find anything that would be of additional help in the documentation... I mean related to instrumenting WS "from clients". We successfully start a custom transaction "from the server" (the one which receives the WS connection) but not "from the clients". Today is common to use GraphQL for example... many apps have real-time constraints so they choose to have bidirectional communication with a server exclusively via WebSocket, no HTTP at all... that's how we do that for example. With this kind of stack (which I guess it's common today) is really difficult to see how is it supposed to monitor from the client... anyway, is this maybe an issue to be discussed on https://github.com/elastic/apm-agent-rum-js?

vigneshshanmugam commented 4 years ago

@nuragic The client could be monitored with the help of Elastic APM RUM agent, however we don't automatically instrument web-socket connections. So it would be up to you for now to create transactions and spans using the API specified here https://www.elastic.co/guide/en/apm/agent/rum-js/current/custom-transactions.html#custom-transactions

nuragic commented 4 years ago

@vigneshshanmugam Yeah, I see, thanks! I'll let you know in case we'll make additional progress on this.

chadi-kazan commented 2 years ago

sorry for bringing this thread out of the dead, but i could not find anything else related to my issue. @nuragic I am facing the exact same situation, I am running apollo client to communicate with a GQL backend (although mine is running on .NET). I would like my transaction monitoring to start from the client. Were you able to finally achieve this somehow? do you mind sharing your solution? @vigneshshanmugam the apm-rum js agent documentation you linked to seems outdated or out of sync, I use typescript and I can see many features missing (like blocking spans on custom transactions for instance) and a lot of the methods are unstable and labelled with undocumented, might be removed. The example in the documentation is also very basic, it would be great to have something more elaborate. thanks

nuragic commented 2 years ago

@chadi-kazan Hi! I'm not working anymore on that particular project but anyway, I didn't find any good solution to start the transaction from the client using the https://github.com/apollographql/subscriptions-transport-ws library. I guess it can be done but it would involve custom code, sorry but I don't recall right now the conclusion. The solution we implemented was to start the transaction on the connection "init" and terminating it on the connection "end" (but on the GraphQL server indeed).