diff --git a/.editorconfig b/.editorconfig index e0dc6b54..7b9556a1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,6 +4,9 @@ root = true max_line_length = 100 indent_size = 2 +[*.md] +max_line_length = 120 + [renovate.json5] max_line_length = 300 diff --git a/.markdownlint.yaml b/.markdownlint.yaml index 2a09bb60..289ae7e8 100644 --- a/.markdownlint.yaml +++ b/.markdownlint.yaml @@ -8,4 +8,4 @@ MD013: line_length: 120 MD024: - allow_different_nesting: true + siblings_only: true diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..de056073 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +**/*.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7d6ff95a..7ff1a2ff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing -It's recommended to use the [mise](https://mise.jdx.dev/) for development. +It's recommended to use the [mise][mise] for development. ## Building locally @@ -20,7 +20,7 @@ It's recommended to use the [mise](https://mise.jdx.dev/) for development. Acceptance test cases are defined in `oats.yaml` files in the examples directory. The test cases are run by [oats]. -If a test case fails (lets say `examples/nodejs`), follows these steps: +If a test case fails (let's say `examples/nodejs`), follow these steps: 1. Build a new image: `mise run build-lgtm dev1` 2. `oats -timeout 2h -lgtm-version dev1 examples/nodejs` (automatically installed by `mise`) @@ -28,12 +28,12 @@ If a test case fails (lets say `examples/nodejs`), follows these steps: You can run all everything together using `mise run test`. -[oats]: https://github.com/grafana/oats - ## Architecture diagram -The source code for the architecture diagram is a -[google slide](https://docs.google.com/presentation/d/1txMBBitezscvtJIXRHNSXnCekjMRM29GmHufUSI0NRw/edit?slide=id.g26040f0db78_0_0#slide=id.g26040f0db78_0_0). +> [!NOTE] +> The architecture diagram is only accessible to Grafana employees. + +The source code for the architecture diagram is a [Google slide][architecture]. Take a screenshot of the slide and save it as `img/overview.png`. ## OTel Collector @@ -44,3 +44,10 @@ Take a screenshot of the slide and save it as `img/overview.png`. ./otelcol-contrib --config docker/otelcol-config.yaml --config docker/otelcol-export-http.yaml \ print-initial-config --feature-gates otelcol.printInitialConfig > merged.yaml ``` + + + + +[architecture]: https://docs.google.com/presentation/d/1txMBBitezscvtJIXRHNSXnCekjMRM29GmHufUSI0NRw/edit?slide=id.g26040f0db78_0_0#slide=id.g26040f0db78_0_0 +[mise]: https://github.com/jdx/mise +[oats]: https://github.com/grafana/oats diff --git a/README.md b/README.md index f89fe441..84feb84f 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,18 @@ An OpenTelemetry backend in a Docker image. + ![Components included in the Docker image: OpenTelemetry collector, Prometheus, Tempo, Loki, Grafana, Pyroscope](img/overview.png) The `grafana/otel-lgtm` Docker image is an open source backend for OpenTelemetry -that’s intended for development, demo, and testing environments. +that's intended for development, demo, and testing environments. If you are looking for a production-ready, out-of-the box solution to monitor applications and minimize MTTR (mean time to resolution) with OpenTelemetry and Prometheus, -you should try [Grafana Cloud Application Observability](https://grafana.com/products/cloud/application-observability/). +you should try [Grafana Cloud Application Observability][app-o11y]. ## Documentation -- Blog post: [An OpenTelemetry backend in a Docker image: Introducing grafana/otel-lgtm](https://grafana.com/blog/2024/03/13/an-opentelemetry-backend-in-a-docker-image-introducing-grafana/otel-lgtm/) +- Blog post: [_An OpenTelemetry backend in a Docker image: Introducing grafana/otel-lgtm_][otel-lgtm] ## Get the Docker image @@ -20,14 +21,23 @@ The Docker image is available on Docker hub: +If the [`OTEL_EXPORTER_OTLP_ENDPOINT`][otlp-endpoint] variable is set, the OpenTelemetry Collector will send data (logs, metrics, and traces) to the specified endpoint using "OTLP/HTTP". -In addition, you can provide -[OTEL_EXPORTER_OTLP_HEADERS](https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/#otel_exporter_otlp_headers), +In addition, you can provide [`OTEL_EXPORTER_OTLP_HEADERS`][otlp-headers], for example, to authenticate with the backend. #### Send data to Grafana Cloud -You can find the values for the environment variables in your -[Grafana Cloud account](https://grafana.com/docs/grafana-cloud/send-data/otlp/send-data-otlp/#manual-opentelemetry-setup-for-advanced-users). +You can find the values for the environment variables in your [Grafana Cloud account][otel-setup]. ### Persist data across container instantiation -The various components in the repository are configured to write their data to the /data +The various components in the repository are configured to write their data to the `/data` directory. If you need to persist data across containers being created and destroyed, -you can mount a volume to the /data directory. Note that this image is intended for +you can mount a volume to the `/data` directory. Note that this image is intended for development, demo, and testing environments and persisting data to an external volume doesn't change that. However, this feature could be useful in certain cases for some users even in testing situations. -## Run lgtm in kubernetes +## Run lgtm in Kubernetes ```sh -# create k8s resources +# Create k8s resources kubectl apply -f k8s/lgtm.yaml -# port forwarding +# Configure port forwarding kubectl port-forward service/lgtm 3000:3000 4317:4317 4318:4318 # Using mise @@ -92,17 +100,17 @@ mise k8s-port-forward ## Send OpenTelemetry Data -There's no need to configure anything: The Docker image works with OpenTelemetry's defaults. +There's no need to configure anything: the Docker image works with OpenTelemetry's defaults. ```sh -# Not needed as these are the defaults in OpenTelemetry: +# Not needed, but these are the defaults in OpenTelemetry export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 ``` ## View Grafana -Log in to [http://localhost:3000](http://localhost:3000) with user _admin_ and password _admin_. +Navigate to and log in with the default built-in user `admin` and password `admin`. ## Build the Docker image from scratch @@ -116,41 +124,57 @@ mise build-lgtm ## Build and run the example app -> **_NOTE:_** You can run everything together using -> [mise](https://mise.jdx.dev/) with `mise run all` +> [!TIP] +> You can run everything together using [mise][mise] with `mise run all`. + +### Run Run the example REST service: +#### Unix/Linux + ```sh -# Unix/Linux ./run-example.sh +``` + +#### Windows (PowerShell) -# Windows (PowerShell) +```powershell ./run-example +``` + +#### Unix/Linux Using mise -# Using mise (Unix/Linux) +```sh mise run example ``` -Generate traffic: +### Generate traffic + +#### Unix/Linux ```sh -# Unix/Linux ./generate-traffic.sh +``` + +#### Windows (PowerShell) -# Windows (PowerShell) +```powershell ./generate-traffic +``` + +#### Unix/Linux Using mise -# Using mise (Unix/Linux) +```sh mise run generate-traffic ``` -> **_NOTE:_** You can use [OTel Checker](https://github.com/grafana/otel-checker/) -> to check if the instrumentation is correct. +> [!TIP] +> You can use [OTel Checker][otel-checker] to check if the instrumentation is correct. ## Run example apps in different languages -The example apps are in the `examples/` directory. +The example apps are in the [`examples/`][examples] directory. Each example has a `run.sh` or `run.cmd` script to start the app. Every example implements a rolldice service, which returns a random number between 1 and 6. @@ -163,8 +187,22 @@ Each example uses a different application port | Java | `curl http://localhost:8080/rolldice` | | Go | `curl http://localhost:8081/rolldice` | | Python | `curl http://localhost:8082/rolldice` | -| dotnet | `curl http://localhost:8083/rolldice` | +| .NET | `curl http://localhost:8083/rolldice` | +| Node.js | `curl http://localhost:8084/rolldice` | ## Related Work -- Metrics, Logs, Traces and Profiles in Grafana: +- [Metrics, Logs, Traces and Profiles in Grafana][mltp] + + + + +[app-o11y]: https://grafana.com/products/cloud/application-observability/ +[examples]: https://github.com/grafana/docker-otel-lgtm/tree/main/examples +[mise]: https://github.com/jdx/mise +[mltp]: https://github.com/grafana/intro-to-mltp +[otel-checker]: https://github.com/grafana/otel-checker/ +[otel-lgtm]: https://grafana.com/blog/2024/03/13/an-opentelemetry-backend-in-a-docker-image-introducing-grafana/otel-lgtm/ +[otel-setup]: https://grafana.com/docs/grafana-cloud/send-data/otlp/send-data-otlp/#manual-opentelemetry-setup-for-advanced-users +[otlp-endpoint]: https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/#otel_exporter_otlp_endpoint +[otlp-headers]: https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/#otel_exporter_otlp_headers diff --git a/generate-traffic.cmd b/generate-traffic.cmd index 1b7adc81..e76d3673 100644 --- a/generate-traffic.cmd +++ b/generate-traffic.cmd @@ -5,5 +5,6 @@ curl -s http://localhost:8081/rolldice curl -s http://localhost:8082/rolldice curl -s http://localhost:8083/rolldice + curl -s http://localhost:8084/rolldice timeout /t 2 goto loop