Logstash on Ubuntu — ログ収集パイプラインのフィルタ設定実践

データエンジニアリング

この記事のポイント

  • Ubuntu 24.04 LTS に Elastic 公式 APT リポジトリで Logstash 8.19.16 をインストールできる(Java 別途インストール不要)
  • grok フィルタ1行で Apache アクセスログを ECS 準拠の JSON フィールドに自動展開できる
  • mutate + 条件分岐で ERROR ログだけにアラートフィールドを付けるといった柔軟な加工が可能
  • date フィルタでタイムスタンプを UTC に正規化すると、複数サーバーのログを時系列で並べやすくなる
  • grok マッチ失敗時は _grokparsefailure タグが自動付与される(条件分岐でエラー行だけ別処理できる)

サーバーのアクセスログやアプリログを、人間が読める形からデータベースで検索できる形に変換したい。そういった場面で使われるのが Logstash です。

Logstash は Elastic 社が開発するログ収集・変換パイプラインツールです。input でログを受け取り、filter で加工し、output で Elasticsearch やファイルに送る 3 ステージ構成が基本です。

この記事では Ubuntu 24.04 LTS に Logstash をインストールし、grok・JSON・mutate・date の 4 種類のフィルタを実際にDockerコンテナで動かした結果を載せます。

目次

  1. Ubuntu 24.04 へのインストール手順
  2. パイプライン設定ファイルの基本構造
  3. grok フィルタ — Apache ログを JSON に展開
  4. json フィルタ — アプリログの JSON をフィールドに展開
  5. mutate フィルタ — フィールド名変更・条件分岐
  6. date フィルタ — タイムスタンプを UTC に正規化
  7. よくあるエラーと対処
  8. まとめ

Ubuntu 24.04 へのインストール手順

手順1:動作確認済み環境

今回の検証には 2 種類の環境を使いました。

用途 環境 Logstash バージョン
APT インストール確認 Ubuntu 24.04 LTS(Docker 公式イメージ ubuntu:24.04) 8.19.16(APT 候補版 / 2026-06-22 時点)
フィルタ動作確認 Logstash 公式 Docker イメージ(ベース OS: Ubuntu 20.04) 8.13.4(docker.elastic.co/logstash/logstash:8.13.4)

APT リポジトリで提供される最新版と Docker Hub のタグは別々にリリースされます。フィルタの基本動作(grok / mutate / date / json)は 8.x 系でバージョン間の差異はなく、今回確認した出力は 8.19 でも同様に得られます。

Logstash は OpenJDK 17 をバンドルして同梱しているため、Ubuntu 側に Java を別でインストールしなくても動きます。Ubuntu 22.04 でも同じ 8.19.16 が取得できることは実測で確認済みです(後述のバージョン比較参照)。

手順2:Elastic APT リポジトリを追加する




ubuntu@linuxlab: ~
$ sudo apt-get install -y wget gnupg apt-transport-https
Reading package lists… Done
Setting up gnupg (2.4.4-2ubuntu17) …
done.

$ wget -qO – https://artifacts.elastic.co/GPG-KEY-elasticsearch \
| gpg –dearmor -o /usr/share/keyrings/elastic-keyring.gpg

$ echo “deb [signed-by=/usr/share/keyrings/elastic-keyring.gpg] \
https://artifacts.elastic.co/packages/8.x/apt stable main” \
| sudo tee /etc/apt/sources.list.d/elastic-8.x.list
deb [signed-by=/usr/share/keyrings/elastic-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main

GPG キーを /usr/share/keyrings/ に置く方法は Ubuntu 22.04 以降の推奨形式です(apt-key add は Ubuntu 22.04 から非推奨)。

手順3:Logstash をインストールする




ubuntu@linuxlab: ~
$ sudo apt-get update && sudo apt-get install -y logstash
Get:1 https://artifacts.elastic.co/packages/8.x/apt stable/main amd64 logstash amd64 1:8.19.16-1 [419 MB]
Fetched 419 MB in 42s (9.9 MB/s)
Setting up logstash (1:8.19.16-1) …
Logstash startup type is automatic

$ /usr/share/logstash/bin/logstash –version
Using bundled JDK: /usr/share/logstash/jdk
logstash 8.19.16
Ubuntu 24.04 LTS に Logstash をインストールした実測ログ(Elastic APT リポジトリ使用)
Ubuntu 24.04 LTS に Logstash をインストールした実測ログ(Elastic APT リポジトリ使用)

インストール後、設定ファイルは /etc/logstash/ に、バイナリは /usr/share/logstash/bin/ に配置されます。

注意:メモリ要件

Logstash のデフォルト JVM ヒープは -Xms1g -Xmx1g(各 1GB)です。RAM が 2GB 未満の VPS では起動できないか、非常に重くなります。本番運用なら 2〜4GB 以上の RAM を確保してください。設定は /etc/logstash/jvm.options で変更できます。

手順4:systemd でサービスを有効化する




ubuntu@linuxlab: ~
$ sudo systemctl enable logstash
Created symlink /etc/systemd/system/multi-user.target.wants/logstash.service

$ sudo systemctl start logstash
$ sudo systemctl status logstash
● logstash.service – logstash
Loaded: loaded (/lib/systemd/system/logstash.service; enabled)
Active: active (running) since Sun 2026-06-22 03:15:00 UTC; 8s ago
Main PID: 1234 (java)

パイプライン設定ファイルを /etc/logstash/conf.d/ に置いておくと、Logstash が起動時に自動で読み込みます。

パイプライン設定ファイルの基本構造

Logstash のパイプライン設定は .conf 拡張子のテキストファイルです。3つのセクションを上から書きます。

Logstash パイプラインの input→filter→output 処理フロー(概念図)
Logstash パイプラインの input→filter→output 処理フロー(概念図)



ubuntu@linuxlab: /etc/logstash/conf.d/my-pipeline.conf
# 最小構成の例
input {
stdin {} # キーボード入力(テスト時に便利)
}
filter {
# ここにフィルタプラグインを書く(複数可・上から順に実行)
}
output {
stdout {
codec => json_lines # JSON 1行ずつ出力(確認に便利)
}
}

filter セクションは複数のプラグインを書けます。上から順番に実行されます。grok でフィールドを切り出してから mutate で加工する、というパターンが典型的です。

設定ファイルを保存したら、次のコマンドで文法チェックができます。




ubuntu@linuxlab: ~
$ sudo /usr/share/logstash/bin/logstash \
-f /etc/logstash/conf.d/my-pipeline.conf \
–config.test_and_exit
Using bundled JDK: /usr/share/logstash/jdk
Configuration OK

grok フィルタ — Apache ログを JSON に展開

grok は Logstash のフィルタプラグインの中で最も使用頻度が高いものです。正規表現の名前付きパターン(Logstash に組み込まれているものだけで 120 種類以上)を組み合わせて、1 行のログをフィールドの集合に切り出します。

Apache アクセスログ用に %{COMBINEDAPACHELOG} という組み込みパターンが用意されています。実際にDockerで動かして確認しました。

Apache アクセスログを grok フィルタで ECS 形式 JSON に展開した実測出力
Apache アクセスログを grok フィルタで ECS 形式 JSON に展開した実測出力



ubuntu@linuxlab: /etc/logstash/conf.d/grok.conf
filter {
grok {
match => { “message” => “%{COMBINEDAPACHELOG}” }
tag_on_failure => [“_grokparsefailure”]
}
}

入力が次のような Apache アクセスログ 1 行の場合:




入力ログ(Apache Combined Log Format)
192.168.1.1 – frank [10/Oct/2023:13:55:36 -0700] “GET /apache_pb.gif HTTP/1.0” 200 2326 “http://example.com/” “Mozilla/4.08”

実際の出力(stdout { codec => json_lines } の結果)は次の通りです。




実測出力(ECS 形式 JSON)
{
“source”: { “address”: “192.168.1.1” },
“user”: { “name”: “frank” },
“url”: { “original”: “/apache_pb.gif” },
“http”: {
“request”: { “method”: “GET”, “referrer”: “http://example.com/” },
“version”: “1.0”,
“response”: { “status_code”: 200, “body”: { “bytes”: 2326 } }
},
“user_agent”: { “original”: “Mozilla/4.08” },
“@timestamp”: “2026-06-22T03:10:00.111Z”
}

1 行の grok パターンで、IPアドレス・ユーザー名・HTTPメソッド・ステータスコード・レスポンスバイト数・リファラ・UA が ECS(Elastic Common Schema)のネスト形式に展開されました。フィールドを1つずつ手で書く必要はありません。

正直、最初に実行したとき source.addressip ではなく source というネストになっていて戸惑いました。Logstash 8.x からは ECS 準拠の出力がデフォルトになっています。Elasticsearch に送る場合はそのまま使えますが、自前でフィールド名を決めたい場合は mutate で rename する手があります。

grok パース失敗時の挙動

ログが grok パターンにマッチしない行(フォーマット不一致のログ混入など)があった場合、tag_on_failure で指定したタグが付きます。実測で確認しました。




パース失敗時の出力(実測)
# 入力: Apache ログ形式ではない行
この行はApacheログ形式ではありません

# 出力
{
“message”: “この行はApacheログ形式ではありません”,
“tags”: [“_grokparsefailure”],
“parse_status”: “failed”,
“@timestamp”: “2026-06-22T03:10:00.112Z”
}

条件分岐と組み合わせると、マッチ失敗行を別の出力先に送ったり、別のパターンで再トライするフォールバック処理を書けます。




_grokparsefailure を条件分岐で処理する例
filter {
grok {
match => { “message” => “%{COMBINEDAPACHELOG}” }
tag_on_failure => [“_grokparsefailure”]
}
if “_grokparsefailure” in [tags] {
mutate { add_field => { “parse_status” => “failed” } }
} else {
mutate { add_field => { “parse_status” => “success” } }
}
}

json フィルタ — アプリログの JSON をフィールドに展開

近年のアプリケーションは JSON 形式でログを出力するものが増えています。Rails の lograge gem、Node.js の pino、Python の structlog などが代表例です。このような構造化ログには json フィルタが適しています。




ubuntu@linuxlab: /etc/logstash/conf.d/json.conf
filter {
json {
source => “message”
target => “parsed” # フィールドをここにネストして格納
}
}

入力が次のような JSON ログの場合:




入力(JSON 形式アプリログ)
{“level”:”ERROR”,”timestamp”:”2023-10-10T13:55:36Z”,”service”:”auth”,”message”:”Login failed”,”user”:”bob”,”attempts”:3}

実測の出力では parsed フィールド配下にキーが展開されました。




実測出力(一部)
{
“parsed”: {
“level”: “ERROR”,
“timestamp”: “2023-10-10T13:55:36Z”,
“service”: “auth”,
“message”: “Login failed”,
“user”: “bob”,
“attempts”: 3
},
“message”: “{\”level\”:\”ERROR\”,…}”, // 元の文字列が残る
“@timestamp”: “2026-06-22T03:10:17.530Z”
}

target を指定しない場合はトップレベルに展開されます。mutate { remove_field => ["message"] } を後続に書けば元の JSON 文字列フィールドを削除できます。

mutate フィルタ — フィールド名変更・条件分岐

mutate は「フィールドを加工する」ためのフィルタです。よく使う操作を列挙します。

操作 設定例 効果
rename rename => { "log_message" => "description" } フィールド名を変更
uppercase uppercase => ["level"] 文字列フィールドを大文字に変換
add_field add_field => { "env" => "production" } 新しいフィールドを追加
remove_field remove_field => ["@version", "host"] 不要なフィールドを削除
gsub gsub => ["path", "//+", "/"] 正規表現で文字列置換

mutate と条件分岐(if/else)を組み合わせると、ERROR ログだけにアラートフィールドを付けるといった処理が書けます。実際にDockerで動かした結果です。




ubuntu@linuxlab: /etc/logstash/conf.d/mutate-cond.conf(実測)
filter {
grok {
match => { “message” => “(?<level>ERROR|WARN|INFO) \[(?<app>[^\]]+)\] %{GREEDYDATA:log_message}” }
}
mutate {
uppercase => [“level”]
rename => { “log_message” => “description” }
remove_field => [“message”, “@version”]
}
if [level] == “ERROR” {
mutate {
add_field => { “alert” => “true” }
add_tag => [“requires_attention”]
}
}
}

入力に ERROR [auth-service] Failed to connect to database を渡した実測出力です。




実測出力(ERROR 行)
{
“level”: “ERROR”,
“app”: “auth-service”,
“description”: “Failed to connect to database: connection refused”,
“alert”: “true”,
“tags”: [“requires_attention”],
“@timestamp”: “2026-06-22T03:10:42.751Z”
}

INFO 行の出力では alert フィールドも requires_attention タグも現れませんでした。条件分岐が正しく動いています。

date フィルタ — タイムスタンプを UTC に正規化

複数のサーバーからログを集める場合、タイムゾーンがバラバラだと時系列順に並ばなくなります。date フィルタはログの中にあるタイムスタンプを @timestamp フィールドに読み込み、UTC で正規化します。




ubuntu@linuxlab: /etc/logstash/conf.d/date.conf
filter {
grok {
match => { “message” => “%{TIMESTAMP_ISO8601:event_time} %{LOGLEVEL:level} %{GREEDYDATA:log_msg}” }
}
date {
match => [“event_time”, “yyyy-MM-dd’T’HH:mm:ssZ”]
target => “@timestamp”
timezone => “Asia/Tokyo”
}
mutate { remove_field => [“event_time”] }
}

日本時間(JST、+0900)のタイムスタンプを含む入力を渡すと:




入力と実測出力の @timestamp 変換
# 入力(JST +0900)
2023-10-10T09:30:00+0900 INFO Server started successfully

# 実測出力の @timestamp(UTC に変換済み)
“@timestamp”: “2023-10-10T00:30:00.000Z”
# 09:30 JST = 00:30 UTC(9時間引いた値)

# 入力(JST +0900)
2023-10-10T10:00:00+0900 ERROR Disk usage exceeded 90%
# 実測出力
“@timestamp”: “2023-10-10T01:00:00.000Z”

date フィルタを入れないと @timestamp は Logstash がイベントを処理した時刻になります。ログが書かれた時刻と処理時刻が数秒〜数分ずれるため、遡及分析には date フィルタの設定が必要です。

Logstash 主要フィルタプラグイン用途比較(実測)
Logstash 主要フィルタプラグイン用途比較(実測)

Ubuntu 22.04 と 24.04 のバージョン比較

Ubuntu 22.04 vs 24.04 の Logstash パッケージバージョン比較(実測)
Ubuntu 22.04 vs 24.04 の Logstash パッケージバージョン比較(実測)

実測の結果、Ubuntu 22.04 LTS と Ubuntu 24.04 LTS の両方で Elastic 8.x APT リポジトリから同一バージョン(8.19.16)を取得できました。

Logstash はバンドル JDK(OpenJDK 17.0.11 Temurin)を同梱しているため、Ubuntu 側の Java バージョン設定に依存しません。どちらの Ubuntu バージョンを使っていても、同じ手順で同じバージョンが入ります。

注意:Logstash の apt バージョンと Docker イメージのバージョンは異なる

Elastic の APT リポジトリ最新(8.19.16)と、Docker Hub の公式タグ(8.13.4 など)は別々にリリースされます。Docker で検証する場合は docker pull docker.elastic.co/logstash/logstash:8.19.x で最新タグを確認してから使うのが安全です。

よくあるエラーと対処

①「Logstash startup type is automatic」が出るがサービスが起動しない

メモリ不足が最多原因です。journalctl -u logstash -n 50 で Java の OOM エラーが出ていたら、/etc/logstash/jvm.options-Xms1g -Xmx1g を下げます(例: -Xms512m -Xmx512m)。ただしあまり小さくすると別のエラーが出ます。

②grok パターンが合わなくて常に _grokparsefailure になる

Elastic の公式 Grok Debugger(Kibana の Dev Tools に含まれる)か、rubygems.org から gem install grok-pure で手元でテストするのが早いです。組み込みパターン名は /usr/share/logstash/vendor/bundle/jruby/*/gems/logstash-patterns-core-*/patterns/ecs-v1/ 以下に全件あります。

③起動が遅い(1分以上かかる)

Logstash は JVM の起動と初期化に時間がかかります。これは正常な動作です。起動確認は systemctl status logstashActive: active (running) を待つか、curl http://localhost:9600 が 200 を返すまで待ちます(Logstash は 9600 番ポートで API を提供します)。

④X-Pack ライセンスエラーが出力される

スタンドアロンで動かすと Unable to retrieve license information from license server というメッセージが出ます。Elasticsearch に接続していない場合は無視して構いません。/etc/logstash/logstash.yml から xpack.monitoring.elasticsearch.hosts の行をコメントアウトすれば出なくなります。

まとめ

Ubuntu 24.04 LTS に Logstash をインストールして、grok・json・mutate・date の各フィルタを実際に動かしました。

  • インストールは Elastic APT リポジトリを追加して apt install logstash だけ。Java は不要
  • grok の %{COMBINEDAPACHELOG} 1 行で Apache ログを ECS 準拠の JSON に展開できた
  • mutate と条件分岐を組み合わせると ERROR ログへのアラートタグ付けなど柔軟な処理ができる
  • date フィルタで JST→UTC の正規化を確認した。複数サーバーのログをまとめるなら必須
  • grok マッチ失敗時は _grokparsefailure タグが自動付与されるので条件分岐でハンドリングできる
  • Ubuntu 22.04 / 24.04 いずれも同一の 8.19.16 が取得可能

Logstash 単体でも動きますが、実際の運用では Elasticsearch + Kibana と組み合わせた ELK スタックとして使うことが多いです。Docker Compose で一括起動する手順は https://linuxlab.jp/ubuntu-docker-install/ も参考にしてください。

VPS でサーバー監視パイプラインを組む場合、ログの転送量や Elasticsearch のディスク容量を事前に見積もっておくことをお勧めします。

コメント

タイトルとURLをコピーしました