CLOVER🍀

That was when it all began.

GrafanaのDocker OpenTelemetry LGTMを試す

これは、なにをしたくて書いたもの?

OpenTelemetryに関する勉強をしたい時に、ちょっとネックになるのはミドルウェアが多いことです。

Grafana LGTMスタックが有名かと思いますが、これを揃えるのはまあまあ手間です…。

ちょっとどうしようかなと考えていたのですが、そういえばDocker OpenTelemetry LGTMを試したことがなかったので
1度やっておこうかなということで。

Grafana LGTMスタック

Grafana LGTMスタックとは、以下のスタックのことです。

  • Grafana Loki
  • Grafana
  • Grafana Tempo
  • Grafana Mimir

ちなみにGrafana Lokiはまだ扱ったことがありません。

またGrafana Mimirはバージョン3になってから構成要素にApache Kafkaが出てきたので、また複雑になったようでして…。

他の選択肢

Grafana LGTMスタックをどこまで深堀するかにはちょっと悩んでいますが、他の選択肢はこのあたりでしょうか。

このあたりで使ってみたいものもあるのですが、今回は特に触れません。

Docker OpenTelemetry LGTM

それはそれとして、Grafana LGTMスタックを簡単に試せればよいのですが、その用途でDocker OpenTelemetry LGTMが
あります。

Docker OpenTelemetry LGTMについてのドキュメントはこちら。

Docker OpenTelemetry LGTM | OpenTelemetry documentation

Docker OpenTelemetry LGTMは、OpenTelemetry Collector、Grafana、Grafana Loki、Grafana Mimir、Grafana Tempo、
Grafana Pyroscope、そしてPrometheusを組み合わせたOpenTelemetryバックエンドです。用途としては開発、デモ向けですね。

The Grafana docker-otel-lgtm project provides an open source backend for OpenTelemetry in a Docker image. This project is the easiest way to set up an OpenTelemetry backend with an OpenTelemetry Collector, Grafana, Loki, Mimir, and Tempo for self-managed development, demo, and testing environments. For production observability solutions, refer to the insights documentation.

GitHubリポジトリーはこちら。

GitHub - grafana/docker-otel-lgtm: OpenTelemetry backend in a Docker image

Docker Hubはこちら。

grafana/otel-lgtm

Docker OpenTelemetry LGTMに関するブログエントリーはこちらです。

An OpenTelemetry backend in a Docker image: Introducing grafana/otel-lgtm | Grafana Labs

Observability in under 5 seconds: Reflecting on a year of grafana/otel-lgtm | Grafana Labs

ひとまず使ってみましょう。

環境

今回の環境はこちら。

$ docker version
Client: Docker Engine - Community
 Version:           29.2.1
 API version:       1.53
 Go version:        go1.25.6
 Git commit:        a5c7197
 Built:             Mon Feb  2 17:17:26 2026
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          29.2.1
  API version:      1.53 (minimum version 1.44)
  Go version:       go1.25.6
  Git commit:       6bc6209
  Built:            Mon Feb  2 17:17:26 2026
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v2.2.1
  GitCommit:        dea7da592f5d1d2b7755e3a161be07f43fad8f75
 runc:
  Version:          1.3.4
  GitCommit:        v1.3.4-0-gd6d73eb8
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Docker OpenTelemetry LGTMを動かしてみる

まずはDockerイメージをpullしてみます。現時点でのバージョンは0.17.1です。

$ docker image pull grafana/otel-lgtm:0.17.1

2.5Gあるようです。

$ docker image ls
                                                                                                                                                    i Info →   U  In Use
IMAGE                      ID             DISK USAGE   CONTENT SIZE   EXTRA
grafana/otel-lgtm:0.17.1   557ddac3121c       2.56GB          588MB

使い方を見ると、どうもGitHubリポジトリーをクローンしてから使う想定のようです。サンプルなども含まれているから
でしょうか。

まずは単体で使ってみましょう。

docker-otel-lgtm / Run the Docker image

シェルスクリプトをダウンロード。

$ curl -LO https://raw.githubusercontent.com/grafana/docker-otel-lgtm/refs/tags/v0.17.1/run-lgtm.sh
$ chmod +x run-lgtm.sh

引数にバージョンを取るようです。未指定だとlatestですね。

RELEASE=${1:-latest}

というわけで、実行。

$ ./run-lgtm.sh 0.17.1

起動時のログ。

0.17.1: Pulling from grafana/otel-lgtm
Digest: sha256:557ddac3121c7b470b59dfb4f69a4d24d9f6a3c9d63b330152498a3650f720bf
Status: Image is up to date for grafana/otel-lgtm:0.17.1
docker.io/grafana/otel-lgtm:0.17.1
Running Grafana v12.3.2 logging=false
Running OpenTelemetry Collector v0.144.0 logging=false
Running Loki v3.6.4 logging=false
Running Prometheus v3.9.1 logging=false
Running Tempo v2.10.0 logging=false
Waiting for the OpenTelemetry collector and the Grafana LGTM stack to start up...
Running Pyroscope v1.18.0 logging=false
Prometheus is up and running. Startup time: 1 seconds
Otelcol is up and running. Startup time: 1 seconds
Tempo is up and running. Startup time: 1 seconds
Pyroscope is up and running. Startup time: 2 seconds
Loki is up and running. Startup time: 2 seconds
Grafana is up and running. Startup time: 12 seconds
Total startup time: 12 seconds

Startup Time Summary:
---------------------
Grafana: 12 seconds
Loki: 2 seconds
Prometheus: 1 seconds
Tempo: 1 seconds
Pyroscope: 2 seconds
OpenTelemetry collector: 1 seconds
Total: 12 seconds
The OpenTelemetry collector and the Grafana LGTM stack are up and running. (created /tmp/ready)
Open ports:
 - 4317: OpenTelemetry GRPC endpoint
 - 4318: OpenTelemetry HTTP endpoint
 - 3000: Grafana (http://localhost:3000). User: admin, password: admin
 - 4040: Pyroscope endpoint
 - 9090: Prometheus endpoint

ブログなどによると、この行が出力されていると起動済みらしいです。

The OpenTelemetry collector and the Grafana LGTM stack are up and running. (created /tmp/ready)

状態を確認。

$ docker container ps
CONTAINER ID   IMAGE                      COMMAND                   CREATED              STATUS              PORTS                                                                                                                                                                                                    NAMES
c0368ea6a08b   grafana/otel-lgtm:0.17.1   "/otel-lgtm/run-all.…"   About a minute ago   Up About a minute   0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp, 0.0.0.0:4040->4040/tcp, [::]:4040->4040/tcp, 0.0.0.0:4317-4318->4317-4318/tcp, [::]:4317-4318->4317-4318/tcp, 0.0.0.0:9090->9090/tcp, [::]:9090->9090/tcp   lgtm

lgtmというコンテナ名で起動するようですね。

またOSはRed Hat Enterprise Linuxのようです。

$ docker container exec -it lgtm cat /etc/os-release
NAME="Red Hat Enterprise Linux"
VERSION="9.7 (Plow)"
ID="rhel"
ID_LIKE="fedora"
VERSION_ID="9.7"
PLATFORM_ID="platform:el9"
PRETTY_NAME="Red Hat Enterprise Linux 9.7 (Plow)"
ANSI_COLOR="0;31"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:redhat:enterprise_linux:9::baseos"
HOME_URL="https://www.redhat.com/"
DOCUMENTATION_URL="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9"
BUG_REPORT_URL="https://issues.redhat.com/"

REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 9"
REDHAT_BUGZILLA_PRODUCT_VERSION=9.7
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="9.7"

ミドルウェアのバージョンはここを見るとよさそうです。

# renovate: datasource=github-releases depName=grafana packageName=grafana/grafana
ARG GRAFANA_VERSION=v12.3.2
# renovate: datasource=github-releases depName=prometheus packageName=prometheus/prometheus
ARG PROMETHEUS_VERSION=v3.9.1
# renovate: datasource=github-releases depName=tempo packageName=grafana/tempo
ARG TEMPO_VERSION=v2.10.0
# renovate: datasource=github-releases depName=loki packageName=grafana/loki
ARG LOKI_VERSION=v3.6.4
# renovate: datasource=github-releases depName=pyroscope packageName=grafana/pyroscope
ARG PYROSCOPE_VERSION=v1.18.0
# renovate: datasource=github-releases depName=opentelemetry-collector packageName=open-telemetry/opentelemetry-collector-releases
ARG OPENTELEMETRY_COLLECTOR_VERSION=v0.144.0

https://github.com/grafana/docker-otel-lgtm/blob/v0.17.1/docker/Dockerfile#L1-L12

確認。

## Grafana
$ docker container exec -it lgtm /otel-lgtm/grafana/bin/grafana --version
grafana version 12.3.2


## Grafana Loki
$ docker container exec -it lgtm /otel-lgtm/loki/loki --version
loki, version 3.6.4 (branch: release-3.6.x, revision: d8052669)
  build user:       root@742cd10d2e09
  build date:       2026-01-21T08:06:38Z
  go version:       go1.25.4
  platform:         linux/amd64
  tags:             netgo


## Grafana Tempo
$ docker container exec -it lgtm /otel-lgtm/tempo/tempo --version
tempo, version 2.10.0 (branch: HEAD, revision: 5773eb8b0)
  build user:
  build date:
  go version:       go1.25.5
  platform:         linux/amd64
  tags:             unknown


## Grafana Pyroscope
$ docker container exec -it lgtm /otel-lgtm/pyroscope/pyroscope --version
2026/02/08 11:51:07 maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined
pyroscope, version 1.18.0 (branch: HEAD, revision: e542ef3a6)
  build user:
  build date:       2026-01-16T16:34:17Z
  go version:       go1.24.12
  platform:         linux/amd64
  tags:             netgo,embedassets


## Prometheus
$ docker container exec -it lgtm /otel-lgtm/prometheus/prometheus --version
prometheus, version 3.9.1 (branch: HEAD, revision: 9ec59baffb547e24f1468a53eb82901e58feabd8)
  build user:       root@61c3a9212c9e
  build date:       20260107-16:08:09
  go version:       go1.25.5
  platform:         linux/amd64
  tags:             netgo,builtinassets


## OpenTelemetry Collector Contrib
$ docker container exec -it lgtm /otel-lgtm/otelcol-contrib/otelcol-contrib --version
otelcol-contrib version 0.144.0

よくよく見ると、Grafana Mimirは入っていないんですね。

http://localhost:3000にアクセスすると、Grafanaが参照できます。ログインは求められませんでしたね。

データソースはこれだけ登録されています。

シェルスクリプトで、コンテナ起動時のオプションを見てみます。

$RUNTIME container run \
    --name lgtm \
    -p 3000:3000 \
    -p 4040:4040 \
    -p 4317:4317 \
    -p 4318:4318 \
    -p 9090:9090 \
    --rm \
    -ti \
    -v "${LOCAL_VOLUME}"/grafana:/data/grafana:"${MOUNT_OPTS}" \
    -v "${LOCAL_VOLUME}"/prometheus:/data/prometheus:"${MOUNT_OPTS}" \
    -v "${LOCAL_VOLUME}"/loki:/data/loki:"${MOUNT_OPTS}" \
    -e GF_PATHS_DATA=/data/grafana \
    --env-file .env \
    "$IMAGE"

どうやらバインドマウントでデータを永続化しているみたいです。

LOCAL_VOLUMEというのはこちら。

LOCAL_VOLUME=${PWD}/container

カレントディレクトリー配下には、containerディレクトリーがありました。

$ ll container
合計 20
drwxrwxr-x 5 xxxxx xxxxx 4096  28 20:33 ./
drwxr-x--- 7 xxxxx xxxxx 4096  28 20:33 ../
drwxrwxr-x 4 xxxxx xxxxx 4096  28 20:34 grafana/
drwxrwxr-x 8 xxxxx xxxxx 4096  28 20:33 loki/
drwxrwxr-x 5 xxxxx xxxxx 4096  28 20:34 prometheus/

永続化を考えずに、かつシェルスクリプトなしで実行する場合はこうでしょうか。

$ docker container run -it --rm --name lgtm -p 3000:3000 -p 4040:4040 -p 4317:4317 -p 4318:4318 -p 9090:9090 -e GF_PATHS_DATA=/data/grafana grafana/otel-lgtm:0.17.1

サンプルアプリケーションを動かしてみる

最後はサンプルアプリケーションを動かしてみましょう。

これはGitHubリポジトリーに含まれているので、cloneします。

$ git clone https://github.com/grafana/docker-otel-lgtm
$ cd docker-otel-lgtm
$ git checkout v0.17.1

run-example.shを動かすように書かれていますが、中身はJavaのサンプルを動かすようですね。

#!/bin/bash

set -euo pipefail

cd examples/java
./run.sh
#!/bin/bash

set -euo pipefail

cd examples/java
./run.sh

サンプルの種類はこれだけあるようです。

$ ll examples
合計 32
drwxrwxr-x 8 xxxxx xxxxx 4096  28 20:57 ./
drwxrwxr-x 9 xxxxx xxxxx 4096  28 20:57 ../
drwxrwxr-x 3 xxxxx xxxxx 4096  28 20:57 dotnet/
drwxrwxr-x 2 xxxxx xxxxx 4096  28 20:57 ebpf-profiler/
drwxrwxr-x 2 xxxxx xxxxx 4096  28 20:57 go/
drwxrwxr-x 8 xxxxx xxxxx 4096  28 20:57 java/
drwxrwxr-x 2 xxxxx xxxxx 4096  28 20:57 nodejs/
drwxrwxr-x 2 xxxxx xxxxx 4096  28 20:57 python/

examples/java/run.shを見てみます。

#!/bin/bash

set -euox pipefail

if [[ ! -f ./target/rolldice.jar ]]; then
        ./mvnw clean package
fi

# renovate: datasource=github-releases depName=opentelemetry-java-instrumentation packageName=open-telemetry/opentelemetry-java-instrumentation
opentelemetry_javaagent_version=2.24.0
jar=opentelemetry-javaagent-${opentelemetry_javaagent_version}.jar
if [[ ! -f ./${jar} ]]; then
        curl -vL https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v${opentelemetry_javaagent_version}/opentelemetry-javaagent.jar -o ${jar} # editorconfig-checker-disable-line

fi
export OTEL_RESOURCE_ATTRIBUTES="service.name=rolldice,service.instance.id=127.0.0.1:8080"
# uncomment the next line to switch to Prometheus native histograms.
# export OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=base2_exponential_bucket_histogram
java -Dotel.metric.export.interval=500 -Dotel.bsp.schedule.delay=500 -javaagent:${jar} -jar ./target/rolldice.jar

では実行。

$ ./run-example.sh

Javaのインストールが必要なようです。

+ [[ ! -f ./target/rolldice.jar ]]
+ ./mvnw clean package
The JAVA_HOME environment variable is not defined correctly,
this environment variable is needed to run this program.

Dockerfileを見るとJava 25があればよさそうなので、追加。

$ sudo apt install openjdk-25-jdk

気を取り直して実行。

$ ./run-example.sh

OpenJDK 25のインストールだけでOKでした。

最終的にSpring Bootアプリケーションが起動。

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v4.0.2)

ドキュメントによるとhttp://localhost:8080/rolldiceにアクセスすればよさそうです。

$ curl localhost:8080/rolldice
6


$ curl localhost:8080/rolldice
{"timestamp":"2026-02-08T12:03:30.267Z","status":500,"error":"Internal Server Error","path":"/rolldice"}

どうも、整数か500エラーを返すアプリケーションになっているようです。

  /** Simulates rolling a dice. */
  @GetMapping("/rolldice")
  public String index(@RequestParam("player") Optional<String> player) throws InterruptedException {
    veryLongCalculation();
    if (random.nextInt(10) < 3) {
      throw new RuntimeException("simulating an error");
    }
    int result = this.getRandomNumber(1, 6);
    if (player.isPresent()) {
      logger.info("{} is rolling the dice: {}", player.get(), result);
    } else {
      logger.info("Anonymous player is rolling the dice: {}", result);
    }
    return Integer.toString(result);
  }

https://github.com/grafana/docker-otel-lgtm/blob/v0.17.1/examples/java/src/main/java/com/grafana/example/RollController.java

GrafanaでDrilldownを見てみます。

メトリクス。

ログ。

トレース。

プロファイル。

トレースからログまでのドリルダウン。

こんなところでしょうか。

おわりに

GrafanaのDocker OpenTelemetry LGTMを試してみました。

Grafana LGTMスタックはひとつひとつ見ていくととてもとても深いので、こうやって簡単に立ち上げられると便利ですね。

その分、中身はよくわからないまま使うことになりますが…。

とはいえ、これでGrafana LGTMに慣れていくのはありですね。