Upgrade to Pro — share decks privately, control downloads, hide ads and more …

オブザーバビリティ入門

 オブザーバビリティ入門

Cybozu
PRO

July 13, 2023
Tweet

More Decks by Cybozu

Other Decks in Technology

Transcript

  1. 1
    2023/05/16
    運⽤本部 Necoチーム
    池添 明宏
    サイボウズ開運研修2023
    オブザーバビリティ⼊⾨

    View Slide

  2. この講義のコンセプト
    ▶ 誰に
    n サイボウズの開発・運⽤・品質保証に関わるメンバー
    ▶ 何を学んでもらうか
    n オブザーバビリティの重要性や⽤途
    n ログ・メトリクス・トレース
    n 出⼒する際の決まり事や注意点
    n 収集したデータの活⽤⽅法
    2

    View Slide

  3. オブザーバビリティとは
    3

    View Slide

  4. 4
    - オブザーバビリティ・エンジニアリングより
    オブザーバビリティとは、システムがどのよう
    な状態になったとしても、どんなに斬新で奇妙
    な状態であっても、どれだけ理解し説明できる
    かを⽰す尺度です。

    オブザーバビリティ(可観測性)とは

    View Slide

  5. オブザーバビリティの実現に必要な物
    ▶ データ(テレメトリー)の収集
    n 3つの柱:ログ、メトリクス、トレース
    n 第4の柱:プロファイル
    ▶ 収集したデータを活⽤するツール
    n 検索、分析、可視化ツール
    n アラート通知ツール
    5

    View Slide

  6. なぜオブザーバビリティが重要なのか
    ▶ クラウドネイティブ技術の導⼊やマイクロサービス化により
    システムが複雑化している
    ▶ デリバリーが⾼速化しシステムの稼働状況の監視やユーザー
    の利⽤状況の分析がより重要になっている
    ▶ ユーザー数の増加に伴いパフォーマンスや可⽤性への要件が
    ⾼まっている
    ▶ セキュリティ攻撃⼿段が多様化している
    6

    View Slide

  7. オブザーバビリティは誰のためのもの?
    ▶ 従来は運⽤チームが主体となって活⽤していた。
    ▶ 近年では開発やビジネスでの利⽤が広がっている。
    ▶ 将来的にはフロントエンドや品質保証⾯での活⽤も期待。
    7

    View Slide

  8. 8
    - ⼊⾨監視より
    監視とは役割ではなくスキルであり、チーム内の全員があ
    る程度のレベルに⾄っておくべきです。
    ソフトウェアエンジニアはアプリケーションについて誰よ
    りも詳しいので、素晴らしいアプリケーション監視の仕組
    みをデザインするには最⾼の場所にいるのです。

    監視とは役割ではなくスキルである

    View Slide

  9. 9
    ビジネス
    ü ユーザーの利⽤状況を
    分析し、ビジネス上の
    意志決定に利⽤
    ü 従量課⾦
    運⽤
    ü 障害時のアラート
    ü 問題箇所の発⾒
    ü オートスケーリング
    ü プログレッシブデリバ
    リーの実現
    開発・テスト
    ü 性能測定
    ü デバッグ
    ü ユーザーの利⽤状況に
    応じた機能の改善
    ü Flaky Testの発⾒
    ü テスト時間の分析
    オブザーバビリティの⽤途

    View Slide

  10. オブザーバビリティを⽀える3本柱
    10

    View Slide

  11. オブザーバビリティを⽀える3本柱
    ▶ ログ
    n 発⽣したイベントの詳細情報をタイムス
    タンプとともに記録
    ▶ メトリクス
    n 統計情報を時系列で記録
    ▶ トレース
    n 呼び出された処理やかかった時間を記録
    11
    logs
    metrics traces

    View Slide

  12. ログ
    12

    View Slide

  13. ログ
    ▶ ログとは
    n プログラムが何かを実⾏したり、何かが発⽣したときのイベントを記
    録するもの
    ▶ ログの種類
    n アクセスログ
    n アプリケーションログ・システムログ
    n 監査ログ
    13

    View Slide

  14. ログの集め⽅
    14
    App
    Container
    Runtime
    App
    Agent
    Agent
    ファイルに
    ログを出⼒
    ファイルに
    ログを出⼒
    標準出⼒/
    標準エラー出⼒
    ストレージ
    に保存
    ファイルからログを読む。
    必要に応じてローテーション

    View Slide

  15. ログのフォーマット
    ▶ テキスト形式でもよいが、構造化(JSONやlogfmt)しておく
    と分析しやすくなる。
    ▶ メッセージだけでなく、コンテキスト情報を含める
    n ログレベル、タイムスタンプ、サービス名、ユーザーID
    n リクエストID, トレースID, 呼び出した関数名やファイルの⾏数
    15

    View Slide

  16. 構造化ログの出⼒例
    ▶ JSON形式
    16
    {"severity":"INFO", "logged_at":"2023-05-15T04:47:09.882Z", "caller":"zap/options.go:212",
    "message":"finished unary call with code OK", "service":"sample", "utsname":"sample-57cfb5bf75-hbgjr",
    "grpc.start_time":"2023-05-15T04:47:09Z", "system":"grpc", "span.kind":"server",
    "grpc.service":"sample.v2beta2.Clusters", "grpc.method":"Join", "grpc.code":"OK", "grpc.time_ms":4.534}
    time="2023-05-15T04:50:27Z" level=info msg="Reconciliation completed" application=argocd/worker
    dedup_ms=0 dest-name= dest-namespace=worker dest-server="https://kubernetes.default.svc" diff_ms=49
    fields.level=2 git_ms=16 health_ms=4 live_ms=9 settings_ms=0 sync_ms=0 time_ms=125
    ▶ logfmt形式

    View Slide

  17. ログ出⼒のライブラリ
    ▶ ファイルや標準出⼒・標準エラー出⼒に出⼒
    ▶ 各⾔語で⽤意されているライブラリを使う
    n Java: logback
    n Go: zapなど
    ▶ ログ出⼒はパフォーマンスやファイル書き込みなどで注意す
    べき点が多いので、⾃作は避けよう。
    17

    View Slide

  18. ログのレベル
    ログレベル ⽤途
    CRITICAL 即座に終了するような致命的なエラーが発⽣した。
    ERROR データベースやファイルに書き込めないなど、リクエストの処理またはプロセス⾃体が続
    ⾏不可能になる問題が発⽣した。
    スタックトレースとか、ソフトウェアが実⾏したアクションの結果など、問題の診断情報
    を⼗分に出⼒する。
    WARN 処理を打ち切る必要がなく、今のところ正常に続⾏できるが、将来的に問題につながり得
    る事象が発⽣した。将来何か問題があったとき、真っ先に⾒返してほしいログ。
    潜在的な問題。リソースがキャパシティに近いとか。何かアクションが必要な物。
    INFO 正常な動作の軌跡。サーバが起動したとかリクエストが来たとか。
    外界に影響を与える処理は info ログを出す。繰り返し処理の開始・終了時に info ログを
    出す。
    nice-to-haveなインフォメーション。”Service started”とか”Listening on port 5050”とか。
    DEBUG 関数の出⼊りの記録や⽂字列解析の途中結果など、デバッグ⽤の情報。
    productionでは通常無効化しておき、問題が起きたときに有効化する。
    18

    View Slide

  19. いつログを出すか
    ▶ エラー発⽣時、問題が起きそうなとき、設定の読み込み時、
    繰り返しや時間のかかる処理の開始と終了時、なんらかの意
    思決定をしたとき、外部サービスの呼び出し時など。
    ▶ メトリクスやトレースやプロファイルで出⼒すべき情報を
    ログに出⼒しない。適切な技術を選択する。
    ▶ 不必要なログを出さない。⼤量のログはディスク容量を圧迫
    し、検索性能の劣化を引き起こす。
    19

    View Slide

  20. 何をログに出すか
    ▶ エラーを解決するために必要な詳細情報を出⼒する
    n ログを読んだエンジニアが何をすればいいのか分かるようにする。
    n データを識別するためのID、関数のパラメータ、処理にかかった時間、
    リトライ回数、タイムアウト時間、スタックトレースなどを含める。
    ▶ 暗号めいたログメッセージは避ける。
    n メッセージを読めば発⽣している事象が分かるようにする。
    20

    View Slide

  21. 秘密情報の扱いに注意
    ▶ パスワードやトークン、顧客情報、顧客⼊⼒データはログに
    出⼒しないこと。
    ▶ アクセス元IPアドレス、ユーザーID、ドメインIDなどは⼗分
    に注意して扱うこと。GDPRへの考慮も必要となる。
    21

    View Slide

  22. ログの分析
    ▶ Neco
    n Grafanaで閲覧。LogQLで絞り込みや加⼯が可能。
    22

    View Slide

  23. LogQLの例
    23
    {job=~"argocd/.*"}
    |= "Reconciliation completed"
    | logfmt | time_ms > 1000
    | line_format "{{.application}}: {{.time_ms}}"
    n {label="value"} でラベルによる絞り込み。=~ で正規表現指定
    n |= で grep による絞り込み
    n logfmt や json で構造化ログをパースして絞り込み
    n line_format で指定した形式でログを表⽰

    View Slide

  24. デモ
    ▶ ラベルで絞り込んでみよう
    ▶ grep的にログを検索してみよう
    ▶ JSON形式とlogfmt形式のログを
    パースして絞り込んでみよう
    24

    View Slide

  25. メトリクス
    25

    View Slide

  26. メトリクス
    ▶ メトリクスとは
    n アプリケーションやシステムの挙動に関する様々な統計情報
    n ⼀定周期で統計情報を収集し、時系列データとして記録する
    ▶ メトリクスによって分かること
    n 現在のアプリケーションの状態
    n 過去のある時点でアプリケーションがどのような状態だったか
    n ある期間内に状態がどのように変化したか
    26

    View Slide

  27. メトリクス収集の仕組み
    27
    App
    Push Gateway
    Agent
    OS
    Exporter
    App
    Service
    Agent
    Agent
    ジョブの完了時など
    にメトリクスをpush
    サーバーやOSに関する
    情報などを収集
    ストレージ
    に保存
    周期的(Necoでは30秒)にAPI
    を実⾏してメトリクスを収集

    View Slide

  28. メトリクスのフォーマット
    ▶ アプリケーションに対してHTTPで"/metrics"のAPIを実⾏す
    るとテキスト形式のメトリクスを返す
    ▶ Prometheus形式がデファクトスタンダード
    n 数多くのOSSがこのフォーマットでメトリクスを出している
    n DatadogやNew RelicなどのベンダーツールもPrometheus⽅式をサ
    ポートしている
    n 各⾔語向けのライブラリが⽤意されている
    28

    View Slide

  29. Prometheus形式のメトリクス例
    29
    # HELP http_server_api_requests_total A counter for requests to the wrapped handler.
    # TYPE http_server_api_requests_total counter
    http_server_api_requests_total{code="200",method="get"} 157
    http_server_api_requests_total{code="500",method="get"} 16
    http_server_api_requests_total{code="200",method="post"} 21
    http_server_api_requests_total{code="500",method="post"} 3
    # HELP http_server_request_duration_seconds A histogram of latencies for requests.
    # TYPE http_server_request_duration_seconds histogram
    http_server_request_duration_seconds_bucket{handler="/api/v1/todo",method="get",le="0.25"} 99
    http_server_request_duration_seconds_bucket{handler="/api/v1/todo",method="get",le="0.5"} 190
    http_server_request_duration_seconds_bucket{handler="/api/v1/todo",method="get",le="1"} 343
    http_server_request_duration_seconds_bucket{handler="/api/v1/todo",method="get",le="2.5"} 343
    http_server_request_duration_seconds_bucket{handler="/api/v1/todo",method="get",le="5"} 343
    http_server_request_duration_seconds_bucket{handler="/api/v1/todo",method="get",le="10"} 343
    http_server_request_duration_seconds_bucket{handler="/api/v1/todo",method="get",le="+Inf"} 343
    http_server_request_duration_seconds_sum{handler="/api/v1/todo",method="get"} 157.30460066099994
    http_server_request_duration_seconds_count{handler="/api/v1/todo",method="get"} 343
    ラベル 値
    メトリクス名

    View Slide

  30. メトリクスとして出⼒する情報の例
    ▶ インフラ
    n コンテナごとのCPUやメモリ、ディスクの使⽤量
    n Kubernetesのリソースに関する情報
    ▶ アプリケーション
    n リクエスト数、エラーの数、キャッシュヒット率、CPUやI/Oを利⽤
    する処理にかかる時間、リモート呼び出しの処理の回数や時間など
    n そのほか有⽤な物はなんでも出しておくのがおすすめ
    30

    View Slide

  31. メトリクス名の付け⽅
    ▶ 名前の付け⽅
    n https://prometheus.io/docs/practices/naming/
    31
    http_server_request_duration_seconds_bucket
    チーム名や製品名などメトリクスを分類するための
    プレフィックスを付ける(例: kintone_ap_, mysql_)
    必要に応じてサフィックスを付ける
    総カウント数→total
    ヒストグラム→bucketなど
    必要に応じて単位を付ける
    seconds, bytesなど
    メトリクスの内容を表す
    名前を付ける

    View Slide

  32. メトリクスに含めるラベル
    ▶ ラベルはメトリクスを分析する際の切り⼝となる。適切なラ
    ベルの決定が重要となる。
    ▶ 例
    n サーバーごとのCPU負荷を分析したい→サーバー名をラベルにする
    n APIごとの処理時間を分析したい→API名をラベルにする
    32

    View Slide

  33. ラベル設計の注意点
    ▶ ⾼いカーディナリティのラベルを避ける。
    n 分析時の性能劣化やデータ容量の肥⼤化を引き起こす可能性がある。
    ▶ メトリクスにセンシティブな情報を含めない。
    33
    http_server_requests_total{method="GET", userid="0000830"}
    HTTPのメソッドは、GET,
    POST, DELETEなど決まった
    ものしかないのでカーディナ
    リティが低い。
    ユーザーIDは⾮常に種類が多く
    カーディナリティが⾼い。
    またセンシティブなデータ。

    View Slide

  34. メトリクスの値
    ▶ メトリクスの値は単⼀の浮動⼩数点で表現する
    n 例:リクエスト数、エラー数、処理時間、データサイズ
    n 静的な情報を表現するときは値に1を指定する。
    n ステータスを表現する場合は、1/0でtrue/falseを指定する。
    34
    kintone_info{version="23.2.0"} 1
    kintone_status{status="healthy"} 1
    kintone_status{status="unhealthy"} 0

    View Slide

  35. 35
    Histogram
    観測値の集計データ
    例: HTTPリクエストサ
    イズや、リクエストの
    レイテンシー
    Gauge
    現在の値を⽰す
    例: ディスクの使⽤量、
    CPUの使⽤率
    Counter
    増加する値を⽰す
    例: APIのリクエスト数
    の累計、パケットの合
    計受信サイズ
    メトリクスのタイプ

    View Slide

  36. メトリクス設計の⽅法論
    ▶ RED(Request Rate, Request Error Rate, Request Duration)
    n リクエストにおけるエラーの割合とかかった時間。
    n サービスの利⽤ユーザーへの影響が分かりやすい指標。
    ▶ USE(Utilization, Errors, Saturation)
    n リソースの利⽤率、エラー数、飽和状態の割合。
    n データベースやメッセージキューなどに適した指標。
    ▶ The Four Golden Signals(Latency, Traffic, Errors, Saturation)
    n ユーザー向け、⾮ユーザー向けのどちらにも使える指標。
    36

    View Slide

  37. メトリクスの分析
    ▶ NecoではGrafana (VictoriaMetrics)を利⽤してメトリクスの
    分析をおこなう。
    ▶ 活⽤例
    n 特定の条件にマッチしたときにアラートを発⾏
    n メトリクスを集計してパフォーマンスの分析
    n SLI/SLOの計算に利⽤
    37

    View Slide

  38. PromQLの例
    38
    # APIのリクエストにかかった時間の99パーセンタイルをverbごとに集計
    histogram_quantile(0.99,
    sum by (verb, le) (
    rate(apiserver_request_duration_seconds_bucket{}[5m])
    )
    )
    n histogram_quantile で分位数(パーセンタイル)を計算
    n sum で合計値を計算
    n rate で秒間あたりの変化数を計算

    View Slide

  39. デモ
    ▶ ダッシュボードを⾒てみよう
    ▶ どんなメトリクスがあるのか⾒てみよう
    ▶ PromQLでメトリクスを集計してみよう
    39

    View Slide

  40. トレース
    40

    View Slide

  41. トレースとは
    ▶ 呼び出しの記録
    n いつ、どの処理が呼ばれ、どれくらいの時間がかかったかの記録
    ▶ 分散トレースとは
    n 複数のコンポーネントにまたがったトレース
    41
    Nginx Kintone
    Slash
    MySQL

    View Slide

  42. トレースとスパン
    42
    Span
    Nginx Kintone
    Slash
    MySQL
    Span /api
    Span /auth Span /items
    Span /auth
    Span SELECT
    Span SELECT Span INSERT
    time
    Trace
    スパン
    作業や操作の単位
    トレース
    複数のスパンで構成
    されるリクエストの
    開始から終了までの単位

    View Slide

  43. トレースデータの集め⽅
    43
    App
    Collector
    App
    App
    ストレージ
    に保存
    APIを実⾏してスパン
    情報を書き込み
    トレースIDが同⼀の複数のスパン
    を1つのトレースとして扱う

    View Slide

  44. トレースデータのフォーマット
    ▶ OpenTelemetry Protocol(OTLP)
    n https://opentelemetry.io/docs/specs/otel/protocol/otlp/
    ▶ 通信にはHTTPまたはgRPCを利⽤。
    ▶ 各⾔語向けのOpenTelemetryクライアントライブラリが⽤意
    されている。
    n https://opentelemetry.io/docs/instrumentation/
    44

    View Slide

  45. スパンデータの例
    45
    {
    "resource_spans": [
    {
    "resource": {
    "attributes": [
    {
    "key": "service.name",
    "value": {
    "stringValue": "my.service"
    }
    }
    ]
    },
    "scope_spans": [
    {
    "spans": [
    {
    "traceId": "5B8EFFF798038103D269B633813FC60C",
    "spanId": "EEE19B7EC3C1B174",
    "parentSpanId": "EEE19B7EC3C1B173",
    "name": "I'm a server span",
    "startTimeUnixNano": 1544712660000000000,
    "endTimeUnixNano": 1544712661000000000,
    "kind": 2,
    "attributes": [
    {
    "key": "my.span.attr",
    "value": {
    "stringValue": "some value"
    }
    サービス名などコンポーネント
    に固有の情報
    トレースやスパンを識別するた
    めのID、開始時間と終了時間、
    その他スパンに関する様々な情
    報を含める

    View Slide

  46. Attributesに何を含めるべきか
    ▶ ResourceのAttributes
    n サービス名やnamespace, バージョン情報など
    n Conventions
    n https://opentelemetry.io/docs/specs/otel/resource/semantic_conventions/
    ▶ SpanのAttributes
    n HTTPのステータスコード、メソッド、URL、クライアントIPなど
    n Conventions
    n https://opentelemetry.io/docs/specs/otel/trace/semantic_conventions/
    46

    View Slide

  47. コンテキストの伝搬
    ▶ 分散トレーシングを可能にするためには、コンポーネント間
    でコンテキスト(トレースIDなど)を伝搬する必要がある。
    ▶ HTTP通信の場合はHTTPヘッダーに、gRPC通信の場合はメ
    タデータに、コンテキストを埋め込む。
    47
    context
    context
    Nginx Kintone
    Slash
    MySQL

    View Slide

  48. コンテキストに含める情報
    ▶ コンテキストはチームをまたがってやりとりするため、仕様
    を定めておくことが⼤事。
    ▶ W3C Trace Context
    n https://www.w3.org/TR/trace-context/
    48
    # {version}-{trace_id}-{span_id}-{trace_flags}
    traceparent: 00-80e1afed08e019fc1110464cfa66635c-7a085853722dc6d2-01

    View Slide

  49. サンプリング
    ▶ すべてのトレース情報を記
    録すると量が膨⼤になる。
    ▶ ⾼レイテンシーやエラーが
    発⽣したものと、正常なト
    レースからランダムにサン
    プリングしたものだけを記
    録する。
    49
    https://opentelemetry.io/docs/concepts/sampling/

    View Slide

  50. トレースデータの分析
    ▶ ボトルネックの検出
    ▶ エラーの発⽣箇所の発⾒
    ▶ コンポーネント間の依存関係の理解
    ▶ ログやメトリクスにトレースIDを埋
    め込むことで、データを連係させる
    こともできる。
    50

    View Slide

  51. デモ
    ▶ トレースデータを⾒てみよう
    ▶ トレースIDを埋め込んだログから
    トレースデータにジャンプしてみよ

    51

    View Slide

  52. まとめ
    52

    View Slide

  53. まとめ
    ▶ オブザーバビリティは、運⽤だけでなく開発やビジネスなど
    広い分野で重要度が⾼まっている。
    ▶ ログ、メトリクス、トレースはオブザーバビリティを向上さ
    せるための重要な要素である。必要なデータを適切に出⼒し
    よう。
    ▶ 収集したデータを活⽤するためのツールを使いこなそう。
    53

    View Slide