Skip to main content
Deno 2 is finally here šŸŽ‰ļø
Learn more

Test CI

deno-observability

Metrics exporting for Denoā€™s runtime, initially targetting OpenMetrics (Prometheus) and the Datadog API

Project Status

The code in this repository will be a sorta scratch-pad until a v1.0 possibly eventually happens. Iā€™m trying to reconsile the design differences between pushing & polling, and figure out one way of instrumenting metrics that will be able to transmit to different types of metric sinks.

The current version requires Deno 1.15 or later.

The Deno --unstable flag is not required, while any latency metrics will be very rough unless --allow-hrtime is passed.

Prometheus Example

Itā€™s standard to run a Prometheus exporter on its own dedicated port to keep it separate from whatever API you may be hosting. Or if you arenā€™t hosting an API at all, you may not already have any HTTP server.

Hereā€™s an example of that:

import { runMetricsServer } from "https://deno.land/x/observability@v0.1.0/sinks/openmetrics/server.ts";

runMetricsServer({ port: 9090 });
console.log("Now serving http://localhost:9090/metrics");

You can also run the demo directly, which simulates extra HTTP traffic to make the metrics more full:

deno run --allow-net https://deno.land/x/observability@v0.1.0/demo.ts

If you would like to expose metrics on your existing web server, youā€™ll want to look at mod.ts for inspiration instead of importing it as-is.

Deno Metrics

  • deno_ops_dispatched: # of operations started, split into 3 categories & faceted by op name

  • deno_ops_completed: # of operations finished, split into 3 categories & faceted by op name

  • deno_open_resources: # of currently registered Deno resources, split by resource type.

    • A process starts up with 3: stdin, stdout, stderr.
    • Starting the metrics server will add 1 tcpListener.
    • Your metrics HTTP request seemingly always shows up as an additional tcpStream.
    • All other resources are from your applicationā€™s own code (or libraries in use).
  • deno_memory_rss_bytes: # of total resident bytes held by the Deno process

  • deno_memory_heap_total_bytes: allocated size of the Deno heap space

  • deno_memory_heap_used_bytes: used size of the Deno heap space

  • deno_memory_external_bytes: Not Yet Implemented in Deno. Currently 0.

Hereā€™s an example of the payload:

# TYPE deno_ops_dispatched counter
deno_ops_dispatched_total{op_type="sync"} 179
deno_ops_dispatched_total{op_type="async"} 252
# TYPE deno_ops_completed counter
deno_ops_completed_total{op_type="sync"} 179
deno_ops_completed_total{op_type="async"} 245
# TYPE deno_open_resources gauge
deno_open_resources{res_type="stdin"} 1
deno_open_resources{res_type="stdout"} 1
deno_open_resources{res_type="stderr"} 1
deno_open_resources{res_type="tcpListener"} 1
deno_open_resources{res_type="child"} 30
deno_open_resources{res_type="tcpStream"} 2
# TYPE deno_memory_rss_bytes gauge
# UNIT deno_memory_rss_bytes bytes
deno_memory_rss_bytes 3232380
# TYPE deno_memory_heap_total_bytes gauge
# UNIT deno_memory_heap_total_bytes bytes
deno_memory_heap_total_bytes 3948544
# TYPE deno_memory_heap_used_bytes gauge
# UNIT deno_memory_heap_used_bytes bytes
deno_memory_heap_used_bytes 3690960
# TYPE deno_memory_external_bytes gauge
# UNIT deno_memory_external_bytes bytes
deno_memory_external_bytes 16384

HTTP Server Metrics

  • denohttp_handled_requests: Number of HTTP requests that have been received and responded to in full.
  • denohttp_requests_in_flight: Current number of HTTP requests being served.
  • denohttp_request_duration_seconds: A histogram of the HTTP request durations, including writing a response.
  • denohttp_response_bytes_total: Number of bytes transmitted in response to HTTP requests. Includes a facet for which aspect of the HTTP response the bytes were a part of.
# TYPE denohttp_handled_requests counter
# HELP denohttp_handled_requests Number of HTTP requests that have been received and responded to in full.
denohttp_handled_requests{code="404",method="get"} 1218
denohttp_handled_requests{code="200",method="get"} 6
# TYPE denohttp_requests_in_flight gauge
# HELP denohttp_requests_in_flight Current number of HTTP requests being served.
denohttp_requests_in_flight 1
# TYPE denohttp_request_duration_seconds histogram
# UNIT denohttp_request_duration_seconds seconds
# HELP denohttp_request_duration_seconds A histogram of the HTTP request durations, including writing a response.
denohttp_request_duration_seconds_bucket{le="0.01"} 1219
denohttp_request_duration_seconds_bucket{le="0.1"} 1224
denohttp_request_duration_seconds_bucket{le="1"} 1224
denohttp_request_duration_seconds_bucket{le="+Inf"} 1224
denohttp_request_duration_seconds_sum 0.704
denohttp_request_duration_seconds_count 1224
# TYPE denohttp_response_bytes counter
# UNIT denohttp_response_bytes bytes
# HELP denohttp_response_bytes Number of bytes transmitted in response to HTTP requests.
denohttp_response_bytes_total{purpose="body"} 25247
denohttp_response_bytes_total{purpose="framing"} 31782
denohttp_response_bytes_total{purpose="header"} 24936

TODO

  • Serve data from Deno.metrics()
  • Serve data from Deno.resources()
  • Accept custom metrics from the userā€™s code
  • Include ā€˜createdā€™ timestamp on counters to aid in monotonic tracking
  • Publish on deno.land
  • Keep track of previous metrics to include zero gauges in future bodies

License

MIT