gcログローテーション

setenv.bat

PS D:\dev\container\tomcat9\bin> more .\setenv.bat @echo off set "CATALINA_OPTS=-Xlog:gc*:file=d:\dev\runtime\logs\gc.log:time,uptime,level,tags:filecount=60"

起動時のオプション表示

D:\dev\container\tomcat9\bin>startup.bat Using CATALINA_BASE: "D:\dev\container\tomcat9" Using CATALINA_HOME: "D:\dev\container\tomcat9" Using CATALINA_TMPDIR: "D:\dev\container\tomcat9\temp" Using JRE_HOME: "D:\dev\runtime\java\jdk\jdk-17.0.14" Using CLASSPATH: "D:\dev\container\tomcat9\bin\bootstrap.jar;D:\dev\container\tomcat9\bin\tomcat-juli.jar" Using CATALINA_OPTS: "-Xlog:gc*:file=d:\dev\runtime\logs\gc.log:time,uptime,level,tags:filecount=60"

tomcatのPID検出

jcmd.exe -l

PS D:\dev\container\tomcat9-1\bin> jcmd.exe -l 22212 jdk.jcmd/sun.tools.jcmd.JCmd -l 5516 org.apache.catalina.startup.Bootstrap start 7804 org.apache.catalina.startup.Bootstrap start

プロセスを見つける。複数のtomcatが動いている場合は

# Bootstrapを含むJavaプロセスをすべて取得 $tomcatProcesses = Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -like "*org.apache.catalina.startup.Bootstrap*" } 【実行例】 PS D:\dev\container\tomcat9-1\bin> $tomcatProcesses ProcessId Name HandleCount WorkingSetSize VirtualSize --------- ---- ----------- -------------- ----------- 7804 java.exe 526 122044416 15080996864 5516 java.exe 532 121135104 15085416448

VM.log オプションがあるか確認

jcmd.exe help

PS D:\dev\container\tomcat9-1\bin> $tomcatProcesses ProcessId Name HandleCount WorkingSetSize VirtualSize --------- ---- ----------- -------------- ----------- 7804 java.exe 526 122044416 15080996864 5516 java.exe 532 121135104 15085416448 PS D:\dev\container\tomcat9-1\bin> $tomcatProcesses[0].ProcessId 7804 PS D:\dev\container\tomcat9\bin> jcmd.exe $tomcatProcesses[0].ProcessId help 7804: The following commands are available: Compiler.CodeHeap_Analytics ~省略~ VM.log ~省略~ For more information about a specific command use 'help <command>'.

サービスオブジェクト

PS D:\dev\container\tomcat9-1\bin> $tomcatProcesses[0] | select-object * ProcessName : java.exe Handles : 526 VM : 15080996864 WS : 122044416 Path : D:\dev\runtime\java\jdk\jdk-17.0.14\bin\java.exe Caption : java.exe Description : java.exe InstallDate : Name : java.exe Status : CreationClassName : Win32_Process CreationDate : 2025/05/11 13:20:50 CSCreationClassName : Win32_ComputerSystem CSName : FARTYOSHIPC ExecutionState : Handle : 7804 KernelModeTime : 18750000 OSCreationClassName : Win32_OperatingSystem OSName : Microsoft Windows 11 Pro|C:\WINDOWS|\Device\Harddisk1\Partition3 Priority : 8 TerminationDate : UserModeTime : 43906250 WorkingSetSize : 122044416 CommandLine : "D:\dev\runtime\java\jdk\jdk-17.0.14\bin\java.exe" -Djava.util.logging.config.file="D:\ dev\container\tomcat9\conf\logging.properties" -Djava.util.logging.manager=org.apache.ju li.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs =org.apache.catalina.webresources -Dsun.io.useCanonCaches=false -Xlog:gc*:file=d:\dev\ru ntime\logs\gc.log:time,uptime,level,tags:filecount=60 -Dignore.endorsed.dirs="" -classp ath "D:\dev\container\tomcat9\bin\bootstrap.jar;D:\dev\container\tomcat9\bin\tomcat-juli .jar" -Dcatalina.base="D:\dev\container\tomcat9" -Dcatalina.home="D:\dev\container\tomca t9" -Djava.io.tmpdir="D:\dev\container\tomcat9\temp" org.apache.catalina.startup.Bootstr ap start ExecutablePath : D:\dev\runtime\java\jdk\jdk-17.0.14\bin\java.exe HandleCount : 526 MaximumWorkingSetSize : 1380 MinimumWorkingSetSize : 200 OtherOperationCount : 22469 OtherTransferCount : 674609 PageFaults : 100153 PageFileUsage : 678128 ParentProcessId : 21376 PeakPageFileUsage : 731348 PeakVirtualSize : 15097581568 PeakWorkingSetSize : 171044 PrivatePageCount : 694403072 ProcessId : 7804 QuotaNonPagedPoolUsage : 35 QuotaPagedPoolUsage : 467 QuotaPeakNonPagedPoolUsage : 132 QuotaPeakPagedPoolUsage : 467 ReadOperationCount : 4595 ReadTransferCount : 20574507 SessionId : 1 ThreadCount : 53 VirtualSize : 15080996864 WindowsVersion : 10.0.26100 WriteOperationCount : 154 WriteTransferCount : 23492 PSComputerName : CimClass : root/cimv2:Win32_Process CimInstanceProperties : {Caption, Description, InstallDate, Name...} CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties

ローテーション

jcmd.exe VM.log

PS D:\dev\container\tomcat9\bin> jcmd.exe $tomcatProcesses[0].ProcessId VM.log rotate 7804: Command executed successfully

gc.log

PS D:\dev\container\tomcat9\bin> dir D:\dev\runtime\logs\ ディレクトリ: D:\dev\runtime\logs Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2025/05/11 13:06 0 gc.log -a---- 2025/05/11 12:47 7343 gc.log.0 -a---- 2025/05/11 12:52 2499 gc.log.00 -a---- 2025/05/11 12:52 4890 gc.log.01 -a---- 2025/05/11 12:53 0 gc.log.02 -a---- 2025/05/11 12:48 4890 gc.log.1 -a---- 2025/05/11 12:50 0 gc.log.2 -a---- 2025/05/11 12:50 0 gc.log.3

スクリプト

# JavaとTomcatの設定 $jdkBin = "C:\Program Files\Java\jdk-17\bin" $gcLogRelativePath = "logs\gc.log" $thresholdDate = (Get-Date).AddDays(-60) $today = Get-Date -Format "yyyyMMdd" # Bootstrapを含むJavaプロセスをすべて取得 $tomcatProcesses = Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -like "*org.apache.catalina.startup.Bootstrap*" } if ($tomcatProcesses.Count -eq 0) { Write-Error "Tomcatプロセスが見つかりませんでした。" exit 1 } $instanceIndex = 1 foreach ($proc in $tomcatProcesses) { $pid = $proc.ProcessId $cmdline = $proc.CommandLine # CATALINA_BASE を推測(-Dcatalina.base=...) if ($cmdline -match "-Dcatalina\.base=([^\s\"]+)") { $catalinaBase = $matches[1] } else { Write-Warning "CATALINA_BASE を取得できません(PID=$pid)。スキップします。" continue } # ログファイルパス $gcLogPath = Join-Path $catalinaBase $gcLogRelativePath $backupDir = Split-Path $gcLogPath $instanceId = "inst$instanceIndex" $backupFile = Join-Path $backupDir ("gc_${today}_$instanceId.log") # ローテーション実行 Write-Output "[$instanceId] jcmd $pid VM.log rotate" & "$jdkBin\jcmd.exe" $pid "VM.log" "rotate" Start-Sleep -Seconds 2 # ログをバックアップ if (Test-Path $gcLogPath) { Copy-Item -Path $gcLogPath -Destination $backupFile -Force Write-Output "[$instanceId] GCログを $backupFile に保存しました。" } else { Write-Warning "[$instanceId] gc.log が存在しません。" } # 60日より古い gc_*.log を削除 Get-ChildItem -Path $backupDir -Filter "gc_*.log" | ForEach-Object { if ($_.Name -match "gc_(\d{8})(?:_inst\d+)?\.log") { $logDate = [datetime]::ParseExact($matches[1], "yyyyMMdd", $null) if ($logDate -lt $thresholdDate) { Remove-Item $_.FullName -Force Write-Output "[$instanceId] 削除: $($_.Name)" } } } $instanceIndex++ }

タスクスケジューラ登録方法

$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `\"C:\Scripts\rotate_gc_log.ps1`\"" $Trigger = New-ScheduledTaskTrigger -Daily -At 0:00 Register-ScheduledTask -TaskName "RotateGcLog" -Action $Action -Trigger $Trigger -Description "Tomcat GCログのローテーション" -User "SYSTEM" -RunLevel Highest

補足

-ExecutionPolicy Bypass: スクリプトの実行ポリシー制限を無視(安全なスクリプトならOK)
-User "SYSTEM": サーバー起動時に自動実行可能なSYSTEMアカウントで登録
-RunLevel Highest: 管理者権限で実行