零からの

ゆるーく綴るブログ

VPC内のElasticsearch(Kibana)を参照する

ほぼ自分メモ。

AWSでElasticsearchを構築している場合、Kibanaも一緒に構築されるため分析用に利用することができる。

ただし、VPC内に構築している場合のアクセスについてどのようにしていくかが悩みどころでした。

最初はNginxでリバプロさせることを考えたが複数環境の場合にそれぞれ構築するのもなぁと思っていたところ、EC2でWindows Serverを構築するのが簡単そうだったので試すことにした。

やりたかったことは Amazon Web Services ブログ の通り。

EC2の構築については こちら が参考になりました。

AWSの構成はTerraformで簡単につくってみて、参照できるところまで確認。

github.com

意外に簡単にできたのでよかった。

ただ、セキュリティグループの設定だけはハマりがちでした。

Fluentdのtime_slice_formatの挙動確認

file outputのオプションについて、time_slice_formatがよくわからなかったので挙動を確認してみた。

file - Fluentd

デフォルトだと%Y%m%dだが、挙動確認のため意図的に%Y%m%d%H%Mに変更する。

※なお、%Y%m%d%H%M%Sまで指定可能

確認環境

構成

.
├── docker
│   └── fluentd
│       ├── Dockerfile
│       └── etc
│           └── fluent.conf
└── docker-compose.yml

設定ファイル

docker/fluentd/etc/fluent.conf

<source>
  @type  forward
  @id    input1
  @label @mainstream
  port  24224
</source>

<filter **>
  @type stdout
</filter>

<label @mainstream>
  <match nginx>
    @type             file
    @id               output_nginx
    path              /fluentd/log/nginx.*.log
    symlink_path      /fluentd/log/nginx.log
    append            true
    time_slice_format %Y%m%d%H%M # ココ!!
    time_slice_wait   1m
    time_format       %Y%m%dT%H%M%S%z
  </match>
  <match **>
    @type             file
    @id               output_other
    path              /fluentd/log/data.*.log
    symlink_path      /fluentd/log/data.log
    append            true
    time_slice_format %Y%m%d
    time_slice_wait   10m
    time_format       %Y%m%dT%H%M%S%z
  </match>
</label>

Dockerfile

docker/fluentd/Dockerfile

FROM fluent/fluentd:v1.11.2-1.0
COPY docker/fluentd/etc/fluent.conf /fluentd/etc/fluent.conf

docker-compose.yml

version: '3'
services:
  nginx:
    image: nginx:latest
    environment:
      - TZ=Asia/Tokyo
    ports:
      - '8080:80'
    links:
      - fluentd
    logging:
      driver: fluentd
      options:
        fluentd-address: localhost:24224
        tag: nginx
  fluentd:
    build:
      context: .
      dockerfile: docker/fluentd/Dockerfile
    environment:
      - TZ=Asia/Tokyo
    ports:
      - '24224:24224'
      - '24224:24224/udp'

確認結果

1分でバッファファイルからフォーマット通りのファイルに変更されることを確認

# time_slice_formatの指定時間内はバッファファイル
/fluentd/log $ ls -lha
total 20
drwxr-xr-x    1 fluent   fluent      4.0K Aug  8 05:11 .
drwxr-xr-x    1 fluent   fluent      4.0K Aug  5 22:19 ..
-rw-r--r--    1 fluent   nogroup      401 Aug  8 05:11 nginx.b5ac56c0fae21db227b1f693e482e1e51.log
-rw-r--r--    1 fluent   nogroup       79 Aug  8 05:11 nginx.b5ac56c0fae21db227b1f693e482e1e51.log.meta
lrwxrwxrwx    1 fluent   nogroup       56 Aug  8 05:11 nginx.log -> /fluentd/log/nginx.b5ac56c0fae21db227b1f693e482e1e51.log

# time_slice_formatの指定時間経過後はフォーマット通りのファイル名に更新される
/fluentd/log $ ls -lha
total 16
drwxr-xr-x    1 fluent   fluent      4.0K Aug  8 05:13 .
drwxr-xr-x    1 fluent   fluent      4.0K Aug  5 22:19 ..
-rw-r--r--    1 fluent   nogroup      401 Aug  8 05:13 nginx.202008080511.log
lrwxrwxrwx    1 fluent   nogroup       56 Aug  8 05:11 nginx.log -> /fluentd/log/nginx.b5ac56c0fae21db227b1f693e482e1e51.log

今回は極端な例なので分単位にしたが、デフォルト通り1時間単位で良さそう。

Getting Started with Next.js

Elasticsearchと絡めて何か作れないかと思ったのと、最新のJavascript Frameworkについていけてないのでお試して調べて見たメモ。

環境

例によってDocker Composeで。

version: '3'
services:
  node:
    image: node:14.6.0-buster
    environment:
      - TZ=Asia/Tokyo

Dockerを起動する。今回はお試しなのでRunコマンドで。

docker-compose run --rm -p 3000:3000 node bash

セットアップ

こちらに沿って行う。

yarn create next-app

...
? What is your project named? › my-app # なんでもOK。今回はそのままmy-app

# 少し時間が経過して以下のように出力されればOK
...
Success! Created my-app at /my-app
Inside that directory, you can run several commands:

  yarn dev
    Starts the development server.

  yarn build
    Builds the app for production.

  yarn start
    Runs the built app in production mode.

We suggest that you begin by typing:

  cd my-app
  yarn dev

Done in 47.25s.

とりあえず、開発中はyarn devで良さそう。

my-appは以下の構成になっている。

.
|-- README.md
|-- node_modules
|-- package.json
|-- pages
|-- public
|-- styles
`-- yarn.lock

この中でpagesがルーティングに関連しているらしい。

pages配下はこのような感じ。

./pages/
|-- _app.js
|-- api
|   `-- hello.js
`-- index.js

起動してみる。

yarn dev

起動後、 http://localhost:3000 にアクセスすると以下のような画面が表示される。

f:id:kzp:20200730231955p:plain

また、pagesの階層にある通り http://localhost:3000/api/hello にアクセスした場合は以下のようになる。

f:id:kzp:20200730232015p:plain

最後に

ReactやNext.jsというキーワードは聞いたことがあったが、触れてみたことがなかったので軽く触ってみた。

ただのhello world的なやつなのでこれから少しずつ調べてみることにする。

Elasticsearch等と掛け合わせて何かできるのが理想。

DockerログをFluentdに流す

Fluentd ロギング・ドライバを使ってDockerのアプリログをFluentdに流せるので試してみた。

今回はnginxのログを収集する。

環境

fluent.confは以下のようにする。

<source>
  @type forward
</source>

<match docker.**>
  @type stdout
</match>

docker-compose.ymlは以下のようにする。

Dockerfileは前回のエントリーと同じであるため省略。

version: '3'
services:
  fluentd:
    build:
      context: .
      dockerfile: docker/fluentd/Dockerfile
    environment:
      - TZ=Asia/Tokyo
    ports:
      - 24224:24224
    volumes:
      - ./docker/fluentd/etc:/fluentd/etc

確認

Fluentdを起動する。

stdoutにしているためバックグラウンド起動としていない。

docker-compose up

次にnginxもDockerで起動する。

ターミナルはFluentdとは別で起動する。

docker run -it -p 8080:80 \
       --log-driver=fluentd \
       --log-opt fluentd-address=localhost:24224 \
       --log-opt tag=docker.{{.Name}} \
       nginx:latest

起動したら、http://localhost:8080 にアクセスする。

さきほど起動したFluentd側のログが以下のようになれば、nginxのログが流れていることが確認できる。

fluentd_1  | 2020-07-26 05:52:31.000000000 +0000 docker.loving_lamarr: {"log":"/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration\r","container_id":"19df98bb6889da6762b0643e9c827904334500da6b1cc6fc02627189cf0cf775","container_name":"/loving_lamarr","source":"stdout"}
fluentd_1  | 2020-07-26 05:52:31.000000000 +0000 docker.loving_lamarr: {"container_id":"19df98bb6889da6762b0643e9c827904334500da6b1cc6fc02627189cf0cf775","container_name":"/loving_lamarr","source":"stdout","log":"/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/\r"}
fluentd_1  | 2020-07-26 05:52:31.000000000 +0000 docker.loving_lamarr: {"container_id":"19df98bb6889da6762b0643e9c827904334500da6b1cc6fc02627189cf0cf775","container_name":"/loving_lamarr","source":"stdout","log":"/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh\r"}
fluentd_1  | 2020-07-26 05:52:31.000000000 +0000 docker.loving_lamarr: {"container_id":"19df98bb6889da6762b0643e9c827904334500da6b1cc6fc02627189cf0cf775","container_name":"/loving_lamarr","source":"stdout","log":"10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf\r"}
fluentd_1  | 2020-07-26 05:52:31.000000000 +0000 docker.loving_lamarr: {"source":"stdout","log":"10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf\r","container_id":"19df98bb6889da6762b0643e9c827904334500da6b1cc6fc02627189cf0cf775","container_name":"/loving_lamarr"}
fluentd_1  | 2020-07-26 05:52:31.000000000 +0000 docker.loving_lamarr: {"container_id":"19df98bb6889da6762b0643e9c827904334500da6b1cc6fc02627189cf0cf775","container_name":"/loving_lamarr","source":"stdout","log":"/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh\r"}
fluentd_1  | 2020-07-26 05:52:31.000000000 +0000 docker.loving_lamarr: {"container_id":"19df98bb6889da6762b0643e9c827904334500da6b1cc6fc02627189cf0cf775","container_name":"/loving_lamarr","source":"stdout","log":"/docker-entrypoint.sh: Configuration complete; ready for start up\r"}
fluentd_1  | 2020-07-26 05:53:24.000000000 +0000 docker.loving_lamarr: {"container_name":"/loving_lamarr","source":"stdout","log":"172.17.0.1 - - [26/Jul/2020:05:53:24 +0000] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36\" \"-\"\r","container_id":"19df98bb6889da6762b0643e9c827904334500da6b1cc6fc02627189cf0cf775"}
fluentd_1  | 2020-07-26 05:53:27.000000000 +0000 docker.loving_lamarr: {"log":"172.17.0.1 - - [26/Jul/2020:05:53:27 +0000] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36\" \"-\"\r","container_id":"19df98bb6889da6762b0643e9c827904334500da6b1cc6fc02627189cf0cf775","container_name":"/loving_lamarr","source":"stdout"}
fluentd_1  | 2020-07-26 05:53:28.000000000 +0000 docker.loving_lamarr: {"source":"stdout","log":"172.17.0.1 - - [26/Jul/2020:05:53:28 +0000] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36\" \"-\"\r","container_id":"19df98bb6889da6762b0643e9c827904334500da6b1cc6fc02627189cf0cf775","container_name":"/loving_lamarr"}
fluentd_1  | 2020-07-26 05:53:29.000000000 +0000 docker.loving_lamarr: {"log":"172.17.0.1 - - [26/Jul/2020:05:53:29 +0000] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36\" \"-\"\r","container_id":"19df98bb6889da6762b0643e9c827904334500da6b1cc6fc02627189cf0cf775","container_name":"/loving_lamarr","source":"stdout"}
fluentd_1  | 2020-07-26 05:53:30.000000000 +0000 docker.loving_lamarr: {"log":"172.17.0.1 - - [26/Jul/2020:05:53:30 +0000] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36\" \"-\"\r","container_id":"19df98bb6889da6762b0643e9c827904334500da6b1cc6fc02627189cf0cf775","container_name":"/loving_lamarr","source":"stdout"}

最後に

Fluentdのportを公開することでnginxからFluentdへログを転送することが確認できた。

ただ、今回の設定だといろいろなログが混ざっているので、S3へのログアーカイブなどを行うにはfilterなどひと手間加える必要がありそう。

設定周りも今後調査していく。

FluentdからElasticsearchへ転送する

前回のエントリーで標準出力できるところまで確認したので、同じ内容をElasticsearchに登録できるようにしてみた。

環境

Fluentdだけでなく、ElasticsearchやKibanaのコンテナを登録する。

.
├── docker
│   └── fluentd
│       ├── Dockerfile
│       └── etc
│           └── fluent.conf
└── docker-compose.yml

docker/fluentd/Dockerfile

ほぼDocker公式通り。(3. Customize Dockerfile to install plugins (optional))

FROM fluent/fluentd:v1.11-1

# Use root account to use apk
USER root

# below RUN includes plugin as examples elasticsearch is not required
# you may customize including plugins as you wish
RUN apk add --no-cache --update --virtual .build-deps \
        sudo build-base ruby-dev \
 && sudo gem install fluent-plugin-elasticsearch \
 && sudo gem sources --clear-all \
 && apk del .build-deps \
 && rm -rf /tmp/* /var/tmp/* /usr/lib/ruby/gems/*/cache/*.gem

COPY docker/fluentd/etc/fluent.conf /fluentd/etc/

USER fluent

docker/fluentd/etc/fluent.conf

elasticsearchプラグインを参照。

logstash_formatをtrueにした場合は、logstash-YYYY.MM.DDとなるがlogstash_prefixで任意の値も設定可能。(ここではhelloとした)

<source>
  @type dummy
  dummy {"hello":"world"}
  tag hello_world
</source>

<match **>
  @type elasticsearch
  host elasticsearch
  port 9200
  logstash_format true
  logstash_prefix hello
</match>

docker-compose.yml

version: '3'
services:
  fluentd:
    build:
      context: .
      dockerfile: docker/fluentd/Dockerfile
    environment:
      - TZ=Asia/Tokyo
    volumes:
      - ./docker/fluentd/etc:/fluentd/etc
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.8.0
    environment:
      - TZ=Asia/Tokyo
      - discovery.type=single-node
    ports:
      - 9200:9200
  kibana:
    image: docker.elastic.co/kibana/kibana:7.8.0
    environment:
      - TZ=Asia/Tokyo
    ports:
      - 5601:5601

実行

Dockerを起動させてみる。

[warn]: #0 Could not communicate to Elasticsearch, resetting connection and trying again. Connection refused - connect(2) for 172.18.0.2:9200 (Errno::ECONNREFUSED)のようなログが出力された場合はESへの転送に失敗している。

docker-compose up -d

確認

Kibanaで確認する。

http://localhost:5601にアクセスする。

Discover > Create index pattern > Index patternにhelloと入力する。

以下の画像のように「hello-YYYY.MM.DD」と表示されていればOK。 Time Filter field nameは@timestampを選択して、インデックスを作成する。

f:id:kzp:20200724234932p:plain
Create Index Pattern

データも登録・表示することが確認できる。

f:id:kzp:20200724235013p:plain
Discover

最後に

ESへの登録、Kibanaでの表示まで確認することができた。

次はアプリログを取り込むことを確認していく。

Fluentd on Dockerの構築

ログ収集を行うためにfluentdを使用するが、その前提となる環境構築メモ。

環境構築

公式を参考に進める。

.
├── docker-compose.yml
└── fluentd
    └── etc
        └── fluent.conf

docker-compose.yml

version: '3'
services:
  fluentd:
    image: fluent/fluentd:v1.11-1
    volumes:
      - ./fluentd/etc:/fluentd/etc

fluent.confは、とりあえずHello worldをやってみるため、こちらを参考に設定する。

<source>
  @type dummy
  dummy {"hello":"world"}
</source>

実行

Dockerを起動させてみる。

docker-compose up

fluentd_1  | 2020-07-24 13:02:19 +0000 [info]: parsing config file is succeeded path="/fluentd/etc/fluent.conf"
fluentd_1  | 2020-07-24 13:02:19 +0000 [info]: gem 'fluentd' version '1.11.1'
fluentd_1  | 2020-07-24 13:02:19 +0000 [error]: config error in:
fluentd_1  | <source>
fluentd_1  |   @type dummy
fluentd_1  |   dummy {"hello":"world"}
fluentd_1  | </source>
fluentd_1  |
fluentd_1  | 2020-07-24 13:02:19 +0000 [error]: config error file="/fluentd/etc/fluent.conf" error_class=Fluent::ConfigError error="'tag' parameter is required"
fluentd_fluentd_1 exited with code 1

エラーになった…

再実行

エラーメッセージを見るとtagが必須とのこと。

fluent.confを次のように修正した。

<source>
  @type dummy
  dummy {"hello":"world"}
  tag hello_world
</source>

修正後、Dockerを起動する。

docker-compose up

fluentd_1  | 2020-07-24 13:04:10 +0000 [info]: parsing config file is succeeded path="/fluentd/etc/fluent.conf"
fluentd_1  | 2020-07-24 13:04:10 +0000 [info]: gem 'fluentd' version '1.11.1'
fluentd_1  | 2020-07-24 13:04:10 +0000 [warn]: both of Plugin @id and path for <storage> are not specified. Using on-memory store.
fluentd_1  | 2020-07-24 13:04:10 +0000 [warn]: both of Plugin @id and path for <storage> are not specified. Using on-memory store.
fluentd_1  | 2020-07-24 13:04:10 +0000 [info]: using configuration file: <ROOT>
fluentd_1  |   <source>
fluentd_1  |     @type dummy
fluentd_1  |     dummy {"hello":"world"}
fluentd_1  |     tag "hello_world"
fluentd_1  |   </source>
fluentd_1  | </ROOT>
fluentd_1  | 2020-07-24 13:04:10 +0000 [info]: starting fluentd-1.11.1 pid=6 ruby="2.5.8"
fluentd_1  | 2020-07-24 13:04:10 +0000 [info]: spawn command to main:  cmdline=["/usr/bin/ruby", "-Eascii-8bit:ascii-8bit", "/usr/bin/fluentd", "-c", "/fluentd/etc/fluent.conf", "-p", "/fluentd/plugins", "--under-supervisor"]
fluentd_1  | 2020-07-24 13:04:10 +0000 [info]: adding source type="dummy"
fluentd_1  | 2020-07-24 13:04:10 +0000 [warn]: #0 both of Plugin @id and path for <storage> are not specified. Using on-memory store.
fluentd_1  | 2020-07-24 13:04:10 +0000 [warn]: #0 both of Plugin @id and path for <storage> are not specified. Using on-memory store.
fluentd_1  | 2020-07-24 13:04:10 +0000 [info]: #0 starting fluentd worker pid=20 ppid=6 worker=0
fluentd_1  | 2020-07-24 13:04:10 +0000 [info]: #0 fluentd worker is now running worker=0
fluentd_1  | 2020-07-24 13:04:11 +0000 [warn]: #0 no patterns matched tag="hello_world"
fluentd_1  | 2020-07-24 13:04:12 +0000 [warn]: #0 no patterns matched tag="hello_world"
fluentd_1  | 2020-07-24 13:04:14 +0000 [warn]: #0 no patterns matched tag="hello_world"
fluentd_1  | 2020-07-24 13:04:18 +0000 [warn]: #0 no patterns matched tag="hello_world"

エラーはなくなったが[warn]: #0 no patterns matched tag="hello_world"と表示される。

これは、インプットに対してのアウトプットが存在しないことが原因の模様。

そこで、fluent.confを次のように修正する。

<source>
  @type dummy
  dummy {"hello":"world"}
  tag hello_world
</source>

<match hello_world.**>
  @type stdout
</match>

修正後、Dockerを起動する。

docker-compose up

fluentd_1  | 2020-07-24 13:07:38 +0000 [info]: parsing config file is succeeded path="/fluentd/etc/fluent.conf"
fluentd_1  | 2020-07-24 13:07:39 +0000 [info]: gem 'fluentd' version '1.11.1'
fluentd_1  | 2020-07-24 13:07:39 +0000 [warn]: both of Plugin @id and path for <storage> are not specified. Using on-memory store.
fluentd_1  | 2020-07-24 13:07:39 +0000 [warn]: both of Plugin @id and path for <storage> are not specified. Using on-memory store.
fluentd_1  | 2020-07-24 13:07:39 +0000 [info]: using configuration file: <ROOT>
fluentd_1  |   <source>
fluentd_1  |     @type dummy
fluentd_1  |     dummy {"hello":"world"}
fluentd_1  |     tag "hello_world"
fluentd_1  |   </source>
fluentd_1  |   <match hello_world.**>
fluentd_1  |     type stdout
fluentd_1  |   </match>
fluentd_1  | </ROOT>
fluentd_1  | 2020-07-24 13:07:39 +0000 [info]: starting fluentd-1.11.1 pid=6 ruby="2.5.8"
fluentd_1  | 2020-07-24 13:07:39 +0000 [info]: spawn command to main:  cmdline=["/usr/bin/ruby", "-Eascii-8bit:ascii-8bit", "/usr/bin/fluentd", "-c", "/fluentd/etc/fluent.conf", "-p", "/fluentd/plugins", "--under-supervisor"]
fluentd_1  | 2020-07-24 13:07:39 +0000 [warn]: #0 'type' is deprecated parameter name. use '@type' instead.
fluentd_1  | 2020-07-24 13:07:39 +0000 [info]: adding match pattern="hello_world.**" type="stdout"
fluentd_1  | 2020-07-24 13:07:39 +0000 [info]: adding source type="dummy"
fluentd_1  | 2020-07-24 13:07:39 +0000 [warn]: #0 both of Plugin @id and path for <storage> are not specified. Using on-memory store.
fluentd_1  | 2020-07-24 13:07:39 +0000 [warn]: #0 both of Plugin @id and path for <storage> are not specified. Using on-memory store.
fluentd_1  | 2020-07-24 13:07:39 +0000 [info]: #0 starting fluentd worker pid=20 ppid=6 worker=0
fluentd_1  | 2020-07-24 13:07:39 +0000 [info]: #0 fluentd worker is now running worker=0
fluentd_1  | 2020-07-24 13:07:40.084009100 +0000 hello_world: {"hello":"world"}
fluentd_1  | 2020-07-24 13:07:41.001777200 +0000 hello_world: {"hello":"world"}
fluentd_1  | 2020-07-24 13:07:42.021463500 +0000 hello_world: {"hello":"world"}
fluentd_1  | 2020-07-24 13:07:43.037985700 +0000 hello_world: {"hello":"world"}

期待した内容が出力されるようになった。

最後に

fluentdがなんとなく動くことが確認できた。

最終的にはログをElasticsearchやS3に置いていきたいので引き続き調査を進める。

Elasticsearchにkuromojiを導入する

kuromojiを導入することで日本語の分析が可能になるので試してみる。

環境

Dockerの設定を以下のように変更した。

構成

.
├── docker
│   └── elasticsearch
│       └── Dockerfile
└── docker-compose.yml

Dockerfile

FROM docker.elastic.co/elasticsearch/elasticsearch:7.8.0

RUN /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-kuromoji

docker-compose.yml

version: '3'
services:
  elasticsearch:
    build:
      context: .
      dockerfile: docker/elasticsearch/Dockerfile
    container_name: elasticsearch
    environment:
      - TZ=Asia/Tokyo
      - discovery.type=single-node
    ports:
      - 9200:9200

インデックス作成

以下のように作成する。

curl -H "Content-Type: application/json" -XPUT "http://localhost:9200/kuromoji_index?pretty" -d '
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_kuromoji_analyzer": {
          "type": "custom",
          "tokenizer": "kuromoji_tokenizer"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "sample_text": {
        "type": "text",
        "analyzer": "my_kuromoji_analyzer",
        "fielddata": true,
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        }
      }
    }
  }
}
'

設定できたことを確認する。

curl -XGET "http://localhost:9200/kuromoji_index?pretty"

{
  "kuromoji_index" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "sample_text" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword"
            }
          },
          "analyzer" : "my_kuromoji_analyzer",
          "fielddata" : true
        }
      }
    },
    "settings" : {
      "index" : {
        "number_of_shards" : "1",
        "provided_name" : "kuromoji_index",
        "creation_date" : "1596157759579",
        "analysis" : {
          "analyzer" : {
            "my_kuromoji_analyzer" : {
              "type" : "custom",
              "tokenizer" : "kuromoji_tokenizer"
            }
          }
        },
        "number_of_replicas" : "1",
        "uuid" : "RRaSWI1ES7SnxGtEkPJe4Q",
        "version" : {
          "created" : "7080099"
        }
      }
    }
  }
}

確認

データ投入

curl -H "Content-Type: application/json" -XPOST "http://localhost:9200/kuromoji_index/_doc?pretty" -d '{ "sample_text": "今日の晩ごはんはカレー" }'

クエリ実行

curl -H "Content-Type: application/json" -XGET "http://localhost:9200/kuromoji_index/_search?pretty" -d '
{
  "query": { "match": { "sample_text": "今日" } }
}'

{
  "took" : 148,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "kuromoji_index",
        "_type" : "_doc",
        "_id" : "nWvye3MBck8r_7svDEjq",
        "_score" : 0.2876821,
        "_source" : {
          "sample_text" : "今日の晩ごはんはカレー"
        }
      }
    ]
  }
}

ヒットする。

ちなみに「今」だと

curl -H "Content-Type: application/json" -XGET "http://localhost:9200/kuromoji_index/_search?pretty" -d '
{
  "query": { "match": { "sample_text": "今" } }
}'

{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

ヒットしない。

最後に

kuromojiの設定から使用までをざっと確認した。

kuromojiの詳細についてはまだ理解できていないが、こちらが参考になりそう。