Explorar el Código

docs(telemetry-plugin): Add API docs & how-to guide (#3526)

Michael Bromley hace 8 meses
padre
commit
eefa578846

+ 4 - 19
docker-compose.yml

@@ -126,28 +126,11 @@ services:
             - GF_AUTH_ANONYMOUS_ENABLED=true
             - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
             - GF_FEATURE_TOGGLES_ENABLE=alertingSimplifiedRouting,alertingQueryAndExpressionsStepMode
-        entrypoint:
-            - sh
-            - -euc
-            - |
-                mkdir -p /etc/grafana/provisioning/datasources
-                cat <<EOF > /etc/grafana/provisioning/datasources/ds.yaml
-                apiVersion: 1
-                datasources:
-                - name: Loki
-                type: loki
-                access: proxy 
-                orgId: 1
-                url: http://loki:3100
-                basicAuth: false
-                isDefault: true
-                version: 1
-                editable: false
-                EOF
-                /run.sh
         image: grafana/grafana:latest
         ports:
             - '3200:3000'
+        volumes:
+          - grafana-storage:/var/lib/grafana
         networks:
             - loki
 
@@ -170,3 +153,5 @@ volumes:
         driver: local
     jaeger_data:
         driver: local
+    grafana-storage:
+        driver: local

BIN
docs/docs/guides/how-to/telemetry/grafana-logs.webp


BIN
docs/docs/guides/how-to/telemetry/grafana-trace.webp


+ 254 - 0
docs/docs/guides/how-to/telemetry/index.md

@@ -0,0 +1,254 @@
+---
+title: "Open Telemetry"
+---
+
+[Open Telemetry](https://opentelemetry.io/) is a set of APIs, libraries, agents, and instrumentation to provide observability for applications. 
+It provides a standard way to collect and export telemetry data such as traces, metrics, and logs from applications.
+
+From Vendure v3.3, Vendure has built-in support for Open Telemetry, via the `@vendure/telemetry-plugin` package. 
+This package provides a set of decorators and utilities to instrument Vendure services and entities with Open Telemetry.
+
+In this guide we will set up a local Vendure server with Open Telemetry, collecting traces and logs
+using the following parts:
+
+- [Open Telemetry](https://opentelemetry.io/): The standard for observability.
+- [Vendure Telemetry Plugin](/reference/core-plugins/telemetry-plugin/): Instruments the Vendure server & worker for Open Telemetry.
+- [Jaeger](https://www.jaegertracing.io/): A distributed tracing system that can be used to collect and visualize traces.
+- [Loki](https://grafana.com/oss/loki/): A log aggregation system that can be used to collect and visualize logs.
+- [Grafana](https://grafana.com/oss/grafana/): A visualization tool that can be used to visualize traces and logs from Jaeger and Loki.
+
+:::info
+There are many other tools and services that can be used with Open Telemetry, such as Prometheus, Zipkin, Sentry, Dynatrace and others.
+
+In this guide we have chosen some widely-used and open-source tools to demonstrate the capabilities of Open Telemetry.
+:::
+
+## Setup
+
+### Set up Jaeger, Loki & Grafana
+
+We will be using Docker to run Jaeger, Loki, and Grafana locally. Create a file called `docker-compose.yml` 
+in the root of your project (standard Vendure installations already have one) and add the following contents:
+
+```yaml
+services:
+    jaeger:
+        image: jaegertracing/all-in-one:latest
+        ports:
+            - '4318:4318' # OTLP HTTP receiver
+            - '16686:16686' # Web UI
+        environment:
+            - COLLECTOR_OTLP_ENABLED=true
+        volumes:
+            - jaeger_data:/badger
+        networks:
+            - jaeger
+
+    loki:
+        image: grafana/loki:3.4
+        ports:
+            - '3100:3100'
+        networks:
+            - loki
+
+    grafana:
+        environment:
+            - GF_PATHS_PROVISIONING=/etc/grafana/provisioning
+            - GF_AUTH_ANONYMOUS_ENABLED=true
+            - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
+            - GF_FEATURE_TOGGLES_ENABLE=alertingSimplifiedRouting,alertingQueryAndExpressionsStepMode
+        image: grafana/grafana:latest
+        ports:
+            - '3200:3000'
+        networks:
+            - loki
+            - jaeger
+        volumes:
+            - grafana-storage:/var/lib/grafana
+
+    networks:
+        loki:
+            driver: bridge
+        jaeger:
+            driver: bridge
+
+    volumes:
+        jaeger_data:
+            driver: local
+        grafana-storage:
+            driver: local
+```
+
+You can start the services using the following command:
+
+```bash
+docker-compose up -d jaeger loki grafana
+```
+
+Once the images have downloaded and the containers are running, you can access:
+
+- Jaeger at [http://localhost:16686](http://localhost:16686)
+- Grafana at [http://localhost:3200](http://localhost:3200)
+
+### Install the Telemetry Plugin
+
+```bash
+npm install @vendure/telemetry-plugin
+```
+
+Add the plugin to your Vendure config:
+
+```ts
+import { VendureConfig, LogLevel } from '@vendure/core';
+import { TelemetryPlugin } from '@vendure/telemetry-plugin';
+
+export const config: VendureConfig = {
+    // ... other config options
+    plugins: [
+        TelemetryPlugin.init({
+            loggerOptions: {
+                // Optional: log to the console as well as
+                // sending to the telemetry server. Can be
+                // useful for debugging.
+                logToConsole: LogLevel.Verbose,
+            },
+        }),
+    ],
+};
+```
+
+### Set environment variables
+
+In order to send telemetry data to the Jaeger and Loki services, you need to set some environment variables.
+In a standard Vendure installation, there is an `.env` file in the root of the project. We will add the following:
+
+```env
+# Open Telemetry
+OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:3100/otlp
+OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces
+OTEL_LOGS_EXPORTER=otlp
+```
+
+### Create a preload script
+
+The Open Telemetry libraries for Node.js instrument underlying libraries such as NestJS, GraphQL,
+Redis, database drivers, etc. to collect telemetry data. In order to do this, they need to be
+preloaded before any of the Vendure application code. This is done by means of a preload script.
+
+Create a file called `preload.ts` in the src dir of your project with the following contents:
+
+```ts title="src/preload.ts"
+import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-proto';
+import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
+import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
+import { NodeSDK } from '@opentelemetry/sdk-node';
+import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
+import { getSdkConfiguration } from '@vendure/telemetry-plugin/preload';
+import 'dotenv/config';
+
+const traceExporter = new OTLPTraceExporter();
+const logExporter = new OTLPLogExporter();
+
+const config = getSdkConfiguration({
+    config: {
+        spanProcessors: [new BatchSpanProcessor(traceExporter)],
+        logRecordProcessors: [new BatchLogRecordProcessor(logExporter)],
+    },
+});
+
+const sdk = new NodeSDK(config);
+
+sdk.start();
+```
+
+:::info
+There are many, many configuration options available for Open Telemetry. The above is an example that works
+with the services used in this guide. The important things is to make sure the use the
+`getSdkConfiguration` function from the `@vendure/telemetry-plugin/preload` package, as this will ensure that
+the Vendure core is instrumented correctly.
+:::
+
+To run the preload script, you need to set the `--require` flag when starting the Vendure server. We will 
+also set an environment variable to distinguish the server from the worker process.
+
+You can do this by adding the following script to your `package.json`:
+
+```json
+{
+    "scripts": {
+        // highlight-start
+        "dev:server": "OTEL_RESOURCE_ATTRIBUTES=service.name=vendure-server ts-node --require ./src/preload.ts ./src/index.ts",
+        "dev:worker": "OTEL_RESOURCE_ATTRIBUTES=service.name=vendure-worker ts-node --require ./src/preload.ts ./src/index-worker.ts",
+        // highlight-end
+        "dev": "concurrently npm:dev:*",
+        "build": "tsc",
+        // highlight-start
+        "start:server": "OTEL_RESOURCE_ATTRIBUTES=service.name=vendure-server node --require ./dist/preload.js ./dist/index.js",
+        "start:worker": "OTEL_RESOURCE_ATTRIBUTES=service.name=vendure-worker node --require ./dist/preload.js ./dist/index-worker.js",
+        // highlight-end
+        "start": "concurrently npm:start:*"
+    },
+}
+```
+
+## Viewing Logs
+
+Once you have started up your server with the preload script, Loki should start receiving logs.
+
+Let's take a look at the logs in Grafana.
+
+Open the Grafana dashboard at [http://localhost:3200](http://localhost:3200) and
+select **Connections** > **Data Sources** from the left-hand menu. Then click the "Add data source" button.
+
+Find "Loki" and select it. In the config form that opens, set the URL to `http://loki:3100` and click "Save & Test".
+
+Now you can select **Drilldown** > **Logs** from the left-hand menu. In the "Data source" dropdown, select "Loki".
+
+![Grafana logs](./grafana-logs.webp)
+
+## Viewing Traces
+
+You can view traces in Jaeger by going to [http://localhost:16686](http://localhost:16686).
+
+Select the "vendure-dev-server" service from the dropdown and click "Find Traces".
+
+Clicking a trace will show you the details of the trace.
+
+![Jaeger traces](./jaeger-trace.webp)
+
+You can also view traces in Grafana by connecting it to Jaeger.
+
+To do this, go to the Grafana dashboard at [http://localhost:3200](http://localhost:3200) and
+select **Connections** > **Data Sources** from the left-hand menu. Then click the "Add data source" button.
+
+Find "Jaeger" and select it. In the config form that opens, set the URL to `http://jaeger:16686` and click "Save & Test".
+
+Now you can select **Explore** from the left-hand menu, select "Jaeger" from the dropdown and then click the 
+"search" tab and select the "vendure-dev-server" service from the dropdown.
+
+Clicking the blue "Run Query" button will show you the traces for that service.
+
+![Grafana traces](./grafana-trace.webp)
+
+## Instrumenting Your Plugins
+
+You can also instrument your own plugins and services with Open Telemetry. To do so,
+add the [Instrument decorator](/reference/typescript-api/telemetry/instrument) to your service class:
+
+```ts
+import { Injectable } from '@nestjs/common';
+// highlight-next-line
+import { Instrument } from '@vendure/core';
+
+// highlight-next-line
+@Instrument()
+@Injectable()
+export class MyService {
+
+    async myMethod() {
+        // ...
+    }
+}
+```
+
+You should now be able to see calls to `MyService.myMethod` in your traces.

BIN
docs/docs/guides/how-to/telemetry/jaeger-trace.webp


+ 6 - 1
docs/docs/reference/core-plugins/telemetry-plugin/index.md

@@ -11,7 +11,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## TelemetryPlugin
 
-<GenerationInfo sourceFile="packages/telemetry-plugin/src/telemetry.plugin.ts" sourceLine="102" packageName="@vendure/telemetry-plugin" since="3.3.0" />
+<GenerationInfo sourceFile="packages/telemetry-plugin/src/telemetry.plugin.ts" sourceLine="107" packageName="@vendure/telemetry-plugin" since="3.3.0" />
 
 The TelemetryPlugin is used to instrument the Vendure application and collect telemetry data using
 [OpenTelemetry](https://opentelemetry.io/).
@@ -22,6 +22,11 @@ The TelemetryPlugin is used to instrument the Vendure application and collect te
 npm install @vendure/telemetry-plugin
 ```
 
+:::info
+For a complete guide to setting up and working with Open Telemetry, see
+the [Implementing Open Telemetry guide](/guides/how-to/telemetry/).
+:::
+
 ## Configuration
 
 The plugin is configured via the `TelemetryPlugin.init()` method. This method accepts an options object

+ 106 - 0
docs/docs/reference/core-plugins/telemetry-plugin/otel-logger.md

@@ -0,0 +1,106 @@
+---
+title: "OtelLogger"
+isDefaultIndex: false
+generated: true
+---
+<!-- This file was generated from the Vendure source. Do not modify. Instead, re-run the "docs:build" script -->
+import MemberInfo from '@site/src/components/MemberInfo';
+import GenerationInfo from '@site/src/components/GenerationInfo';
+import MemberDescription from '@site/src/components/MemberDescription';
+
+
+## OtelLogger
+
+<GenerationInfo sourceFile="packages/telemetry-plugin/src/config/otel-logger.ts" sourceLine="46" packageName="@vendure/telemetry-plugin" since="3.3.0" />
+
+A logger that emits logs to OpenTelemetry and optionally to the console.
+
+```ts title="Signature"
+class OtelLogger implements VendureLogger {
+    constructor(options: OtelLoggerOptions)
+    debug(message: string, context?: string) => void;
+    warn(message: string, context?: string) => void;
+    info(message: string, context?: string) => void;
+    error(message: string, context?: string) => void;
+    verbose(message: string, context?: string) => void;
+}
+```
+* Implements: <code><a href='/reference/typescript-api/logger/vendure-logger#vendurelogger'>VendureLogger</a></code>
+
+
+
+<div className="members-wrapper">
+
+### constructor
+
+<MemberInfo kind="method" type={`(options: <a href='/reference/core-plugins/telemetry-plugin/otel-logger#otelloggeroptions'>OtelLoggerOptions</a>) => OtelLogger`}   />
+
+
+### debug
+
+<MemberInfo kind="method" type={`(message: string, context?: string) => void`}   />
+
+
+### warn
+
+<MemberInfo kind="method" type={`(message: string, context?: string) => void`}   />
+
+
+### info
+
+<MemberInfo kind="method" type={`(message: string, context?: string) => void`}   />
+
+
+### error
+
+<MemberInfo kind="method" type={`(message: string, context?: string) => void`}   />
+
+
+### verbose
+
+<MemberInfo kind="method" type={`(message: string, context?: string) => void`}   />
+
+
+
+
+</div>
+
+
+## OtelLoggerOptions
+
+<GenerationInfo sourceFile="packages/telemetry-plugin/src/config/otel-logger.ts" sourceLine="14" packageName="@vendure/telemetry-plugin" since="3.3.0" />
+
+Options for the OtelLogger.
+
+```ts title="Signature"
+interface OtelLoggerOptions {
+    logToConsole?: LogLevel;
+}
+```
+
+<div className="members-wrapper">
+
+### logToConsole
+
+<MemberInfo kind="property" type={`<a href='/reference/typescript-api/logger/log-level#loglevel'>LogLevel</a>`}   />
+
+If set to a LogLevel, the logger will also log to the console.
+This can be useful for local development or debugging.
+
+*Example*
+
+```ts
+import { LogLevel } from '@vendure/core';
+import { TelemetryPlugin } from '@vendure/telemetry-plugin';
+
+// ...
+
+TelemetryPlugin.init({
+  loggerOptions: {
+    logToConsole: LogLevel.Verbose,
+  },
+});
+```
+
+
+</div>

+ 6 - 2
docs/docs/reference/core-plugins/telemetry-plugin/telemetry-plugin-options.md

@@ -26,7 +26,7 @@ interface TelemetryPluginOptions {
 
 ### loggerOptions
 
-<MemberInfo kind="property" type={`OtelLoggerOptions`}   />
+<MemberInfo kind="property" type={`<a href='/reference/core-plugins/telemetry-plugin/otel-logger#otelloggeroptions'>OtelLoggerOptions</a>`}   />
 
 The options for the OtelLogger.
 
@@ -43,7 +43,11 @@ TelemetryPlugin.init({
 ```
 ### methodHooks
 
-<MemberInfo kind="property" type={`Array&#60;MethodHookConfig&#60;any&#62;&#62;`}   />
+<MemberInfo kind="property" type={`Array&#60;MethodHookConfig&#60;any&#62;&#62;`}  experimental="true" />
+
+**Status: Developer Preview**
+
+This API may change in a future release.
 
 Method hooks allow you to add extra telemetry actions to specific methods.
 To define hooks on a method, use the <a href='/reference/core-plugins/telemetry-plugin/register-method-hooks#registermethodhooks'>registerMethodHooks</a> function.

+ 36 - 0
packages/telemetry-plugin/src/config/otel-logger.ts

@@ -3,10 +3,46 @@ import { DefaultLogger, LogLevel, VENDURE_VERSION, VendureLogger } from '@vendur
 
 export const otelLogger = logs.getLogger('@vendure/core', VENDURE_VERSION);
 
+/**
+ * @description
+ * Options for the OtelLogger.
+ *
+ * @since 3.3.0
+ * @docsCategory core plugins/TelemetryPlugin
+ * @docsPage OtelLogger
+ */
 export interface OtelLoggerOptions {
+    /**
+     * @description
+     * If set to a LogLevel, the logger will also log to the console.
+     * This can be useful for local development or debugging.
+     *
+     * @example
+     * ```ts
+     * import { LogLevel } from '@vendure/core';
+     * import { TelemetryPlugin } from '@vendure/telemetry-plugin';
+     *
+     * // ...
+     *
+     * TelemetryPlugin.init({
+     *   loggerOptions: {
+     *     logToConsole: LogLevel.Verbose,
+     *   },
+     * });
+     * ```
+     */
     logToConsole?: LogLevel;
 }
 
+/**
+ * @description
+ * A logger that emits logs to OpenTelemetry and optionally to the console.
+ *
+ * @since 3.3.0
+ * @docsCategory core plugins/TelemetryPlugin
+ * @docsPage OtelLogger
+ * @docsWeight 0
+ */
 export class OtelLogger implements VendureLogger {
     private defaultLogger?: DefaultLogger;
 

+ 6 - 1
packages/telemetry-plugin/src/telemetry.plugin.ts

@@ -19,6 +19,11 @@ import { TelemetryPluginOptions } from './types';
  * npm install \@vendure/telemetry-plugin
  * ```
  *
+ * :::info
+ * For a complete guide to setting up and working with Open Telemetry, see
+ * the [Implementing Open Telemetry guide](/guides/how-to/telemetry/).
+ * :::
+ *
  * ## Configuration
  *
  * The plugin is configured via the `TelemetryPlugin.init()` method. This method accepts an options object
@@ -113,7 +118,7 @@ import { TelemetryPluginOptions } from './types';
         config.logger = new OtelLogger(TelemetryPlugin.options.loggerOptions ?? {});
         return config;
     },
-    // compatibility: '>3.3.0',
+    compatibility: '>3.3.0',
 })
 export class TelemetryPlugin {
     static options: TelemetryPluginOptions = {};

+ 6 - 0
packages/telemetry-plugin/src/types.ts

@@ -35,6 +35,10 @@ export interface TelemetryPluginOptions {
     loggerOptions?: OtelLoggerOptions;
     /**
      * @description
+     * **Status: Developer Preview**
+     *
+     * This API may change in a future release.
+     *
      * Method hooks allow you to add extra telemetry actions to specific methods.
      * To define hooks on a method, use the {@link registerMethodHooks} function.
      *
@@ -61,6 +65,8 @@ export interface TelemetryPluginOptions {
      *   ],
      * });
      * ```
+     *
+     * @experimental
      */
     methodHooks?: Array<MethodHookConfig<any>>;
 }

+ 1 - 1
packages/telemetry-plugin/tsconfig.json

@@ -4,7 +4,7 @@
         "module": "NodeNext",
         "moduleResolution": "NodeNext",
         "declaration": true,
-        "removeComments": true,
+        "removeComments": false,
         "strictPropertyInitialization": false,
         "sourceMap": true,
         "allowJs": true