銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

Visual Studioからdocker composeを使っていて、突然「unexpected character "»" in variable name near "\ufeff" 」というエラーが出たら

"\ufeff" はかの有名なByte Order Mark(BOM)です。 現状のdocker composeでは.envファイルなどにBOMがあると正しく処理ができずエラーになるようです。

github.com

Visual Studio使わない場合でも起こりえると思いますが、Visual Studioを使った docker composeの起動で発生しました。この図のようにdocker compose用のプロジェクトに.envファイルを配置できるのですが、

最初作成したときは動作していたものの、一度Visual Studioを閉じて、開き直したタイミングでタイトルのエラーが出ました。どうやらBOM付UTF-8で保存されてしまったようです。

BOMなしに変更するには、Visual Studioの「ファイル」メニューで名前を付けて保存を選び、同じファイル名で上書き保存のオプションでエンコード付きで保存を選び、

Unicode (UTF-8シグネチャなし)を選び保存します。

以上で動作するようになりました。

インサイドWindows第7版(下)第10章の書評

今回、インサイドWindows第7版(下)を山内さんより献本いただきました。全部読了する前に、最も興味を惹かれた第10章「管理、診断、トレース」を読んで、書評を掲載します。なお、ご自身のブログにて目次が公開されています。

yamanxworld.blogspot.com

この章はレジストリからはじまりWindowsサービス、タスクスケジューラー、WMI、ETW、DTraceと説明がつづいていきます。レジストリから始まるのは、残りの機能の紹介にレジストリが必要だからですが、いきなり11章読んでも理解できたように、必要なところを読み進めて、必要に応じて参照されている節を読めば理解できる構成になっていました。

11章はまずレジストリに関する説明から始まります。レジストリに関しては以前まとめたことがあるのですが、やはりこのとき調べた情報以上に網羅されています。

tech.tanaka733.net

tech.tanaka733.net

まず、レジストリを参照・変更できるツールの話からはじまり、使用法、データ型、論理構造と進んでいきます。それを操作するには何を使うのか、何のために使うのか、を説明したあとに、詳細の説明をしていくという流れで、丁寧に理解を深めていくことができました。

また、いたるところで実習というのが用意されていて、例えばレジストリでは、特定のプロセスが利用しているレジストリキーを特定するという手順が紹介されています。今読んだこの機能を実際に使うとできるんだろうというところを実際に試すことができます。

ちなみに、ここまでが「10.1.8 Process Monitorの内部」で、レジストリについてもまだ半分程度の量です。後半はレジストリの内部構造の説明へと進んでいきます。その記述の詳細さに圧倒されました。

レジストリの次はWindowsサービスに移ります。今まで、都度必要な時に必要な知識を調べて使っていたWindowsサービスですが、この節で体系立てて知ることができました。Windowsサービスの前にレジストリの説明がしてあるのは、おそらくWindowsサービスがレジストリを大いに利用しているためで、どのレジストリキーにどの設定を保存しているかがまとめられています。サービスアカウントやSIDなども説明されています。網羅性があり辞書のように使える部分がありながら、学習用として読み進めて理解を深めることができると感じました。

Windowsサービスでは、共有サービスプロセスについても説明されており、プロセス一覧でよく見る「Svchost」とは何ぞやみたいな疑問にも説明できるようになります。

タスクスケジュラーやWMI、ETWと進むについて、アーキテクチャ図やデータ構造などを表現する図が多いことに気づきました。詳細な説明に加えて図があるため、とてもわかりやすくなっています。ETWについては10年近く前に利用していましたが、そのとき出ていたはずの第6版にはすでにETWの章があったらしいので、読めばよかったなあと後悔しています。(当時、インサイドWindowsを読むという発想が出てこなかった)

tech.tanaka733.net

第7版で追加された項目もあります(最初のブログ記事に記載されています)が、第10章の中で追加された中ではDTraceが興味を惹かれました。もう少しいろいろ触ってみたいと思います。

今回、翻訳本の書評なのですが、これだけの詳細な文章や図などを日本語で読めるということがまずうれしいです。外資系企業に勤めるものとして他人事ではないのですが、概要レベルはともかき、詳細な技術情報となるとどうしても翻訳コストがかかって英語のみ、あるいは機械翻訳ベースの提供となってしまう点があります。特にもともとアプリケーションエンジニアをやっていて、Windows OSそのものにはそこまで詳しくない私としては、この内容を英語で読むとかなり時間がかかるはずなので、非常に助かります。 また、訳注がついており、原文の翻訳だけだと理解しづらかったり試しづらかったりする箇所の補足がされています。

積読も多いし、個人的な事情でいろいろ忙しい年になっていますが、この本はきちんと時間をとって一通り読み込もうを思っています。

OpenTelemetry .NETを理解する (7) おさらいとASP .NET Coreでの計装サンプル公開

ここでいちどおさらいです。

OpenTelemetry .NETの現在地

GitHubのページで確認できる通り、Logs、Metrics、Tracesの3要素ともStableになりました。

github.com

が、注意書きにある通り、ILoggerなどのログフレームワークから出力されたログを取り込む OpenTelemetryLoggerProviderはStableですが、これをOTLP (OpenTelemetry Protocol)でエクスポートする部分はまだStableになっていません。また、HttpClientなどの自動計装などもstableなバージョンが出ていないものもあり、使い方によってはStableではないものを使う必要がでてきます。

OpenTelemetry .NETの始め方

まずはドキュメントのGetting Startedを読みましょう。

opentelemetry.io

Consoleアプリケーションを計装してテレメトリーデータをConsole出力するので、データ保存や可視化の機能は試せませんが、コンソール内で完結するので使い方を把握するのに最適です。

ASP.NET Coreで一通り試す

次にLogs、Metrics、Tracesの3種類のデータを収集し、オブザーバビリティバックエンドを利用してデータ保存や可視化の機能まで試したい場合、ASP.NET Coreのアプリで試すのが一番よいと思っています。ここまで取り上げてきた機能を中心に、ASP.NET CoreにMetrics、Logs、Tracesを一通り設定し、OTEL ExporterでエクスポートしているサンプルをGitHubに公開しました。

github.com

エクスポート先はotel/opentelemetry-collector イメージを使ったDockerコンテナを想定していて、New Relic に送信するサンプルコマンドも上げています。オブザーバビリティバックエンド側で収集したデータを可視化できます。一例をあげてみます。

Tracesをもとにしたリクエスト数や1トランザクションあたりの平均所要時間のグラフ。

同じくTracesを基にした分散トレーシング。

Microsoft.Extensions.Loggingを使ったログ出力を、ログ処理部分のコード変更なしにOTELで収集できるロギング。

また、このロギングではTraceを識別するidが自動で付与されるため、トランザクションごとに出力されたログや例外処理時のログをすぐに特定できます。

ASP.NET CoreのRuntime Metricsを連携したMetrics。

さてこのコードの中で以前のブログで説明した部分が変わっている部分があります。Spanに例外状態を設定する部分です。

tech.tanaka733.net

以前のブログでは、以下のコードではSpanの状態が例外ステータスにならなかったのが、今回検証したところ修正されていました。

activity?.SetStatus(ActivityStatusCode.Error, "error happened.");

このようにこのコードだけでSpanが例外状態となります。

さて、次回からは別のライブラリやフレームワークを使うときにどこまでOpenTelemetry .NETで計測できるか試してみたいと思います。