iT邦幫忙

2023 iThome 鐵人賽

DAY 27
1

cover

在現代的軟體開發中,系統的複雜度越來越高,單靠傳統的單一監控工具已經無法有效地了解系統的狀態。為了對付日益茁壯的複雜系統,最近 Observability 這個話題又再度回到社群的視野中。

是一種幫助我們了解系統狀態的概念,它提供了一種方法來收集、分析和可視化系統的數據。

什麼是 Observability

Observability 是指系統的狀態能夠被收集到的資訊並且主動觀察到。在軟體系統中,Observability 可以通過收集和分析系統的 Log 來滿足。這些 Log 包括:

  • 系統的事件 Log
  • 系統的 Trace 數據
  • 系統的效能 metrics

通過主動收集和分析視覺化這些資訊,我們可以理解複雜系統的行為,並在發生問題時,可以快速定位和解決問題。

為什麼要導入 Observability ? 很重要嗎?

Observability 是對於團隊健康發展與成長,有著很重要的關鍵角色。它可以幫助我們:

  • 透過偵測故障的基礎設施來確認系統錯誤狀態
  • 從收集到的錯誤訊息去知道問題的 root cause
  • 收集相關的產品服務指標,去衡量你的目標達成率 (像是 OKR)
  • 協助調查客戶服務回報的問題,並有個很清晰的問題情境跟分析結果

在現代的軟體開發中,盡早的發現問題並改善,直接的影響就是可以省下大量的成本,從下圖中可以看到在不同階段的修復成本,會隨著功能被推進,而讓成本以指數級上升。

Image From deepsource

GCP logging & trace

Google Cloud Platform (GCP) 提供了強大的 logging 和 trace 工具,讓你可以輕鬆地收集、分析和儲存系統的 Log 和 Trace 資訊。

Before

在這邊我會嘗試使用 opentelemetry 這個框架去嘗試收集 API 內的資訊,opentelemetry 是一個開源的 Observability 框架,提供了一個統一的 API 與流程,來用於收集各種 data source 的資訊。

我們需要先安裝 opentelemetry 的 PHP SDK:

composer require opentelemetry/opentelemetry-sdk-php

然後在 docker-compose.yaml 加入下面的服務,這樣才可以在本地驗證資料傳送的流程。

version: '3.7'
services:
    zipkin:
        image: openzipkin/zipkin-slim
        ports:
            - "9411:9411"
    jaeger:
        image: jaegertracing/all-in-one
        environment:
            COLLECTOR_ZIPKIN_HOST_PORT: 9412

        ports:
            - "9412:9412"
            - "16686:16686"

application 初始化的位置加入下面的 TracerProvider

$zipkinExporter = new ZipkinExporter(
    PsrTransportFactory::discover()->create('http://zipkin:9411/api/v2/spans', 'application/json')
);

$tracerProvider =  new TracerProvider(
    new SimpleSpanProcessor($zipkinExporter)
);

在 laravel 中可以把 $tracerProvider 使用 ServiceProvider 註冊

$tracer = $tracerProvider->getTracer('io.opentelemetry.contrib.php');

$rootSpan = $tracer
    ->spanBuilder('root')
    ->startSpan();
$scope = $rootSpan->activate();

for ($i = 0; $i < 3; $i++) {
    // start a span, register some events
    $span = $tracer->spanBuilder('loop-' . $i)->startSpan();

    $span->setAttribute('remote_ip', '1.1.2.2')
        ->setAttribute('country', 'USA');

    $span->addEvent('found_login' . $i, [
        'id' => $i,
        'username' => 'user-No-' . $i,
    ]);
    $span->addEvent('generated_session', [
        'id' => md5((string) microtime(true)),
    ]);

    $span->end();
}
$scope->detach();
$rootSpan->end();

然後在本地的 jaeger :http://localhost:16686/ 就可以看到剛才加入的 trace 了

Span 的資訊

opentelemetry 的用法介紹

在需要收集一個流程的情境下,可以使用 Trace 來幫我們收集到各種相關的資訊,例如,我們可以使用以下 code 來收集一個 HTTP request 的流程中的資訊:

// 建立一個 Span
$span = $tracerProvider->startSpan('http.request');

// 記錄 HTTP request 的開始時間
$span->addEvent('start');

// 發出 HTTP request
$response = Http::get('https://example.com');

// 記錄 HTTP request 的結束時間
$span->addEvent('end');

// 結束 Span
$span->end();

所以你可以看到,實際上設定會因為你的 exporter 去完成 tracer provider 的初始化,所以在下一篇的地方,會講到另一個很方便的工具 OpenTelemetry Collector,讓實際上的 production 的維運作業更方變更簡化。

References


上一篇
#25 讓 Notification 時時刻刻聯繫你的使用者 (2/2)
下一篇
#27 讓你像福爾摩斯般替系統把脈:GCP trace 與 opentelemetry 整合 (2/2)
系列文
Laravel 擴展宇宙:從 1 到 100 十倍速打造產品獨角獸30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言