Elasticsearch でログなどの時系列データを扱う場合、基本的にはデータは時間とともに増え続けていくことになります。 このようなデータは 1 つのインデックスに保存し続けると肥大化してしまうため、以下のように日付ごとにインデックスを分けて保存する方法があります。
logs-20260920 logs-20260921 logs-20260922
最近の Elasticsearch では、こうした用途には Data stream を利用する方法が一般的です。Data stream では、複数の Backing index が自動的に管理され、データのローテーションやライフサイクル管理も組み合わせやすくなっています。 一方で、既存システムとの互換性や運用上の理由などから、昔ながらの「日付付きインデックス名」を使いたいケースもあります。 ところが、いざ日付付きインデックスを自分で管理しようとすると、事前に考えるべき事項や設定の手順が多く、手間取ることがあります。 ここでは、基本に立ち返って、日付付きインデックス名を使って時系列データを管理する方法を整理してみることにします。
インデックス名を指定して書き込む
日付付きインデックスを使う場合、まず考える必要があるのが「どのインデックスにデータを書き込むか」という点です。 例えば、2026 年 9 月 21 日に投入するデータは、以下の様にインデックス名に当日の日付を含むインデックスに保存するとします。
logs-20260921
この場合、データを書き込む側でインデックス名を決定し、書き込みを行う必要があります。 実現方法としては、大きく次の3つが考えられます。
- クライアント側でインデックス名を生成する
- Date index name processorを利用する
- Date mathを利用する
クライアント側でインデックス名を生成する
最も単純なのは、データを書き込むクライアント側で日付を取得し、インデックス名を生成する方法です。 例えば Logstash や Beats では、日付を利用してインデックス名を動的に生成できます。 また、スクリプトから Elasticsearch へデータを投入する場合も、同様の処理をスクリプト側に実装できます。
概念的には、以下の様な処理になります。
インデックス名生成に用いる日時を取得
↓
指定したフォーマットに基づき 2026.09.20 のような文字列を作成
↓
インデックス名 logs-2026.09.20 を生成
↓
生成したインデックス名を指定して書き込み
クライアント側で適切なインデックス名を指定して書き込みを行うため、Elasticsearch 側では特別な仕組みは必要ありません。 一方で、クライアント毎にインデックス名を生成するロジックを実装する必要があります。
本記事では詳細な説明は省略しますが、Logstash や Filebeat における設定方法については以下に記載があります。
Logstash
Elasticsearch output plugin | Logstash Plugins
Filebeat
Configure the Elasticsearch output | Beats
Date index name processor を利用する
Elasticsearchには、Date index name processor という Ingest Processor があります。 この Processor を利用することで、ドキュメントに含まれる日時フィールドをもとに、書き込み先のインデックス名を決定できます。
公式ドキュメントには以下の記述があります。
Date index name processor | Elasticsearch Reference
The processor sets the _index metadata field with a date math index name expression based on the provided index name prefix, a date or timestamp field in the documents being processed and the provided date rounding.
例えば一日ごとにインデックスを作成し、書き込むデータの @timestamp フィールドの値を元に書き込み先のインデックスを決定する場合は、まず以下のような Ingest pipeline を作成します。
PUT _ingest/pipeline/logs-daily
{
"processors": [
{
"date_index_name": {
"field": "@timestamp",
"index_name_prefix": "logs-",
"date_rounding": "d",
"index_name_format": "yyyyMMdd"
}
}
]
}
その後、データを書き込む際には以下のようにします。
PUT /logs/_doc/1?pipeline=logs-daily { "@timestamp": "2026-09-20T10:00:00.000Z" }
こうすることで、書き込み先のインデックス名は logs-20260920 下記となり、対象のインデックスにデータが書き込まれます。
このことは書き込みの実行結果から確認できます。
{
"_index": "logs-20260920",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
なお、データの書き込み時に、書き込み先のインデックス名を logs としていますが、実際の書き込み先インデックスは Ingest pipeline にて決定されます。 Ingest pipeline の作成時に指定した index_name_pipeline に合わせる必要はなく、どのようなインデックス名を指定しても Ingest pipeline にて決定されたインデックスへ書き込みが行われます。
この方法の特徴は、データに含まれる日時を基準にする ことです。
上記の例の場合、時刻を参照するフィールド名を @timestamp としているため、9 月 21 日に書き込みを行う場合でも、 @timestamp フィールドの日付が 9 月 20 日であれば、9 月 20 日のインデックスに書き込まれることになります。
ログの発生日時などを基準にインデックスを分けたい場合に適しています。
Date math を利用する
もう一つの方法は書き込むインデックス名に直接 Date math を指定するものです。
Elasticsearch API conventions | Elasticsearch Reference
Date mathを使うと、書き込もうとするインデックス名の中に日時に基づく式を記述できます。 例えば、以下のような形式を使うことで、書き込み時点の日付を利用してインデックスを指定できます。
<logs-{now/d{yyyyMMdd}}>
API 呼び出しの際には各種記号は URL エンコードする必要があるため、実際のリクエストでは以下の様にします。 以下の例では実行時の日付を元にインデックス名を決定し、書き込みを行います。
PUT /%3Clogs-%7Bnow%2Fd%7ByyyyMMdd%7D%7D%3E/_doc/1
{
"@timestamp": "2026-09-20T10:00:00.000Z"
}
この方法では、処理の流れは Date index name processor と異なり、ドキュメントに含まれるタイムスタンプではなく、データを投入する日時を基準にします。
そのため前節の例とは逆に、@timestamp フィールドの日付が 9 月 20 日であっても、9 月 21 日に書き込みを行う場合は、 9 月 21 日のインデックスに書き込まれることになります。
複数のインデックスを管理する
日付付きインデックスを作成すると、次に問題になるのが複数インデックスの管理です。 日付ごとに複数作成されたインデックスを個別に管理するのではなく、Elasticsearch の機能を組み合わせて管理します。
Aliasを使って複数インデックスをまとめる
日付付きインデックスを使うと、同じ種類のデータが複数のインデックスに分散して書き込まれます。 このため、検索を行う場合も複数のインデックスを対象として行うことになりますが、検索のたびに複数のインデックス名を指定するのは面倒です。
そこで Alias を利用します。 例えば、logs というAliasを作り、複数のインデックスを指し示すようにしておきます。
POST /_aliases
{
"actions": [
{
"add": {
"index": "logs-20260920",
"alias": "logs"
}
},
{
"add": {
"index": "logs-20260921",
"alias": "logs"
}
}
]
}
すると検索時には、以下のように Alias を指定するだけで、 複数のインデックスをまとめて検索できます。
GET logs/_search
日付付きインデックスを利用する場合、検索用のAliasを用意する ことで、利用者側に個々のインデックスの存在を意識させずに済みます。
ILMで保持期間を管理する
日付付きインデックスを使って一つのインデックスの肥大化を防いでも、時間とともにインデックス数が増えることで、全体のデータ量は増え続けていきます。 このため、個々のインデックスを作成から一定期間後に削除することで、クラスターの空きストレージ容量が枯渇することを防ぎます。
このようなライフサイクル管理には ILM(Index Lifecycle Management) を利用できます。 例えば「インデックス作成後 30 日間だけ保持する」という要件であれば、まず以下のようなポリシーを作成します。
PUT _ilm/policy/delete-after-30d
{
"policy": {
"phases": {
"hot": {
"actions": {}
},
"delete": {
"min_age": "30d",
"actions": {
"delete": {}
}
}
}
}
}
その後、このポリシーを対象のインデックスに適用することで ILM の管理対象とします。
PUT /logs-20260920/_settings
{
"index": {
"lifecycle": {
"name": "delete-after-30d"
}
}
}
このようにすることで、以下の流れを自動化することができます。
日付付きインデックスを作成 ↓ ILM によって保持期間を管理 ↓ 期限を過ぎたインデックスを削除
なお、本記事で説明するような日付付きインデックスを使う場合、ILM の説明でよく登場するロールオーバーの設定は不要です。
ロールオーバーとは、Alias や Data stream で複数のインデックスを管理する際、書き込み先が特定のインデックスとなるように設定しておき、必要に応じてこれを切り替えるというものです。 一方、書き込み先のインデックス名を書き込み日時やデータに含まれる日時に応じて決定してする場合、対象の日時に応じて書き込み先インデックスが切り替えられます。 このため、ロールオーバーにより書き込み先インデックスを切り替える必要がありません。
Index Templateを利用する
日付付きインデックスは、新しいものが次々と作成されます。 そのため、インデックスを作成するたびに Alias や ILM の設定を手動で行うのは現実的ではありません。 そこで Index Template を利用して、新しいインデックスが新しく作成された際に同じ設定を自動的に適用します。
インデックス名が logs- で始まるインデックスを対象として、前述の Alias と ILM の設定を適用する場合は以下の様なテンプレートを作成します。
PUT /_index_template/logs-template
{
"index_patterns": ["logs-*"],
"template": {
"settings": {
"index.lifecycle.name": "delete-after-30d"
},
"aliases": {
"logs": {}
}
}
}
ILM ポリシー delete-after-30d は別途作成しておく必要があります。 また、Index Template による設定は、テンプレート作成後に新規作成されたインデックスにのみ適用されます。 このため、テンプレート作成前にデータ投入が開始され、既に作成済みのインデックスがある場合は、個別に手動で設定する必要があります。
まとめ
日付付きインデックスを利用した時系列データ管理では、登場する個々の仕組みはシンプルなものです。 ですが、インデックスの作成から削除までの流れを自動化するには以下の様にそれぞれを組み合わせて用いる必要があります。
- 書き込み先のインデックス名を決定する
- Aliasで複数インデックスをまとめて検索する
- ILMで保持期間を管理する
- Index Templateで新しいインデックスの作成時に必要な設定を自動適用する
書き込み先の決定方法については、以下の 3 つの方法があります。
- クライアント側で日付付きインデックス名を生成する
- Date index name processorでドキュメントの日時を利用する
- Date mathで投入日時を利用する
ポイントとなるのは、「何の日付を基準にインデックスを分けるのか」 という点です。 ログの発生日時を基準にするのであればDate index name processor、データを Elasticsearch へ投入した日時を基準にするのであれば Date math、というように使い分けられます。 Logstash や Filebeat などクライアント側で書き込み先インデックス名を生成する場合は、どの日時を基準とするかを選択できます。
| 方法 | 基準となる日時 |
|---|---|
| クライアント側で生成 | クライアント側で決定 |
| Date index name processor | ドキュメント内の日時 |
| Date math | データ投入時の日時 |
現在広く利用されている Data stream は、こうしたことを内部で自動的に行うことで簡略化するもの、ととらえることもできます。 一見すると古い方法に見える「日付付きインデックス」ですが、個々の仕組みを知ることで、Elasticsearch のインデックス管理をより深く理解することにもつながると思われます。。
