在 Kibana 的 console 中,我们可以使用一些命令对 Elasticsearch 进行交互。那么我们是否可以扩展我们需要的一些命令呢?比如:

在上面,我们打入 GET _cat/example,它将显示右边的输出。这个是我们扩展的一个命令。
Elasticsearch 带有一组可以执行各种任务的功能。 但是,如果你想实现自己的任何功能,则需要在 Elasticsearch 的主代码库中实现。 为了保护你免受所有这些额外步骤的影响,Elasticsearch 提供了在 Elasticsearch 代码中添加插件的选项,该插件能够实现你的功能。
在今天的展示中,我将使用最新的 Elastic Stack 8.4.0 来进行展示。
如果你还没有安装好自己的 Elastic Stack,请参考如下的文章来安装 Elasticsearch 及 Kibana:
在我之前的文章
我已经展示了如何为 ingest pipeline 创建 processors。在上面的第二篇文章中,我使用了一个叫做 elasticsearch-plugin-archtype 的插件。我们可以使用如下的命令来创建一个最为基本的插件模板:
- mvn archetype:generate \
- -DarchetypeGroupId=org.codelibs \
- -DarchetypeArtifactId=elasticsearch-plugin-archetype \
- -DarchetypeVersion=6.6.0 \
- -DgroupId=com.liuxg \
- -DartifactId=elasticsearch-plugin \
- -Dversion=1.0-SNAPSHOT \
- -DpluginName=rest_handler

上面已经帮我们创建了一个最为基本的插件模板。它在当前的目录下创建了一个叫做 elasticsearch-plugin 的目录。我们首先进入到该目录中:
- $ pwd
- /Users/liuxg/java/plugins/elasticsearch-plugin
- $ tree -L 8
- .
- ├── pom.xml
- └── src
- └── main
- ├── assemblies
- │ └── plugin.xml
- ├── java
- │ └── com
- │ └── liuxg
- │ ├── rest
- │ │ └── Restrest_handlerAction.java
- │ └── rest_handlerPlugin.java
- └── plugin-metadata
- └── plugin-descriptor.properties
上面是它的文件结构。因为我们想为 Elastic Stack 8.4.0 构建插件,所以,我们必须在 pom.xml 中修改相应的版本信息:
pom.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <name>elasticsearch-plugin</name>
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.liuxg</groupId>
- <artifactId>elasticsearch-plugin</artifactId>
- <version>1.0-SNAPSHOT</version>
- <packaging>jar</packaging>
- <description>elasticsearch rest_handler plugin</description>
- <inceptionYear>2019</inceptionYear>
- <licenses>
- <license>
- <name>The Apache Software License, Version 2.0</name>
- <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
- <distribution>repo</distribution>
- </license>
- </licenses>
- <properties>
- <elasticsearch.version>8.4.0</elasticsearch.version>
- <elasticsearch.plugin.classname>com.liuxg.rest_handlerPlugin</elasticsearch.plugin.classname>
- <log4j.version>2.11.1</log4j.version>
- <maven.compiler.source>1.8</maven.compiler.source>
- <maven.compiler.target>1.8</maven.compiler.target>
- </properties>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.8.0</version>
- <configuration>
- <source>${maven.compiler.source}</source>
- <target>${maven.compiler.target}</target>
- <encoding>UTF-8</encoding>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.22.1</version>
- <configuration>
- <includes>
- <include>**/*Tests.java</include>
- </includes>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-source-plugin</artifactId>
- <version>3.0.1</version>
- <executions>
- <execution>
- <id>attach-sources</id>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-assembly-plugin</artifactId>
- <version>3.1.0</version>
- <configuration>
- <appendAssemblyId>false</appendAssemblyId>
- <outputDirectory>${project.build.directory}/releases/</outputDirectory>
- <descriptors>
- <descriptor>${basedir}/src/main/assemblies/plugin.xml</descriptor>
- </descriptors>
- </configuration>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- <dependencies>
- <dependency>
- <groupId>org.elasticsearch</groupId>
- <artifactId>elasticsearch</artifactId>
- <version>${elasticsearch.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-api</artifactId>
- <version>${log4j.version}</version>
- <scope>provided</scope>
- </dependency>
- </dependencies>
- </project>
在上面,我们把 elasticsearch.version 设置为 8.4.0。其它的保持不变。
接下来,我们来修改 rest_handlerPlugin.java 文件:
rest_handlerPlugin.java
- package com.liuxg;
-
- import java.util.List;
- import java.util.function.Supplier;
-
- import com.liuxg.rest.Restrest_handlerAction;
- import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
- import org.elasticsearch.cluster.node.DiscoveryNodes;
- import org.elasticsearch.common.settings.ClusterSettings;
- import org.elasticsearch.common.settings.IndexScopedSettings;
- import org.elasticsearch.common.settings.Settings;
- import org.elasticsearch.common.settings.SettingsFilter;
- import org.elasticsearch.plugins.ActionPlugin;
- import org.elasticsearch.plugins.Plugin;
- import org.elasticsearch.rest.RestController;
- import org.elasticsearch.rest.RestHandler;
-
- import static java.util.Collections.singletonList;
-
- public class rest_handlerPlugin extends Plugin implements ActionPlugin {
- @Override
- public List<RestHandler> getRestHandlers(final Settings settings,
- final RestController restController,
- final ClusterSettings clusterSettings,
- final IndexScopedSettings indexScopedSettings,
- final SettingsFilter settingsFilter,
- final IndexNameExpressionResolver indexNameExpressionResolver,
- final Supplier<DiscoveryNodes> nodesInCluster) {
- return singletonList(new Restrest_handlerAction());
- }
- }
这个文件会让 Elasticsearch 知道你的插件。
我们接下来修改 Restrest_handlerAction.java 文件如下:
Restrest_handlerAction.java
- package com.liuxg.rest;
-
- import org.elasticsearch.client.internal.node.NodeClient;
- import org.elasticsearch.common.Table;
- import org.elasticsearch.rest.RestRequest;
- import org.elasticsearch.rest.RestResponse;
- import org.elasticsearch.rest.action.cat.AbstractCatAction;
- import org.elasticsearch.rest.action.cat.RestTable;
-
- import java.util.List;
-
- import static org.elasticsearch.rest.RestRequest.Method.GET;
- import static org.elasticsearch.rest.RestRequest.Method.POST;
-
-
- public class Restrest_handlerAction extends AbstractCatAction {
- @Override
- public List
routes() { - return List.of(
- new Route(GET, "/_cat/example"),
- new Route(POST, "/_cat/example"));
- }
-
- @Override
- public String getName() {
- return "rest_handler_cat_example";
- }
-
- @Override
- protected RestChannelConsumer doCatRequest(final RestRequest request, final NodeClient client) {
- final String message = request.param("message", "Hello from Cat Example action");
-
- Table table = getTableWithHeader(request);
- table.startRow();
- table.addCell(message);
- table.endRow();
- return channel -> {
- try {
- channel.sendResponse(RestTable.buildResponse(table, channel));
- } catch (final Exception e) {
- channel.sendResponse(new RestResponse(channel, e));
- }
- };
- }
-
- @Override
- protected void documentation(StringBuilder sb) {
- sb.append(documentation());
- }
-
- public static String documentation() {
- return "/_cat/example\n";
- }
-
- @Override
- protected Table getTableWithHeader(RestRequest request) {
- final Table table = new Table();
- table.startHeaders();
- table.addCell("test", "desc:test");
- table.endHeaders();
- return table;
- }
- }
该文件将定义插件的路由和处理这些路由的代码。
这样我们就修改完了我们的代码。
我们在项目的根目录下使人如下的命令来进行编译:
mvn clean install
- $ mvn clean install
- [INFO] Scanning for projects...
- [INFO]
- [INFO] -------------------< com.liuxg:elasticsearch-plugin >-------------------
- [INFO] Building elasticsearch-plugin 1.0-SNAPSHOT
- [INFO] --------------------------------[ jar ]---------------------------------
- [INFO]
- [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ elasticsearch-plugin ---
- [INFO]
- [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ elasticsearch-plugin ---
- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
- [INFO] skip non existing resourceDirectory /Users/liuxg/java/plugins/elasticsearch-plugin/src/main/resources
- [INFO]
- [INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ elasticsearch-plugin ---
- [INFO] Changes detected - recompiling the module!
- [INFO] Compiling 2 source files to /Users/liuxg/java/plugins/elasticsearch-plugin/target/classes
- [INFO]
- [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ elasticsearch-plugin ---
- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
- [INFO] skip non existing resourceDirectory /Users/liuxg/java/plugins/elasticsearch-plugin/src/test/resources
- [INFO]
- [INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ elasticsearch-plugin ---
- [INFO] No sources to compile
- [INFO]
- [INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ elasticsearch-plugin ---
- [INFO] No tests to run.
- [INFO]
- [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ elasticsearch-plugin ---
- [INFO] Building jar: /Users/liuxg/java/plugins/elasticsearch-plugin/target/elasticsearch-plugin-1.0-SNAPSHOT.jar
- [INFO]
- [INFO] >>> maven-source-plugin:3.0.1:jar (attach-sources) > generate-sources @ elasticsearch-plugin >>>
- [INFO]
- [INFO] <<< maven-source-plugin:3.0.1:jar (attach-sources) < generate-sources @ elasticsearch-plugin <<<
- [INFO]
- [INFO]
- [INFO] --- maven-source-plugin:3.0.1:jar (attach-sources) @ elasticsearch-plugin ---
- [INFO] Building jar: /Users/liuxg/java/plugins/elasticsearch-plugin/target/elasticsearch-plugin-1.0-SNAPSHOT-sources.jar
- [INFO]
- [INFO] --- maven-assembly-plugin:3.1.0:single (default) @ elasticsearch-plugin ---
- [INFO] Reading assembly descriptor: /Users/liuxg/java/plugins/elasticsearch-plugin/src/main/assemblies/plugin.xml
- [WARNING] The following patterns were never triggered in this artifact exclusion filter:
- o 'org.elasticsearch:elasticsearch'
-
- [INFO] Building zip: /Users/liuxg/java/plugins/elasticsearch-plugin/target/releases/elasticsearch-plugin-1.0-SNAPSHOT.zip
- [INFO]
- [INFO] --- maven-install-plugin:2.4:install (default-install) @ elasticsearch-plugin ---
- [INFO] Installing /Users/liuxg/java/plugins/elasticsearch-plugin/target/elasticsearch-plugin-1.0-SNAPSHOT.jar to /Users/liuxg/.m2/repository/com/liuxg/elasticsearch-plugin/1.0-SNAPSHOT/elasticsearch-plugin-1.0-SNAPSHOT.jar
- [INFO] Installing /Users/liuxg/java/plugins/elasticsearch-plugin/pom.xml to /Users/liuxg/.m2/repository/com/liuxg/elasticsearch-plugin/1.0-SNAPSHOT/elasticsearch-plugin-1.0-SNAPSHOT.pom
- [INFO] Installing /Users/liuxg/java/plugins/elasticsearch-plugin/target/elasticsearch-plugin-1.0-SNAPSHOT-sources.jar to /Users/liuxg/.m2/repository/com/liuxg/elasticsearch-plugin/1.0-SNAPSHOT/elasticsearch-plugin-1.0-SNAPSHOT-sources.jar
- [INFO] Installing /Users/liuxg/java/plugins/elasticsearch-plugin/target/releases/elasticsearch-plugin-1.0-SNAPSHOT.zip to /Users/liuxg/.m2/repository/com/liuxg/elasticsearch-plugin/1.0-SNAPSHOT/elasticsearch-plugin-1.0-SNAPSHOT.zip
- [INFO] ------------------------------------------------------------------------
- [INFO] BUILD SUCCESS
- [INFO] ------------------------------------------------------------------------
- [INFO] Total time: 5.352 s
- [INFO] Finished at: 2022-09-06T10:55:38+08:00
- [INFO] ------------------------------------------------------------------------
编译成功后,我们可以在 target 目录先看到如下的安装文件:
- $ pwd
- /Users/liuxg/java/plugins/elasticsearch-plugin
- $ ls target/releases
- elasticsearch-plugin-1.0-SNAPSHOT.zip
上面显示的 elasticsearch-plugin-1.0-SNAPSHOT.zip 就是我们可以安装的插件文件。
我们接下来换到 Elasticsearch 的安装目录下,并打入如下的命令:
- $ pwd
- /Users/liuxg/elastic0/elasticsearch-8.4.0
- $ bin/elasticsearch-plugin install file:Users/liuxg/java/plugins/elasticsearch-plugin/target/releases/elasticsearch-plugin-1.0-SNAPSHOT.zip
- -> Installing file:Users/liuxg/java/plugins/elasticsearch-plugin/target/releases/elasticsearch-plugin-1.0-SNAPSHOT.zip
- -> Downloading file:Users/liuxg/java/plugins/elasticsearch-plugin/target/releases/elasticsearch-plugin-1.0-SNAPSHOT.zip
- [=================================================] 100%
- -> Installed rest_handler
- -> Please restart Elasticsearch to activate any plugins installed
- $ ./bin/elasticsearch-plugin list
- rest_handler
从上面的显示中,我们可以看出来 rest_handler 插件已经被成功地安装。我们接下来需要重新启动 Elasticsearch。这个非常重要!
我们打开 Kibana,并打入如下的命令:

我们也可以直接在 terminal 中打入如下的命令:
curl -k --user elastic:V_USqc1cWM40W_pIHnni https://localhost:9200/_cat/example
- $ curl -k --user elastic:V_USqc1cWM40W_pIHnni https://localhost:9200/_cat/example
- Hello from Cat Example action
整个项目的代码可以在地址下载:GitHub - liu-xiao-guo/rest_handler_plugin
参考:
【1】elasticsearch/plugins/examples at main · elastic/elasticsearch · GitHub