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

Re:ゼロから始める Observability

neno
May 25, 2024

Re:ゼロから始める Observability

.NET ラボ 2024/05/25 での発表資料

ブログ: Re:ゼロから始める Observability

neno

May 25, 2024
Tweet

More Decks by neno

Other Decks in Technology

Transcript

  1. 自己紹介 1 • 所属: NTTコミュニケーションズ イノベーションセンター • Microsoft MVP for

    Developer Technologies (2024~) • .NET / Web Development • 趣味: C#, OSS, ドール, 一眼(α7 IV) • 執心領域 • C# ⇔ TypeScript • SignalR • Observability / OpenTelemetry 何縫ねの。 nenoNaninu nenoMake ブログ https://blog.neno.dev その他 https://neno.dev
  2. OSS 紹介 2 属性を付与するだけ Tapper • C# の型定義から TypeScript の型定義を生成する

    .NET Tool/ library • JSON / MessagePack 対応! https://github.com/nenoNaninu/Tapper
  3. OSS 紹介 3 • C# の SignalR Client を強く型付けするための Source

    Generator TypedSignalR.Client Before After (using TypedSignalR.Client) こんな SignalR の Hub と Receiver の interface が あったとして… 脱文字列! 全てが強く型付け! https://github.com/nenoNaninu/TypedSignalR.Client
  4. 4 • TypeScript の SignalR Client を強く型付けするための .NET Tool /

    library TypedSignalR.Client.TypeScript Before After (using TypedSignalR.Client.TypeScript) 脱文字列! 全てが強く型付け! TypeScript 用の型を C# から自動生成 MessagePack Hub Protocol 対応! https://github.com/nenoNaninu/TypedSignalR.Client.TypeScript 属性を付与するだけ! OSS 紹介
  5. 5 • SignalR 使ったアプリを快適に開発するための GUI を自動生成する library • 2 step

    で利用可能! • http pipeline に middleware の追加 • Hub と Receiver を定義してる interface に属性を付与 • JWT 認証 サポート • パラメータのユーザ定義型サポート • JSON で入力! SignalR 版 SwaggerUI TypedSignalR.Client.DevTools https://github.com/nenoNaninu/TypedSignalR.Client.DevTools OSS 紹介
  6. AspNetCore.SignalR.OpenTelemetry OSS 紹介 6 https://github.com/nenoNaninu/AspNetCore.SignalR.OpenTelemetry • トレースのための計装 • 最低限のログ •

    接続時 • Transport 層の情報も出力(WebSocket 等) • メソッド呼び出し時 • HubName.MethodName の素朴なログ • メソッド呼び出し毎にログのスコープを追加 • HubName, MethodName, InvocationId を 振っているのでログの検索性が向上 • Duration • 切断時 • 切断時に例外が発生していれば例外もログに出力 Inspired by HttpLogging SignalR のメソッド呼び出し毎に スパンが切られるように https://github.com/nenoNaninu/AspNetCore.SignalR.OpenTelemetry
  7. お品書き 7 • What is Observability? • OpenTelemetry 関連用語 •

    Observability を高めていく • OpenTelemetry Collector の活用
  8. タイトルの経緯 8 • ASP.NET Core と W3C Trace Context とお手軽ロギング。

    • https://blog.neno.dev/entry/2023/07/04/181843 • 明日から使える ASP.NET Core ロギング術! • https://blog.neno.dev/entry/2023/07/23/202823 • C# ではじめる OpenTelemetry。 • https://blog.neno.dev/entry/2023/12/23/194947 過去にいろいろ書いているので Re とつけても良いでしょう…!
  9. What is Observability? 12 • システムの出力から内部の状態を理解できるようにする事 Observability とは (各社共通) ログの目的

    • ソフトウェアの振る舞いをログから理解できるようにする事 • https://blog.neno.dev/entry/2023/07/04/181843
  10. What is Observability? 13 • システムの出力から内部の状態を理解できるようにする事 Observability とは (各社共通) Observability

    とはつまりログ…? ログの目的 • ソフトウェアの振る舞いをログから理解できるようにする事 • https://blog.neno.dev/entry/2023/07/04/181843
  11. What is Observability? 14 ソフトウェアの振る舞いを理解するための理想的なログ • いつ • どのコンポーネントが •

    どの論理操作の中で • どういう親子関係 • どういうコンテキスト • どういうパラメータで • なにをして • それはどの程度の重要度か • そしてどのような結果で終わり • どの程度時間がかかったか
  12. What is Observability? 15 ソフトウェアの振る舞いを理解するための理想的なログ (赤字)は Microsoft.Extensions.Logging との対応 • いつ

    (Timestamp) • どのコンポーネントが (Category) • どの論理操作の中で (TraceId) • どういう親子関係 (SpanId) • どういうコンテキスト (Scope) • どういうパラメータで (State) • なにをして (EventId / Message) • それはどの程度の重要度か (LogLevel) • そしてどのような結果で終わり • どの程度時間がかかったか
  13. What is Observability? 16 ソフトウェアの振る舞いを理解するための理想的なログ ライブラリが 面倒見てくれる (赤字)は Microsoft.Extensions.Logging との対応

    • いつ (Timestamp) • どのコンポーネントが (Category) • どの論理操作の中で (TraceId) • どういう親子関係 (SpanId) • どういうコンテキスト (Scope) • どういうパラメータで (State) • なにをして (EventId / Message) • それはどの程度の重要度か (LogLevel) • そしてどのような結果で終わり • どの程度時間がかかったか
  14. What is Observability? 17 ソフトウェアの振る舞いを理解するための理想的なログ ライブラリが 面倒見てくれる 開発者がいろいろ 考える必要あり (赤字)は

    Microsoft.Extensions.Logging との対応 • いつ (Timestamp) • どのコンポーネントが (Category) • どの論理操作の中で (TraceId) • どういう親子関係 (SpanId) • どういうコンテキスト (Scope) • どういうパラメータで (State) • なにをして (EventId / Message) • それはどの程度の重要度か (LogLevel) • そしてどのような結果で終わり • どの程度時間がかかったか
  15. What is Observability? 18 ソフトウェアの振る舞いを理解するための理想的なログ ライブラリが 面倒見てくれる 開発者がいろいろ 考える必要あり 実装次第

    (赤字)は Microsoft.Extensions.Logging との対応 • いつ (Timestamp) • どのコンポーネントが (Category) • どの論理操作の中で (TraceId) • どういう親子関係 (SpanId) • どういうコンテキスト (Scope) • どういうパラメータで (State) • なにをして (EventId / Message) • それはどの程度の重要度か (LogLevel) • そしてどのような結果で終わり • どの程度時間がかかったか
  16. What is Observability? 20 • いわゆる Observability 3本柱 • ログ

    • トレース • メトリクス おそらく半分は正しい
  17. What is Observability? 21 • いわゆる Observability 3本柱 • ログ

    • トレース • メトリクス おそらく半分は正しい ログを役割事に 細分化したに過ぎない
  18. What is Observability? 22 • いわゆる Observability 3本柱 • ログ

    • トレース • メトリクス おそらく半分は正しい ログを役割事に 細分化したに過ぎない やっぱりログじゃん
  19. What is Observability? 23 • いわゆる Observability 3本柱 • ログ

    • トレース • メトリクス おそらく半分は正しい ログを役割事に 細分化したに過ぎない やっぱりログじゃん もう半分は?
  20. What is Observability? 24 • 現代のソフトウェアは大規模かつ複雑になりました • 分散アーキテクチャ • マイクロサービス

    • Cloud Native 等々 • 結果的に発生する問題が複雑になりました • 従来のやり方では解決困難 そもそも Observability が声高に叫ばれている原因
  21. What is Observability? 25 • 現代のソフトウェアは大規模かつ複雑になりました • 分散アーキテクチャ • マイクロサービス

    • Cloud Native 等々 • 結果的に発生する問題が複雑になりました • 従来のやり方では解決困難 そもそも Observability が声高に叫ばれている原因 これを解決したい
  22. What is Observability? 28 • 予期できていない問題が発生する • 静的で単純な構成ではなく、動的で複雑な構成になったため • Unknown

    unknowns に対処するする必要がある 大規模かつ複雑になり発生した課題 「遅い・重い」から「使えない」まで
  23. What is Observability? 29 • 予期できていない問題が発生する • 静的で単純な構成ではなく、動的で複雑な構成になったため • Unknown

    unknowns に対処するする必要がある • 再現が困難、あるいは不可能 • 本番環境でのみ問題が発生する 大規模かつ複雑になり発生した課題 「遅い・重い」から「使えない」まで
  24. What is Observability? 30 • 予期できていない問題が発生する • 静的で単純な構成ではなく、動的で複雑な構成になったため • Unknown

    unknowns に対処するする必要がある • 再現が困難、あるいは不可能 • 本番環境でのみ問題が発生する • エスパー/直感による問題解決の限界 • 規模が大きくなるにつれブラックボックスは必然的に増える • 1サービス複数チームだと顕著 大規模かつ複雑になり発生した課題 「遅い・重い」から「使えない」まで
  25. OpenTelemetry 関連用語 36 Span 1 Span 3 Span 5 Span

    2 Span 4 Service A Service B Service C Trace HTTP W3C Trace Context
  26. OpenTelemetry 関連用語 37 Span 1 Span 3 Span 5 Span

    2 Span 4 Service A Service B Service C Trace HTTP W3C Trace Context W3C Trace Context のより詳細は以下のブログで。 【C#】ASP.NET Core と W3C Trace Context とお手軽ロギング。 https://blog.neno.dev/entry/2023/07/04/181843
  27. OpenTelemetry 関連用語 38 • Attribute [1] • key-value pair •

    Key MUST be a non-null and non-empty string. • Value is either: • A primitive type: string, boolean, double (IEEE 754-1985) or signed 64 bit integer. • An array of primitive type values. • OpenTelemetry における data model の様々なところで用いられる • 例えばスパンには様々な情報を attribute として詰め込める • Key は lowercase 推奨 (SHOULD) [2] • 規則として HTTP[3] や RPC[4] で使うべき key 名や value の型が定められている OpenTelemetry の用語 [1] https://github.com/open-telemetry/opentelemetry-specification/blob/v1.32.0/specification/common/README.md#attribute [2] https://github.com/open-telemetry/semantic-conventions/blob/v1.25.0/docs/general/attribute-naming.md#attribute-naming [3] https://github.com/open-telemetry/semantic-conventions/blob/v1.25.0/docs/http/http-spans.md#common-attributes [4] https://github.com/open-telemetry/semantic-conventions/blob/v1.25.0/docs/rpc/rpc-spans.md#common-attributes
  28. OpenTelemetry 関連用語 39 • Attribute [1] • key-value pair •

    Key MUST be a non-null and non-empty string. • Value is either: • A primitive type: string, boolean, double (IEEE 754-1985) or signed 64 bit integer. • An array of primitive type values. • OpenTelemetry における data model の様々なところで用いられる • 例えばスパンには様々な情報を attribute として詰め込める • Key は lowercase 推奨 (SHOULD) [2] • 規則として HTTP[3] や RPC[4] で使うべき key 名や value の型が定められている OpenTelemetry の用語 [1] https://github.com/open-telemetry/opentelemetry-specification/blob/v1.32.0/specification/common/README.md#attribute [2] https://github.com/open-telemetry/semantic-conventions/blob/v1.25.0/docs/general/attribute-naming.md#attribute-naming [3] https://github.com/open-telemetry/semantic-conventions/blob/v1.25.0/docs/http/http-spans.md#common-attributes [4] https://github.com/open-telemetry/semantic-conventions/blob/v1.25.0/docs/rpc/rpc-spans.md#common-attributes spec なのか semconv なのか 意識して区別する事をオススメ
  29. OpenTelemetry 関連用語 40 • IsRecording • false の場合 span に

    attribute 等のデータを保存できない • Sampled • W3C Trace Context の trace-flags: sampled に相当 OpenTelemetry における trace 関係の用語 https://github.com/open-telemetry/opentelemetry-specification/blob/v1.32.0/specification/trace/sdk.md#sampling
  30. OpenTelemetry 関連用語 41 • BCL • System.Diagnostics.Activity • OpenTelemetry.Api •

    OpenTelemetry.Trace.TelemetrySpan • Activity の薄いラッパー C# における Span の表現 基本的に Activity を直接いじれば OK
  31. Observability を高めていく 45 • テレメトリデータ • ログ • トレース •

    メトリクス • 分析 • 大きなテレメトリデータの集合をいかに問題解決のために分析できるか • 前提としてテレメトリデータに十分な情報量を詰め込む必要がある Observability を確保するための必須要素
  32. Observability を高めていく 46 • テレメトリデータ • ログ • トレース •

    メトリクス • 分析 • 大きなテレメトリデータの集合をいかに問題解決のために分析できるか • 前提としてテレメトリデータに十分な情報量を詰め込む必要がある Observability を確保するための必須要素 Observability 3本柱はあくまで テレメトリデータのデータ型に対する言及に過ぎない
  33. Observability を高めていく 47 • テレメトリデータ • ログ • トレース •

    メトリクス • 分析 • 大きなテレメトリデータの集合をいかに問題解決のために分析できるか • 前提としてテレメトリデータに十分な情報量を詰め込む必要がある Observability を確保するための必須要素 テレメトリデータに関する 仕様・規則・ライブラリ提供等が OpenTelemetry の責務 Observability 3本柱はあくまで テレメトリデータのデータ型に対する言及に過ぎない
  34. Observability を高めていく 48 • テレメトリデータ • ログ • トレース •

    メトリクス • 分析 • 大きなテレメトリデータの集合をいかに問題解決のために分析できるか • 前提としてテレメトリデータに十分な情報量を詰め込む必要がある Observability を確保するための必須要素 テレメトリデータに関する 仕様・規則・ライブラリ提供等が OpenTelemetry の責務 分析(機能)は Observability backend の責務 Observability 3本柱はあくまで テレメトリデータのデータ型に対する言及に過ぎない
  35. Observability を高めていく 50 • お手軽に詳細な Trace/Span/Metrics が取得できるようになる • 計装ライブラリを導入するだけで目的は達成可能か? •

    No OpenTelemetry + 計装ライブラリを導入する https://opentelemetry.io/docs/specs/status/ ソフトウェアの振る舞いを理解する事ができるだけの 十分な情報量が必要
  36. Observability を高めていく 51 • お手軽に詳細な Trace/Span/Metrics が取得できるようになる • 計装ライブラリを導入するだけで目的は達成可能か? •

    No OpenTelemetry + 計装ライブラリを導入する https://opentelemetry.io/docs/specs/status/ 自分たちのサービスに合わせた 計装が必須 ソフトウェアの振る舞いを理解する事ができるだけの 十分な情報量が必要
  37. Observability を高めていく 52 ソフトウェアの振る舞いを理解するための理想的なログ (再掲) ライブラリが 面倒見てくれる 開発者がいろいろ 考える必要あり 実装次第

    (赤字)は Microsoft.Extensions.Logging との対応 • いつ (Timestamp) • どのコンポーネントが (Category) • どの論理操作の中で (TraceId) • どういう親子関係 (SpanId) • どういうコンテキスト (Scope) • どういうパラメータで (State) • なにをして (EventId / Message) • それはどの程度の重要度か (LogLevel) • そしてどのような結果で終わり • どの程度時間がかかったか
  38. • いつ (timestamp) • どのコンポーネントが • どの論理操作の中で (trace_id) • どういう親子関係

    (span_id) • どういうコンテキスト (attribute) • どういうパラメータで (attribute) • なにをして (name) • それはどの程度の重要度か • そしてどのような結果で終わり (attribute) • どの程度時間がかかったか (duration) Observability を高めていく 53 ソフトウェアの振る舞いを理解するための理想的なスパン 開発者がいろいろ 考える必要あり ライブラリが 面倒見てくれる https://github.com/open-telemetry/opentelemetry-proto https://github.com/open-telemetry/opentelemetry-specification/blob/v1.32.0/specification/common/mapping-to-non-otlp.md#span-status 実装次第 (赤字)は OpenTelemetry との対応 otel.status_code
  39. Observability を高めていく 54 • Cardinality の高い情報 • Cardinality is simply

    a reflection of an attribute’s uniqueness. High-cardinality data contains a lot of very specific values, while low-cardinality data has only a few. [1] • 例: • Cardinality の高い情報: user-id, email addresses • Cardinality の低い情報: geo-location, cloud providers どのようなコンテキスト/パラメータを含めると良いか? [1] https://www.honeycomb.io/getting-started/understanding-high-cardinality-role-observability
  40. Observability を高めていく 55 • Cardinality の高い情報 • Cardinality is simply

    a reflection of an attribute’s uniqueness. High-cardinality data contains a lot of very specific values, while low-cardinality data has only a few. [1] • 例: • Cardinality の高い情報: user-id, email addresses • Cardinality の低い情報: geo-location, cloud providers どのようなコンテキスト/パラメータを含めると良いか? [1] https://www.honeycomb.io/getting-started/understanding-high-cardinality-role-observability ログもスパンも Cardinality の高い情報が好ましい
  41. Observability を高めていく 56 • Cardinality の高い情報 • Cardinality is simply

    a reflection of an attribute’s uniqueness. High-cardinality data contains a lot of very specific values, while low-cardinality data has only a few. [1] • 例: • Cardinality の高い情報: user-id, email addresses • Cardinality の低い情報: geo-location, cloud providers どのようなコンテキスト/パラメータを含めると良いか? [1] https://www.honeycomb.io/getting-started/understanding-high-cardinality-role-observability Cardinality が高い情報は 問題がどういう状況で起きたのかを 多く示唆してくれる ログもスパンも Cardinality の高い情報が好ましい
  42. Observability を高めていく 57 • Cardinality の高い情報 • Cardinality is simply

    a reflection of an attribute’s uniqueness. High-cardinality data contains a lot of very specific values, while low-cardinality data has only a few. [1] • 例: • Cardinality の高い情報: user-id, email addresses • Cardinality の低い情報: geo-location, cloud providers どのようなコンテキスト/パラメータを含めると良いか? [1] https://www.honeycomb.io/getting-started/understanding-high-cardinality-role-observability Cardinality が高い情報は 問題がどういう状況で起きたのかを 多く示唆してくれる 問題解決が簡単になる ログもスパンも Cardinality の高い情報が好ましい
  43. Observability を高めていく 58 • Activity.SetTag() • コンテキスト: user-id, org-id, plan-type

    等 • パラメータ: 操作対象の entity の id, 操作する際に用いる value など Attribute の追加の仕方
  44. Observability を高めていく 59 • Activity.SetTag() • コンテキスト: user-id, org-id, plan-type

    等 • パラメータ: 操作対象の entity の id, 操作する際に用いる value など Attribute の追加の仕方 コンテキストに関しては Middleware/Filter で追加しておくと便利
  45. Observability を高めていく 60 • Activity.SetTag() • コンテキスト: user-id, org-id, plan-type

    等 • パラメータ: 操作対象の entity の id, 操作する際に用いる value など Attribute の追加の仕方 追加した attribute をどう生かすか?は Observability backend 次第 コンテキストに関しては Middleware/Filter で追加しておくと便利
  46. Observability を高めていく 61 • System.Diagnostics.ActivitySource を用いる • AspNetCore.SignalR.OpenTelemetry [1] から引用

    自前で Span を切る [1] https://github.com/nenoNaninu/AspNetCore.SignalR.OpenTelemetry/tree/v1.4.0
  47. Observability を高めていく 62 • System.Diagnostics.ActivitySource を用いる • AspNetCore.SignalR.OpenTelemetry [1] から引用

    自前で Span を切る ActivitySource を static で new [1] https://github.com/nenoNaninu/AspNetCore.SignalR.OpenTelemetry/tree/v1.4.0
  48. Observability を高めていく 63 • System.Diagnostics.ActivitySource を用いる • AspNetCore.SignalR.OpenTelemetry [1] から引用

    自前で Span を切る ActivitySource を static で new Span を切りたい所で Activity を start する [1] https://github.com/nenoNaninu/AspNetCore.SignalR.OpenTelemetry/tree/v1.4.0
  49. Observability を高めていく 64 • System.Diagnostics.ActivitySource を用いる • AspNetCore.SignalR.OpenTelemetry [1] から引用

    自前で Span を切る ActivitySource を static で new Span を切りたい所で Activity を start する [1] https://github.com/nenoNaninu/AspNetCore.SignalR.OpenTelemetry/tree/v1.4.0 OpenTelemetry と Activity を繋げる
  50. OpenTelemetry Collector の活用 66 • Application が直接 telemetry data を

    backend に送信 Collector なし https://opentelemetry.io/docs/collector/deployment/no-collector/
  51. OpenTelemetry Collector の活用 67 • Application は OpenTelemetry Collector に

    telemetry data を送信 • Telemetry data のプロキシ Collector あり https://opentelemetry.io/docs/collector/deployment/agent/
  52. OpenTelemetry Collector の活用 69 • 恐らく Collector に対する一番の需要はコレ • 不要な

    telemetry data を observability backend に送る必要はない • ノイズでしかないトレース • 大規模であれば正常な trace の多くは不要 • 異常なものが異常なものと分かるくらいに正常な telemetry data があれば十分 • Observability backend に対する無駄な課金 • Collector で tail sampling • Tail sampling の対になるのは Head sampling 不要なトレースは observability backend に送りたくない https://github.com/open-telemetry/opentelemetry.io/blob/2024.05/content/en/docs/concepts/sampling/index.md https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/tailsamplingprocessor
  53. OpenTelemetry Collector の活用 70 • 自分たちにとって不要な情報 (attribute) を抜くオプション等が ライブラリ/フレームワークに側に存在しない •

    Collector で抜くしかない • 不要な情報例 • 個人情報 • Http のクエリ 不要な情報は取り除きたい https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/attributesprocessor Observability backend は 様々なステークホルダーが触るため 不要な情報は削ぎ落しておく必要がある
  54. OpenTelemetry Collector の活用 71 • OpenTelemetry のメリットの一つは spec/semconv が決まっているため、 様々な言語・ライブラリ・フレームワークで開発していても

    統一された telemetry data が出力される事。 • Observability backend において各サービスに対し 横断的・統一的な query が記述・実行可能 • Semconv に則っていないとこのメリットが失われる。 • 困った事に、実態として則っていないものがある。 • 具体的には opentelemetry-python は semconv に則っていない。 Attribute を semantic conventions に統一したい https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/attributesprocessor Collector で attribute を加工して semconv に則らせる