目次
こんにちは、那須です。
Windows Server上で構成されているシステムを運用している中で、例えばストレージ使用率が100%に近づいてきたら不要なファイルやログなどを削除するような運用項目はないでしょうか? 削除したくても一体いつどのディレクトリのサイズが増えたのかがわからないと対応が難しかったりしますよね。
ストレージ使用率が閾値を超えた → どのディレクトリが使用率上昇の原因になっているのかを調査する、という対応をNew Relic Flexを使って最初からやっておけばいいのでは?と思いました。なので、その仕組みを書き記します。
対象読者
- Windows Serverを運用している人
- ディレクトリごとのサイズをOSにログインして調べるのが面倒な人
- 定期的にディレクトリサイズの推移を確認して報告しないといけない人
検証環境
OS | Microsoft Windows Server 2022 Datacenter |
インスタンスサイズ | t3.medium(2vCPU, 4GiB Memory) |
インスタンスの状態 | EC2インスタンスを起動しただけ |
前提条件
New Relic infrastructure agentがインストールされて基本的なメトリクスがNew Relicで表示されている状態からスタートします。もしまだそうなっていない方は、New Relicドキュメントから進めてみてください。
https://docs.newrelic.com/jp/docs/infrastructure/install-infrastructure-agent/windows-installation/install-infrastructure-monitoring-agent-windows/
New Relic Flex設定内容
Windowsには標準でディレクトリごとのサイズを教えてくれるコマンドがあるようでありません。なので以下のようなPowerShellスクリプトを準備して任意の場所に置きます。今回は以下のパスで進めます。Depthオプションで1を指定していますが、最初からどの深さまでディレクトリサイズを把握したいのか次第で数字を調整してください。まずはこれを実行して想定通りに結果が表示されることは確認しておきましょう。
C:/Program Files/New Relic/newrelic-infra/scripts/directory_size_check.ps1
$directories = Get-ChildItem -Path $args[0] -Depth 1 -Directory -Recurse -ErrorAction SilentlyContinue
$DirectorySizes = foreach ($directory in $directories) {
$size = (Get-ChildItem -Path $directory.FullName -File -Recurse | Measure-Object -Property Length -Sum).Sum
$sizeInMB = $size / 1MB
[PSCustomObject]@{
DirectoryName = $directory.FullName
SizeInMB = [Math]::Round($sizeInMB,2)
}
}
$DirectorySizes | ConvertTo-Json
実行結果はこのようにJSONで出力されます。
[
{
"DirectoryName": "C:\\path1",
"SizeInMB": 1.1
},
{
"DirectoryName": "C:\\path2",
"SizeInMB": 0.2
}
]
スクリプトの動作確認ができたら、以下の内容でYAMLファイルを作って以下に置きましょう。ファイル名はなんでもOKです。
C:\Program Files\New Relic\newrelic-infra\integrations.d\directory_size_check.yml
intervalで実行間隔を指定します。event_typeでNew Relic内のイベント名(SQLでいうテーブル名)を指定します。commands.timeoutでスクリプトの実行時間にあわせてミリ秒で指定しましょう。commands.runで先ほど作成したスクリプトを引数つけて実行するよう指定します。この例ではCドライブ直下(ファイルがなければさらにその下)のディレクトリごとのサイズを収集します。
integrations:
- name: nri-flex
interval: 10m
config:
name: directory_size_check
apis:
- event_type: DirectorySizeCheck
shell: powershell
commands:
- run: "& \"C:/Program Files/New Relic/newrelic-infra/scripts/directory_size_check.ps1\" \"C:/\""
timeout: 300000
もしdirectory_size_check.ps1をリモートからとってきた場合はPowerShellの実行ポリシーで実行できないと思いますので、commands.runの部分は以下のように実行ポリシーを指定しましょう(Bypassでいいのかは考えないといけませんね)
integrations:
- name: nri-flex
interval: 10m
config:
name: directory_size_check
apis:
- event_type: DirectorySizeCheck
shell: powershell
commands:
- run: "powershell.exe -ExecutionPolicy Bypass -File \"C:/Program Files/New Relic/newrelic-infra/scripts/directory_size_check.ps1\" \"C:/\""
timeout: 300000
New Relic infrastructure agentの再起動はしなくても大丈夫です。このYAMLファイルを置いた瞬間からYAMLファイルで定義した内容が自動で実行され始めます。あとはNew Relicでメトリクスが表示されることを確認するだけです。
結果確認
Flexで送ったデータは何もしなければNew Relicで自動で表示されることはありません。なのでNRQLでダッシュボード表示するなどしましょう。
単純にデータが来ているかどうかを確認するには以下のNRQLで確かめます。
FROM DirectorySizeCheck SELECT *
テーブル表示だと運用では使いづらいですよね。なのでディレクトリごとに時系列で折れ線グラフで表示させましょう。
directory_size_check.ps1でNew Relicに送信している情報はDirectoryNameとSizeInMBの2つなので、これらを指定してNRQLを書きます。
FROM DirectorySizeCheck SELECT latest(SizeInMB) FACET DirectoryName SINCE 1 hour ago TIMESERIES 10 minutes
サイズに変化がないので横一直線の面白くないグラフが出来上がりましたが、ディレクトリごとのサイズはこれでだいたい把握できますね。例えばC:\test_dirで急にサイズ増大した場合は、さきほどのNRQLでWHEREを追加して絞り込めば知りたい情報だけが見れるグラフを表示できます。
改善したいこと
directory_size_check.ps1を実行すると、そのタイミングで約20%のCPU使用率が記録されます(t3.mediumの場合)。たぶんスクリプトの作りが悪いのだと思いますが、今のところ代替案がありません… こういう情報はせいぜい1日1回夜間にチェックする形になることが多いので、クリティカルな問題にはならないと思います。が、これを使われる方は実行タイミングの負荷には十分お気をつけください。
Linuxでもできる?
Linuxに対しても同じような仕組みを作ることもできます。ただ本記事のようなことをしなくてもNew Relic FlexのGitHubにサンプルがありますので、こちらを好きなように変更して適用するだけでOKです。
https://github.com/newrelic/nri-flex/blob/master/examples/linux/linux-directory-size.yml
さいごに
ディレクトリごとのサイズをNew Relicで可視化するまでの流れをご紹介しました。今までならOSにログインして手作業で調査していたことがNew Relic Flexを使うことで誰も運用中に手を動かすことなく調査に必要な情報が手に入ります。運用業務を効率的に実施するためにこういった仕組みをうまく活用していきましょう!
- カテゴリー