【マイクロサービス全体の完全な可視性を実現】Cloudflareと[baselime]の統合を動作検証

はじめに
これによってCloudflareはオブザーバビリティ関連の市場に進出したと発表をしており、Cloudflareの機能としてオブザーバビリティ関連が増えてくることと思います。
まだbaselimeを触ったことがなかったのでこの機会に検証してみます。
Cloudflare BLOG: https://www.cloudflare.com/ja-jp/press-releases/2024/cloudflare-enters-observability-market-with-acquisition-baselime/
.
Cloudflare Developer Week 2024まとめ: https://blog.cloudflare.com/developer-week-2024-wrap-up-ja-jp
※現状、Cloudflare Workersとbaselimeとの統合はbeta版機能となっております。
[baselime]とは?
オブザーバビリティとは?
オブザーバビリティの主要な要素として下記があげられます。
・log
・metrics
・trace
・alert
これらの要素を統合して、システムの動作をリアルタイムで監視し、異常を迅速に検出・対応できるようにすることです。
[baselime]の動作検証
network構成イメージ図

baselimeのアカウント作成 & API Key作成
動作検証するためにまずはbaselimeアカウントを作成する必要があります。
https://console.baselime.io/login
Cloudflareアカウントに接続するためには下記のドキュメントを参考にして下さい。
https://baselime.io/docs/sending-data/platforms/cloudflare/logpush/
baselime用のAPI Keyを発行するためにbaselimeにログインします。

API Keys項目に移動して「Add API Key」をクリックします。

任意の名前を入力して「Create API Key」をクリックします。

無事に作成されると下記のようにAPI Keyが作成されます。

参考ドキュメント
Cloudflare公式ドキュメント:https://developers.cloudflare.com/workers/observability/baselime-integration/
baselime公式ドキュメント:https://baselime.io/docs/sending-data/platforms/cloudflare/traces/
上記のドキュメントを参考に作成していきます。
そのまま作っても出来るのですが、今回はせっかくですのでhonoを使って試していきます。
オリジンWEBサーバ用意
検証で使用するWEBサーバを用意しておきます。
/api/v1/01.phpにGETしたら、1秒sleepしてjsonを返す簡単なプログラムを用意します。
例:
<?php
sleep(1);
$response = array(
"message" => "01"
);
$jsonResponse = json_encode($response);
header('Content-Type: application/json');
echo $jsonResponse;
?>
workers設定
まずhonoを使ってworkersを下記コマンドで作成します。
$ npm create hono@latest test-workers-baselime-hono
>create-hono version 0.8.1
>Using target directory … test-workers-baselime-hono
>? Which template do you want to use? cloudflare-workers
> Cloning the template
>? Do you want to install project dependencies? no
>Copied project files
>Get started with: cd test-workers-baselime-hono
npm installを実行して必要なファイルをインストールします。
$ cd test-workers-baselime-hono
$ npm install
cloudflareにログインを行います。
$ wrangler login
$ wrangler whoami
wrangler.tomlを編集します。
※FQDNとDOMAINはそれぞれのCloudflareの環境に合わせてください。
name = "test-workers-baselime-hono"
compatibility_date = "2023-12-01"
compatibility_flags = [ "nodejs_compat" ]
main = "src/index.ts"
workers_dev = false
route = { pattern = "[FQDN]/baselime-hono/*", zone_name = "[DOMAIN]" }
この状態で一度deployしておきます。
$ npx wrangler deploy
この段階ではまだ何も表示されませんが、特に問題ありません。
Cloudflareログイン -> Workers & Pagesにてworkersが作成されたことを確認します。

workersをbaselimeと統合します。
事前にbaselimeにログインしておいて下さい。
Cloudflareログイン -> Workers & Pages -> test-workers-baselime-hono -> インテグレーション -> Baselimeに移動します。
baselimeのインテグレーションの追加をクリックします。

同意しますをクリックします。

同意しますをクリックすると下記のように接続を許可するか聞かれますので、「Authorize Access」をクリックします。

接続に成功すると下記画面のようになります。

Baselime environmentは環境に合わせて選択してください。
その他の項目は今回はひとまずデフォルトのままで終了をクリックします。

baselimeに情報を転送するためのworkersが作成されたことを確認します。

次にhono側にてbaselimeの接続に必要なpackageをインストールします。
$ npm i @microlabs/otel-cf-workers
src/index.tsを編集します。
※[ORIGIN IP or FQDN]にはオリジンWEBサーバのIP、もしくはFQDNをそれぞれの環境に合わせてください。
import { Hono } from 'hono'
import { instrument, ResolveConfigFn } from '@microlabs/otel-cf-workers'
const app = new Hono()
app.get('/baselime-hono/', async (c) => {
const response = await fetch("https://[ORIGIN IP or FQDN]/api/v1/01.php", {
method: "GET",
headers: { 'Content-Type': 'application/json' }
});
const data = await response.json();
return c.json({ message: data });
})
const config: ResolveConfigFn = (env, _trigger) => {
return {
exporter: {
url: 'https://otel.baselime.io/v1',
headers: { 'x-api-key': env.BASELIME_API_KEY },
},
service: { name: env.SERVICE_NAME },
}
}
const fetchHandler: ExportedHandler = { fetch: app.fetch }
export default instrument(fetchHandler, config)WorkersにSecretを登録します。
「Enter a secret value」には事前に作成したbaselimeのAPI Keyを入力します。
$ npx wrangler secret put BASELIME_API_KEY
>wrangler 3.60.0
>-------------------
>Enter a secret value: … ****************************************
>Creating the secret for the Worker "test-workers-baselime-hono"
>Success! Uploaded secret BASELIME_API_KEY
CloudflareのWorkersの画面からsecretが登録されたことを確認します。

wrangler.tomlに下記を追加します。
tail_consumersにはbaselimeと統合した際に作成されたworkersを指定します。
SERVICE_NAMEにはhonoで作成したworkersの名前と同じものを指定します。
logpush = true
tail_consumers = [{service = "test-workers-baselime-hono-tail"}]
[vars]
SERVICE_NAME = "test-workers-baselime-hono"
ここまで出来たら、workersをデプロイします
npx wrangler deploy
curlやブラウザから下記URLにアクセスしてみます。
$ curl https://[cloudflareのFQDN]/baselime-hono/;
>{"message":"01"}
baselimeにログインしてserviceから「test-workers-baselime-hono」を検索します。

requestの項目でrequestが取れてることが確認できました。

また、traceの項目でworkersの処理時間の情報も確認できました。

トレースをクリックしてみますと、下記のようにグラフィカルに表示もできます。

ただこれだと全体処理の時間しかわからないので、せっかくなのでspanを切って関数ごとの処理時間を取得するように変更してみましょう。
src/index.tsを編集します。
処理が少なすぎてレイテンシーの値が0になってしまうのでわざとsleepを入れて時間稼ぎをしてます。
※[ORIGIN IP or FQDN]にはオリジンWEBサーバのIP、もしくはFQDNをそれぞれの環境に合わせてください。
import { Hono } from 'hono'
import { instrument, ResolveConfigFn } from '@microlabs/otel-cf-workers'
import { trace, Span } from '@opentelemetry/api';
const app = new Hono()
const tracer = trace.getTracer('sugiki-custom-traces');
function handleError(span: Span): void {
span.setAttribute('error', true);
span.end();
}
async function fetchFromWebServer(): Promise<any> {
const span = tracer.startSpan('fetchFromGoogle');
try {
const response = await fetch("https://[ORIGIN IP or FQDN]/api/v1/01.php", {
method: "GET",
headers: {
'Content-Type': 'application/json'
}
});
const data = await response.json();
span.end();
return data;
} catch (error: any) {
handleError(span);
throw error;
}
}
async function createResponse(data: any): Promise<Response> {
const span = tracer.startSpan('createResponse');
try {
const jsonResponse = {
message: data
};
span.end();
return new Response(JSON.stringify(jsonResponse), {
headers: {
'Content-Type': 'application/json'
}
});
} catch (error: any) {
handleError(span);
throw error;
}
}
app.get('/baselime-hono/', async () => {
const rootSpan = tracer.startSpan('handler.fetch');
try {
const data = await fetchFromWebServer();
const jsonResponse = await createResponse(data);
rootSpan.end();
return jsonResponse;
} catch (error) {
handleError(rootSpan);
throw error;
}
});
const config: ResolveConfigFn = (env, _trigger) => {
return {
exporter: {
url: 'https://otel.baselime.io/v1',
headers: { 'x-api-key': env.BASELIME_API_KEY },
},
service: { name: env.SERVICE_NAME }, }
}
const fetchHandler: ExportedHandler = { fetch: app.fetch }
export default instrument(fetchHandler, config)
workersをデプロイします。
npx wrangler deploy
curlやブラウザから下記URLにアクセスしてみます。
$ curl https://[cloudflareのFQDN]/baselime-hono/;
>{"message":"01"}
baselimeからtraceを確認してみるとspanごとに項目が表示されてることが確認できました。

spanごとのレイテンシーを取得できてることが確認できました。
(fetchFromWebServer関数のレイテンシー情報)

(createResponse関数のレイテンシー情報)

オリジンWEBサーバのURLを存在しないものにすればエラーになるので、試してみましょう。
コードの下記箇所を書き換えます。
01.phpを01.phpaaaaaにしてみます。
const response = await fetch("https://[ORIGIN IP or FQDN]/api/v1/01.php", {`↓
const response = await fetch("https://[ORIGIN IP or FQDN]/api/v1/01.phpaaaaa", {`workersをデプロイします。
npx wrangler deploy
curlやブラウザから下記URLにアクセスしてみます。(もちろんエラーが返ります。)
$ curl https://[cloudflareのFQDN]/baselime-hono/;
>Internal Server Error
baselimeからtraceを確認してみるとエラー情報が取得できてることが確認できました。


エラーのログ情報もbaselimeで確認できますので、原因の調査が捗りそうです。
※ログが長すぎて下記画像は途中で切ってます。

最後に
baselimeではalert機能や、カスタムダッシュボード作成などできることはもっとあるのですが、長くなりすぎてしまうのでここまでとさせて頂きました。
オブザーバビリティ関連はこれからももっと盛り上がっていくと思いますので、こういう機能がcloudflareで使えるようになったのは素直に嬉しいです。
個人的にはCloudflareの管理画面にbaselimeの画面が統合されると管理画面が一つで済むのでとても楽になるので期待しています。
そしてCloudflareなら上記以外でも、
・パフォーマンスの向上
・サイトの信頼性の向上
・セキュリティの向上
が、一つのサービスで実現できますので非常におすすめです。
Cloudflareに、アクセリアの運用サポートをプラスしたCDNサービスを提供しています
移行支援によるスムーズな導入とともに、お客様の運用負担を最小限にとどめながら、WEBサイトのパフォーマンスとセキュリティを最大限に高めます。運用サポートはフルアウトソーシングからミニマムサポートまで、ご要望に合わせてご提供します。
Cloudflare(クラウドフレア)の導入や運用について、またそれ以外のことでもなにか気になることがございましたらお気軽にご相談下さい。
サービスにご興味をお持ちの方は
お気軽にお問い合わせください。
Webからお問い合わせ
お問い合わせお電話からお問い合わせ
平日09:30 〜 18:00
Free Service
![【マイクロサービス全体の完全な可視性を実現】Cloudflareと[baselime]の統合を動作検証 - アクセリア株式会社](/wp/wp-content/themes/accelia/assets/image/logo.png)










