RuntimeTools / appmetrics

Node Application Metrics provides a foundational infrastructure for collecting resource and performance monitoring data for Node.js-based applications.
https://developer.ibm.com/open/node-application-metrics/
Apache License 2.0
970 stars 125 forks source link

Probably stupid question, but is it supposed to run via HTTPS? #640

Closed neilyoung closed 4 years ago

neilyoung commented 4 years ago

The thing is: It doesn't show anything useful if the server is running secure

mattcolegate commented 4 years ago

Hi @neilyoung,

appmetrics is designed to run alongside a Node.js application to provide monitoring information for that application. It doesn't matter to appmetrics if your application outputs to console, HTTP or HTTPS, it will run alongside just the same. Information from appmetrics can be output by your application by utilising the monitoring.on function to obtain the monitoring data as an object (see https://github.com/RuntimeTools/appmetrics#modifying-your-application-to-use-appmetrics). Your application is then free to output that data in whatever form you wish. If you are looking for something more visual in output, might I suggest https://github.com/runtimetools/appmetrics-dash ? It uses either your or it's own HTTP server to visually display data from appmetrics on a web dashboard.

neilyoung commented 4 years ago

If you are looking for something more visual in output, might I suggest https://github.com/runtimetools/appmetrics-dash ? It uses either your or it's own HTTP server to visually display data from appmetrics on a web dashboard.

This is what I'm using. And it just displays a screen full of empty field:

image

Setup like so:

(package.json): "appmetrics-dash": "^5.3.0", Then first line of my server code:

// Before all other 'require' statements
require('appmetrics-dash').attach()

As far as I know that was it.

My server is started like so:

var server = url.protocol === 'http:' ? http.createServer(app).listen(port, () => {
    logger.info('non-Secure server started  at %s', args.srv_url)
}) :
    https.createServer(options, app).listen(port, () => {
        logger.info('secure server started at %s', args.srv_url)
        http.createServer((req, res) => {
            res.writeHead(302, { 'location': 'https://' + req.headers.host + req.url })
            res.end()
        }).listen(80)
    })

A call to the dashboard route brings the above screen.

mattcolegate commented 4 years ago

That's interesting - there's code in appmetrics-dash to support both https and http servers - I wonder if it's being thrown off by your http redirect server? Does it work if you create a http server rather than a https server?

neilyoung commented 4 years ago

Will check later and let you know

mattcolegate commented 4 years ago

I threw together a quick sample HTTPS server and can confirm that appmetrics-dash appeared on https://localhost:3000/appmetrics-dash with meaningful data

test.js.txt

mattcolegate commented 4 years ago

I've now recreated your issue using your code snippet above - it looks like although the dashboard is available in both places data is only being sent to one of them. Your secure site's appmetrics-dash is empty, but your http redirect's one (on http://<host>:80/appmetrics-dash) is populated with data.

test.js.txt

To get your data going back where it should, you'll need to use the appmetrics-dash.monitor()method to just target your secure server - have a look at the following example to see what to do:

solution.js.txt

neilyoung commented 4 years ago

Cool. Thanks. As you said, it works via HTTPS, if I omit HTTP. Will try your latest suggestion now. Having another problem on the same machine with another node server running at 8443, secure.

Same setup: First line the require statement. No HTTP server only HTTPS.

The first attempt to get the dashboard crashes the node server:

[Thu May 14 14:01:01 2020] com.ibm.diagnostics.healthcenter.loader INFO: Node Application Metrics 5.1.1.202005141355 (Agent Core 4.0.5)
[Thu May 14 14:01:02 2020] com.ibm.diagnostics.healthcenter.mqtt INFO: Connecting to broker localhost:1883
events.js:292
      throw er; // Unhandled 'error' event
      ^

Error [ERR_STREAM_WRITE_AFTER_END]: write after end
    at write_ (_http_outgoing.js:646:17)
    at ServerResponse.write (_http_outgoing.js:638:15)
    at ReadStream.ondata (_stream_readable.js:708:22)
    at ReadStream.emit (events.js:315:20)
    at ReadStream.EventEmitter.emit (domain.js:485:12)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:273:9)
    at ReadStream.Readable.push (_stream_readable.js:214:10)
    at internal/fs/streams.js:242:14
    at /home/decades/awss-server/node_modules/async-listener/glue.js:188:31
Emitted 'error' event on ServerResponse instance at:
    at errorOrDestroy (internal/streams/destroy.js:128:12)
    at ServerResponse.onerror (_stream_readable.js:745:9)
    at ServerResponse.emit (events.js:327:22)
    at ServerResponse.EventEmitter.emit (domain.js:485:12)
    at writeAfterEndNT (_http_outgoing.js:701:7)
    at /home/decades/awss-server/node_modules/async-listener/glue.js:188:31
    at processTicksAndRejections (internal/process/task_queues.js:85:21) {
  code: 'ERR_STREAM_WRITE_AFTER_END'
}

Reproducible. With each attempt to access something.

neilyoung commented 4 years ago

OK, found it. I had to place the call to

dash.monitor({ server: server }) // Does not work yet

after all

app.thisandthat setups

neilyoung commented 4 years ago

Just one thing: There is a file resourceRegistry.log written by your plugin. Can this be omitted?

mattcolegate commented 4 years ago

Unfortunately at the moment it can't - it's generated automatically by one of our dependencies' dependencies. There is an open issue for it at https://github.com/IBM/node-ibmapm-restclient/issues/5

neilyoung commented 4 years ago

Ok. Understand. What about authentication? Haven't found yet.

mattcolegate commented 4 years ago

Currently appmetrics-dash doesn't have built-in security such as authentication-based access. We do support the passing through of code to run when the endpoint is hit via <appmetrics-dash>.attach(options.middleware) or <application-dash>.monitor(options.middleware) so it should be possible to put a third-party security solution in place.

neilyoung commented 4 years ago

@mattcolegate May I ask you, what the mqtt broker thing does? Is it required to monitor the things, via the appmetrics-dash route?

Then: Is there a way to add own probes, like counters etc?

mattcolegate commented 4 years ago

MQTT http://mqtt.org/ is a transport mechanism that can be used by appmetrics to communicate with an MQTT broker, such as https://mosquitto.org/. It is not required to monitor things via the appmetrics-dash route. You can certainly add your own probes - there is no official guide, but there are some pull requests that you can look at to get an idea of what to do.

neilyoung commented 4 years ago

OK, thanks. I don't need that. Can MQTT be disabled at all?

mattcolegate commented 4 years ago

Change com.ibm.diagnostics.healthcenter.mqtt=on to off in .../node_modules/appmetrics/appmetrics.properties

neilyoung commented 4 years ago

Cool. Thanks.