diff --git a/website_docs/_index.md b/website_docs/_index.md index b76096d41d..859f8026cc 100644 --- a/website_docs/_index.md +++ b/website_docs/_index.md @@ -12,16 +12,16 @@ export data. ## Status and Releases -| | Tracing | Metrics | -| ----- | ------- | ------- | -| API | GA | Alpha | -| SDK | Beta | Alpha | +| Signal | API Status | SDK Status | +|---------|-------------|-------------------| +| Trace | Stable | Release Candidate | +| Metrics | Development | Development | +| Logs | Roadmap | Roadmap | You can find release information [here](https://github.com/open-telemetry/opentelemetry-js/releases) ## Further Reading - [OpenTelemetry for JavaScript on GitHub](https://github.com/open-telemetry/opentelemetry-js) -- [Getting Started](https://github.com/open-telemetry/opentelemetry-js/blob/main/getting-started/README.md) -- [API Documentation](https://open-telemetry.github.io/opentelemetry-js) -- [Getting In Touch (Gitter)](https://gitter.im/open-telemetry/opentelemetry-sdk-trace-node) +- [API Reference](https://open-telemetry.github.io/opentelemetry-js-api) +- [SDK Reference](https://open-telemetry.github.io/opentelemetry-js) diff --git a/website_docs/exporters.md b/website_docs/exporters.md index c1ce99369a..562b914e47 100644 --- a/website_docs/exporters.md +++ b/website_docs/exporters.md @@ -3,11 +3,15 @@ title: "Exporters" weight: 3 --- -In order to visualize and analyze your traces, you will need to export them to a tracing backend such as Jaeger or Zipkin. -OpenTelemetry JS provides exporters for some common open source tracing backends. +In order to visualize and analyze your traces and metrics, you will need to export them to a backend such as [Jaeger](https://www.jaegertracing.io/) or [Zipkin](https://zipkin.io/). OpenTelemetry JS provides exporters for some common open source backends. Below you will find some introductions on how to setup backends and the matching exporters. +- [Jaeger](#jaeger) +- [Zipkin](#zipkin) +- [Prometheus](#prometheus) +- [OpenTelemetry Collector](#opentelemetry-collector) + ## Jaeger To set up Jaeger as quickly as possible, run it in a docker container: @@ -64,6 +68,43 @@ const { BatchSpanProcessor } = require("@opentelemetry/tracing"); provider.addSpanProcessor(new BatchSpanProcessor(new ZipkinExporter())) ``` +## Prometheus + +To set up Prometheus as quickly as possible, run it in a docker container. +You will need a `prometheus.yml` to configure the backend, use the following example +and modify it to your needs: + +```yml +global: + scrape_interval: 15s + evaluation_interval: 15s + +scrape_configs: + - job_name: "prometheus" + static_configs: + - targets: ["localhost:9090"] +``` + +With this file you can now start the docker container: + +```shell +docker run \ + -p 9090:9090 \ + -v ${PWD}/prometheus.yml:/etc/prometheus/prometheus.yml \ + prom/prometheus +``` + +Update your opentelemetry configuration to use the exporter and to send data to your prometheus backend: + +```javascript +const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus'); +const { MeterProvider } = require('@opentelemetry/metrics'); +const meter = new MeterProvider({ + exporter: new PrometheusExporter({port: 9090}), + interval: 1000, +}).getMeter('prometheus'); +``` + ## OpenTelemetry Collector If you are looking for a vendor-agnostic way to receive, process and export your diff --git a/website_docs/getting_started/nodejs.md b/website_docs/getting_started/nodejs.md index e2555b9a1e..9f681e3eaa 100644 --- a/website_docs/getting_started/nodejs.md +++ b/website_docs/getting_started/nodejs.md @@ -15,6 +15,12 @@ This guide will show you how to get started with tracing in Node.js. - [Instrumentation Modules](#instrumentation-modules) - [Setup](#setup) - [Run Application](#run-application) +- [Metrics](#metrics) + - [Dependencies](#dependencies-2) + - [Core Dependencies](#core-dependencies-1) + - [Exporter](#exporter-1) + - [Setup](#setup-1) + - [Run Application](#run-application-1) ## Example Application @@ -220,3 +226,119 @@ Now, when you open in your web browser, you should see t ``` + +## Metrics + +### Dependencies + +The following dependencies are required to collect metrics in your Node.js application. + +#### Core Dependencies + +These dependencies are required to configure the tracing SDK and create spans. + +- `@opentelemetry/metrics` + +#### Exporter + +In the following example, we will use the `ConsoleMetricExporter` which prints all spans to the console. + +In order to visualize and analyze your metrics, you will need to export them to a metrics backend. +Follow [these instructions](../exporters.md) for setting up a backend and exporter. + +### Setup + +You need a `Meter` to create and monitor metrics. A `Meter` in OpenTelemetry is the mechanism used to create and manage metrics, labels, and metric exporters. + +Create a file named `monitoring.js` and add the following code: + +```javascript +/* monitoring.js */ +'use strict'; + +const { MeterProvider, ConsoleMetricExporter } = require('@opentelemetry/metrics'); + +const meter = new MeterProvider({ + new ConsoleMetricExporter(), + interval: 1000, +}).getMeter('your-meter-name'); +``` + +Now you can require this file from your application code and use the `Meter` to create and manage metrics. The simplest of these metrics is a counter. + +Let's create and export from your `monitoring.js` file a middleware function that express can use to count all requests by route. Modify the `monitoring.js` file so it looks like this: + +```javascript +/* monitoring.js */ +'use strict'; + +const { MeterProvider, ConsoleMetricExporter } = require('@opentelemetry/metrics'); + +const meter = new MeterProvider({ + new ConsoleMetricExporter(), + interval: 1000, +}).getMeter('your-meter-name'); + +const requestCount = meter.createCounter("requests", { + description: "Count all incoming requests" +}); + +const boundInstruments = new Map(); + +module.exports.countAllRequests = () => { + return (req, res, next) => { + if (!boundInstruments.has(req.path)) { + const labels = { route: req.path }; + const boundCounter = requestCount.bind(labels); + boundInstruments.set(req.path, boundCounter); + } + + boundInstruments.get(req.path).add(1); + next(); + }; +}; +``` + +Now import and use this middleware in your application code `app.js`: + +```javascript +/* app.js */ +const express = require("express"); +const { countAllRequests } = require("./monitoring"); +const app = express(); +app.use(countAllRequests()); +/* ... */ +``` + +Now when you make requests to your service, your meter will count all requests. + +**Note**: Creating a new labelSet and binding on every request is not ideal because creating the labelSet can often be an expensive operation. Therefore, the instruments are created and stored in a Map according to the route key. + +### Run Application + +First, install the dependencies as described above. Here you need to add the following: + +```shell +npm install --save @opentelemetry/metrics +``` + +Now you can run your application: + +```shell +$ node app.js +Listening for requests on http://localhost:8080 +``` + +Now, when you open in your web browser, you should see the metrics printed in the console by the `ConsoleMetricExporter`. + +```json +{ + "name": "requests", + "description": "Count all incoming requests", + "unit": "1", + "metricKind": 0, + "valueType": 1 +} +{ "route": "/" } +"value": "1" +``` diff --git a/website_docs/instrumentation.md b/website_docs/instrumentation.md index 9ac4e7cacd..2de62ce6c5 100644 --- a/website_docs/instrumentation.md +++ b/website_docs/instrumentation.md @@ -5,6 +5,14 @@ weight: 3 This guide will cover creating and annotating spans, creating and annotating metrics, how to pass context, and a guide to automatic instrumentation for JavaScript. This simple example works in the browser as well as with Node.JS +- [Example Application](#example-application) +- [Creating Spans](#creating-spans) +- [Attributes](#attributes) + - [Semantic Attributes](#semantic-attributes) +- [Span Status](#span-status) + +## Example Application + In the following this guide will use the following sample app: ```javascript @@ -161,3 +169,30 @@ function doWork(parent) { span.end(); } ``` + +## Span Status + +A status can be set on a span, to indicate if the traced operation has completed successfully (`Ok`) or with an `Error`. The default status is `Unset`. + +The status can be set at any time before the span is finished: + +```javascript +function doWork(parent) { + const span = tracer.startSpan('doWork', { + parent, + }); + span.setStatus({ + code: opentelemetry.SpanStatusCode.OK, + message: 'Ok.' + }) + for (let i = 0; i <= Math.floor(Math.random() * 40000000); i += 1) { + if(i > 10000) { + span.setStatus({ + code: opentelemetry.SpanStatusCode.ERROR, + message: 'Error.' + }) + } + } + span.end(); +} +```