はじめに:環境情報取得は「どこで・どんな設定で動いているか」を数字と言葉で残すこと
業務システムで一番困るのは、 「開発環境では再現しないのに、本番だけでバグが出る」 「同じコードなのに、サーバーによって挙動が違う」 という状況です。
こういうときに必ず必要になるのが 環境情報 です。
どの OS か どの .NET ランタイムか 何ビットプロセスか どのマシン名・ユーザー名か どのカルチャ・タイムゾーンか
こういった情報を ログにきちんと残しておくことで、
「この不具合は、特定の環境だけで起きている」 「設定の違いが原因だ」
といった切り分けができるようになります。
ここでは、初心者向けに
Environmentクラスで取れる基本情報- OS・プロセス・CPU・メモリなどの環境情報
- 実務で使える「環境情報ダンプユーティリティ」
- いつ・どこで環境情報をログに残すべきか
を、例題付きでかみ砕いて説明します。
Environment クラスで取れる基本的な環境情報
OS・マシン名・ユーザー名・プロセス情報など
C# では、環境情報の入口としてまず覚えるべきなのが System.Environment クラスです。 ここから、かなり多くの「今動いている環境の情報」を取得できます。
代表的なものをまとめて見てみます。
public static void ShowBasicEnvironment()
{
Console.WriteLine($"OSVersion: {Environment.OSVersion}");
Console.WriteLine($"Is64BitOperatingSystem: {Environment.Is64BitOperatingSystem}");
Console.WriteLine($"Is64BitProcess: {Environment.Is64BitProcess}");
Console.WriteLine($"MachineName: {Environment.MachineName}");
Console.WriteLine($"UserName: {Environment.UserName}");
Console.WriteLine($"CurrentDirectory: {Environment.CurrentDirectory}");
Console.WriteLine($"ProcessorCount: {Environment.ProcessorCount}");
}
C#それぞれの意味は、感覚的にはこんな感じです。
OSVersion どの OS か(Windows のバージョンなど)
Is64BitOperatingSystem OS が 64bit かどうか
Is64BitProcess このアプリが 64bit プロセスかどうか(AnyCPU / x86 / x64 の違い)
MachineName サーバー名・PC 名
UserName このプロセスを動かしているユーザー(サービスアカウントなど)
CurrentDirectory 「カレントディレクトリ」(相対パスの基準になる場所)
ProcessorCount 論理 CPU コア数(並列処理の設計に関係する)
ここでの重要ポイントは、 「バグ報告に必ず書いてほしい情報の多くが、コードから自動で取れる」 ということです。
OS・ランタイム・カルチャ・タイムゾーンなどの情報
「どの .NET」「どの文化圏」「どの時間帯」で動いているか
環境差でバグが出やすいのが、 ランタイムのバージョン、カルチャ(言語・地域)、タイムゾーンです。
これらもコードから取得できます。
using System;
using System.Globalization;
public static void ShowRuntimeAndCulture()
{
Console.WriteLine($".NET Runtime: {Environment.Version}");
Console.WriteLine($"CurrentCulture: {CultureInfo.CurrentCulture}");
Console.WriteLine($"CurrentUICulture: {CultureInfo.CurrentUICulture}");
Console.WriteLine($"TimeZone: {TimeZoneInfo.Local.DisplayName}");
}
C#意味をざっくり言うと、
Environment.Version 今動いている .NET ランタイムのバージョン
CurrentCulture 日付・数値・通貨などのフォーマットに使われる文化圏(例:ja-JP)
CurrentUICulture UI の言語(リソースの選択に使われる)
TimeZoneInfo.Local ローカルタイムゾーン(例:Tokyo Standard Time)
ここでの重要ポイントは、 「日付・数値・文字列の挙動はカルチャとタイムゾーンに強く依存する」 ということです。
例えば、
DateTime.ToString()の表示形式double.Parse("1,23")の解釈- 日付の「日曜始まりか月曜始まりか」
などは、カルチャによって変わります。
「開発環境(ja-JP)では動くのに、本番(en-US)では落ちる」 というバグは、環境情報をログに残していないと見つけづらくなります。
実務で使える「環境情報ダンプユーティリティ」
一度にまとめてログに吐き出せるようにしておく
毎回バラバラに Environment を呼ぶのは面倒なので、 「環境情報をまとめてダンプするユーティリティ」 を作っておくと便利です。
ILogger と組み合わせた例を見てみましょう。
using System;
using System.Diagnostics;
using System.Globalization;
using Microsoft.Extensions.Logging;
public static class EnvironmentLogger
{
public static void LogEnvironment(ILogger logger, string context)
{
using var process = Process.GetCurrentProcess();
logger.LogInformation(
"EnvironmentDump Context={Context} " +
"MachineName={MachineName} UserName={UserName} " +
"OSVersion={OSVersion} Is64BitOS={Is64BitOS} Is64BitProcess={Is64BitProcess} " +
"ProcessorCount={ProcessorCount} " +
"CurrentDirectory={CurrentDirectory} " +
"RuntimeVersion={RuntimeVersion} " +
"CurrentCulture={CurrentCulture} CurrentUICulture={CurrentUICulture} " +
"TimeZone={TimeZone} " +
"ProcessId={ProcessId} ProcessName={ProcessName}",
context,
Environment.MachineName,
Environment.UserName,
Environment.OSVersion,
Environment.Is64BitOperatingSystem,
Environment.Is64BitProcess,
Environment.ProcessorCount,
Environment.CurrentDirectory,
Environment.Version,
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture,
TimeZoneInfo.Local.DisplayName,
process.Id,
process.ProcessName);
}
}
C#使い方の例です。
// アプリ起動時に一度だけ
EnvironmentLogger.LogEnvironment(_logger, "AppStart");
// 重大なエラー発生時にも
EnvironmentLogger.LogEnvironment(_logger, "FatalError");
C#ログには、例えばこんな行が残ります。
「EnvironmentDump Context=AppStart MachineName=WEB01 UserName=svc_app OSVersion=Microsoft Windows NT 10.0.20348.0 Is64BitOS=True Is64BitProcess=True ProcessorCount=8 CurrentDirectory=C:\apps\MyService RuntimeVersion=7.0.10 CurrentCulture=ja-JP CurrentUICulture=ja-JP TimeZone=(UTC+09:00) Osaka, Sapporo, Tokyo ProcessId=1234 ProcessName=MyService」
ここでの重要ポイントは、
「環境情報は“まとめて一行で”残す」 「いつ・どの文脈で取ったか(Context)を付ける」
ということです。
これにより、
- 本番サーバーごとの環境差
- 起動時とエラー時の環境の違い
などを後から比較しやすくなります。
いつ環境情報をログに残すべきか
起動時・重大エラー時・診断モード開始時
環境情報は、毎秒取るようなものではありません。 「ここで環境を知っておきたい」というタイミングに絞ってログに残すのが実務的です。
代表的なタイミングは次のような場面です。
アプリ起動時 「このバージョンのアプリが、どの環境で動いているか」を記録しておく。
重大なエラー発生時 「このエラーが起きたときの環境」をセットで残しておく。
診断モード開始時 「今から負荷試験します」「今から調査モードに入ります」といったタイミング。
ここでの重要ポイントは、 「環境情報は“バグ報告のテンプレ”をコードで自動化したもの」 という感覚です。
人間が「OS は?」「何ビット?」「カルチャは?」と聞き回る代わりに、 アプリが自分でそれをログに書いておいてくれるイメージです。
まとめ:環境情報取得は“バグの再現条件を機械的に残す”ためのユーティリティ
環境情報取得の本質を一言で言うと、
「このアプリが、 どの OS・どの .NET・どのマシン・どのユーザー・どのカルチャ・どのタイムゾーンで動いていたかを、 ログとして機械的に残し、 バグの再現条件や環境差を後から正確に語れるようにする」
ことです。
押さえておきたいポイントは次の通りです。
Environmentクラスから、OS・マシン名・ユーザー名・プロセス情報・CPU数などを簡単に取得できる。CultureInfoやTimeZoneInfoから、カルチャ・タイムゾーンを取得でき、日付・数値・文字列の挙動に直結する。EnvironmentLoggerのようなユーティリティを作り、「環境情報をまとめて一行でログに残す」形にしておくと実務で使いやすい。- 起動時・重大エラー時・診断モード開始時など、「ここで環境を知っておきたい」タイミングでログを出すのが現実的。
ここまでイメージできていれば、 「本番だけで起きる謎のバグ」に対して、 “環境情報という武器”を持った状態で戦えるようになります。
