あなたがWebサイトの管理者であるとします。GNU wget コマンドを使ってWebサイトのHTML群をダウンロードするとします。コマンドラインでwgetを実行する時にオプションとして -o logfile を指定するとログをファイルに保存することができます。そのログの内容はたとえば下記のようなテキストです。
...
--2026-10-23 22:03:04-- http://www.myapp.jp/index.html
Resolving www.myapp.jp (www.myapp.jp)... 153.122.205.45
Connecting to www.myapp.jp (www.myapp.jp)|153.122.205.45|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: 'www.myapp.jp/index.html'
0K ...... 8.47M=0.001s
2026-10-23 22:03:04 (8.47 MB/s) - 'www.myapp.jp/index.html' saved [6836]
Loading robots.txt; please ignore errors.
--2026-10-23 22:03:34-- http://www.myapp.jp/member/index.html
Reusing existing connection to www.myapp.jp:80.
HTTP request sent, awaiting response... 401 Unauthorized
Authentication selected: Basic realm="Please type your user-id and password"
Reusing existing connection to www.myapp.jp:80.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: 'www.myapp.jp/member/index.html'
0K ......... 3.54M=0.003s
2026-10-23 22:03:34 (3.54 MB/s) - 'www.myapp.jp/member/index.html' saved [9843]
Incomplete or invalid multibyte sequence encountered
--2026-10-23 22:03:35-- http://www.myapp.jp/img/common/f_logo.png
Reusing existing connection to www.myapp.jp:80.
HTTP request sent, awaiting response... 200 OK
Length: 5098 (5.0K) [image/png]
Saving to: 'www.myapp.jp/img/common/f_logo.png'
0K .... 100% 39.9M=0s
2026-10-23 22:03:35 (39.9 MB/s) - 'www.myapp.jp/img/common/f_logo.png' saved [5098/5098]
--2026-10-23 22:03:36-- http://www.myapp.jp/privacy/index.html
Reusing existing connection to www.myapp.jp:80.
HTTP request sent, awaiting response... 404 Not Found
2026-10-23 22:03:36 ERROR 404: Not Found.
--2026-10-23 22:03:37-- http://www.myapp.jp/img/index/page_top.png
Reusing existing connection to www.myapp.jp:80.
HTTP request sent, awaiting response... 200 OK
Length: 1350 (1.3K) [image/png]
Saving to: 'www.myapp.jp/img/index/page_top.png'
0K . 100% 15.8M=0s
...
HTTPステータス 200 OK が応答されたURLには問題がないからさておくとして 404 Not Found が応答されたURLには注意を払うべきでしょう。wgetのログの中から情報を抽出して 404 Not Found が応答されたURLの一覧リストを作りたくなるでしょう。URLとHTTP応答ステータスがテキスト1行にレイアウトされていれば wgetのログを grep コマンドでフィルタするだけで必要十分なリストが得られるでしょう。
ところが上記のサンプルをみればすぐわかる、wgetのログの形式は 行指向 でありません。HTTP要求の情報とHTTP応答の情報が別の行に出力されている。このままではgrepコマンドで後処理することが難しい。困った。
wgetのログファイルを 行指向 のテキストファイルに変換するプログラムを作ろう。WgetLogDigest と呼ぶことにします。WgetLogDigest は下記のようなテキストを出力します。
2026-10-23 22:03:04 http://www.myapp.jp/index.html 200 OK
2026-10-23 22:03:34 http://www.myapp.jp/member/index.html 200 OK
2026-10-23 22:03:35 http://www.myapp.jp/img/common/f_logo.png 200 OK
2026-10-23 22:03:36 http://www.myapp.jp/privacy/index.html 404 Not Found
2026-10-23 22:03:37 http://www.myapp.jp/img/index/page_top.png 200 OK
各行はTABで区切られています。
yyyy-MM—dd hh:mm:ss \t URL \t status \t message
わたしはJavaで WgetLogDigest を開発しました。GitHubでレポジトリを公開しました。
Java/Gradle/Kotlinのビルドツール Gradleのカスタムプラグインとして WgetLogDigest を利用することができます。
Gradleの build.gradle のサンプルを下記に示します。ここでは wgetのログがファイルとして与えられたと仮定しています。ログを行指向フォーマットに変換し、出力されたテキストをOSのgrepコマンドでフィルタしています。
plugins {
id("com.kazurayam.wget-log-digest-plugin") version "0.1.11"
}
tasks.register('digest', com.kazurayam.wgetlog.DigesterTask) {
wgetLogFile = file("../plugin/src/test/fixtures/wget.log")
outputFile = file("./build/tmp/out/straight.txt")
}
import org.gradle.process.ExecOperations
interface InjectedExecOps {
@javax.inject.Inject
ExecOperations getExecOps()
}
tasks.register('listFaultyURLs') {
dependsOn('digest')
def injected = project.objects.newInstance(InjectedExecOps)
def stdout = new ByteArrayOutputStream()
doLast {
new ByteArrayOutputStream().withStream { os ->
def result = injected.execOps.exec {
commandLine 'grep', 'Not Found', "./build/tmp/out/straight.txt"
ignoreExitValue = true
standardOutput = os
}
def outputFile = file("./build/tmp/out/faultyURLs.txt")
outputFile.text = os.toString()
}
}
}
わたしが関係しているシステムで得られたwgetログにこのビルドを実行すると下記のような faulty URL のリストが得られました。
2026-10-23 22:03:06 http://www.myapp.com/robots.txt 404 Not Found
2026-10-23 22:03:26 https://www.myapp.com/robots.txt 404 Not Found
2026-10-23 22:03:36 http://www.myapp.com/privacy/index.html 404 Not Found
2026-10-23 22:04:43 http://www.myapp.com/member/documents/20261017/%E9%9A%A8%EF%BD%AC149%E8%9D%97%E6%A8%A3%E6%90%A8%E8%AD%BD%EF%BD%AE%E9%80%B5%EF%BD%BC%E9%81%98%E9%B7%B9%E5%AF%94%E9%9A%B2%87%E8%8E%A8%9A2026%E9%81%98%E4%B9%9D%83%E5%8A%B1%CE%9F%E7%B9%A7%EF%BD%B0%E7%B9%9D%EF%BD%A9%E7%B9%9D%A0.pdf 404 Not Found
2026-10-23 22:04:55 http://www.myapp.com/member/movie.html 404 Not Found
2026-10-23 22:04:58 http://www.myapp.com/images/school_01s.gif 404 Not Found
2026-10-23 22:05:20 http://www.myapp.com/images/qr_bg.gif 404 Not Found
これによってわたしは自分のWebサイトにたくさんのミスを発見することができました。有効だと思います。
ソースコードはここにあります
素朴なJavaコードなので読むのは簡単でしょう。説明は省略します。
Gradleプラグインとしてでなく WgetLogDigest のJavaクラスをjarをダウンロードして直接使うこともできます。