Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 12c82932ca | |||
| 78f0f6c288 | |||
| 1a88ceb40a | |||
| 8a15e82845 |
@@ -4,4 +4,3 @@ _site
|
||||
.DS_Store
|
||||
Gemfile.lock
|
||||
.idea
|
||||
.jekyll-cache
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<meta charset="utf-8">
|
||||
<title>Redirecting…</title>
|
||||
<script>location="https://opensearch.org/docs"+location.pathname</script>
|
||||
<meta name="robots" content="noindex">
|
||||
<h1>Redirecting…</h1>
|
||||
<a href="https://opensearch.org/docs">Click here if you are not redirected.</a>
|
||||
</html>
|
||||
@@ -1,4 +0,0 @@
|
||||
## Code of Conduct
|
||||
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
|
||||
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
|
||||
opensource-codeofconduct@amazon.com with any additional questions or comments.
|
||||
@@ -1,59 +0,0 @@
|
||||
# Contributing Guidelines
|
||||
|
||||
Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
|
||||
documentation, we greatly value feedback and contributions from our community.
|
||||
|
||||
Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
|
||||
information to effectively respond to your bug report or contribution.
|
||||
|
||||
|
||||
## Reporting Bugs/Feature Requests
|
||||
|
||||
We welcome you to use the GitHub issue tracker to report bugs or suggest features.
|
||||
|
||||
When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already
|
||||
reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
|
||||
|
||||
* A reproducible test case or series of steps
|
||||
* The version of our code being used
|
||||
* Any modifications you've made relevant to the bug
|
||||
* Anything unusual about your environment or deployment
|
||||
|
||||
|
||||
## Contributing via Pull Requests
|
||||
Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
|
||||
|
||||
1. You are working against the latest source on the *main* branch.
|
||||
2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
|
||||
3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
|
||||
|
||||
To send us a pull request, please:
|
||||
|
||||
1. Fork the repository.
|
||||
2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
|
||||
3. Ensure local tests pass.
|
||||
4. Commit to your fork using clear commit messages.
|
||||
5. Send us a pull request, answering any default questions in the pull request interface.
|
||||
6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
|
||||
|
||||
GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
|
||||
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
|
||||
|
||||
|
||||
## Finding contributions to work on
|
||||
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.
|
||||
|
||||
|
||||
## Code of Conduct
|
||||
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
|
||||
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
|
||||
opensource-codeofconduct@amazon.com with any additional questions or comments.
|
||||
|
||||
|
||||
## Security issue notifications
|
||||
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
|
||||
|
||||
|
||||
## Licensing
|
||||
|
||||
See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
|
||||
@@ -1,32 +0,0 @@
|
||||
source "https://rubygems.org"
|
||||
|
||||
# Hello! This is where you manage which Jekyll version is used to run.
|
||||
# When you want to use a different version, change it below, save the
|
||||
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
|
||||
#
|
||||
# bundle exec jekyll serve
|
||||
#
|
||||
# This will help ensure the proper Jekyll version is running.
|
||||
# Happy Jekylling!
|
||||
gem "jekyll", "~> 4.2.0"
|
||||
|
||||
# This is the default theme for new Jekyll sites. You may change this to anything you like.
|
||||
gem "just-the-docs", "~> 0.3.3"
|
||||
gem "jekyll-remote-theme", "~> 0.4"
|
||||
gem "jekyll-redirect-from", "~> 0.16"
|
||||
|
||||
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
|
||||
# uncomment the line below. To upgrade, run `bundle update github-pages`.
|
||||
|
||||
# gem 'github-pages', group: :jekyll_plugins
|
||||
|
||||
# If you have any plugins, put them here!
|
||||
group :jekyll_plugins do
|
||||
gem "jekyll-sitemap"
|
||||
end
|
||||
|
||||
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
||||
|
||||
# Performance-booster for watching directories on Windows
|
||||
gem "wdm", "~> 0.1.0" if Gem.win_platform?
|
||||
@@ -1 +1 @@
|
||||
Copyright OpenSearch contributors.
|
||||
Copyright 2021 OpenSearch contributors.
|
||||
|
||||
@@ -1,297 +0,0 @@
|
||||
<img src="https://opensearch.org/assets/img/opensearch-logo-themed.svg" height="64px">
|
||||
|
||||
# OpenSearch documentation
|
||||
|
||||
This repository contains the documentation for OpenSearch, the search, analytics, and visualization suite with advanced security, alerting, SQL support, automated index management, deep performance analysis, and more. You can find the rendered documentation at [opensearch.org/docs](https://opensearch.org/docs).
|
||||
|
||||
Community contributions remain essential in keeping this documentation comprehensive, useful, well-organized, and up-to-date.
|
||||
|
||||
|
||||
## How you can help
|
||||
|
||||
- Do you work on one of the various OpenSearch plugins? Take a look at the documentation for the plugin. Is everything accurate? Will anything change in the near future?
|
||||
|
||||
Often, engineering teams can keep existing documentation up-to-date with minimal effort, thus freeing up the documentation team to focus on larger projects.
|
||||
|
||||
- Do you have expertise in a particular area of OpenSearch? Cluster sizing? The query DSL? Painless scripting? Aggregations? JVM settings? Take a look at the [current content](https://opensearch.org/docs/opensearch/) and see where you can add value. The [documentation team](#points-of-contact) is happy to help you polish and organize your drafts.
|
||||
|
||||
- Are you an OpenSearch Dashboards expert? How did you set up your visualizations? Why is a particular dashboard so valuable to your organization? We have [very little](https://opensearch.org/docs/opensearch-dashboards/) on how to use OpenSearch Dashboards, only how to install it.
|
||||
|
||||
- Are you a web developer? Do you want to add an optional dark mode to the documentation? A "copy to clipboard" button for our code samples? Other improvements to the design or usability? See [major changes](#major-changes) for information on building the website locally.
|
||||
|
||||
- Our [issue tracker](https://github.com/opensearch-project/documentation-website/issues) contains documentation bugs and other content gaps, some of which have colorful labels like "good first issue" and "help wanted."
|
||||
|
||||
|
||||
## Points of contact
|
||||
|
||||
If you encounter problems or have questions when contributing to the documentation, these people can help:
|
||||
|
||||
- [aetter](https://github.com/aetter)
|
||||
- [ashwinkumar12345](https://github.com/ashwinkumar12345)
|
||||
- [keithhc2](https://github.com/keithhc2)
|
||||
- [snyder114](https://github.com/snyder114)
|
||||
|
||||
|
||||
## How the website works
|
||||
|
||||
This repository contains many [Markdown](https://guides.github.com/features/mastering-markdown/) files organized into Jekyll "collections" (e.g. `_search-plugins`, `_opensearch`, etc.). Each Markdown file correlates with one page on the website.
|
||||
|
||||
Using plain text on GitHub has many advantages:
|
||||
|
||||
- Everything is free, open source, and works on every operating system. Use your favorite text editor, Ruby, Jekyll, and Git.
|
||||
- Markdown is easy to learn and looks good in side-by-side diffs.
|
||||
- The workflow is no different than contributing code. Make your changes, build locally to check your work, and submit a pull request. Reviewers check the PR before merging.
|
||||
- Alternatives like wikis and WordPress are full web applications that require databases and ongoing maintenance. They also have inferior versioning and content review processes compared to Git. Static websites, such as the ones Jekyll produces, are faster, more secure, and more stable.
|
||||
|
||||
In addition to the content for a given page, each Markdown file contains some Jekyll [front matter](https://jekyllrb.com/docs/front-matter/). Front matter looks like this:
|
||||
|
||||
```
|
||||
---
|
||||
layout: default
|
||||
title: Alerting security
|
||||
nav_order: 10
|
||||
parent: Alerting
|
||||
has_children: false
|
||||
---
|
||||
```
|
||||
|
||||
If you're making [trivial changes](#trivial-changes), you don't have to worry about front matter.
|
||||
|
||||
If you want to reorganize content or add new pages, keep an eye on `has_children`, `parent`, and `nav_order`, which define the hierarchy and order of pages in the lefthand navigation. For more information, see the documentation for [our upstream Jekyll theme](https://pmarsceill.github.io/just-the-docs/docs/navigation-structure/).
|
||||
|
||||
|
||||
## Contribute content
|
||||
|
||||
There are three ways to contribute content, depending on the magnitude of the change.
|
||||
|
||||
- [Trivial changes](#trivial-changes)
|
||||
- [Minor changes](#minor-changes)
|
||||
- [Major changes](#major-changes)
|
||||
|
||||
|
||||
### Trivial changes
|
||||
|
||||
If you just need to fix a typo or add a sentence, this web-based method works well:
|
||||
|
||||
1. On any page in the documentation, click the **Edit this page** link in the lower-left.
|
||||
|
||||
1. Make your changes.
|
||||
|
||||
1. Choose **Create a new branch for this commit and start a pull request** and **Commit changes**.
|
||||
|
||||
|
||||
### Minor changes
|
||||
|
||||
If you want to add a few paragraphs across multiple files and are comfortable with Git, try this approach:
|
||||
|
||||
1. Fork this repository.
|
||||
|
||||
1. Download [GitHub Desktop](https://desktop.github.com), install it, and clone your fork.
|
||||
|
||||
1. Navigate to the repository root.
|
||||
|
||||
1. Create a new branch.
|
||||
|
||||
1. Edit the Markdown files in `/docs`.
|
||||
|
||||
1. Commit, push your changes to your fork, and submit a pull request.
|
||||
|
||||
|
||||
### Major changes
|
||||
|
||||
If you're making major changes to the documentation and need to see the rendered HTML before submitting a pull request, here's how to build locally:
|
||||
|
||||
1. Fork this repository.
|
||||
|
||||
1. Download [GitHub Desktop](https://desktop.github.com), install it, and clone your fork.
|
||||
|
||||
1. Navigate to the repository root.
|
||||
|
||||
1. Install [Ruby](https://www.ruby-lang.org/en/) if you don't already have it. We recommend [RVM](https://rvm.io/), but use whatever method you prefer:
|
||||
|
||||
```
|
||||
curl -sSL https://get.rvm.io | bash -s stable
|
||||
rvm install 2.6
|
||||
ruby -v
|
||||
```
|
||||
|
||||
1. Install [Jekyll](https://jekyllrb.com/) if you don't already have it:
|
||||
|
||||
```
|
||||
gem install bundler jekyll
|
||||
```
|
||||
|
||||
1. Install dependencies:
|
||||
|
||||
```
|
||||
bundle install
|
||||
```
|
||||
|
||||
1. Build:
|
||||
|
||||
```
|
||||
sh build.sh
|
||||
```
|
||||
|
||||
1. If the build script doesn't automatically open your web browser (it should), open [http://localhost:4000/docs/](http://localhost:4000/docs/).
|
||||
|
||||
1. Create a new branch.
|
||||
|
||||
1. Edit the Markdown files in each collection (e.g. `_security-plugin/`).
|
||||
|
||||
If you're a web developer, you can customize `_layouts/default.html` and `_sass/custom/custom.scss`.
|
||||
|
||||
1. When you save a file, marvel as Jekyll automatically rebuilds the site and refreshes your web browser. This process can take anywhere from 10-30 seconds.
|
||||
|
||||
1. When you're happy with how everything looks, commit, push your changes to your fork, and submit a pull request.
|
||||
|
||||
|
||||
## Writing tips
|
||||
|
||||
1. Try to stay consistent with existing content and consistent within your new content. Don't call the same plugin KNN, k-nn, and k-NN in three different places.
|
||||
|
||||
1. Shorter paragraphs are better than longer paragraphs. Use headers, tables, lists, and images to make your content easier for readers to scan.
|
||||
|
||||
1. Use **bold** for user interface elements, *italics* for key terms or emphasis, and `monospace` for Bash commands, file names, REST paths, and code.
|
||||
|
||||
1. Markdown file names should be all lowercase, use hyphens to separate words, and end in `.md`.
|
||||
|
||||
1. Avoid future tense. Use present tense.
|
||||
|
||||
**Bad**: After you click the button, the process will start.
|
||||
|
||||
**Better**: After you click the button, the process starts.
|
||||
|
||||
1. "You" refers to the person reading the page. "We" refers to the OpenSearch contributors.
|
||||
|
||||
**Bad**: Now that we've finished the configuration, we have a working cluster.
|
||||
|
||||
**Better**: At this point, you have a working cluster, but we recommend adding dedicated master nodes.
|
||||
|
||||
1. Don't use "this" and "that" to refer to something without adding a noun.
|
||||
|
||||
**Bad**: This can cause high latencies.
|
||||
|
||||
**Better**: This additional loading time can cause high latencies.
|
||||
|
||||
1. Use active voice.
|
||||
|
||||
**Bad**: After the request is sent, the data is added to the index.
|
||||
|
||||
**Better**: After you send the request, the OpenSearch cluster indexes the data.
|
||||
|
||||
1. Introduce acronyms before using them.
|
||||
|
||||
**Bad**: Reducing customer TTV should accelerate our ROIC.
|
||||
|
||||
**Better**: Reducing customer time to value (TTV) should accelerate our return on invested capital (ROIC).
|
||||
|
||||
1. Spell out one through nine. Start using numerals at 10. If a number needs a unit (GB, pounds, millimeters, kg, celsius, etc.), use numerals, even if the number if smaller than 10.
|
||||
|
||||
**Bad**: 3 kids looked for thirteen files on a six GB hard drive.
|
||||
|
||||
**Better**: Three kids looked for 13 files on a 6 GB hard drive.
|
||||
|
||||
|
||||
## New releases
|
||||
|
||||
1. Branch.
|
||||
1. Change the `opensearch_version`, `opensearch_major_minor_version`, and `lucene_version` variables in `_config.yml`.
|
||||
1. Start up a new cluster using the updated Docker Compose file in `docs/install/docker.md`.
|
||||
1. Update the version table in `version-history.md`.
|
||||
|
||||
Use `curl -XGET https://localhost:9200 -u admin:admin -k` to verify the OpenSearch and Lucene versions.
|
||||
|
||||
1. Update the plugin compatibility table in `_opensearch/install/plugin.md`.
|
||||
|
||||
Use `curl -XGET https://localhost:9200/_cat/plugins -u admin:admin -k` to get the correct version strings.
|
||||
|
||||
1. Update the plugin compatibility table in `_dashboards/install/plugins.md`.
|
||||
|
||||
Use `docker ps` to find the ID for the OpenSearch Dashboards node. Then use `docker exec -it <opensearch-dashboards-node-id> /bin/bash` to get shell access. Finally, run `./bin/opensearch-dashboards-plugin list` to get the plugins and version strings.
|
||||
|
||||
1. Run a build (`build.sh`), and look for any warnings or errors you introduced.
|
||||
1. Verify that the individual plugin download links in `docs/install/plugins.md` and `docs/opensearch-dashboards/plugins.md` work.
|
||||
1. Check for any other bad links (`check-links.sh`). Expect a few false positives for the `localhost` links.
|
||||
1. Submit a PR.
|
||||
|
||||
|
||||
## Classes within Markdown
|
||||
|
||||
This documentation uses a modified version of the [just-the-docs](https://github.com/pmarsceill/just-the-docs) Jekyll theme, which has some useful classes for labels and buttons:
|
||||
|
||||
```
|
||||
[Get started](#get-started){: .btn .btn-blue }
|
||||
|
||||
## Get started
|
||||
New
|
||||
{: .label .label-green }
|
||||
```
|
||||
|
||||
* Labels come in default (blue), green, purple, yellow, and red.
|
||||
* Buttons come in default, purple, blue, green, and outline.
|
||||
* Warning, tip, and note blocks are available (`{: .warning }`, etc.).
|
||||
* If an image has a white background, you can use `{: .img-border }` to add a one pixel border to the image.
|
||||
|
||||
These classes can help with readability, but should be used *sparingly*. Each addition of a class damages the portability of the Markdown files and makes moving to a different Jekyll theme (or a different static site generator) more difficult.
|
||||
|
||||
Besides, standard Markdown elements suffice for most documentation.
|
||||
|
||||
|
||||
## Labels for APIs
|
||||
|
||||
Each API operation has a label indicating when it was introduced. For most operations, this label is 1.0:
|
||||
|
||||
```
|
||||
## Get roles
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
```
|
||||
|
||||
If we introduce a breaking change to an operation, add an additional label with a link to the release note for that breaking change:
|
||||
|
||||
```
|
||||
## Get roles
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
[Last breaking change 2.0](https://example.com)
|
||||
{: .label .label-red }
|
||||
```
|
||||
|
||||
|
||||
## Math
|
||||
|
||||
If you want to use the sorts of pretty formulas that [MathJax](https://www.mathjax.org) allows, add `has_math: true` to the Jekyll page metadata. Then insert LaTeX math into HTML tags with the rest of your Markdown content:
|
||||
|
||||
```
|
||||
## Math
|
||||
|
||||
Some Markdown paragraph. Here's a formula:
|
||||
|
||||
<p>
|
||||
When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
|
||||
\[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\]
|
||||
</p>
|
||||
|
||||
And back to Markdown.
|
||||
```
|
||||
|
||||
|
||||
## Code of conduct
|
||||
|
||||
This project has adopted an [Open Source Code of Conduct](https://opensearch.org/codeofconduct.html).
|
||||
|
||||
|
||||
## Security
|
||||
|
||||
See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the Apache-2.0 License.
|
||||
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright OpenSearch contributors.
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
** (MIT License) Just the Docs 0.3.3 - https://github.com/pmarsceill/just-the-docs
|
||||
|
||||
Copyright (c) 2016 Patrick Marsceill
|
||||
|
||||
** (MIT License) Jekyll Pure Liquid Table of Contents 1.1.0 - https://github.com/allejo/jekyll-toc
|
||||
|
||||
Copyright (c) 2017 Vladimir Jimenez
|
||||
|
||||
** (MIT License) Bootstrap Icons 1.4.1 - https://github.com/twbs/icons
|
||||
|
||||
Copyright (c) 2019-2020 The Bootstrap Authors
|
||||
@@ -1,87 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Agents and ingestion tools
|
||||
nav_order: 100
|
||||
has_children: false
|
||||
has_toc: false
|
||||
redirect_from:
|
||||
- /clients/agents-and-ingestion-tools/
|
||||
---
|
||||
|
||||
# Agents and ingestion tools
|
||||
|
||||
Historically, many multiple popular agents and ingestion tools have worked with Elasticsearch OSS, such as Beats, Logstash, Fluentd, FluentBit, and OpenTelemetry. OpenSearch aims to continue to support a broad set of agents and ingestion tools, but not all have been tested or have explicitly added OpenSearch compatibility.
|
||||
|
||||
As an intermediate compatibility solution, OpenSearch has a setting that instructs the cluster to return version 7.10.2 rather than its actual version.
|
||||
|
||||
If you use clients that include a version check, such as recent versions of Logstash OSS or Filebeat OSS, enable the setting:
|
||||
|
||||
```json
|
||||
PUT _cluster/settings
|
||||
{
|
||||
"persistent": {
|
||||
"compatibility": {
|
||||
"override_main_response_version": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[Just like any other setting]({{site.url}}{{site.baseurl}}/opensearch/configuration/), the alternative is to add the following line to `opensearch.yml` on each node and then restart the node:
|
||||
|
||||
```yml
|
||||
compatibility.override_main_response_version: true
|
||||
```
|
||||
|
||||
|
||||
## Downloads
|
||||
|
||||
You can download the OpenSearch output plugin for Logstash from [OpenSearch downloads](https://opensearch.org/downloads.html). The Logstash output plugin is compatible with OpenSearch and Elasticsearch OSS (7.10.2 or lower).
|
||||
|
||||
These are the latest versions of Beats OSS with OpenSearch compatibility. For more information, see the [compatibility matrices](#compatibility-matrices).
|
||||
|
||||
- [Filebeat OSS 7.12.1](https://www.elastic.co/downloads/past-releases/filebeat-oss-7-12-1)
|
||||
- [Metricbeat OSS 7.12.1](https://www.elastic.co/downloads/past-releases/metricbeat-oss-7-12-1)
|
||||
- [Packetbeat OSS 7.12.1](https://www.elastic.co/downloads/past-releases/packetbeat-oss-7-12-1)
|
||||
- [Heartbeat OSS 7.12.1](https://elastic.co/downloads/past-releases/heartbeat-oss-7-12-1)
|
||||
- [Winlogbeat OSS 7.12.1](https://www.elastic.co/downloads/past-releases/winlogbeat-oss-7-12-1)
|
||||
- [Auditbeat OSS 7.12.1](https://elastic.co/downloads/past-releases/auditbeat-oss-7-12-1)
|
||||
|
||||
Some users report compatibility issues with ingest pipelines on these versions of Beats. If you use ingest pipelines with OpenSearch, consider using the 7.10.2 versions of Beats instead.
|
||||
{: .note }
|
||||
|
||||
|
||||
## Compatibility Matrices
|
||||
|
||||
*Italicized* cells are untested, but indicate what a value theoretically should be based on existing information.
|
||||
|
||||
|
||||
### Compatibility Matrix for Logstash
|
||||
|
||||
| | Logstash OSS 7.x to 7.11.x | Logstash OSS 7.12.x\* | Logstash 7.13.x without OpenSearch output plugin | Logstash 7.13.x with OpenSearch output plugin |
|
||||
| :---| :--- | :--- | :--- | :--- |
|
||||
| Elasticsearch OSS 7.x to 7.9.x | *Yes* | *Yes* | *No* | *Yes* |
|
||||
| Elasticsearch OSS 7.10.2 | *Yes* | *Yes* | *No* | *Yes* |
|
||||
| ODFE 1.x to 1.12 | *Yes* | *Yes* | *No* | *Yes* |
|
||||
| ODFE 1.13 | *Yes* | *Yes* | *No* | *Yes* |
|
||||
| OpenSearch 1.0 | Yes via version setting | Yes via version setting | *No* | *Yes* |
|
||||
|
||||
\* Most current compatible version with Elasticsearch OSS.
|
||||
|
||||
|
||||
### Compatibility Matrix for Beats
|
||||
|
||||
| | Beats OSS 7.x to 7.11.x\*\* | Beats OSS 7.12.x\* | Beats 7.13.x |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| Elasticsearch OSS 7.x to 7.9.x | *Yes* | *Yes* | No |
|
||||
| Elasticsearch OSS 7.10.2 | *Yes* | *Yes* | No |
|
||||
| ODFE 1.x to 1.12 | *Yes* | *Yes* | No |
|
||||
| ODFE 1.13 | *Yes* | *Yes* | No |
|
||||
| OpenSearch 1.0 | Yes via version setting | Yes via version setting | No |
|
||||
| Logstash OSS 7.x to 7.11.x | *Yes* | *Yes* | *Yes* |
|
||||
| Logstash OSS 7.12.x\* | *Yes* | *Yes* | *Yes* |
|
||||
| Logstash 7.13.x with OpenSearch output plugin | *Yes* | *Yes* | *Yes* |
|
||||
|
||||
\* Most current compatible version with Elasticsearch OSS.
|
||||
|
||||
\*\* Beats OSS includes all Apache 2.0 Beats agents (i.e. Filebeat, Metricbeat, Auditbeat, Heartbeat, Winlogbeat, Packetbeat).
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: OpenSearch CLI
|
||||
nav_order: 52
|
||||
has_children: false
|
||||
---
|
||||
|
||||
# OpenSearch CLI
|
||||
|
||||
The OpenSearch CLI command line interface (opensearch-cli) lets you manage your OpenSearch cluster from the command line and automate tasks.
|
||||
|
||||
Currently, opensearch-cli supports the [Anomaly Detection]({{site.url}}{{site.baseurl}}/monitoring-plugins/ad/) and [k-NN]({{site.url}}{{site.baseurl}}/search-plugins/knn/) plugins, along with arbitrary REST API paths. Among other things, you can use opensearch-cli to create and delete detectors, start and stop them, and check k-NN statistics.
|
||||
|
||||
Profiles let you easily access different clusters or sign requests with different credentials. opensearch-cli supports unauthenticated requests, HTTP basic signing, and IAM signing for Amazon Web Services.
|
||||
|
||||
This example moves a detector (`ecommerce-count-quantity`) from a staging cluster to a production cluster:
|
||||
|
||||
```bash
|
||||
opensearch-cli ad get ecommerce-count-quantity --profile staging > ecommerce-count-quantity.json
|
||||
opensearch-cli ad create ecommerce-count-quantity.json --profile production
|
||||
opensearch-cli ad start ecommerce-count-quantity.json --profile production
|
||||
opensearch-cli ad stop ecommerce-count-quantity --profile staging
|
||||
opensearch-cli ad delete ecommerce-count-quantity --profile staging
|
||||
```
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
1. [Download](https://opensearch.org/downloads.html){:target='\_blank'} and extract the appropriate installation package for your computer.
|
||||
|
||||
1. Make the `opensearch-cli` file executable:
|
||||
|
||||
```bash
|
||||
chmod +x ./opensearch-cli
|
||||
```
|
||||
|
||||
1. Add the command to your path:
|
||||
|
||||
```bash
|
||||
export PATH=$PATH:$(pwd)
|
||||
```
|
||||
|
||||
1. Confirm the CLI is working properly:
|
||||
|
||||
```bash
|
||||
opensearch-cli --version
|
||||
```
|
||||
|
||||
|
||||
## Profiles
|
||||
|
||||
Profiles let you easily switch between different clusters and user credentials. To get started, run `opensearch-cli profile create` with the `--auth-type`, `--endpoint`, and `--name` options:
|
||||
|
||||
```bash
|
||||
opensearch-cli profile create --auth-type basic --endpoint https://localhost:9200 --name docker-local
|
||||
```
|
||||
|
||||
Alternatively, save a configuration file to `~/.opensearch-cli/config.yaml`:
|
||||
|
||||
```yaml
|
||||
profiles:
|
||||
- name: docker-local
|
||||
endpoint: https://localhost:9200
|
||||
user: admin
|
||||
password: foobar
|
||||
- name: aws
|
||||
endpoint: https://some-cluster.us-east-1.es.amazonaws.com
|
||||
aws_iam:
|
||||
profile: ""
|
||||
service: es
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
opensearch-cli commands use the following syntax:
|
||||
|
||||
```bash
|
||||
opensearch-cli <command> <subcommand> <flags>
|
||||
```
|
||||
|
||||
For example, the following command retrieves information about a detector:
|
||||
|
||||
```bash
|
||||
opensearch-cli ad get my-detector --profile docker-local
|
||||
```
|
||||
|
||||
For a request to the OpenSearch CAT API, try the following command:
|
||||
|
||||
```bash
|
||||
opensearch-cli curl get --path _cat/plugins --profile aws
|
||||
```
|
||||
|
||||
Use the `-h` or `--help` flag to see all supported commands, subcommands, or usage for a specific command:
|
||||
|
||||
```bash
|
||||
opensearch-cli -h
|
||||
opensearch-cli ad -h
|
||||
opensearch-cli ad get -h
|
||||
```
|
||||
-145
@@ -1,145 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Go client
|
||||
nav_order: 80
|
||||
---
|
||||
|
||||
# Go client
|
||||
|
||||
The OpenSearch Go client lets you connect your Go application with the data in your OpenSearch cluster.
|
||||
|
||||
|
||||
## Setup
|
||||
|
||||
If you're creating a new project:
|
||||
|
||||
```go
|
||||
go mod init
|
||||
```
|
||||
|
||||
To add the client to your project, import it like any other module:
|
||||
|
||||
```go
|
||||
go get github.com/opensearch-project/opensearch-go
|
||||
```
|
||||
|
||||
## Sample code
|
||||
|
||||
This sample code creates a client, adds an index with non-default settings, inserts a document, searches for the document, deletes the document, and finally deletes the index:
|
||||
|
||||
```go
|
||||
package main
|
||||
import (
|
||||
"os"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
opensearch "github.com/opensearch-project/opensearch-go"
|
||||
opensearchapi "github.com/opensearch-project/opensearch-go/opensearchapi"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
const IndexName = "go-test-index1"
|
||||
func main() {
|
||||
// Initialize the client with SSL/TLS enabled.
|
||||
client, err := opensearch.NewClient(opensearch.Config{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
},
|
||||
Addresses: []string{"https://localhost:9200"},
|
||||
Username: "admin", // For testing only. Don't store credentials in code.
|
||||
Password: "admin",
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Println("cannot initialize", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Print OpenSearch version information on console.
|
||||
fmt.Println(client.Info())
|
||||
|
||||
// Define index mapping.
|
||||
mapping := strings.NewReader(`{
|
||||
'settings': {
|
||||
'index': {
|
||||
'number_of_shards': 4
|
||||
}
|
||||
}
|
||||
}`)
|
||||
|
||||
// Create an index with non-default settings.
|
||||
res := opensearchapi.CreateRequest{
|
||||
Index: IndexName,
|
||||
Body: mapping,
|
||||
}
|
||||
fmt.Println("creating index", res)
|
||||
|
||||
// Add a document to the index.
|
||||
document := strings.NewReader(`{
|
||||
"title": "Moneyball",
|
||||
"director": "Bennett Miller",
|
||||
"year": "2011"
|
||||
}`)
|
||||
|
||||
docId := "1"
|
||||
req := opensearchapi.IndexRequest{
|
||||
Index: IndexName,
|
||||
DocumentID: docId,
|
||||
Body: document,
|
||||
}
|
||||
insertResponse, err := req.Do(context.Background(), client)
|
||||
if err != nil {
|
||||
fmt.Println("failed to insert document ", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(insertResponse)
|
||||
|
||||
// Search for the document.
|
||||
content := strings.NewReader(`{
|
||||
"size": 5,
|
||||
"query": {
|
||||
"multi_match": {
|
||||
"query": "miller",
|
||||
"fields": ["title^2", "director"]
|
||||
}
|
||||
}
|
||||
}`)
|
||||
|
||||
search := opensearchapi.SearchRequest{
|
||||
Body: content,
|
||||
}
|
||||
|
||||
searchResponse, err := search.Do(context.Background(), client)
|
||||
if err != nil {
|
||||
fmt.Println("failed to search document ", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(searchResponse)
|
||||
|
||||
// Delete the document.
|
||||
delete := opensearchapi.DeleteRequest{
|
||||
Index: IndexName,
|
||||
DocumentID: docId,
|
||||
}
|
||||
|
||||
deleteResponse, err := delete.Do(context.Background(), client)
|
||||
if err != nil {
|
||||
fmt.Println("failed to delete document ", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("deleting document")
|
||||
fmt.Println(deleteResponse)
|
||||
|
||||
// Delete previously created index.
|
||||
deleteIndex := opensearchapi.IndicesDeleteRequest{
|
||||
Index: []string{IndexName},
|
||||
}
|
||||
|
||||
deleteIndexResponse, err := deleteIndex.Do(context.Background(), client)
|
||||
if err != nil {
|
||||
fmt.Println("failed to delete index ", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("deleting index", deleteIndexResponse)
|
||||
}
|
||||
```
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Grafana
|
||||
nav_order: 150
|
||||
has_children: false
|
||||
---
|
||||
|
||||
# Grafana support
|
||||
|
||||
Grafana has a data source plugin that lets you explore and visualize your OpenSearch data. For information on getting started with the plugin, see the [Grafana overview page](https://grafana.com/grafana/plugins/grafana-opensearch-datasource/).
|
||||
@@ -1,96 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Compatibility
|
||||
nav_order: 1
|
||||
has_children: false
|
||||
redirect_from:
|
||||
- /clients/
|
||||
---
|
||||
|
||||
# OpenSearch client compatibility
|
||||
|
||||
OpenSearch provides clients for several popular programming languages, with more coming. In general, clients are compatible with clusters running the same major version of OpenSearch (`major.minor.patch`).
|
||||
|
||||
For example, a 1.0.0 client works with an OpenSearch 1.1.0 cluster, but might not support any non-breaking API changes in OpenSearch 1.1.0. A 1.2.0 client works with the same cluster, but might allow you to pass unsupported options in certain functions. We recommend using the same version for both, but if your tests pass after a cluster upgrade, you don't necessarily need to upgrade your clients immediately.
|
||||
|
||||
{% comment %}
|
||||
* [OpenSearch Java client]({{site.url}}{{site.baseurl}}/clients/java/)
|
||||
{% endcomment %}
|
||||
* [OpenSearch Python client]({{site.url}}{{site.baseurl}}/clients/python/)
|
||||
* [OpenSearch JavaScript (Node.js) client]({{site.url}}{{site.baseurl}}/clients/javascript/)
|
||||
* [OpenSearch Go client]({{site.url}}{{site.baseurl}}/clients/go/)
|
||||
|
||||
|
||||
## Legacy clients
|
||||
|
||||
Most clients that work with Elasticsearch OSS 7.10.2 *should* work with OpenSearch, but the latest versions of those clients might include license or version checks that artificially break compatibility. This page includes recommendations around which versions of those clients to use for best compatibility with OpenSearch.
|
||||
|
||||
Client | Recommended version
|
||||
:--- | :---
|
||||
[Java low-level REST client](https://search.maven.org/artifact/org.elasticsearch.client/elasticsearch-rest-client/7.13.4/jar) | 7.13.4
|
||||
[Java high-level REST client](https://search.maven.org/artifact/org.elasticsearch.client/elasticsearch-rest-high-level-client/7.13.4/jar) | 7.13.4
|
||||
[Python Elasticsearch client](https://pypi.org/project/elasticsearch/7.13.4/) | 7.13.4
|
||||
[Elasticsearch Node.js client](https://www.npmjs.com/package/@elastic/elasticsearch/v/7.13.0) | 7.13.0
|
||||
|
||||
If you test a legacy client and verify that it works, please [submit a PR](https://github.com/opensearch-project/documentation-website/pulls) and add it to this table.
|
||||
|
||||
|
||||
{% comment %}
|
||||
## Python 3 test code
|
||||
|
||||
This code indexes a single document and is equivalent to `PUT /python-test-index1/_doc/1`.
|
||||
|
||||
```python
|
||||
from elasticsearch import Elasticsearch
|
||||
|
||||
host = 'localhost'
|
||||
port = 9200
|
||||
# For testing only. Do not store credentials in code.
|
||||
auth = ('admin', 'admin')
|
||||
|
||||
es = Elasticsearch(
|
||||
hosts = [{'host': host, 'port': port}],
|
||||
http_auth = auth,
|
||||
use_ssl = True,
|
||||
verify_certs = False
|
||||
)
|
||||
|
||||
document = {
|
||||
"title": "Moneyball",
|
||||
"director": "Bennett Miller",
|
||||
"year": "2011"
|
||||
}
|
||||
|
||||
response = es.index(index='python-test-index1', id='1', body=document, refresh=True)
|
||||
|
||||
print(response)
|
||||
```
|
||||
|
||||
|
||||
## Node.js test code
|
||||
|
||||
This code is equivalent to `GET /`.
|
||||
|
||||
```js
|
||||
const { Client } = require('@elastic/elasticsearch')
|
||||
const client = new Client({
|
||||
node: 'https://localhost:9200',
|
||||
auth: {
|
||||
// For testing only. Don't store credentials in code.
|
||||
username: 'admin',
|
||||
password: 'admin'
|
||||
},
|
||||
ssl: {
|
||||
// ca: fs.readFileSync('./cacert.pem'),
|
||||
rejectUnauthorized: false
|
||||
}
|
||||
})
|
||||
|
||||
async function run () {
|
||||
const { body } = await client.info();
|
||||
console.log(body);
|
||||
}
|
||||
|
||||
run().catch(console.log)
|
||||
```
|
||||
{% endcomment %}
|
||||
@@ -1,133 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: OpenSearch Java high-level REST client
|
||||
nav_order: 60
|
||||
---
|
||||
|
||||
# OpenSearch Java high-level REST client
|
||||
|
||||
The OpenSearch Java high-level REST client allows you to interact with your OpenSearch clusters and indices through Java methods and data structures rather than HTTP methods and JSON.
|
||||
|
||||
You submit requests to your cluster using request objects, which allows you to create indices, add data to documents, or complete other operations with your cluster. In return, you get back response objects that have all of the available information, such as the associated index or ID, from your cluster.
|
||||
|
||||
## Setup
|
||||
|
||||
To start using the OpenSearch Java high-level REST client, ensure that you have the following dependency in your project's `pom.xml` file:
|
||||
|
||||
```
|
||||
<dependency>
|
||||
<groupId>org.opensearch.client</groupId>
|
||||
<artifactId>opensearch-rest-high-level-client</artifactId>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
You can now start your OpenSearch cluster. The OpenSearch 1.x high-level REST client works with the 1.x versions of OpenSearch.
|
||||
|
||||
## Sample code
|
||||
|
||||
```java
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.CredentialsProvider;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
|
||||
import org.opensearch.action.admin.indices.delete.DeleteIndexRequest;
|
||||
import org.opensearch.action.delete.DeleteRequest;
|
||||
import org.opensearch.action.delete.DeleteResponse;
|
||||
import org.opensearch.action.get.GetRequest;
|
||||
import org.opensearch.action.get.GetResponse;
|
||||
import org.opensearch.action.index.IndexRequest;
|
||||
import org.opensearch.action.index.IndexResponse;
|
||||
import org.opensearch.action.support.master.AcknowledgedResponse;
|
||||
import org.opensearch.client.RequestOptions;
|
||||
import org.opensearch.client.RestClient;
|
||||
import org.opensearch.client.RestClientBuilder;
|
||||
import org.opensearch.client.RestHighLevelClient;
|
||||
import org.opensearch.client.indices.CreateIndexRequest;
|
||||
import org.opensearch.client.indices.CreateIndexResponse;
|
||||
import org.opensearch.common.settings.Settings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class RESTClientSample {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
//Point to keystore with appropriate certificates for security.
|
||||
System.setProperty("javax.net.ssl.trustStore", "/full/path/to/keystore");
|
||||
System.setProperty("javax.net.ssl.trustStorePassword", "password-to-keystore");
|
||||
|
||||
//Establish credentials to use basic authentication.
|
||||
//Only for demo purposes. Do not specify your credentials in code.
|
||||
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
|
||||
|
||||
credentialsProvider.setCredentials(AuthScope.ANY,
|
||||
new UsernamePasswordCredentials("admin", "admin"));
|
||||
|
||||
//Create a client.
|
||||
RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "https"))
|
||||
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
|
||||
@Override
|
||||
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
|
||||
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
|
||||
}
|
||||
});
|
||||
RestHighLevelClient client = new RestHighLevelClient(builder);
|
||||
|
||||
//Create a non-default index with custom settings and mappings.
|
||||
CreateIndexRequest createIndexRequest = new CreateIndexRequest("custom-index");
|
||||
|
||||
createIndexRequest.settings(Settings.builder() //Specify in the settings how many shards you want in the index.
|
||||
.put("index.number_of_shards", 4)
|
||||
.put("index.number_of_replicas", 3)
|
||||
);
|
||||
//Create a set of maps for the index's mappings.
|
||||
HashMap<String, String> typeMapping = new HashMap<String,String>();
|
||||
typeMapping.put("type", "integer");
|
||||
HashMap<String, Object> ageMapping = new HashMap<String, Object>();
|
||||
ageMapping.put("age", typeMapping);
|
||||
HashMap<String, Object> mapping = new HashMap<String, Object>();
|
||||
mapping.put("properties", ageMapping);
|
||||
createIndexRequest.mapping(mapping);
|
||||
CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
|
||||
|
||||
//Adding data to the index.
|
||||
IndexRequest request = new IndexRequest("custom-index"); //Add a document to the custom-index we created.
|
||||
request.id("1"); //Assign an ID to the document.
|
||||
|
||||
HashMap<String, String> stringMapping = new HashMap<String, String>();
|
||||
stringMapping.put("message:", "Testing Java REST client");
|
||||
request.source(stringMapping); //Place your content into the index's source.
|
||||
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
|
||||
|
||||
//Getting back the document
|
||||
GetRequest getRequest = new GetRequest("custom-index", "1");
|
||||
GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
|
||||
|
||||
System.out.println(response.getSourceAsString());
|
||||
|
||||
//Delete the document
|
||||
DeleteRequest deleteDocumentRequest = new DeleteRequest("custom-index", "1"); //Index name followed by the ID.
|
||||
DeleteResponse deleteResponse = client.delete(deleteDocumentRequest, RequestOptions.DEFAULT);
|
||||
|
||||
//Delete the index
|
||||
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("custom-index"); //Index name.
|
||||
AcknowledgedResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
|
||||
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Elasticsearch OSS Java high-level REST client
|
||||
|
||||
We recommend using the OpenSearch client to connect to OpenSearch clusters, but if you must use the Elasticsearch OSS Java high-level REST client, version 7.10.2 of the Elasticsearch OSS client also works with the 1.x versions of OpenSearch.
|
||||
|
||||
### Migrating to the OpenSearch Java high-level REST client
|
||||
|
||||
Migrating from the Elasticsearch OSS client to the OpenSearch high-level REST client is as simple as changing your Maven dependency to one that references [OpenSearch's dependency](#setup).
|
||||
|
||||
Afterward, change all references of `org.elasticsearch` to `org.opensearch`, and you're ready to start submitting requests to your OpenSearch cluster.
|
||||
@@ -1,141 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: JavaScript client
|
||||
nav_order: 90
|
||||
---
|
||||
|
||||
# JavaScript client
|
||||
|
||||
The OpenSearch JavaScript client provides a safer and easier way to interact with your OpenSearch cluster. Rather than using OpenSearch from the browser and potentially exposing your data to the public, you can build an OpenSearch client that takes care of sending requests to your cluster.
|
||||
|
||||
The client contains a library of APIs that let you perform different operations on your cluster and return a standard response body. The example here demonstrates some basic operations like creating an index, adding documents, and searching your data.
|
||||
|
||||
## Setup
|
||||
|
||||
To add the client to your project, install it from [npm](https://www.npmjs.com):
|
||||
|
||||
```bash
|
||||
npm install @opensearch-project/opensearch
|
||||
```
|
||||
|
||||
To install a specific major version of the client, run the following command:
|
||||
|
||||
```bash
|
||||
npm install @opensearch-project/opensearch@<version>
|
||||
```
|
||||
|
||||
If you prefer to add the client manually or just want to examine the source code, see [opensearch-js](https://github.com/opensearch-project/opensearch-js) on GitHub.
|
||||
|
||||
Then require the client:
|
||||
|
||||
```javascript
|
||||
const { Client } = require("@opensearch-project/opensearch");
|
||||
```
|
||||
|
||||
## Sample code
|
||||
|
||||
```javascript
|
||||
"use strict";
|
||||
|
||||
var host = "localhost";
|
||||
var protocol = "https";
|
||||
var port = 9200;
|
||||
var auth = "admin:admin"; // For testing only. Don't store credentials in code.
|
||||
var ca_certs_path = "/full/path/to/root-ca.pem";
|
||||
|
||||
// Optional client certificates if you don't want to use HTTP basic authentication.
|
||||
// var client_cert_path = '/full/path/to/client.pem'
|
||||
// var client_key_path = '/full/path/to/client-key.pem'
|
||||
|
||||
// Create a client with SSL/TLS enabled.
|
||||
var { Client } = require("@opensearch-project/opensearch");
|
||||
var fs = require("fs");
|
||||
var client = new Client({
|
||||
node: protocol + "://" + auth + "@" + host + ":" + port,
|
||||
ssl: {
|
||||
ca: fs.readFileSync(ca_certs_path),
|
||||
// You can turn off certificate verification (rejectUnauthorized: false) if you're using self-signed certificates with a hostname mismatch.
|
||||
// cert: fs.readFileSync(client_cert_path),
|
||||
// key: fs.readFileSync(client_key_path)
|
||||
},
|
||||
});
|
||||
|
||||
async function search() {
|
||||
// Create an index with non-default settings.
|
||||
var index_name = "books";
|
||||
var settings = {
|
||||
settings: {
|
||||
index: {
|
||||
number_of_shards: 4,
|
||||
number_of_replicas: 3,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
var response = await client.indices.create({
|
||||
index: index_name,
|
||||
body: settings,
|
||||
});
|
||||
|
||||
console.log("Creating index:");
|
||||
console.log(response.body);
|
||||
|
||||
// Add a document to the index.
|
||||
var document = {
|
||||
title: "The Outsider",
|
||||
author: "Stephen King",
|
||||
year: "2018",
|
||||
genre: "Crime fiction",
|
||||
};
|
||||
|
||||
var id = "1";
|
||||
|
||||
var response = await client.index({
|
||||
id: id,
|
||||
index: index_name,
|
||||
body: document,
|
||||
refresh: true,
|
||||
});
|
||||
|
||||
console.log("Adding document:");
|
||||
console.log(response.body);
|
||||
|
||||
// Search for the document.
|
||||
var query = {
|
||||
query: {
|
||||
match: {
|
||||
title: {
|
||||
query: "The Outsider",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
var response = await client.search({
|
||||
index: index_name,
|
||||
body: query,
|
||||
});
|
||||
|
||||
console.log("Search results:");
|
||||
console.log(response.body.hits);
|
||||
|
||||
// Delete the document.
|
||||
var response = await client.delete({
|
||||
index: index_name,
|
||||
id: id,
|
||||
});
|
||||
|
||||
console.log("Deleting document:");
|
||||
console.log(response.body);
|
||||
|
||||
// Delete the index.
|
||||
var response = await client.indices.delete({
|
||||
index: index_name,
|
||||
});
|
||||
|
||||
console.log("Deleting index:");
|
||||
console.log(response.body);
|
||||
}
|
||||
|
||||
search().catch(console.log);
|
||||
```
|
||||
@@ -1,246 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Advanced configurations
|
||||
parent: Logstash
|
||||
nav_order: 230
|
||||
---
|
||||
|
||||
# Advanced configurations
|
||||
|
||||
This section describes how to set up advanced configuration options, like referencing field values and conditional statements, for Logstash.
|
||||
|
||||
## Referencing field values
|
||||
|
||||
To get access to a field, use the `- field` syntax.
|
||||
You can also surround the field name by square brackets `- [field]` which makes it more explicit that you're referring to a field.
|
||||
|
||||
|
||||
For example, if you have the following event:
|
||||
|
||||
```bash
|
||||
{
|
||||
"request": "/products/view/123",
|
||||
"verb": "GET",
|
||||
"response": 200,
|
||||
"headers": {
|
||||
"request_path" => "/"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To access the `request` field, use `- request` or `- [request]`.
|
||||
|
||||
If you want to reference nested fields, use the square brackets syntax and specify the path to the field. With each level being enclosed within square brackets: `- [headers][request_path]`.
|
||||
|
||||
You can reference fields using the `sprintf` format. This is also called string expansion. You need to add a % sign and then wrap the field reference within curly brackets.
|
||||
|
||||
You need to reference field values when using conditional statements.
|
||||
|
||||
For example, you can make the file name dynamic and contain the type of the processed events - either `access` or `error`. The `type` option is mainly used for conditionally applying filter plugins based on the type of events being processed.
|
||||
|
||||
Let's add a `type` option and specify a value of `access`.
|
||||
|
||||
|
||||
```yml
|
||||
input {
|
||||
file {
|
||||
path => ""
|
||||
start_position => "beginning"
|
||||
type => "access"
|
||||
}
|
||||
http {
|
||||
type => "access"
|
||||
}
|
||||
}
|
||||
|
||||
filter {
|
||||
mutate {
|
||||
remove_field => {"host"}
|
||||
}
|
||||
}
|
||||
|
||||
output {
|
||||
stdout {
|
||||
codec => rubydebug
|
||||
}
|
||||
file {
|
||||
path => "%{[type]}.log"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Start Logstash and send an HTTP request. The processed event is output in the terminal. The event now includes a field named `type`.
|
||||
|
||||
You'll see the `access.log` file created within the Logstash directory.
|
||||
|
||||
## Conditional statements
|
||||
|
||||
You can use conditional statements to control the flow of code execution based on some conditions.
|
||||
|
||||
Syntax:
|
||||
|
||||
```yml
|
||||
if EXPR {
|
||||
...
|
||||
} else if EXPR {
|
||||
...
|
||||
} else {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
`EXPR` is any valid Logstash syntax that evaluates to a boolean value.
|
||||
For example, you can check if an event type is set to `access` or `error` and perform some action based on that:
|
||||
|
||||
```yml
|
||||
if [type] == "access" {
|
||||
...
|
||||
} else if [type] == "error" {
|
||||
file { .. }
|
||||
} else {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
You can compare a field value to some arbitrary value:
|
||||
|
||||
```yml
|
||||
if [headers][content_length] >= 1000 {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
You can regex:
|
||||
|
||||
```yml
|
||||
if [some_field =~ /[0-9]+/ {
|
||||
//some field only contains digits
|
||||
}
|
||||
```
|
||||
|
||||
You can use arrays:
|
||||
|
||||
```yml
|
||||
if [some_field] in ["one", "two", "three"] {
|
||||
some field is either "one", "two", or "three"
|
||||
}
|
||||
```
|
||||
|
||||
You can use boolean operators:
|
||||
|
||||
```yml
|
||||
if [type] == "access" or [type] == "error" {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Formatting dates
|
||||
|
||||
You can use the `sprintf` format or string expansion to format dates.
|
||||
For example, you might want the current date to be part of the filename.
|
||||
|
||||
To format the date, add a plus sign in curly brackets followed by the date format - `%{+yyyy-MM-dd}`.
|
||||
|
||||
```yml
|
||||
file {
|
||||
path => "%{[type]}_%{+yyyy_MM_dd}.log"
|
||||
}
|
||||
```
|
||||
|
||||
This is the date stored within the @timestamp fields, which is the time and date of the event.
|
||||
Send a request to the pipeline and verify that a filename is outputted that contains the events date.
|
||||
|
||||
You can embed the date in other outputs as well, for example into the index name in OpenSearch.
|
||||
|
||||
## Sending time information
|
||||
|
||||
You can set the time of events.
|
||||
|
||||
Logstash already sets the time when the event is received by the input plugin within the @timestamp field.
|
||||
In some scenarios, you might need to use a different timestamp.
|
||||
For example, if you have an eCommerce store and you process the orders daily at midnight. When Logstash receives the events at midnight, it sets the timestamp to the current time.
|
||||
But you want it to be the time when the order is placed and not when Logstash received the event.
|
||||
|
||||
Let's change the event timestamp to the date the request is received by the web server. You can do this using a filter plugin named `dates`.
|
||||
The `dates` filter passes a `date` or `datetime` value from a field and uses the results as the event timestamp.
|
||||
|
||||
Add the `date` plugin at the bottom of the `filter` block:
|
||||
|
||||
```yml
|
||||
date {
|
||||
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
|
||||
}
|
||||
```
|
||||
|
||||
timestamp is the field that the `grok` pattern creates.
|
||||
`Z` is the timezone. i.e., UTC offsets.
|
||||
|
||||
Start Logstash and send an HTTP request.
|
||||
|
||||
You can see that the filename contains the date of the request instead of the present date.
|
||||
|
||||
If the passing of the date fails, the `filter` plugin adds a tag named `_datepassfailure` to the text field.
|
||||
|
||||
After you have set the @timestamp field to a new value, you don't really need the other `timestamp` field anymore. You can remove it with the `remove_field` option.
|
||||
|
||||
```yml
|
||||
date {
|
||||
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
|
||||
remove_field => [ "timestamp" ]
|
||||
}
|
||||
```
|
||||
|
||||
## Parsing user agents
|
||||
|
||||
The user agent is the last part of a log entry that consists of the name of the browser, the browser version, and the OS of the device.
|
||||
|
||||
Users might be using a wide range of browsers, devices, and OS's. Doing this manually is hard.
|
||||
|
||||
You can't use `grok` patterns because the `grok` pattern only matches the usage in the string as whole and doesn't figure out which browser the visitor used for instance.
|
||||
|
||||
Logstash ships with a file containing regular expressions for this purpose. This makes it really easy to extract user agent information, which you could send to OpenSearch and run aggregations on.
|
||||
|
||||
To do this, add a `source` option that contains the name of the field. In this case, that's the `agent` field.
|
||||
By default the user agent plugin, adds a number of fields at the top-level of the event.
|
||||
Since that can get pretty confusing, we can add an option named `target` with a value of `ua`, short for user agent. What this does is that it nests the fields within an object named `ua`, making things more organized.
|
||||
|
||||
```yml
|
||||
useragent {
|
||||
source => "agent"
|
||||
target => "ua"
|
||||
}
|
||||
```
|
||||
|
||||
Start Logstah and send an HTTP request.
|
||||
|
||||
You can see a field named `ua` with a number of keys including the browser name and version, the OS, and the device.
|
||||
|
||||
You could OpenSearch Dashboards to create a pie chart that shows how many visitors are from mobile devices and how many are desktop users. Or, you could get statistics on which browser versions are popular.
|
||||
|
||||
## Enriching geographical data
|
||||
|
||||
You can take an IP address and perform geographical lookup to resolve the geographical location of the user using the `geoip` filter.
|
||||
|
||||
The `geoip` filter plugin ships with a database called `geolite 2`, which is provided by a company named MaxMind. `geolite 2` is a popular source of geographical data and it's available for free.
|
||||
Add the `geoip` plugin at the bottom of the `else` block.
|
||||
|
||||
The value of the `source` option is the name of the field containing the IP address, in this case that's `clientip`. You can make this field available using the `grok` pattern.
|
||||
|
||||
```yml
|
||||
geoip {
|
||||
source => "clientip"
|
||||
}
|
||||
```
|
||||
|
||||
Start Logstash and send an HTTP request.
|
||||
|
||||
Within the terminal, you see a new field named `geoip` that contains information such as the timezone, country, continent, city, postal code, and the latitude / longitude pair.
|
||||
|
||||
If you only need the country name for instance, include an option named `fields` with an array of the field names that you want the `geoip` plugin to return.
|
||||
|
||||
Some of the fields are not always available such as city name and region because translating IP addresses into geographical locations is generally not that accurate. If the `geoip` plugin fails to look up the geographical location, it adds a tag named `geoip_lookup_failure`.
|
||||
|
||||
You can use the `geoip` plugin with the OpenSearch output because `location` object within the `geoip` object, is a standard format for representing geospatial data in JSON. This is the same format as OpenSearch uses for its `geo_point` data type.
|
||||
|
||||
You can use the powerful geospatial queries of OpenSearch for working with geographical data.
|
||||
@@ -1,157 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Common filter plugins
|
||||
parent: Logstash
|
||||
nav_order: 220
|
||||
---
|
||||
|
||||
# Common filter plugins
|
||||
|
||||
This page contains a list of common filter plugins.
|
||||
|
||||
## mutate
|
||||
|
||||
You can use the `mutate` filter to change the data type of a field. For example, you can use the `mutate` filter if you're sending events to OpenSearch and you need to change the data type of a field to match any existing mappings.
|
||||
|
||||
To convert the `quantity` field from a `string` type to an `integer` type:
|
||||
|
||||
```yml
|
||||
input {
|
||||
http {
|
||||
host => "127.0.0.1"
|
||||
port => 8080
|
||||
}
|
||||
}
|
||||
|
||||
filter {
|
||||
mutate {
|
||||
convert => {"quantity" => "integer"}
|
||||
}
|
||||
}
|
||||
|
||||
output {
|
||||
file {
|
||||
path => "output.txt"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Sample output
|
||||
|
||||
You can see that the type of the `quantity` field is changed from a `string` to an `integer`.
|
||||
|
||||
```yml
|
||||
{
|
||||
"quantity" => 3,
|
||||
"host" => "127.0.0.1",
|
||||
"@timestamp" => 2021-05-23T19:02:08.026Z,
|
||||
"amount" => 10,
|
||||
"@version" => "1",
|
||||
"headers" => {
|
||||
"request_path" => "/",
|
||||
"connection" => "keep-alive",
|
||||
"content_length" => "41",
|
||||
"http_user_agent" => "PostmanRuntime/7.26.8",
|
||||
"request_method" => "PUT",
|
||||
"cache_control" => "no-cache",
|
||||
"http_accept" => "*/*",
|
||||
"content_type" => "application/json",
|
||||
"http_version" => "HTTP/1.1",
|
||||
"http_host" => "127.0.0.1:8080",
|
||||
"accept_encoding" => "gzip, deflate, br",
|
||||
"postman_token" => "ffd1cdcb-7a1d-4d63-90f8-0f2773069205"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Other data types you can convert to are `float`, `string`, and `boolean` values. If you pass in an array, the `mutate` filter converts all the elements in the array. If you pass a `string` like "world" to cast to an `integer` type, the result is 0 and Logstash continues processing events.
|
||||
|
||||
Logstash supports a few common options for all filter plugins:
|
||||
|
||||
Option | Description
|
||||
:--- | :---
|
||||
`add_field` | Adds one or more fields to the event.
|
||||
`remove_field` | Removes one or more events from the field.
|
||||
`add_tag` | Adds one or more tags to the event. You can use tags to perform conditional processing on events depending on which tags they contain.
|
||||
`remove_tag` | Removes one or more tags from the event.
|
||||
|
||||
For example, you can remove the `host` field from the event:
|
||||
|
||||
```yml
|
||||
input {
|
||||
http {
|
||||
host => "127.0.0.1"
|
||||
port => 8080
|
||||
}
|
||||
}
|
||||
|
||||
filter {
|
||||
mutate {
|
||||
remove_field => {"host"}
|
||||
}
|
||||
}
|
||||
|
||||
output {
|
||||
file {
|
||||
path => "output.txt"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## grok
|
||||
|
||||
With the `grok` filter, you can parse unstructured data and and structure it into fields. The `grok` filter uses text patterns to match text in your logs. You can think of text patterns as variables containing regular expressions.
|
||||
|
||||
The format of a text pattern is as follows:
|
||||
|
||||
```bash
|
||||
%{SYNTAX:SEMANTIC}
|
||||
```
|
||||
|
||||
`SYNTAX` is the format a piece of text should be in for the pattern to match. You can enter any of `grok`'s predefined patterns. For example, you can use the email identifier to match an email address from a given piece of text.
|
||||
|
||||
`SEMANTIC` is an arbitrary name for the matched text. For example, if you're using the email identifier syntax, you can name it “email.”
|
||||
|
||||
The following request consists of the IP address of the visitor, name of the visitor, the timestamp of the request, the HTTP verb and URL, the HTTP status code, and the number of bytes:
|
||||
|
||||
```bash
|
||||
184.252.108.229 - joe [20/Sep/2017:13:22:22 +0200] GET /products/view/123 200 12798
|
||||
```
|
||||
|
||||
To split this request into different fields:
|
||||
|
||||
```yml
|
||||
filter {
|
||||
grok {
|
||||
match => { "message" => " %{IP: ip_address} %{USER:identity}
|
||||
%{USER:auth} \[%{HTTPDATE:reg_ts}\]
|
||||
\"%{WORD:http_verb}
|
||||
%{URIPATHPARAM: req_path}
|
||||
\" %{INT:http_status:int}
|
||||
%{INT:num_bytes:int}"}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
where:
|
||||
|
||||
- `IP`: matches the IP address field.
|
||||
- `USER`: matches the user name.
|
||||
- `WORD`: matches the HTTP verb.
|
||||
- `URIPATHPARAM`: matches the URI path.
|
||||
- `INT`: matches the HTTP status field.
|
||||
- `INT`: matches the number of bytes.
|
||||
|
||||
This is what the event looks like after the `grok` filter breaks it down into individual fields:
|
||||
|
||||
```yml
|
||||
ip_address: 184.252.108.229
|
||||
identity: joe
|
||||
reg_ts: 20/Sep/2017:13:22:22 +0200
|
||||
http_verb:GET
|
||||
req_path: /products/view/123
|
||||
http_status: 200
|
||||
num_bytes: 12798
|
||||
```
|
||||
|
||||
For common log formats, you use the predefined patterns defined here---[Logstash patterns](https://github.com/logstash-plugins/logstash-patterns-core/blob/master/patterns/ecs-v1). You can make any adjustments to the results with the `mutate` filter.
|
||||
@@ -1,40 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Logstash execution model
|
||||
parent: Logstash
|
||||
nav_order: 210
|
||||
---
|
||||
|
||||
# Logstash execution model
|
||||
|
||||
Here's a brief introduction to how Logstash processes events internally.
|
||||
|
||||
## Handling events concurrently
|
||||
|
||||
You can configure Logstash to have a number of inputs listening for events. Each input runs in its own thread to avoid inputs blocking each other. If you have two incoming events at the same time, Logstash handles both events concurrently.
|
||||
|
||||
After receiving an event and possibly applying an input codec, Logstash sends the event to a work queue. Pipeline workers or batchers perform the rest of the work involving filters and outputs along with any codec used at the output. Each pipeline worker also runs within its own thread meaning that Logstash processes multiple events simultaneously.
|
||||
|
||||
## Processing events in batches
|
||||
|
||||
A pipeline worker consumes events from the work queue in batches to optimize the throughput of the pipeline as a whole.
|
||||
|
||||
One reason why Logstash works in batches is that some code needs to be executed regardless of how many events are processed at a time within the pipeline worker. Instead of executing that code 100 times for 100 events, it’s more efficient to execute it once for a batch of 100 events.
|
||||
|
||||
Another reason is that a few output plugins group together events as batches. For example, if you send 100 requests to OpenSearch, the OpenSearch output plugin uses the bulk API to send a single request that groups together the 100 requests.
|
||||
|
||||
Logstash determines the batch size by two configuration options---a number representing the maximum batch size and the batch delay. The batch delay is how long Logstash waits before processing the unprocessed batch of events.
|
||||
If you set the maximum batch size to 50 and the batch delay to 100 ms, Logstash processes a batch if they're either 50 unprocessed events in the work queue or if one hundred milliseconds have elapsed.
|
||||
|
||||
The reason that a batch is processed, even if the maximum batch size isn’t reached, is to reduce the delay in processing and to continue to process events in a timely manner. This works well for pipelines that process a low volume of events.
|
||||
|
||||
Imagine that you’ve a pipeline that processes error logs from web servers and pushes them to OpenSearch. You’re using OpenSearch Dashboards to analyze the error logs. Because you’re possibly dealing with a fairly low number of events, it might take a long time to reach 50 events. Logstash processes the events before reaching this threshold because otherwise there would be a long delay before we see the errors appear in OpenSearch Dashboards.
|
||||
|
||||
The default batch size and batch delay work for most cases. You don’t need to change the default values unless you need to minutely optimize the performance.
|
||||
|
||||
## Optimizing based on CPU cores
|
||||
|
||||
The number of pipeline workers are proportional to the number of CPU cores on the nodes.
|
||||
If you have 5 workers running on a server with 2 CPU cores, the 5 workers won't be able to process events concurrently. On the other hand, running 5 workers on a server running 10 CPU cores limits the throughput of a Logstash instance.
|
||||
|
||||
Instead of running a fixed number of workers, which results in poor performance in some cases, Logstash examines the number of CPU cores of the instance and selects the number of pipeline workers to optimize its performance for the platform on which its running. For instance, your local development machine might not have the same processing power as a production server. So you don't need to manually configure Logstash for different machines.
|
||||
@@ -1,361 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Logstash
|
||||
nav_order: 200
|
||||
has_children: true
|
||||
has_toc: true
|
||||
redirect_from:
|
||||
- /clients/logstash/
|
||||
---
|
||||
|
||||
# Logstash
|
||||
|
||||
Logstash is a real-time event processing engine. It's part of the OpenSearch stack which includes OpenSearch, Beats, and OpenSearch Dashboards.
|
||||
|
||||
You can send events to Logstash from many different sources. Logstash processes the events and sends it one or more destinations. For example, you can send access logs from a web server to Logstash. Logstash extracts useful information from each log and sends it to a destination like OpenSearch.
|
||||
|
||||
Sending events to Logstash lets you decouple event processing from your app. Your app only needs to send events to Logstash and doesn’t need to know anything about what happens to the events afterwards.
|
||||
|
||||
The open-source community originally built Logstash for processing log data but now you can process any type of events, including events in XML or JSON format.
|
||||
|
||||
## Structure of a pipeline
|
||||
|
||||
The way that Logstash works is that you configure a pipeline that has three phases---inputs, filters, and outputs.
|
||||
|
||||
Each phase uses one or more plugins. Logstash has over 200 built-in plugins so chances are that you’ll find what you need. Apart from the built-in plugins, you can use plugins from the community or even write your own.
|
||||
|
||||
The structure of a pipeline is as follows:
|
||||
|
||||
```yml
|
||||
input {
|
||||
input_plugin => {}
|
||||
}
|
||||
|
||||
filter {
|
||||
filter_plugin => {}
|
||||
}
|
||||
|
||||
output {
|
||||
output_plugin => {}
|
||||
}
|
||||
```
|
||||
|
||||
where:
|
||||
|
||||
* `input` receives events like logs from multiple sources simultaneously. Logstash supports a number of input plugins for TCP/UDP, files, syslog, Microsoft Windows EventLogs, stdin, HTTP, and so on. You can also use an open source collection of input tools called Beats to gather events. The input plugin sends the events to a filter.
|
||||
* `filter` parses and enriches the events in one way or the other. Logstash has a large collection of filter plugins that modify events and pass them on to an output. For example, a `grok` filter parses unstructured events into fields and a `mutate` filter changes fields. Filters are executed sequentially.
|
||||
* `output` ships the filtered events to one or more destinations. Logstash supports a wide range of output plugins for destinations like OpenSearch, TCP/UDP, emails, files, stdout, HTTP, Nagios, and so on.
|
||||
|
||||
Both the input and output phases support codecs to process events as they enter or exit the pipeline.
|
||||
Some of the popular codecs are `json` and `multiline`. The `json` codec processes data that’s in JSON format and the `multiline` codec merges multiple line events into a single line.
|
||||
|
||||
You can also write conditional statements within pipeline configurations to perform certain actions, if a certain criteria is met.
|
||||
|
||||
## Install Logstash
|
||||
|
||||
The OpenSearch Logstash plugin has two installation options at this time: Linux (ARM64/X64) and Docker (ARM64/X64).
|
||||
|
||||
Make sure you have [Java Development Kit (JDK)](https://www.oracle.com/java/technologies/javase-downloads.html) version 8 or 11 installed.
|
||||
|
||||
If you're migrating from an existing Logstash installation, you can install the [OpenSearch output plugin](https://rubygems.org/gems/logstash-output-opensearch/) manually and [update pipeline.conf](https://opensearch.org/docs/latest/clients/logstash/ship-to-opensearch/). We include this plugin by default in our tarball and Docker downloads.
|
||||
{: .note }
|
||||
|
||||
### Tarball
|
||||
|
||||
1. Download the Logstash tarball from [OpenSearch downloads](https://opensearch.org/downloads.html).
|
||||
|
||||
2. Navigate to the downloaded folder in the terminal and extract the files:
|
||||
|
||||
```bash
|
||||
tar -zxvf logstash-oss-with-opensearch-output-plugin-7.13.2-linux-x64.tar.gz
|
||||
```
|
||||
|
||||
3. Navigate to the `logstash-7.13.2` directory.
|
||||
- You can add your pipeline configurations to the `config` directory. Logstash saves any data from the plugins in the `data` directory. The `bin` directory contains the binaries for starting Logstash and managing plugins.
|
||||
|
||||
### Docker
|
||||
|
||||
1. Pull the Logstash oss package with the OpenSearch output plugin image:
|
||||
|
||||
```
|
||||
docker pull opensearchproject/logstash-oss-with-opensearch-output-plugin:7.13.2
|
||||
```
|
||||
|
||||
1. Create a Docker network:
|
||||
|
||||
```
|
||||
docker network create test
|
||||
```
|
||||
|
||||
1. Start OpenSearch with this network:
|
||||
|
||||
```
|
||||
docker run -p 9200:9200 -p 9600:9600 --name opensearch --net test -e "discovery.type=single-node" opensearchproject/opensearch:1.0.0
|
||||
```
|
||||
|
||||
1. Start Logstash:
|
||||
|
||||
```
|
||||
docker run -it --rm --name logstash --net test opensearchproject/logstash-oss-with-opensearch-output-plugin:7.13.2 -e 'input { stdin { } } output {
|
||||
opensearch {
|
||||
hosts => ["https://opensearch:9200"]
|
||||
index => "opensearch-logstash-docker-%{+YYYY.MM.dd}"
|
||||
user => "admin"
|
||||
password => "admin"
|
||||
ssl => true
|
||||
ssl_certificate_verification => false
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## Process text from the terminal
|
||||
|
||||
You can define a pipeline that listens for events on `stdin` and outputs events on `stdout`. `stdin` and `stdout` refer to the terminal in which you’re running Logstash.
|
||||
|
||||
To enter some text in the terminal and see the event data in the output:
|
||||
|
||||
1. Use the `-e` argument to pass a pipeline configuration directly to the Logstash binary. In this case, `stdin` is the input plugin and `stdout` is the output plugin:
|
||||
|
||||
```bash
|
||||
bin/logstash -e "input { stdin { } } output { stdout { } }"
|
||||
```
|
||||
Add the `—debug` flag to see a more detailed output.
|
||||
|
||||
2. Enter "hello world" in your terminal. Logstash processes the text and outputs it back to the terminal:
|
||||
|
||||
```yml
|
||||
{
|
||||
"message" => "hello world",
|
||||
"host" => "a483e711a548.ant.amazon.com",
|
||||
"@timestamp" => 2021-05-30T05:15:56.816Z,
|
||||
"@version" => "1"
|
||||
}
|
||||
```
|
||||
|
||||
The `message` field contains your raw input. The `host` field is an IP address when you don’t run Logstash locally. `@timestamp` shows the date and time for when the event is processed. Logstash uses the `@version` field for internal processing.
|
||||
|
||||
3. Press `Ctrl + C` to shut down Logstash.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
If you already have a Logstash process running, you’ll get an error. To fix this issue:
|
||||
|
||||
1. Delete the `.lock` file from the `data` directory:
|
||||
|
||||
```bash
|
||||
cd data
|
||||
rm -rf .lock
|
||||
```
|
||||
|
||||
2. Restart Logstash.
|
||||
|
||||
## Process JSON or HTTP input and output it to a file
|
||||
|
||||
To define a pipeline that handles JSON requests:
|
||||
|
||||
1. Open the `config/pipeline.conf` file in any text editor you like. You can create a pipeline configuration file with any extension, the `.conf` extension is a Logstash convention. Add the `json` codec to accept JSON as the input and the `file` plugin to output the processed events to a `.txt` file:
|
||||
|
||||
```yml
|
||||
input {
|
||||
stdin {
|
||||
codec => json
|
||||
}
|
||||
}
|
||||
output {
|
||||
file {
|
||||
path => "output.txt"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To process inputs from a file, add an input file to the `events-data` directory and then pass its path to the `file` plugin at the input:
|
||||
|
||||
```yml
|
||||
input {
|
||||
file {
|
||||
path => "events-data/input_data.log"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. Start Logstash:
|
||||
|
||||
```bash
|
||||
$ bin/logstash -f config/pipeline.conf
|
||||
```
|
||||
|
||||
`config/pipeline.conf` is a relative path to the `pipeline.conf` file. You can use an absolute path as well.
|
||||
|
||||
3. Add a JSON object in the terminal:
|
||||
|
||||
```json
|
||||
{ "amount": 10, "quantity": 2}
|
||||
```
|
||||
|
||||
The pipeline only handles a single line of input. If you paste some JSON that spans multiple lines, you’ll get an error.
|
||||
|
||||
4. Check that the fields from the JSON object are added to the `output.txt` file:
|
||||
|
||||
```json
|
||||
$ cat output.txt
|
||||
|
||||
{
|
||||
"@version": "1",
|
||||
"@timestamp": "2021-05-30T05:52:52.421Z",
|
||||
"host": "a483e711a548.ant.amazon.com",
|
||||
"amount": 10,
|
||||
"quantity": 2
|
||||
}
|
||||
```
|
||||
|
||||
If you type in some invalid JSON as the input, you'll see a JSON parsing error. Logstash doesn't discard the invalid JSON because you still might want to do something with it. For example, you can trigger an email or send a notification to a Slack channel.
|
||||
|
||||
To define a pipeline that handles HTTP requests:
|
||||
|
||||
1. Use the `http` plugin to send events to Logstash through HTTP:
|
||||
|
||||
```yml
|
||||
input {
|
||||
http {
|
||||
host => "127.0.0.1"
|
||||
port => 8080
|
||||
}
|
||||
}
|
||||
|
||||
output {
|
||||
file {
|
||||
path => "output.txt"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you don’t specify any options, the `http` plugin binds to `localhost` and listens on port 8080.
|
||||
|
||||
2. Start Logstash:
|
||||
|
||||
```bash
|
||||
$ bin/logstash -f config/pipeline.conf
|
||||
```
|
||||
|
||||
3. Use Postman to send an HTTP request. Set `Content-Type` to an HTTP header with a value of `application/json`:
|
||||
|
||||
```json
|
||||
PUT 127.0.0.1:8080
|
||||
|
||||
{
|
||||
"amount": 10,
|
||||
"quantity": 2
|
||||
}
|
||||
```
|
||||
|
||||
Or, you can use the `curl` command:
|
||||
|
||||
```bash
|
||||
curl -XPUT -H "Content-Type: application/json" -d ' {"amount": 7, "quantity": 3 }' http://localhost:8080 (http://localhost:8080/)
|
||||
```
|
||||
|
||||
Even though we haven't added the `json` plugin to the input, the pipeline configuration still works because the HTTP plugin automatically applies the appropriate codec based on the `Content-Type` header.
|
||||
If you specify a value of `applications/json`, Logstash parses the request body as JSON.
|
||||
|
||||
The `headers` field contains the HTTP headers that Logstash receives:
|
||||
|
||||
```json
|
||||
{
|
||||
"host": "127.0.0.1",
|
||||
"quantity": "3",
|
||||
"amount": 10,
|
||||
"@timestamp": "2021-05-30T06:05:48.135Z",
|
||||
"headers": {
|
||||
"http_version": "HTTP/1.1",
|
||||
"request_method": "PUT",
|
||||
"http_user_agent": "PostmanRuntime/7.26.8",
|
||||
"connection": "keep-alive",
|
||||
"postman_token": "c6cd29cf-1b37-4420-8db3-9faec66b9e7e",
|
||||
"http_host": "127.0.0.1:8080",
|
||||
"cache_control": "no-cache",
|
||||
"request_path": "/",
|
||||
"content_type": "application/json",
|
||||
"http_accept": "*/*",
|
||||
"content_length": "41",
|
||||
"accept_encoding": "gzip, deflate, br"
|
||||
},
|
||||
"@version": "1"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Automatically reload the pipeline configuration
|
||||
|
||||
You can configure Logstash to detect any changes to the pipeline configuration file or the input log file and automatically reload the configuration.
|
||||
|
||||
The `stdin` plugin doesn’t supporting automatic reloading.
|
||||
{: .note }
|
||||
|
||||
1. Add an option named `start_position` with a value of `beginning` to the input plugin:
|
||||
|
||||
```yml
|
||||
input {
|
||||
file {
|
||||
path => "/Users/<user>/Desktop/logstash7-12.1/events-data/input_file.log"
|
||||
start_position => "beginning"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Logstash only processes any new events added to the input file and ignores the ones that it has already processed to avoid processing the same event more than once on restart.
|
||||
|
||||
Logstash records its progress in a file that's referred to as a `sinceDB` file. Logstash creates a `sinceDB` file for each file that it watches for changes.
|
||||
|
||||
2. Open the `sinceDB` file to check how much of the input files are processed:
|
||||
|
||||
```bash
|
||||
cd data/plugins/inputs/file/
|
||||
ls -al
|
||||
|
||||
-rw-r--r-- 1 user staff 0 Jun 13 10:50 .sincedb_9e484f2a9e6c0d1bdfe6f23ac107ffc5
|
||||
|
||||
cat .sincedb_9e484f2a9e6c0d1bdfe6f23ac107ffc5
|
||||
|
||||
51575938 1 4 7727
|
||||
```
|
||||
|
||||
The last number in the `sinceDB` file (7727) is the byte offset of the last known event processed.
|
||||
|
||||
5. To process the input file from the beginning, delete the `sinceDB` file:
|
||||
|
||||
```yml
|
||||
rm .sincedb_*
|
||||
```
|
||||
|
||||
2. Start Logstash with a `—-config.reload.automatic` argument:
|
||||
|
||||
```bash
|
||||
bin/logstash -f config/pipeline.conf --config.reload.automatic
|
||||
```
|
||||
|
||||
The `reload` option only reloads if you add a new line at the end of the pipeline configuration file.
|
||||
|
||||
Sample output:
|
||||
|
||||
```yml
|
||||
{
|
||||
"message" => "216.243.171.38 - - [20/Sep/2017:19:11:52 +0200] \"GET /products/view/123 HTTP/1.1\" 200 12798 \"https://codingexplained.com/products\" \"Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)\"",
|
||||
"@version" => "1",
|
||||
"host" => "a483e711a548.ant.amazon.com",
|
||||
"path" => "/Users/kumarjao/Desktop/odfe1/logstash-7.12.1/events-data/input_file.log",
|
||||
"@timestamp" => 2021-06-13T18:03:30.423Z
|
||||
}
|
||||
{
|
||||
"message" => "91.59.108.75 - - [20/Sep/2017:20:11:43 +0200] \"GET /js/main.js HTTP/1.1\" 200 588 \"https://codingexplained.com/products/view/863\" \"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0\"",
|
||||
"@version" => "1",
|
||||
"host" => "a483e711a548.ant.amazon.com",
|
||||
"path" => "/Users/kumarjao/Desktop/odfe1/logstash-7.12.1/events-data/input_file.log",
|
||||
"@timestamp" => 2021-06-13T18:03:30.424Z
|
||||
}
|
||||
```
|
||||
|
||||
7. Add a new line to the input file.
|
||||
- Logstash immediately detects the change and processes the new line as an event.
|
||||
|
||||
8. Make a change to the `pipeline.conf` file.
|
||||
- Logstash immediately detects the change and reloads the modified pipeline.
|
||||
@@ -1,77 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Ship events to OpenSearch
|
||||
parent: Logstash
|
||||
nav_order: 220
|
||||
---
|
||||
|
||||
# Ship events to OpenSearch
|
||||
|
||||
You can Ship Logstash events to an OpenSearch cluster and then visualize your events with OpenSearch Dashboards.
|
||||
|
||||
Make sure you have [Logstash]({{site.url}}{{site.baseurl}}/clients/logstash/index/#install-logstash), [OpenSearch]({{site.url}}{{site.baseurl}}/opensearch/install/index/), and [OpenSearch Dashboards]({{site.url}}{{site.baseurl}}/dashboards/install/index/).
|
||||
{: .note }
|
||||
|
||||
## OpenSearch output plugin
|
||||
|
||||
To run the OpenSearch output plugin, add the following configuration in your `pipeline.conf` file:
|
||||
|
||||
```yml
|
||||
output {
|
||||
opensearch {
|
||||
hosts => "https://localhost:9200"
|
||||
user => "admin"
|
||||
password => "admin"
|
||||
index => "logstash-logs-%{+YYYY.MM.dd}"
|
||||
ssl_certificate_verification => false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Sample walkthrough
|
||||
|
||||
1. Open the `config/pipeline.conf` file and add in the following configuration:
|
||||
|
||||
```yml
|
||||
input {
|
||||
stdin {
|
||||
codec => json
|
||||
}
|
||||
}
|
||||
|
||||
output {
|
||||
opensearch {
|
||||
hosts => "https://localhost:9200"
|
||||
user => "admin"
|
||||
password => "admin"
|
||||
index => "logstash-logs-%{+YYYY.MM.dd}"
|
||||
ssl_certificate_verification => false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This Logstash pipeline accepts JSON input through the terminal and ships the events to an OpenSearch cluster running locally. Logstash writes the events to an index with the `logstash-logs-%{+YYYY.MM.dd}` naming convention.
|
||||
|
||||
2. Start Logstash:
|
||||
|
||||
```bash
|
||||
$ bin/logstash -f config/pipeline.conf --config.reload.automatic
|
||||
```
|
||||
|
||||
`config/pipeline.conf` is a relative path to the `pipeline.conf` file. You can use an absolute path as well.
|
||||
|
||||
3. Add a JSON object in the terminal:
|
||||
|
||||
```json
|
||||
{ "amount": 10, "quantity": 2}
|
||||
```
|
||||
|
||||
4. Start OpenSearch Dashboards and choose **Dev Tools**:
|
||||
|
||||
```json
|
||||
GET _cat/indices?v
|
||||
|
||||
health | status | index | uuid | pri | rep | docs.count | docs.deleted | store.size | pri.store.size
|
||||
green | open | logstash-logs-2021.07.01 | iuh648LYSnmQrkGf70pplA | 1 | 1 | 1 | 0 | 10.3kb | 5.1kb
|
||||
```
|
||||
@@ -1,128 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Python client
|
||||
nav_order: 70
|
||||
---
|
||||
|
||||
# Python client
|
||||
|
||||
The OpenSearch Python client provides a more natural syntax for interacting with your cluster. Rather than sending HTTP requests to a given URL, you can create an OpenSearch client for your cluster and call the client's built-in functions.
|
||||
|
||||
{% comment %}
|
||||
`opensearch-py` is the lower-level of the two Python clients. If you want a general client for assorted operations, it's a great choice. If you want a higher-level client strictly for indexing and search operations, consider [opensearch-dsl-py]({{site.url}}{{site.baseurl}}/clients/python-dsl/).
|
||||
{% endcomment %}
|
||||
|
||||
|
||||
## Setup
|
||||
|
||||
To add the client to your project, install it using [pip](https://pip.pypa.io/):
|
||||
|
||||
```bash
|
||||
pip install opensearch-py
|
||||
```
|
||||
|
||||
Then import it like any other module:
|
||||
|
||||
```python
|
||||
from opensearchpy import OpenSearch
|
||||
```
|
||||
|
||||
If you prefer to add the client manually or just want to examine the source code, see [opensearch-py on GitHub](https://github.com/opensearch-project/opensearch-py).
|
||||
|
||||
|
||||
## Sample code
|
||||
|
||||
```python
|
||||
from opensearchpy import OpenSearch
|
||||
|
||||
host = 'localhost'
|
||||
port = 9200
|
||||
auth = ('admin', 'admin') # For testing only. Don't store credentials in code.
|
||||
ca_certs_path = '/full/path/to/root-ca.pem' # Provide a CA bundle if you use intermediate CAs with your root CA.
|
||||
|
||||
# Optional client certificates if you don't want to use HTTP basic authentication.
|
||||
# client_cert_path = '/full/path/to/client.pem'
|
||||
# client_key_path = '/full/path/to/client-key.pem'
|
||||
|
||||
# Create the client with SSL/TLS enabled, but hostname verification disabled.
|
||||
client = OpenSearch(
|
||||
hosts = [{'host': host, 'port': port}],
|
||||
http_compress = True, # enables gzip compression for request bodies
|
||||
http_auth = auth,
|
||||
# client_cert = client_cert_path,
|
||||
# client_key = client_key_path,
|
||||
use_ssl = True,
|
||||
verify_certs = True,
|
||||
ssl_assert_hostname = False,
|
||||
ssl_show_warn = False,
|
||||
ca_certs = ca_certs_path
|
||||
)
|
||||
|
||||
# Create an index with non-default settings.
|
||||
index_name = 'python-test-index'
|
||||
index_body = {
|
||||
'settings': {
|
||||
'index': {
|
||||
'number_of_shards': 4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response = client.indices.create(index_name, body=index_body)
|
||||
print('\nCreating index:')
|
||||
print(response)
|
||||
|
||||
# Add a document to the index.
|
||||
document = {
|
||||
'title': 'Moneyball',
|
||||
'director': 'Bennett Miller',
|
||||
'year': '2011'
|
||||
}
|
||||
id = '1'
|
||||
|
||||
response = client.index(
|
||||
index = index_name,
|
||||
body = document,
|
||||
id = id,
|
||||
refresh = True
|
||||
)
|
||||
|
||||
print('\nAdding document:')
|
||||
print(response)
|
||||
|
||||
# Search for the document.
|
||||
q = 'miller'
|
||||
query = {
|
||||
'size': 5,
|
||||
'query': {
|
||||
'multi_match': {
|
||||
'query': q,
|
||||
'fields': ['title^2', 'director']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response = client.search(
|
||||
body = query,
|
||||
index = index_name
|
||||
)
|
||||
print('\nSearch results:')
|
||||
print(response)
|
||||
|
||||
# Delete the document.
|
||||
response = client.delete(
|
||||
index = index_name,
|
||||
id = id
|
||||
)
|
||||
|
||||
print('\nDeleting document:')
|
||||
print(response)
|
||||
|
||||
# Delete the index.
|
||||
response = client.indices.delete(
|
||||
index = index_name
|
||||
)
|
||||
|
||||
print('\nDeleting index:')
|
||||
print(response)
|
||||
```
|
||||
-160
@@ -1,160 +0,0 @@
|
||||
title: OpenSearch documentation
|
||||
description: >- # this means to ignore newlines until "baseurl:"
|
||||
Documentation for OpenSearch, the Apache 2.0 search, analytics, and visualization suite with advanced security, alerting, SQL support, automated index management, deep performance analysis, and more.
|
||||
baseurl: "/docs/latest" # the subpath of your site, e.g. /blog
|
||||
url: "https://opensearch.org" # the base hostname & protocol for your site, e.g. http://example.com
|
||||
permalink: /:path/
|
||||
|
||||
opensearch_version: 1.1.0
|
||||
opensearch_major_minor_version: 1.1
|
||||
lucene_version: 8_9_0
|
||||
|
||||
# Build settings
|
||||
markdown: kramdown
|
||||
remote_theme: pmarsceill/just-the-docs@v0.3.3
|
||||
|
||||
# Kramdown settings
|
||||
kramdown:
|
||||
toc_levels: 2..3
|
||||
|
||||
logo: "/assets/images/logo.svg"
|
||||
|
||||
# Aux links for the upper right navigation
|
||||
aux_links:
|
||||
|
||||
color_scheme: opensearch
|
||||
|
||||
# Define Jekyll collections
|
||||
collections:
|
||||
# Define a collection named "tests", its documents reside in the "_tests" directory
|
||||
upgrade-to:
|
||||
permalink: /:collection/:path/
|
||||
output: true
|
||||
opensearch:
|
||||
permalink: /:collection/:path/
|
||||
output: true
|
||||
dashboards:
|
||||
permalink: /:collection/:path/
|
||||
output: true
|
||||
security-plugin:
|
||||
permalink: /:collection/:path/
|
||||
output: true
|
||||
search-plugins:
|
||||
permalink: /:collection/:path/
|
||||
output: true
|
||||
im-plugin:
|
||||
permalink: /:collection/:path/
|
||||
output: true
|
||||
replication-plugin:
|
||||
permalink: /:collection/:path/
|
||||
output: true
|
||||
monitoring-plugins:
|
||||
permalink: /:collection/:path/
|
||||
output: true
|
||||
clients:
|
||||
permalink: /:collection/:path/
|
||||
output: true
|
||||
troubleshoot:
|
||||
permalink: /:collection/:path/
|
||||
output: true
|
||||
external_links:
|
||||
permalink: /:collection/:path/
|
||||
output: true
|
||||
|
||||
just_the_docs:
|
||||
# Define the collections used in the theme
|
||||
collections:
|
||||
upgrade-to:
|
||||
name: Upgrade to OpenSearch
|
||||
# nav_exclude: true
|
||||
nav_fold: true
|
||||
# search_exclude: true
|
||||
opensearch:
|
||||
name: OpenSearch
|
||||
nav_fold: true
|
||||
dashboards:
|
||||
name: OpenSearch Dashboards
|
||||
nav_fold: true
|
||||
security-plugin:
|
||||
name: Security plugin
|
||||
nav_fold: true
|
||||
search-plugins:
|
||||
name: Search plugins
|
||||
nav_fold: true
|
||||
im-plugin:
|
||||
name: Index management plugin
|
||||
nav_fold: true
|
||||
replication-plugin:
|
||||
name: Replication plugin
|
||||
nav_fold: true
|
||||
monitoring-plugins:
|
||||
name: Monitoring plugins
|
||||
nav_fold: true
|
||||
clients:
|
||||
name: Clients and tools
|
||||
nav_fold: true
|
||||
troubleshoot:
|
||||
name: Troubleshooting
|
||||
nav_fold: true
|
||||
external_links:
|
||||
name: External links
|
||||
|
||||
|
||||
# Enable or disable the site search
|
||||
# Supports true (default) or false
|
||||
search_enabled: true
|
||||
|
||||
search:
|
||||
# Split pages into sections that can be searched individually
|
||||
# Supports 1 - 6, default: 2
|
||||
heading_level: 2
|
||||
# Maximum amount of previews per search result
|
||||
# Default: 3
|
||||
previews: 3
|
||||
# Maximum amount of words to display before a matched word in the preview
|
||||
# Default: 5
|
||||
preview_words_before: 5
|
||||
# Maximum amount of words to display after a matched word in the preview
|
||||
# Default: 10
|
||||
preview_words_after: 10
|
||||
# Set the search token separator
|
||||
# Default: /[\s\-/]+/
|
||||
# Example: enable support for hyphenated search words
|
||||
tokenizer_separator: /[\s/]+/
|
||||
# Display the relative url in search results
|
||||
# Supports true (default) or false
|
||||
rel_url: true
|
||||
# Enable or disable the search button that appears in the bottom right corner of every page
|
||||
# Supports true or false (default)
|
||||
button: false
|
||||
|
||||
# Google Analytics Tracking (optional)
|
||||
# e.g, UA-1234567-89
|
||||
ga_tracking: G-BQV14XK08F
|
||||
|
||||
# Disable the just-the-docs theme anchor links in favor of our custom ones
|
||||
# See _includes/head_custom.html
|
||||
heading_anchors: false
|
||||
|
||||
# Adds on-hover anchor links to h2-h6
|
||||
anchor_links: true
|
||||
|
||||
footer_content:
|
||||
|
||||
plugins:
|
||||
- jekyll-remote-theme
|
||||
- jekyll-redirect-from
|
||||
- jekyll-sitemap
|
||||
|
||||
# Exclude from processing.
|
||||
# The following items will not be processed, by default. Create a custom list
|
||||
# to override the default setting.
|
||||
exclude:
|
||||
- Gemfile
|
||||
- Gemfile.lock
|
||||
- node_modules
|
||||
- vendor/bundle/
|
||||
- vendor/cache/
|
||||
- vendor/gems/
|
||||
- vendor/ruby/
|
||||
- README.md
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Browser compatibility
|
||||
parent: OpenSearch Dashboards
|
||||
nav_order: 3
|
||||
---
|
||||
|
||||
# Browser compatibility
|
||||
|
||||
OpenSearch Dashboards supports the following web browsers:
|
||||
|
||||
- Chrome
|
||||
- Firefox
|
||||
- Safari
|
||||
- Edge (Chromium)
|
||||
|
||||
Other Chromium-based browsers might work, as well. Internet Explorer and Microsoft Edge Legacy are **not** supported.
|
||||
@@ -1,142 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Dashboards query language
|
||||
nav_order: 99
|
||||
---
|
||||
|
||||
# Dashboards Query Language
|
||||
|
||||
Similar to the [Query DSL]({{site.url}}{{site.baseurl}}/opensearch/query-dsl/index) that lets you use the HTTP request body to search for data, you can use the Dashbaords Query Language (DQL) in OpenSearch Dashboards to search for data and visualizations.
|
||||
|
||||
For example, if you want to see all visualizations of visits to a host based in the US, enter `geo.dest:US` into the search field, and Dashboards refreshes to display all related data.
|
||||
|
||||
Just like the query DSL, DQL has a handful of query types, so use whichever best fits your use case.
|
||||
|
||||
This section uses the OpenSearch Dashboards sample web log data. To add sample data in Dashboards, log in to OpenSearch Dashboards, choose **Home**, **Add sample data**, and then **Add data**.
|
||||
|
||||
---
|
||||
|
||||
#### Table of contents
|
||||
1. TOC
|
||||
{:toc}
|
||||
|
||||
---
|
||||
|
||||
## Terms query
|
||||
|
||||
The most basic query is to just specify the term you're searching for.
|
||||
|
||||
```
|
||||
host:www.example.com
|
||||
```
|
||||
|
||||
To access an object's nested field, list the complete path to the field separated by periods. For example, to retrieve the `lat` field in the `coordinates` object:
|
||||
|
||||
```
|
||||
coordinates.lat:43.7102
|
||||
```
|
||||
|
||||
DQL also supports leading and trailing wildcards, so you can search for any terms that match your pattern.
|
||||
|
||||
```
|
||||
host.keyword:*.example.com/*
|
||||
```
|
||||
|
||||
To check if a field exists or has any data, use a wildcard to see if Dashboards returns any results.
|
||||
|
||||
```
|
||||
host.keyword:*
|
||||
```
|
||||
|
||||
## Boolean query
|
||||
|
||||
To mix and match, or even combine, multiple queries for more refined results, you can use the boolean operators `and`, `or`, and `not`. DQL is not case sensitive, so `AND` and `and` are the same.
|
||||
|
||||
```
|
||||
host.keyword:www.example.com and response.keyword:200
|
||||
```
|
||||
|
||||
The following example demonstrates how to use multiple operators in one query.
|
||||
|
||||
```
|
||||
geo.dest:US or response.keyword:200 and host.keyword:www.example.com
|
||||
```
|
||||
|
||||
Remember that boolean operators follow the logical precedence order of `not`, `and`, and `or`, so if you have an expression like the previous example, `response.keyword:200 and host.keyword:www.example.com` gets evaluated first, and then Dashboards uses that result to compare with `geo.dest:US`.
|
||||
|
||||
To avoid confusion, we recommend using parentheses to dictate the order you want to evaluate in. If you want to evaluate `geo.dest:US or response.keyword:200` first, your expression becomes:
|
||||
|
||||
```
|
||||
(geo.dest:US or response.keyword:200) and host.keyword:www.example.com
|
||||
```
|
||||
|
||||
## Date and range queries
|
||||
|
||||
DQL also supports inequalities if you're using numeric inequalities.
|
||||
|
||||
```
|
||||
bytes >= 15 and memory < 15
|
||||
```
|
||||
|
||||
Similarly, you can use the same method to find a date before or after your query. `>` indicates a search for a date after your specified date, and `<` returns dates before.
|
||||
|
||||
```
|
||||
@timestamp > "2020-12-14T09:35:33"
|
||||
```
|
||||
|
||||
## Nested field query
|
||||
|
||||
If you have a document with nested fields, you have to specify which parts of the document you want to retrieve.
|
||||
|
||||
Suppose that you have the following document:
|
||||
|
||||
```json
|
||||
{
|
||||
"superheroes":[
|
||||
{
|
||||
"hero-name": "Superman",
|
||||
"real-identity": "Clark Kent",
|
||||
"age": 28
|
||||
},
|
||||
{
|
||||
"hero-name": "Batman",
|
||||
"real-identity": "Bruce Wayne",
|
||||
"age": 26
|
||||
},
|
||||
{
|
||||
"hero-name": "Flash",
|
||||
"real-identity": "Barry Allen",
|
||||
"age": 28
|
||||
},
|
||||
{
|
||||
"hero-name": "Robin",
|
||||
"real-identity": "Dick Grayson",
|
||||
"age": 15
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The following example demonstrates how to use DQL to retrieve a specific field.
|
||||
|
||||
```
|
||||
superheroes: {hero-name: Superman}
|
||||
```
|
||||
|
||||
If you want to retrieve multiple objects from your document, just specify all of the fields you want to retrieve.
|
||||
|
||||
```
|
||||
superheroes: {hero-name: Superman} and superheroes: {hero-name: Batman}
|
||||
```
|
||||
|
||||
The previous boolean and range queries still work, so you can submit a more refined query.
|
||||
|
||||
```
|
||||
superheroes: {hero-name: Superman and age < 50}
|
||||
```
|
||||
|
||||
If your document has an object nested within another object, you can still retrieve data by specifying all of the levels.
|
||||
|
||||
```
|
||||
justice-league.superheroes: {hero-name:Superman}
|
||||
```
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Gantt charts
|
||||
nav_order: 10
|
||||
---
|
||||
|
||||
# Gantt charts
|
||||
|
||||
OpenSearch Dashboards includes a Gantt chart visualization. Gantt charts show the start, end, and duration of unique events in a sequence. Gantt charts are useful in trace analytics, telemetry, and anomaly detection use cases, where you want to understand interactions and dependencies between various events in a schedule.
|
||||
|
||||
For example, consider an index of log data. The fields in a typical set of log data, especially audit logs, contain a specific operation or event with a start time and duration.
|
||||
|
||||
To create a Gantt chart, perform the following steps:
|
||||
|
||||
1. In the visualizations menu, choose **Create visualization** and **Gantt Chart**.
|
||||
1. Choose a source for the chart (e.g. some log data).
|
||||
1. Under **Metrics**, choose **Event**. For log data, each log is an event.
|
||||
1. Select the **Start Time** and **Duration** fields from your data set. The start time is the timestamp for the begining of an event. The duration is the amount of time to add to the start time.
|
||||
1. Under **Results**, choose the number of events to display on the chart. Gantt charts sequence events from earliest to latest based on start time.
|
||||
1. Choose **Panel settings** to adjust axis labels, time format, and colors.
|
||||
1. Choose **Update**.
|
||||
|
||||

|
||||
|
||||
This Gantt chart displays the ID of each log on the y-axis. Each bar is a unique event that spans some amount of time. Hover over a bar to see the duration of that event.
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: About Dashboards
|
||||
nav_order: 1
|
||||
has_children: false
|
||||
has_toc: false
|
||||
redirect_from:
|
||||
- /docs/opensearch-dashboards/
|
||||
- /dashboards/
|
||||
---
|
||||
|
||||
{%- comment -%}The `/docs/opensearch-dashboards/` redirect is specifically to support the UI links in OpenSearch Dashboards 1.0.0.{%- endcomment -%}
|
||||
|
||||
# OpenSearch Dashboards
|
||||
|
||||
OpenSearch Dashboards is the default visualization tool for data in OpenSearch. It also serves as a user interface for many of the OpenSearch plugins, including security, alerting, Index State Management, SQL, and more.
|
||||
|
||||
|
||||
## Get started with OpenSearch Dashboards
|
||||
|
||||
1. After starting OpenSearch Dashboards, you can access it at port 5601. For example, http://localhost:5601.
|
||||
1. Log in with the default username `admin` and password `admin`.
|
||||
1. Choose **Try our sample data** and add the sample flight data.
|
||||
1. Choose **Discover** and search for a few flights.
|
||||
1. Choose **Dashboard**, **[Flights] Global Flight Dashboard**, and wait for the dashboard to load.
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Docker
|
||||
parent: Install OpenSearch Dashboards
|
||||
nav_order: 1
|
||||
---
|
||||
|
||||
# Run OpenSearch Dashboards using Docker
|
||||
|
||||
You *can* start OpenSearch Dashboards using `docker run` after [creating a Docker network](https://docs.docker.com/engine/reference/commandline/network_create/) and starting OpenSearch, but the process of connecting OpenSearch Dashboards to OpenSearch is significantly easier with a Docker Compose file.
|
||||
|
||||
1. Run `docker pull opensearchproject/opensearch-dashboards:{{site.opensearch_version}}`.
|
||||
|
||||
1. Create a [`docker-compose.yml`](https://docs.docker.com/compose/compose-file/) file appropriate for your environment. A sample file that includes OpenSearch Dashboards is available on the OpenSearch [Docker installation page]({{site.url}}{{site.baseurl}}/opensearch/install/docker#sample-docker-compose-file).
|
||||
|
||||
Just like `opensearch.yml`, you can pass a custom `opensearch_dashboards.yml` to the container in the Docker Compose file.
|
||||
{: .tip }
|
||||
|
||||
1. Run `docker-compose up`.
|
||||
|
||||
Wait for the containers to start. Then see the [OpenSearch Dashboards documentation]({{site.url}}{{site.baseurl}}/).
|
||||
|
||||
1. When finished, run `docker-compose down`.
|
||||
@@ -1,135 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Helm
|
||||
parent: Install OpenSearch Dashboards
|
||||
nav_order: 35
|
||||
---
|
||||
|
||||
# Run OpenSearch Dashboards using Helm
|
||||
|
||||
Helm is a package manager that allows you to easily install and manage OpenSearch Dashboards in a Kubernetes cluster. You can define your OpenSearch configurations in a YAML file and use Helm to deploy your applications in a version-controlled and reproducible way.
|
||||
|
||||
The Helm chart contains the resources described in the following table.
|
||||
|
||||
Resource | Description
|
||||
:--- | :---
|
||||
`Chart.yaml` | Information about the chart.
|
||||
`values.yaml` | Default configuration values for the chart.
|
||||
`templates` | Templates that combine with values to generate the Kubernetes manifest files.
|
||||
|
||||
The specification in the default Helm chart supports many standard use cases and setups. You can modify the default chart to configure your desired specifications and set Transport Layer Security (TLS) and role-based access control (RBAC).
|
||||
|
||||
For information about the default configuration, steps to configure security, and configurable parameters, see the
|
||||
[README](https://github.com/opensearch-project/helm-charts/tree/main/charts).
|
||||
|
||||
The instructions here assume you have a Kubernetes cluster with Helm preinstalled. See the [Kubernetes documentation](https://kubernetes.io/docs/setup/) for steps to configure a Kubernetes cluster and the [Helm documentation](https://helm.sh/docs/intro/install/) to install Helm.
|
||||
{: .note }
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you get started, you must first use [Helm to install OpenSearch]({{site.url}}{{site.baseurl}}/opensearch/install/helm/).
|
||||
|
||||
Make sure that you can send requests to your OpenSearch pod:
|
||||
|
||||
```json
|
||||
$ curl -XGET https://localhost:9200 -u 'admin:admin' --insecure
|
||||
{
|
||||
"name" : "opensearch-cluster-master-1",
|
||||
"cluster_name" : "opensearch-cluster",
|
||||
"cluster_uuid" : "hP2gq5bPS3SLp8Z7wXm8YQ",
|
||||
"version" : {
|
||||
"distribution" : "opensearch",
|
||||
"number" : "1.0.0",
|
||||
"build_type" : "tar",
|
||||
"build_hash" : "34550c5b17124ddc59458ef774f6b43a086522e3",
|
||||
"build_date" : "2021-07-02T23:22:21.383695Z",
|
||||
"build_snapshot" : false,
|
||||
"lucene_version" : "8.8.2",
|
||||
"minimum_wire_compatibility_version" : "6.8.0",
|
||||
"minimum_index_compatibility_version" : "6.0.0-beta1"
|
||||
},
|
||||
"tagline" : "The OpenSearch Project: https://opensearch.org/"
|
||||
}
|
||||
```
|
||||
|
||||
## Install OpenSearch Dashboards using Helm
|
||||
|
||||
1. Change to the `opensearch-dashboards` directory:
|
||||
|
||||
```bash
|
||||
cd opensearch-dashboards
|
||||
```
|
||||
|
||||
1. Package the Helm chart:
|
||||
|
||||
```bash
|
||||
helm package .
|
||||
```
|
||||
|
||||
1. Deploy OpenSearch Dashboards:
|
||||
|
||||
```bash
|
||||
helm install --generate-name opensearch-dashboards-1.0.0.tgz
|
||||
```
|
||||
The output shows you the specifications instantiated from the install.
|
||||
To customize the deployment, pass in the values that you want to override with a custom YAML file:
|
||||
|
||||
```bash
|
||||
helm install --values=customvalues.yaml opensearch-dashboards-1.0.0.tgz
|
||||
```
|
||||
|
||||
#### Sample output
|
||||
|
||||
```yaml
|
||||
NAME: opensearch-dashboards-1-1629223356
|
||||
LAST DEPLOYED: Tue Aug 17 18:02:37 2021
|
||||
NAMESPACE: default
|
||||
STATUS: deployed
|
||||
REVISION: 1
|
||||
TEST SUITE: None
|
||||
NOTES:
|
||||
1. Get the application URL by running these commands:
|
||||
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=opensearch-dashboards,app.kubernetes.io/instance=op
|
||||
ensearch-dashboards-1-1629223356" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||
```
|
||||
|
||||
To make sure your OpenSearch Dashboards pod is up and running, run the following command:
|
||||
|
||||
```bash
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
opensearch-cluster-master-0 1/1 Running 0 4m35s
|
||||
opensearch-cluster-master-1 1/1 Running 0 4m35s
|
||||
opensearch-cluster-master-2 1/1 Running 0 4m35s
|
||||
opensearch-dashboards-1-1629223356-758bd8747f-8www5 1/1 Running 0 66s
|
||||
```
|
||||
|
||||
To set up port forwarding to access OpenSearch Dashboards, exit the OpenSearch shell and run the following command:
|
||||
|
||||
```bash
|
||||
$ kubectl port-forward deployment/opensearch-dashboards-1-1629223356 5601
|
||||
```
|
||||
|
||||
You can now access OpenSearch Dashboards from your browser at: http://localhost:5601.
|
||||
|
||||
|
||||
## Uninstall using Helm
|
||||
|
||||
To identify the OpenSearch Dashboards deployment that you want to delete:
|
||||
|
||||
```bash
|
||||
$ helm list
|
||||
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
|
||||
opensearch-1-1629223146 default 1 2021-08-17 17:59:07.664498239 +0000 UTCdeployedopensearch-1.0.0 1.0.0
|
||||
opensearch-dashboards-1-1629223356 default 1 2021-08-17 18:02:37.600796946 +0000 UTCdepl
|
||||
oyedopensearch-dashboards-1.0.0 1.0.0
|
||||
```
|
||||
|
||||
To delete or uninstall a deployment, run the following command:
|
||||
|
||||
```bash
|
||||
helm delete opensearch-dashboards-1-1629223356
|
||||
```
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Install OpenSearch Dashboards
|
||||
nav_order: 1
|
||||
has_children: true
|
||||
redirect_from:
|
||||
- /dashboards/install/
|
||||
---
|
||||
|
||||
# Install and configure OpenSearch Dashboards
|
||||
|
||||
OpenSearch Dashboards has three installation options at this time: Docker images, tarballs, and Helm charts.
|
||||
@@ -1,238 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: OpenSearch Dashboards plugins
|
||||
parent: Install OpenSearch Dashboards
|
||||
nav_order: 50
|
||||
---
|
||||
|
||||
# Standalone plugin install
|
||||
|
||||
If you don't want to use the all-in-one installation options, you can install the various plugins for OpenSearch Dashboards individually.
|
||||
|
||||
---
|
||||
|
||||
#### Table of contents
|
||||
1. TOC
|
||||
{:toc}
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Plugin compatibility
|
||||
|
||||
<table>
|
||||
<thead style="text-align: left">
|
||||
<tr>
|
||||
<th>OpenSearch Dashboards version</th>
|
||||
<th>Plugin versions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>1.1.0</td>
|
||||
<td>
|
||||
<pre>alertingDashboards 1.1.0.0
|
||||
anomalyDetectionDashboards 1.1.0.0
|
||||
ganttChartDashboards 1.1.0.0
|
||||
indexManagementDashboards 1.1.0.0
|
||||
notebooksDashboards 1.1.0.0
|
||||
queryWorkbenchDashboards 1.1.0.0
|
||||
reportsDashboards 1.1.0.0
|
||||
securityDashboards 1.1.0.0
|
||||
traceAnalyticsDashboards 1.1.0.0
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1.0.1</td>
|
||||
<td>
|
||||
<pre>alertingDashboards 1.0.0.0
|
||||
anomalyDetectionDashboards 1.0.0.0
|
||||
ganttChartDashboards 1.0.0.0
|
||||
indexManagementDashboards 1.0.1.0
|
||||
notebooksDashboards 1.0.0.0
|
||||
queryWorkbenchDashboards 1.0.0.0
|
||||
reportsDashboards 1.0.1.0
|
||||
securityDashboards 1.0.1.0
|
||||
traceAnalyticsDashboards 1.0.0.0
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1.0.0</td>
|
||||
<td>
|
||||
<pre>alertingDashboards 1.0.0.0
|
||||
anomalyDetectionDashboards 1.0.0.0
|
||||
ganttChartDashboards 1.0.0.0
|
||||
indexManagementDashboards 1.0.0.0
|
||||
notebooksDashboards 1.0.0.0
|
||||
queryWorkbenchDashboards 1.0.0.0
|
||||
reportsDashboards 1.0.0.0
|
||||
securityDashboards 1.0.0.0
|
||||
traceAnalyticsDashboards 1.0.0.0
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A compatible OpenSearch cluster
|
||||
- The corresponding OpenSearch plugins [installed on that cluster]({{site.url}}{{site.baseurl}}/opensearch/install/plugins/)
|
||||
- The corresponding version of [OpenSearch Dashboards]({{site.url}}{{site.baseurl}}/) (e.g. OpenSearch Dashboards 1.0.0 works with OpenSearch 1.0.0)
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
Navigate to the OpenSearch Dashboards home directory (likely `/usr/share/opensearch-dashboards`) and run the install command for each plugin.
|
||||
|
||||
{% comment %}
|
||||
|
||||
#### Security OpenSearch Dashboards
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-dashboards-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-dashboards-plugins/opensearch-security/opensearchSecurityOpenSearch Dashboards-{{site.opensearch_major_minor_version}}.0.1.zip
|
||||
```
|
||||
|
||||
This plugin provides a user interface for managing users, roles, mappings, action groups, and tenants.
|
||||
|
||||
|
||||
#### Alerting OpenSearch Dashboards
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-dashboards-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-dashboards-plugins/opensearch-alerting/opensearchAlertingOpenSearch Dashboards-{{site.opensearch_major_minor_version}}.0.0.zip
|
||||
```
|
||||
|
||||
This plugin provides a user interface for creating monitors and managing alerts.
|
||||
|
||||
|
||||
#### Index State Management OpenSearch Dashboards
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-dashboards-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-dashboards-plugins/opensearch-index-management/opensearchIndexManagementOpenSearch Dashboards-{{site.opensearch_major_minor_version}}.0.1.zip
|
||||
```
|
||||
|
||||
This plugin provides a user interface for managing policies.
|
||||
|
||||
|
||||
#### Anomaly Detection OpenSearch Dashboards
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-dashboards-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-dashboards-plugins/opensearch-anomaly-detection/opensearchAnomalyDetectionOpenSearch Dashboards-{{site.opensearch_major_minor_version}}.0.0.zip
|
||||
```
|
||||
|
||||
This plugin provides a user interface for adding detectors.
|
||||
|
||||
|
||||
#### Query Workbench OpenSearch Dashboards
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-dashboards-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-dashboards-plugins/opensearch-query-workbench/opensearchQueryWorkbenchOpenSearch Dashboards-{{site.opensearch_major_minor_version}}.0.0.zip
|
||||
```
|
||||
|
||||
This plugin provides a user interface for using SQL queries to explore your data.
|
||||
|
||||
|
||||
#### Trace Analytics
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-dashboards-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-dashboards-plugins/opensearch-trace-analytics/opensearchTraceAnalyticsOpenSearch Dashboards-{{site.opensearch_major_minor_version}}.2.0.zip
|
||||
```
|
||||
|
||||
This plugin uses distributed trace data (indexed in OpenSearch using Data Prepper) to display latency trends, error rates, and more.
|
||||
|
||||
|
||||
#### Notebooks OpenSearch Dashboards
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-dashboards-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-dashboards-plugins/opensearch-notebooks/opensearchNotebooksOpenSearch Dashboards-{{site.opensearch_major_minor_version}}.2.0.zip
|
||||
```
|
||||
|
||||
This plugin lets you combine OpenSearch Dashboards visualizations and narrative text in a single interface.
|
||||
|
||||
|
||||
#### Reports OpenSearch Dashboards
|
||||
|
||||
```bash
|
||||
# x86 Linux
|
||||
sudo bin/opensearch-dashboards-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-dashboards-plugins/opensearch-reports/linux/x64/opensearchReportsOpenSearch Dashboards-{{site.opensearch_major_minor_version}}.2.0-linux-x64.zip
|
||||
# ARM64 Linux
|
||||
sudo bin/opensearch-dashboards-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-dashboards-plugins/opensearch-reports/linux/arm64/opensearchReportsOpenSearch Dashboards-{{site.opensearch_major_minor_version}}.2.0-linux-arm64.zip
|
||||
# x86 Windows
|
||||
sudo bin/opensearch-dashboards-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-dashboards-plugins/opensearch-reports/windows/x64/opensearchReportsOpenSearch Dashboards-{{site.opensearch_major_minor_version}}.2.0-windows-x64.zip
|
||||
```
|
||||
|
||||
This plugin lets you export and share reports from OpenSearch Dashboards dashboards, visualizations, and saved searches.
|
||||
|
||||
|
||||
#### Gantt Chart OpenSearch Dashboards
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-dashboards-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-dashboards-plugins/opensearch-gantt-chart/opensearchGanttChartOpenSearch Dashboards-{{site.opensearch_major_minor_version}}.0.0.zip
|
||||
```
|
||||
|
||||
This plugin adds a new Gantt chart visualization.
|
||||
|
||||
{% endcomment %}
|
||||
|
||||
## List installed plugins
|
||||
|
||||
To check your installed plugins:
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-dashboards-plugin list
|
||||
```
|
||||
|
||||
|
||||
## Remove plugins
|
||||
|
||||
To remove a plugin:
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-dashboards-plugin remove <plugin-name>
|
||||
```
|
||||
|
||||
Then remove all associated entries from `opensearch_dashboards.yml`.
|
||||
|
||||
For certain plugins, you must also remove the "optimze" bundle. This is a sample command for the Anomaly Detection plugin:
|
||||
|
||||
```bash
|
||||
sudo rm /usr/share/opensearch-dashboards/optimize/bundles/opensearch-anomaly-detection-opensearch-dashboards.*
|
||||
```
|
||||
|
||||
Then restart OpenSearch Dashboards. After you remove any plugin, OpenSearch Dashboards performs an optimize operation the next time you start it. This operation takes several minutes even on fast machines, so be patient.
|
||||
|
||||
|
||||
## Update plugins
|
||||
|
||||
OpenSearch Dashboards doesn’t update plugins. Instead, you have to remove the old version and its optimized bundle, reinstall them, and restart OpenSearch Dashboards:
|
||||
|
||||
1. Remove the old version:
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-dashboards-plugin remove <plugin-name>
|
||||
```
|
||||
|
||||
1. Remove the optimized bundle:
|
||||
|
||||
```bash
|
||||
sudo rm /usr/share/opensearch-dashboards/optimize/bundles/<bundle-name>
|
||||
```
|
||||
|
||||
1. Reinstall the new version:
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-dashboards-plugin install <plugin-name>
|
||||
```
|
||||
|
||||
1. Restart OpenSearch Dashboards.
|
||||
|
||||
For example, to remove and reinstall the anomaly detection plugin:
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-plugin remove opensearch-anomaly-detection
|
||||
sudo rm /usr/share/opensearch-dashboards/optimize/bundles/opensearch-anomaly-detection-opensearch-dashboards.*
|
||||
sudo bin/opensearch-dashboards-plugin install <AD OpenSearch Dashboards plugin artifact URL>
|
||||
```
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Tarball
|
||||
parent: Install OpenSearch Dashboards
|
||||
nav_order: 30
|
||||
---
|
||||
|
||||
# Run OpenSearch Dashboards using the tarball
|
||||
|
||||
1. Download the tarball from the [OpenSearch downloads page](https://opensearch.org/downloads.html){:target='\_blank'}.
|
||||
|
||||
1. Extract the TAR file to a directory and change to that directory:
|
||||
|
||||
```bash
|
||||
# x64
|
||||
tar -zxf opensearch-dashboards-{{site.opensearch_version}}-linux-x64.tar.gz
|
||||
cd opensearch-dashboards
|
||||
# ARM64
|
||||
tar -zxf opensearch-dashboards-{{site.opensearch_version}}-linux-arm64.tar.gz
|
||||
cd opensearch-dashboards
|
||||
```
|
||||
|
||||
1. If desired, modify `config/opensearch_dashboards.yml`.
|
||||
|
||||
1. Run OpenSearch Dashboards:
|
||||
|
||||
```bash
|
||||
./bin/opensearch-dashboards
|
||||
```
|
||||
@@ -1,41 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Configure TLS
|
||||
parent: Install OpenSearch Dashboards
|
||||
nav_order: 40
|
||||
---
|
||||
|
||||
# Configure TLS for OpenSearch Dashboards
|
||||
|
||||
By default, for ease of testing and getting started, OpenSearch Dashboards runs over HTTP. To enable TLS for HTTPS, update the following settings in `opensearch_dashboards.yml`.
|
||||
|
||||
Setting | Description
|
||||
:--- | :---
|
||||
opensearch.ssl.verificationMode | This setting is for communications between OpenSearch and OpenSearch Dashboards. Valid values are `full`, `certificate`, or `none`. We recommend `full` if you enable TLS, which enables hostname verification. `certificate` just checks the certificate, not the hostname, and `none` performs no checks (suitable for HTTP). Default is `full`.
|
||||
opensearch.ssl.certificateAuthorities | If `opensearch.ssl.verificationMode` is `full` or `certificate`, specify the full path to one or more CA certificates that comprise a trusted chain for your OpenSearch cluster. For example, you might need to include a root CA _and_ an intermediate CA if you used the intermediate CA to issue your admin, client, and node certificates.
|
||||
server.ssl.enabled | This setting is for communications between OpenSearch Dashboards and the web browser. Set to true for HTTPS, false for HTTP.
|
||||
server.ssl.certificate | If `server.ssl.enabled` is true, specify the full path to a valid client certificate for your OpenSearch cluster. You can [generate your own]({{site.url}}{{site.baseurl}}/security-plugin/configuration/generate-certificates/) or get one from a certificate authority.
|
||||
server.ssl.key | If `server.ssl.enabled` is true, specify the full path (e.g. `/usr/share/opensearch-dashboards-1.0.0/config/my-client-cert-key.pem` to the key for your client certificate. You can [generate your own]({{site.url}}{{site.baseurl}}/security-plugin/configuration/generate-certificates/) or get one from a certificate authority.
|
||||
opensearch_security.cookie.secure | If you enable TLS for OpenSearch Dashboards, change this setting to `true`. For HTTP, set it to `false`.
|
||||
|
||||
This `opensearch_dashboards.yml` configuration shows OpenSearch and OpenSearch Dashboards running on the same machine with the demo configuration:
|
||||
|
||||
```yml
|
||||
opensearch.hosts: ["https://localhost:9200"]
|
||||
opensearch.ssl.verificationMode: full
|
||||
opensearch.username: "kibanaserver"
|
||||
opensearch.password: "kibanaserver"
|
||||
opensearch.requestHeadersWhitelist: [ authorization,securitytenant ]
|
||||
server.ssl.enabled: true
|
||||
server.ssl.certificate: /usr/share/opensearch-dashboards/config/client-cert.pem
|
||||
server.ssl.key: /usr/share/opensearch-dashboards/config/client-cert-key.pem
|
||||
opensearch.ssl.certificateAuthorities: [ "/usr/share/opensearch-dashboards/config/root-ca.pem", "/usr/share/opensearch-dashboards/config/intermediate-ca.pem" ]
|
||||
opensearch_security.multitenancy.enabled: true
|
||||
opensearch_security.multitenancy.tenants.preferred: ["Private", "Global"]
|
||||
opensearch_security.readonly_mode.roles: ["kibana_read_only"]
|
||||
opensearch_security.cookie.secure: true
|
||||
```
|
||||
|
||||
If you use the Docker install, you can pass a custom `opensearch_dashboards.yml` to the container. To learn more, see the [Docker installation page]({{site.url}}{{site.baseurl}}/opensearch/install/docker/).
|
||||
|
||||
After enabling these settings and starting OpenSearch Dashboards, you can connect to it at `https://localhost:5601`. You might have to acknowledge a browser warning if your certificates are self-signed. To avoid this sort of warning (or outright browser incompatibility), best practice is to use certificates from trusted certificate authority.
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: WMS map server
|
||||
nav_order: 5
|
||||
redirect_from:
|
||||
- /docs/opensearch-dashboards/maptiles/
|
||||
---
|
||||
|
||||
{%- comment -%}The `/docs/opensearch-dashboards/maptiles/` redirect is specifically to support the UI links in OpenSearch Dashboards 1.0.0.{%- endcomment -%}
|
||||
|
||||
# Configure WMS map server
|
||||
|
||||
OpenSearch Dashboards includes default map tiles, but if you need more specialized maps, you can configure OpenSearch Dashboards to use a WMS map server:
|
||||
|
||||
1. Open OpenSearch Dashboards at `https://<host>:<port>`. For example, [https://localhost:5601](https://localhost:5601).
|
||||
1. If necessary, log in.
|
||||
1. Choose **Management** and **Advanced Settings**.
|
||||
1. Locate `visualization:tileMap:WMSdefaults`.
|
||||
1. Change `enabled` to true and add the URL of a valid WMS map server:
|
||||
|
||||
```json
|
||||
{
|
||||
"enabled": true,
|
||||
"url": "<wms-map-server-url>",
|
||||
"options": {
|
||||
"format": "image/png",
|
||||
"transparent": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Map services often have licensing fees or restrictions. You're responsible for all such considerations on any map server that you specify.
|
||||
{: .note }
|
||||
@@ -1,124 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Notebooks
|
||||
nav_order: 50
|
||||
redirect_from: /notebooks/
|
||||
has_children: false
|
||||
---
|
||||
|
||||
# Notebooks
|
||||
|
||||
An OpenSearch Dashboards notebook is an interface that lets you easily combine code snippets, live visualizations, and narrative text in a single notebook interface.
|
||||
|
||||
Notebooks let you interactively explore data by running different visualizations that you can share with team members to collaborate on a project.
|
||||
|
||||
A notebook is a document composed of two elements: code blocks (Markdown/SQL/PPL) and visualizations. Choose multiple timelines to compare and contrast visualizations.
|
||||
|
||||
You can also generate [reports]({{site.url}}{{site.baseurl}}/dashboards/reporting/) directly from your notebooks.
|
||||
|
||||
Common use cases include creating postmortem reports, designing runbooks, building live infrastructure reports, and writing documentation.
|
||||
|
||||
Tenants in OpenSearch Dashboards are spaces for saving notebooks and other OpenSearch Dashboards objects. For more information, see [OpenSearch Dashboards multi-tenancy]({{site.url}}{{site.baseurl}}/security-plugin/access-control/multi-tenancy/).
|
||||
{: .note }
|
||||
|
||||
|
||||
## Get started with notebooks
|
||||
|
||||
To get started, choose **Notebooks** within OpenSearch Dashboards.
|
||||
|
||||
|
||||
### Step 1: Create a notebook
|
||||
|
||||
A notebook is an interface for creating reports.
|
||||
|
||||
1. Choose **Create notebook** and enter a descriptive name.
|
||||
1. Choose **Create**.
|
||||
|
||||
Choose **Actions** to rename, duplicate, or delete a notebook.
|
||||
|
||||

|
||||
|
||||
### Step 2: Add a paragraph
|
||||
|
||||
Paragraphs combine code blocks and visualizations for describing data.
|
||||
|
||||
#### Add a code block
|
||||
|
||||
Code blocks support markdown, SQL, and PPL languages.
|
||||
|
||||
Specify the input language on the first line using `%[language type]` syntax.
|
||||
For example, type `%md` for markdown, `%sql` for SQL, and `%ppl` for PPL.
|
||||
|
||||
##### Sample markdown block
|
||||
|
||||
```
|
||||
%md
|
||||
Add in text formatted in markdown.
|
||||
```
|
||||
|
||||

|
||||
|
||||
##### Sample SQL block
|
||||
|
||||
```sql
|
||||
%sql
|
||||
Select * from opensearch_dashboards_sample_data_flights limit 20;
|
||||
```
|
||||
|
||||

|
||||
|
||||
##### Sample PPL block
|
||||
|
||||
```
|
||||
%ppl
|
||||
source=opensearch_dashboards_sample_data_logs | head 20
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
#### Add a visualization
|
||||
|
||||
1. To add a visualization, choose **Add paragraph** and select **Visualization**.
|
||||
1. In **Title**, select your visualization and choose a date range. You can choose multiple timelines to compare and contrast visualizations.
|
||||
1. To run and save a paragraph, choose **Run**.
|
||||
|
||||

|
||||
|
||||
## Paragraph actions
|
||||
|
||||
You can perform the following actions on paragraphs:
|
||||
|
||||
- Add a new paragraph to the top of a report.
|
||||
- Add a new paragraph to the bottom of a report.
|
||||
- Run all the paragraphs at the same time.
|
||||
- Clear the outputs of all paragraphs.
|
||||
- Delete all the paragraphs.
|
||||
|
||||

|
||||
|
||||
## Sample notebooks
|
||||
|
||||
We prepared the following sample notebooks that showcase a variety of use cases:
|
||||
|
||||
- Using SQL to query the OpenSearch Dashboards sample flight data.
|
||||
- Using PPL to query the OpenSearch Dashboards sample web logs data.
|
||||
- Using PPL and visualizations to perform sample root cause event analysis on the OpenSearch Dashboards sample web logs data.
|
||||
|
||||
To add a sample notebook, choose **Actions** and select **Add sample notebooks**.
|
||||
|
||||

|
||||
|
||||
## Create a report
|
||||
|
||||
You can use notebooks to create PNG and PDF reports:
|
||||
|
||||
1. From the top menu bar, choose **Reporting actions**.
|
||||
1. You can choose to **Download PDF** or **Download PNG**.
|
||||
|
||||
Reports generate asynchronously in the background and might take a few minutes, depending on the size of the report. A notification appears when your report is ready to download.
|
||||
|
||||
1. To create a schedule-based report, choose **Create report definition**. For steps to create a report definition, see [Create reports using a definition]({{site.url}}{{site.baseurl}}/dashboards/reporting#create-reports-using-a-definition).
|
||||
1. To see all your reports, choose **View all reports**.
|
||||
|
||||

|
||||
@@ -1,57 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Reporting
|
||||
nav_order: 20
|
||||
---
|
||||
|
||||
|
||||
# Reporting
|
||||
|
||||
You can use OpenSearch Dashboards to create PNG, PDF, and CSV reports. To create reports, you must have the correct permissions. For a summary of the predefined roles and the permissions they grant, see the [security plugin]({{site.url}}{{site.baseurl}}/security-plugin/access-control/users-roles#predefined-roles).
|
||||
|
||||
CSV reports have a non-configurable 10,000 row limit. They have no explicit size limit (e.g. in MB), but extremely large documents could cause report generation to fail with an out of memory error from the V8 JavaScript engine.
|
||||
{: .tip }
|
||||
|
||||
|
||||
## Create reports from Discovery, Visualize, or Dashboard
|
||||
|
||||
Quickly generate an on-demand report from the current view.
|
||||
|
||||
1. From the top menu bar, choose **Reporting**.
|
||||
1. For dashboards or visualizations, choose **Download PDF** or **Download PNG**. From the Discover page, choose **Download CSV**.
|
||||
|
||||
Reports generate asynchronously in the background and might take a few minutes, depending on the size of the report. A notification appears when your report is ready to download.
|
||||
|
||||
1. To create a schedule-based report, choose **Create report definition**. Then proceed to [Create reports using a definition](#create-reports-using-a-definition). This option pre-fills many of the fields for you based on the visualization, dashboard, or data you were viewing.
|
||||
|
||||
|
||||
## Create reports using a definition
|
||||
|
||||
Definitions let you generate reports on a periodic schedule.
|
||||
|
||||
1. From the navigation panel, choose **Reporting**.
|
||||
1. Choose **Create**.
|
||||
1. Under **Report settings**, enter a name and optional description for your report.
|
||||
1. Choose the **Report Source** (i.e. the page from which the report is generated). You can generate reports from the **Dashboard**, **Visualize**, or **Discover** pages.
|
||||
1. Select your dashboard, visualization, or saved search. Then choose a time range for the report.
|
||||
1. Choose an appropriate file format for the report.
|
||||
1. (Optional) Add a header or footer to the report. Headers and footers are only available for dashboard or visualization reports.
|
||||
1. Under **Report trigger**, choose either **On-demand** or **Schedule**.
|
||||
|
||||
For scheduled reports, select either **Recurring** or **Cron based**. You can receive reports daily or at some other time interval. Cron expressions give you even more flexiblity. See [Cron expression reference]({{site.url}}{{site.baseurl}}/monitoring-plugins/alerting/cron/) for more information.
|
||||
|
||||
1. Choose **Create**.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Chromium fails to launch with OpenSearch Dashboards
|
||||
|
||||
While creating a report for dashboards or visualizations, you might see a the following error:
|
||||
|
||||

|
||||
|
||||
This problem can occur for two reasons:
|
||||
|
||||
- You don't have the correct version of `headless-chrome` to match the operating system on which OpenSearch Dashboards is running. Download the correct version [here](https://github.com/opensearch-project/dashboards-reports/releases/tag/chromium-1.12.0.0).
|
||||
|
||||
- You're missing additional dependencies. Install the required dependencies for your operating system from the [additional libraries](https://github.com/opensearch-project/dashboards-reports/blob/main/dashboards-reports/rendering-engine/headless-chrome/README.md#additional-libaries) section.
|
||||
@@ -1 +0,0 @@
|
||||
message: "🌡️ [OpenSearch 1.1.0 arrived October 5 with cross-cluster replication, bucket-level alerting, and much, much more. Grab it here!](/downloads.html)"
|
||||
@@ -1,49 +0,0 @@
|
||||
columns:
|
||||
-
|
||||
title: 'Get Involved'
|
||||
links:
|
||||
-
|
||||
title: Code of Conduct
|
||||
url: '/codeofconduct.html'
|
||||
-
|
||||
title: 'Forums'
|
||||
url: 'https://discuss.opendistrocommunity.dev/'
|
||||
-
|
||||
title: 'Github'
|
||||
url: 'https://github.com/opensearch-project'
|
||||
-
|
||||
title: 'Partners'
|
||||
url: '/partners/'
|
||||
-
|
||||
title: 'Community Projects'
|
||||
url: '/community_projects'
|
||||
-
|
||||
title: 'Resources'
|
||||
links:
|
||||
#-
|
||||
# title: 'Documentation'
|
||||
# url: 'https://github.com/opensearch/documentation'
|
||||
-
|
||||
title: FAQ
|
||||
url: '/faq/'
|
||||
-
|
||||
title: 'Brand Guidelines'
|
||||
url: '/brand.html'
|
||||
-
|
||||
title: 'Trademark Usage Policy'
|
||||
url: '/trademark-usage.html'
|
||||
-
|
||||
title: OpenSearch Disambiguation
|
||||
url: '/disambiguation.html'
|
||||
-
|
||||
title: 'Connect'
|
||||
links:
|
||||
# -
|
||||
# title: 'Twitter'
|
||||
# url: 'https://twitter.com/opensearch_project'
|
||||
#-
|
||||
# title: 'Facebook'
|
||||
# url: 'http://www.facebook.com/opensearch'
|
||||
-
|
||||
title: 'E-mail'
|
||||
url: 'mailto:opensearch@amazon.com'
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"current": "1.1",
|
||||
"past": [
|
||||
"1.0"
|
||||
]
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Dashboards developer guide
|
||||
nav_order: 2
|
||||
permalink: /dashboards-developer-guide/
|
||||
redirect_to: https://github.com/opensearch-project/OpenSearch-Dashboards/blob/main/DEVELOPER_GUIDE.md
|
||||
---
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Javadoc
|
||||
nav_order: 1
|
||||
permalink: /javadoc/
|
||||
redirect_to: https://opensearch.org/javadocs/
|
||||
---
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
nav_exclude: true
|
||||
permalink: /javadocs/
|
||||
redirect_to: https://opensearch.org/javadocs/
|
||||
---
|
||||
@@ -1,456 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Index rollups
|
||||
nav_order: 35
|
||||
has_children: true
|
||||
redirect_from: /im-plugin/index-rollups/
|
||||
has_toc: false
|
||||
---
|
||||
|
||||
# Index rollups
|
||||
|
||||
Time series data increases storage costs, strains cluster health, and slows down aggregations over time. Index rollup lets you periodically reduce data granularity by rolling up old data into summarized indices.
|
||||
|
||||
You pick the fields that interest you and use index rollup to create a new index with only those fields aggregated into coarser time buckets. You can store months or years of historical data at a fraction of the cost with the same query performance.
|
||||
|
||||
For example, say you collect CPU consumption data every five seconds and store it on a hot node. Instead of moving older data to a read-only warm node, you can roll up or compress this data with only the average CPU consumption per day or with a 10% decrease in its interval every week.
|
||||
|
||||
You can use index rollup in three ways:
|
||||
|
||||
1. Use the index rollup API for an on-demand index rollup job that operates on an index that's not being actively ingested such as a rolled-over index. For example, you can perform an index rollup operation to reduce data collected at a five minute interval to a weekly average for trend analysis.
|
||||
2. Use the OpenSearch Dashboards UI to create an index rollup job that runs on a defined schedule. You can also set it up to roll up your indices as it’s being actively ingested. For example, you can continuously roll up Logstash indices from a five second interval to a one hour interval.
|
||||
3. Specify the index rollup job as an ISM action for complete index management. This allows you to roll up an index after a certain event such as a rollover, index age reaching a certain point, index becoming read-only, and so on. You can also have rollover and index rollup jobs running in sequence, where the rollover first moves the current index to a warm node and then the index rollup job creates a new index with the minimized data on the hot node.
|
||||
|
||||
## Create an Index Rollup Job
|
||||
|
||||
To get started, choose **Index Management** in OpenSearch Dashboards.
|
||||
Select **Rollup Jobs** and choose **Create rollup job**.
|
||||
|
||||
### Step 1: Set up indices
|
||||
|
||||
1. In the **Job name and description** section, specify a unique name and an optional description for the index rollup job.
|
||||
2. In the **Indices** section, select the source and target index. The source index is the one that you want to roll up. The source index remains as is, the index rollup job creates a new index referred to as a target index. The target index is where the index rollup results are saved. For target index, you can either type in a name for a new index or you select an existing index.
|
||||
5. Choose **Next**
|
||||
|
||||
After you create an index rollup job, you can't change your index selections.
|
||||
|
||||
### Step 2: Define aggregations and metrics
|
||||
|
||||
Select the attributes with the aggregations (terms and histograms) and metrics (avg, sum, max, min, and value count) that you want to roll up. Make sure you don’t add a lot of highly granular attributes, because you won’t save much space.
|
||||
|
||||
For example, consider a dataset of cities and demographics within those cities. You can aggregate based on cities and specify demographics within a city as metrics.
|
||||
The order in which you select attributes is critical. A city followed by a demographic is different from a demographic followed by a city.
|
||||
|
||||
1. In the **Time aggregation** section, select a timestamp field. Choose between a **Fixed** or **Calendar** interval type and specify the interval and timezone. The index rollup job uses this information to create a date histogram for the timestamp field.
|
||||
2. (Optional) Add additional aggregations for each field. You can choose terms aggregation for all field types and histogram aggregation only for numeric fields.
|
||||
3. (Optional) Add additional metrics for each field. You can choose between **All**, **Min**, **Max**, **Sum**, **Avg**, or **Value Count**.
|
||||
4. Choose **Next**.
|
||||
|
||||
### Step 3: Specify schedule
|
||||
|
||||
Specify a schedule to roll up your indices as it’s being ingested. The index rollup job is enabled by default.
|
||||
|
||||
1. Specify if the data is continuous or not.
|
||||
3. For roll up execution frequency, select **Define by fixed interval** and specify the **Rollup interval** and the time unit or **Define by cron expression** and add in a cron expression to select the interval. To learn how to define a cron expression, see [Alerting]({{site.url}}{{site.baseurl}}/monitoring-plugins/alerting/cron/).
|
||||
4. Specify the number of pages per execution process. A larger number means faster execution and more cost for memory.
|
||||
5. (Optional) Add a delay to the roll up executions. This is the amount of time the job waits for data ingestion to accommodate any processing time. For example, if you set this value to 10 minutes, an index rollup that executes at 2 PM to roll up 1 PM to 2 PM of data starts at 2:10 PM.
|
||||
6. Choose **Next**.
|
||||
|
||||
### Step 4: Review and create
|
||||
|
||||
Review your configuration and select **Create**.
|
||||
|
||||
### Step 5: Search the target index
|
||||
|
||||
You can use the standard `_search` API to search the target index. Make sure that the query matches the constraints of the target index. For example, if you don’t set up terms aggregations on a field, you don’t receive results for terms aggregations. If you don’t set up the maximum aggregations, you don’t receive results for maximum aggregations.
|
||||
|
||||
You can’t access the internal structure of the data in the target index because the plugin automatically rewrites the query in the background to suit the target index. This is to make sure you can use the same query for the source and target index.
|
||||
|
||||
To query the target index, set `size` to 0:
|
||||
|
||||
```json
|
||||
GET target_index/_search
|
||||
{
|
||||
"size": 0,
|
||||
"query": {
|
||||
"match_all": {}
|
||||
},
|
||||
"aggs": {
|
||||
"avg_cpu": {
|
||||
"avg": {
|
||||
"field": "cpu_usage"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Consider a scenario where you collect rolled up data from 1 PM to 9 PM in hourly intervals and live data from 7 PM to 11 PM in minutely intervals. If you execute an aggregation over these in the same query, for 7 PM to 9 PM, you see an overlap of both rolled up data and live data because they get counted twice in the aggregations.
|
||||
|
||||
## Sample Walkthrough
|
||||
|
||||
This walkthrough uses the OpenSearch Dashboards sample e-commerce data. To add that sample data, log in to OpenSearch Dashboards, choose **Home** and **Try our sample data**. For **Sample eCommerce orders**, choose **Add data**.
|
||||
|
||||
Then run a search:
|
||||
|
||||
```json
|
||||
GET opensearch_dashboards_sample_data_ecommerce/_search
|
||||
```
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"took": 23,
|
||||
"timed_out": false,
|
||||
"_shards": {
|
||||
"total": 1,
|
||||
"successful": 1,
|
||||
"skipped": 0,
|
||||
"failed": 0
|
||||
},
|
||||
"hits": {
|
||||
"total": {
|
||||
"value": 4675,
|
||||
"relation": "eq"
|
||||
},
|
||||
"max_score": 1,
|
||||
"hits": [
|
||||
{
|
||||
"_index": "opensearch_dashboards_sample_data_ecommerce",
|
||||
"_type": "_doc",
|
||||
"_id": "jlMlwXcBQVLeQPrkC_kQ",
|
||||
"_score": 1,
|
||||
"_source": {
|
||||
"category": [
|
||||
"Women's Clothing",
|
||||
"Women's Accessories"
|
||||
],
|
||||
"currency": "EUR",
|
||||
"customer_first_name": "Selena",
|
||||
"customer_full_name": "Selena Mullins",
|
||||
"customer_gender": "FEMALE",
|
||||
"customer_id": 42,
|
||||
"customer_last_name": "Mullins",
|
||||
"customer_phone": "",
|
||||
"day_of_week": "Saturday",
|
||||
"day_of_week_i": 5,
|
||||
"email": "selena@mullins-family.zzz",
|
||||
"manufacturer": [
|
||||
"Tigress Enterprises"
|
||||
],
|
||||
"order_date": "2021-02-27T03:56:10+00:00",
|
||||
"order_id": 581553,
|
||||
"products": [
|
||||
{
|
||||
"base_price": 24.99,
|
||||
"discount_percentage": 0,
|
||||
"quantity": 1,
|
||||
"manufacturer": "Tigress Enterprises",
|
||||
"tax_amount": 0,
|
||||
"product_id": 19240,
|
||||
"category": "Women's Clothing",
|
||||
"sku": "ZO0064500645",
|
||||
"taxless_price": 24.99,
|
||||
"unit_discount_amount": 0,
|
||||
"min_price": 12.99,
|
||||
"_id": "sold_product_581553_19240",
|
||||
"discount_amount": 0,
|
||||
"created_on": "2016-12-24T03:56:10+00:00",
|
||||
"product_name": "Blouse - port royal",
|
||||
"price": 24.99,
|
||||
"taxful_price": 24.99,
|
||||
"base_unit_price": 24.99
|
||||
},
|
||||
{
|
||||
"base_price": 10.99,
|
||||
"discount_percentage": 0,
|
||||
"quantity": 1,
|
||||
"manufacturer": "Tigress Enterprises",
|
||||
"tax_amount": 0,
|
||||
"product_id": 17221,
|
||||
"category": "Women's Accessories",
|
||||
"sku": "ZO0085200852",
|
||||
"taxless_price": 10.99,
|
||||
"unit_discount_amount": 0,
|
||||
"min_price": 5.06,
|
||||
"_id": "sold_product_581553_17221",
|
||||
"discount_amount": 0,
|
||||
"created_on": "2016-12-24T03:56:10+00:00",
|
||||
"product_name": "Snood - rose",
|
||||
"price": 10.99,
|
||||
"taxful_price": 10.99,
|
||||
"base_unit_price": 10.99
|
||||
}
|
||||
],
|
||||
"sku": [
|
||||
"ZO0064500645",
|
||||
"ZO0085200852"
|
||||
],
|
||||
"taxful_total_price": 35.98,
|
||||
"taxless_total_price": 35.98,
|
||||
"total_quantity": 2,
|
||||
"total_unique_products": 2,
|
||||
"type": "order",
|
||||
"user": "selena",
|
||||
"geoip": {
|
||||
"country_iso_code": "MA",
|
||||
"location": {
|
||||
"lon": -8,
|
||||
"lat": 31.6
|
||||
},
|
||||
"region_name": "Marrakech-Tensift-Al Haouz",
|
||||
"continent_name": "Africa",
|
||||
"city_name": "Marrakesh"
|
||||
},
|
||||
"event": {
|
||||
"dataset": "sample_ecommerce"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
...
|
||||
```
|
||||
|
||||
Create an index rollup job.
|
||||
This example picks the `order_date`, `customer_gender`, `geoip.city_name`, `geoip.region_name`, and `day_of_week` fields and rolls them into an `example_rollup` target index:
|
||||
|
||||
```json
|
||||
PUT _plugins/_rollup/jobs/example
|
||||
{
|
||||
"rollup": {
|
||||
"enabled": true,
|
||||
"schedule": {
|
||||
"interval": {
|
||||
"period": 1,
|
||||
"unit": "Minutes",
|
||||
"start_time": 1602100553
|
||||
}
|
||||
},
|
||||
"last_updated_time": 1602100553,
|
||||
"description": "An example policy that rolls up the sample ecommerce data",
|
||||
"source_index": "opensearch_dashboards_sample_data_ecommerce",
|
||||
"target_index": "example_rollup",
|
||||
"page_size": 1000,
|
||||
"delay": 0,
|
||||
"continuous": false,
|
||||
"dimensions": [
|
||||
{
|
||||
"date_histogram": {
|
||||
"source_field": "order_date",
|
||||
"fixed_interval": "60m",
|
||||
"timezone": "America/Los_Angeles"
|
||||
}
|
||||
},
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "customer_gender"
|
||||
}
|
||||
},
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "geoip.city_name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "geoip.region_name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "day_of_week"
|
||||
}
|
||||
}
|
||||
],
|
||||
"metrics": [
|
||||
{
|
||||
"source_field": "taxless_total_price",
|
||||
"metrics": [
|
||||
{
|
||||
"avg": {}
|
||||
},
|
||||
{
|
||||
"sum": {}
|
||||
},
|
||||
{
|
||||
"max": {}
|
||||
},
|
||||
{
|
||||
"min": {}
|
||||
},
|
||||
{
|
||||
"value_count": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"source_field": "total_quantity",
|
||||
"metrics": [
|
||||
{
|
||||
"avg": {}
|
||||
},
|
||||
{
|
||||
"max": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can query the `example_rollup` index for the terms aggregations on the fields set up in the rollup job.
|
||||
You get back the same response that you would on the original `opensearch_dashboards_sample_data_ecommerce` source index.
|
||||
|
||||
```json
|
||||
POST example_rollup/_search
|
||||
{
|
||||
"size": 0,
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": {"term": { "geoip.region_name": "California" } }
|
||||
}
|
||||
},
|
||||
"aggregations": {
|
||||
"daily_numbers": {
|
||||
"terms": {
|
||||
"field": "day_of_week"
|
||||
},
|
||||
"aggs": {
|
||||
"per_city": {
|
||||
"terms": {
|
||||
"field": "geoip.city_name"
|
||||
},
|
||||
"aggregations": {
|
||||
"average quantity": {
|
||||
"avg": {
|
||||
"field": "total_quantity"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"total_revenue": {
|
||||
"sum": {
|
||||
"field": "taxless_total_price"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Sample Response
|
||||
|
||||
```json
|
||||
{
|
||||
"took": 476,
|
||||
"timed_out": false,
|
||||
"_shards": {
|
||||
"total": 1,
|
||||
"successful": 1,
|
||||
"skipped": 0,
|
||||
"failed": 0
|
||||
},
|
||||
"hits": {
|
||||
"total": {
|
||||
"value": 281,
|
||||
"relation": "eq"
|
||||
},
|
||||
"max_score": null,
|
||||
"hits": []
|
||||
},
|
||||
"aggregations": {
|
||||
"daily_numbers": {
|
||||
"doc_count_error_upper_bound": 0,
|
||||
"sum_other_doc_count": 0,
|
||||
"buckets": [
|
||||
{
|
||||
"key": "Friday",
|
||||
"doc_count": 53,
|
||||
"total_revenue": {
|
||||
"value": 4858.84375
|
||||
},
|
||||
"per_city": {
|
||||
"doc_count_error_upper_bound": 0,
|
||||
"sum_other_doc_count": 0,
|
||||
"buckets": [
|
||||
{
|
||||
"key": "Los Angeles",
|
||||
"doc_count": 53,
|
||||
"average quantity": {
|
||||
"value": 2.305084745762712
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "Saturday",
|
||||
"doc_count": 43,
|
||||
"total_revenue": {
|
||||
"value": 3547.203125
|
||||
},
|
||||
"per_city": {
|
||||
"doc_count_error_upper_bound": 0,
|
||||
"sum_other_doc_count": 0,
|
||||
"buckets": [
|
||||
{
|
||||
"key": "Los Angeles",
|
||||
"doc_count": 43,
|
||||
"average quantity": {
|
||||
"value": 2.260869565217391
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "Tuesday",
|
||||
"doc_count": 42,
|
||||
"total_revenue": {
|
||||
"value": 3983.28125
|
||||
},
|
||||
"per_city": {
|
||||
"doc_count_error_upper_bound": 0,
|
||||
"sum_other_doc_count": 0,
|
||||
"buckets": [
|
||||
{
|
||||
"key": "Los Angeles",
|
||||
"doc_count": 42,
|
||||
"average quantity": {
|
||||
"value": 2.2888888888888888
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "Sunday",
|
||||
"doc_count": 40,
|
||||
"total_revenue": {
|
||||
"value": 3308.1640625
|
||||
},
|
||||
"per_city": {
|
||||
"doc_count_error_upper_bound": 0,
|
||||
"sum_other_doc_count": 0,
|
||||
"buckets": [
|
||||
{
|
||||
"key": "Los Angeles",
|
||||
"doc_count": 40,
|
||||
"average quantity": {
|
||||
"value": 2.090909090909091
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
...
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -1,243 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Index rollups API
|
||||
parent: Index rollups
|
||||
nav_order: 9
|
||||
---
|
||||
|
||||
# Index rollups API
|
||||
|
||||
Use the index rollup operations to programmatically work with index rollup jobs.
|
||||
|
||||
---
|
||||
|
||||
#### Table of contents
|
||||
- TOC
|
||||
{:toc}
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Create or update an index rollup job
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Creates or updates an index rollup job.
|
||||
You must provide the `seq_no` and `primary_term` parameters.
|
||||
|
||||
#### Request
|
||||
|
||||
```json
|
||||
PUT _plugins/_rollup/jobs/<rollup_id> // Create
|
||||
PUT _plugins/_rollup/jobs/<rollup_id>?if_seq_no=1&if_primary_term=1 // Update
|
||||
{
|
||||
"rollup": {
|
||||
"source_index": "nyc-taxi-data",
|
||||
"target_index": "rollup-nyc-taxi-data",
|
||||
"schedule": {
|
||||
"interval": {
|
||||
"period": 1,
|
||||
"unit": "Days"
|
||||
}
|
||||
},
|
||||
"description": "Example rollup job",
|
||||
"enabled": true,
|
||||
"page_size": 200,
|
||||
"delay": 0,
|
||||
"roles": [
|
||||
"rollup_all",
|
||||
"nyc_taxi_all",
|
||||
"example_rollup_index_all"
|
||||
],
|
||||
"continuous": false,
|
||||
"dimensions": {
|
||||
"date_histogram": {
|
||||
"source_field": "tpep_pickup_datetime",
|
||||
"fixed_interval": "1h",
|
||||
"timezone": "America/Los_Angeles"
|
||||
},
|
||||
"terms": {
|
||||
"source_field": "PULocationID"
|
||||
},
|
||||
"metrics": [
|
||||
{
|
||||
"source_field": "passenger_count",
|
||||
"metrics": [
|
||||
{
|
||||
"avg": {}
|
||||
},
|
||||
{
|
||||
"sum": {}
|
||||
},
|
||||
{
|
||||
"max": {}
|
||||
},
|
||||
{
|
||||
"min": {}
|
||||
},
|
||||
{
|
||||
"value_count": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can specify the following options.
|
||||
|
||||
Options | Description | Type | Required
|
||||
:--- | :--- |:--- |:--- |
|
||||
`source_index` | The name of the detector. | String | Yes
|
||||
`target_index` | Specify the target index that the rolled up data is ingested into. You could either create a new target index or use an existing index. The target index cannot be a combination of raw and rolled up data. | String | Yes
|
||||
`schedule` | Schedule of the index rollup job which can be an interval or a cron expression. | Object | Yes
|
||||
`schedule.interval` | Specify the frequency of execution of the rollup job. | Object | No
|
||||
`schedule.interval.start_time` | Start time of the interval. | Timestamp | Yes
|
||||
`schedule.interval.period` | Define the interval period. | String | Yes
|
||||
`schedule.interval.unit` | Specify the time unit of the interval. | String | Yes
|
||||
`schedule.interval.cron` | Optionally, specify a cron expression to define therollup frequency. | List | No
|
||||
`schedule.interval.cron.expression` | Specify a Unix cron expression. | String | Yes
|
||||
`schedule.interval.cron.timezone` | Specify timezones as defined by the IANA Time Zone Database. Defaults to UTC. | String | No
|
||||
`description` | Optionally, describe the rollup job. | String | No
|
||||
`enabled` | When true, the index rollup job is scheduled. Default is true. | Boolean | Yes
|
||||
`continuous` | Specify whether or not the index rollup job continuously rolls up data forever or just executes over the current data set once and stops. Default is false. | Boolean | Yes
|
||||
`error_notification` | Set up a Mustache message template sent for error notifications. For example, if an index rollup job fails, the system sends a message to a Slack channel. | Object | No
|
||||
`page_size` | Specify the number of buckets to paginate through at a time while rolling up. | Number | Yes
|
||||
`delay` | The number of milliseconds to delay execution of the index rollup job. | Long | No
|
||||
`dimensions` | Specify aggregations to create dimensions for the roll up time window. | Object | Yes
|
||||
`dimensions.date_histogram` | Specify either fixed_interval or calendar_interval, but not both. Either one limits what you can query in the target index. | Object | No
|
||||
`dimensions.date_histogram.fixed_interval` | Specify the fixed interval for aggregations in milliseconds, seconds, minutes, hours, or days. | String | No
|
||||
`dimensions.date_histogram.calendar_interval` | Specify the calendar interval for aggregations in minutes, hours, days, weeks, months, quarters, or years. | String | No
|
||||
`dimensions.date_histogram.field` | Specify the date field used in date histogram aggregation. | String | No
|
||||
`dimensions.date_histogram.timezone` | Specify the timezones as defined by the IANA Time Zone Database. The default is UTC. | String | No
|
||||
`dimensions.terms` | Specify the term aggregations that you want to roll up. | Object | No
|
||||
`dimensions.terms.fields` | Specify terms aggregation for compatible fields. | Object | No
|
||||
`dimensions.histogram` | Specify the histogram aggregations that you want to roll up. | Object | No
|
||||
`dimensions.histogram.field` | Add a field for histogram aggregations. | String | Yes
|
||||
`dimensions.histogram.interval` | Specify the histogram aggregation interval for the field. | Long | Yes
|
||||
`dimensions.metrics` | Specify a list of objects that represent the fields and metrics that you want to calculate. | Nested object | No
|
||||
`dimensions.metrics.field` | Specify the field that you want to perform metric aggregations on. | String | No
|
||||
`dimensions.metrics.field.metrics` | Specify the metric aggregations you want to calculate for the field. | Multiple strings | No
|
||||
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"_id": "rollup_id",
|
||||
"_seqNo": 1,
|
||||
"_primaryTerm": 1,
|
||||
"rollup": { ... }
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Get an index rollup job
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Returns all information about an index rollup job based on the `rollup_id`.
|
||||
|
||||
#### Request
|
||||
|
||||
```json
|
||||
GET _plugins/_rollup/jobs/<rollup_id>
|
||||
```
|
||||
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"_id": "my_rollup",
|
||||
"_seqNo": 1,
|
||||
"_primaryTerm": 1,
|
||||
"rollup": { ... }
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Delete an index rollup job
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Deletes an index rollup job based on the `rollup_id`.
|
||||
|
||||
#### Request
|
||||
|
||||
```json
|
||||
DELETE _plugins/_rollup/jobs/<rollup_id>
|
||||
```
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
200 OK
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Start or stop an index rollup job
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Start or stop an index rollup job.
|
||||
|
||||
#### Request
|
||||
|
||||
```json
|
||||
POST _plugins/_rollup/jobs/<rollup_id>/_start
|
||||
POST _plugins/_rollup/jobs/<rollup_id>/_stop
|
||||
```
|
||||
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
200 OK
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Explain an index rollup job
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Returns detailed metadata information about the index rollup job and its current progress.
|
||||
|
||||
#### Request
|
||||
|
||||
```json
|
||||
GET _plugins/_rollup/jobs/<rollup_id>/_explain
|
||||
```
|
||||
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"example_rollup": {
|
||||
"rollup_id": "example_rollup",
|
||||
"last_updated_time": 1602014281,
|
||||
"continuous": {
|
||||
"next_window_start_time": 1602055591,
|
||||
"next_window_end_time": 1602075591
|
||||
},
|
||||
"status": "running",
|
||||
"failure_reason": null,
|
||||
"stats": {
|
||||
"pages_processed": 342,
|
||||
"documents_processed": 489359,
|
||||
"rollups_indexed": 3420,
|
||||
"index_time_in_ms": 30495,
|
||||
"search_time_in_ms": 584922
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -1,156 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Index transforms
|
||||
nav_order: 20
|
||||
has_children: true
|
||||
redirect_from: /im-plugin/index-transforms/
|
||||
has_toc: false
|
||||
---
|
||||
|
||||
# Index transforms
|
||||
|
||||
Whereas index rollup jobs let you reduce data granularity by rolling up old data into condensed indices, transform jobs let you create a different, summarized view of your data centered around certain fields, so you can visualize or analyze the data in different ways.
|
||||
|
||||
For example, suppose that you have airline data that’s scattered across multiple fields and categories, and you want to view a summary of the data that’s organized by airline, quarter, and then price. You can use a transform job to create a new, summarized index that’s organized by those specific categories.
|
||||
|
||||
You can use transform jobs in two ways:
|
||||
|
||||
1. Use the OpenSearch Dashboards UI to specify the index you want to transform and any optional data filters you want to use to filter the original index. Then select the fields you want to transform and the aggregations to use in the transformation. Finally, define a schedule for your job to follow.
|
||||
2. Use the transforms API to specify all the details about your job: the index you want to transform, target groups you want the transformed index to have, any aggregations you want to use to group columns, and a schedule for your job to follow.
|
||||
|
||||
OpenSearch Dashboards provides a detailed summary of the jobs you created and their relevant information, such as associated indices and job statuses. You can review and edit your job’s details and selections before creation, and even preview a transformed index’s data as you’re choosing which fields to transform. However, you can also use the REST API to create transform jobs and preview transform job results, but you must know all of the necessary settings and parameters to submit them as part of the HTTP request body. Submitting your transform job configurations as JSON scripts offers you more portability, allowing you to share and replicate your transform jobs, which is harder to do using OpenSearch Dashboards.
|
||||
|
||||
Your use cases will help you decide which method to use to create transform jobs.
|
||||
|
||||
## Create a transform job
|
||||
|
||||
If you don't have any data in your cluster, you can use the sample flight data within OpenSearch Dashboards to try out transform jobs. Otherwise, after launching OpenSearch Dashboards, choose **Index Management**. Select **Transform Jobs**, and choose **Create Transform Job**.
|
||||
|
||||
### Step 1: Choose indices
|
||||
|
||||
1. In the **Job name and description** section, specify a name and an optional description for your job.
|
||||
2. In the **Indices** section, select the source and target index. You can either select an existing target index or create a new one by entering a name for your new index. If you want to transform just a subset of your source index, choose **Edit data filter**, and use the OpenSearch query DSL to specify a subset of your source index. For more information about the OpenSearch query DSL, see [query DSL]({{site.url}}{{site.baseurl}}/opensearch/query-dsl/).
|
||||
3. Choose **Next**.
|
||||
|
||||
### Step 2: Select fields to transform
|
||||
|
||||
After specifying the indices, you can select the fields you want to use in your transform job, as well as whether to use groupings or aggregations.
|
||||
|
||||
You can use groupings to place your data into separate buckets in your transformed index. For example, if you want to group all of the airport destinations within the sample flight data, you can group the `DestAirportID` field into a target field of `DestAirportID_terms` field, and you can find the grouped airport IDs in your transformed index after the transform job finishes.
|
||||
|
||||
On the other hand, aggregations let you perform simple calculations. For example, you can include an aggregation in your transform job to define a new field of `sum_of_total_ticket_price` that calculates the sum of all airplane tickets, and then analyze the newly summer data within your transformed index.
|
||||
|
||||
1. In the data table, select the fields you want to transform and expand the drop-down menu within the column header to choose the grouping or aggregation you want to use.
|
||||
|
||||
Currently, transform jobs support histogram, date_histogram, and terms groupings. For more information about groupings, see [Bucket Aggregations]({{site.url}}{{site.baseurl}}/opensearch/bucket-agg/). In terms of aggregations, you can select from `sum`, `avg`, `max`, `min`, `value_count`, `percentiles`, and `scripted_metric`. For more information about aggregations, see [Metric Aggregations]({{site.url}}{{site.baseurl}}/opensearch/metric-agg/).
|
||||
|
||||
2. Repeat step 1 for any other fields that you want to transform.
|
||||
3. After selecting the fields that you want to transform and verifying the transformation, choose **Next**.
|
||||
|
||||
### Step 3: Specify a schedule
|
||||
|
||||
You can configure transform jobs to run once or multiple times on a schedule. Transform jobs are enabled by default.
|
||||
|
||||
1. For **transformation execution frequency**, select **Define by fixed interval** and specify a **transform interval**.
|
||||
2. Under **Advanced**, specify an optional amount for **Pages per execution**. A larger number means more data is processed in each search request, but also uses more memory and causes higher latency. Exceeding allowed memory limits can cause exceptions and errors to occur.
|
||||
3. Choose **Next**.
|
||||
|
||||
### Step 4: Review and confirm details
|
||||
|
||||
After confirming your transform job’s details are correct, choose **Create Transform Job**. If you want to edit any part of the job, choose **Edit** of the section you want to change, and make the necessary changes. You can’t change aggregations or groupings after creating a job.
|
||||
|
||||
### Step 5: Search through the transformed index.
|
||||
|
||||
Once the transform job finishes, you can use the `_search` API operation to search the target index.
|
||||
|
||||
```json
|
||||
GET <target_index>/_search
|
||||
```
|
||||
|
||||
For example, after running a transform job that transforms the flight data based on a `DestAirportID` field, you can run the following request that returns all of the fields that have a value of `SFO`.
|
||||
|
||||
**Sample Request**
|
||||
|
||||
```json
|
||||
GET finished_flight_job/_search
|
||||
{
|
||||
"query": {
|
||||
"match": {
|
||||
"DestAirportID_terms" : "SFO"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Sample Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"took" : 3,
|
||||
"timed_out" : false,
|
||||
"_shards" : {
|
||||
"total" : 5,
|
||||
"successful" : 5,
|
||||
"skipped" : 0,
|
||||
"failed" : 0
|
||||
},
|
||||
"hits" : {
|
||||
"total" : {
|
||||
"value" : 4,
|
||||
"relation" : "eq"
|
||||
},
|
||||
"max_score" : 3.845883,
|
||||
"hits" : [
|
||||
{
|
||||
"_index" : "finished_flight_job",
|
||||
"_type" : "_doc",
|
||||
"_id" : "dSNKGb8U3OJOmC4RqVCi1Q",
|
||||
"_score" : 3.845883,
|
||||
"_source" : {
|
||||
"transform._id" : "sample_flight_job",
|
||||
"transform._doc_count" : 14,
|
||||
"Carrier_terms" : "Dashboards Airlines",
|
||||
"DestAirportID_terms" : "SFO"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_index" : "finished_flight_job",
|
||||
"_type" : "_doc",
|
||||
"_id" : "_D7oqOy7drx9E-MG96U5RA",
|
||||
"_score" : 3.845883,
|
||||
"_source" : {
|
||||
"transform._id" : "sample_flight_job",
|
||||
"transform._doc_count" : 14,
|
||||
"Carrier_terms" : "Logstash Airways",
|
||||
"DestAirportID_terms" : "SFO"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_index" : "finished_flight_job",
|
||||
"_type" : "_doc",
|
||||
"_id" : "YuZ8tOt1OsBA54e84WuAEw",
|
||||
"_score" : 3.6988301,
|
||||
"_source" : {
|
||||
"transform._id" : "sample_flight_job",
|
||||
"transform._doc_count" : 11,
|
||||
"Carrier_terms" : "ES-Air",
|
||||
"DestAirportID_terms" : "SFO"
|
||||
}
|
||||
},
|
||||
{
|
||||
"_index" : "finished_flight_job",
|
||||
"_type" : "_doc",
|
||||
"_id" : "W_-e7bVmH6eu8veJeK8ZxQ",
|
||||
"_score" : 3.6988301,
|
||||
"_source" : {
|
||||
"transform._id" : "sample_flight_job",
|
||||
"transform._doc_count" : 10,
|
||||
"Carrier_terms" : "JetBeats",
|
||||
"DestAirportID_terms" : "SFO"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
@@ -1,729 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Transforms APIs
|
||||
nav_order: 45
|
||||
parent: Index transforms
|
||||
has_toc: true
|
||||
---
|
||||
|
||||
# Transforms APIs
|
||||
|
||||
Aside from using OpenSearch Dashboards, you can also use the REST API to create, start, stop, and complete other operations relative to transform jobs.
|
||||
|
||||
#### Table of contents
|
||||
- TOC
|
||||
{:toc}
|
||||
|
||||
## Create a transform job
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Creates a transform job.
|
||||
|
||||
**Sample Request**
|
||||
|
||||
```json
|
||||
PUT _plugins/_transform/<transform_id>
|
||||
|
||||
{
|
||||
"transform": {
|
||||
"enabled": true,
|
||||
"schedule": {
|
||||
"interval": {
|
||||
"period": 1,
|
||||
"unit": "Minutes",
|
||||
"start_time": 1602100553
|
||||
}
|
||||
},
|
||||
"description": "Sample transform job",
|
||||
"source_index": "sample_index",
|
||||
"target_index": "sample_target",
|
||||
"data_selection_query": {
|
||||
"match_all": {}
|
||||
},
|
||||
"page_size": 1,
|
||||
"groups": [
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "customer_gender",
|
||||
"target_field": "gender"
|
||||
}
|
||||
},
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "day_of_week",
|
||||
"target_field": "day"
|
||||
}
|
||||
}
|
||||
],
|
||||
"aggregations": {
|
||||
"quantity": {
|
||||
"sum": {
|
||||
"field": "total_quantity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Sample Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"_id": "sample",
|
||||
"_version": 7,
|
||||
"_seq_no": 13,
|
||||
"_primary_term": 1,
|
||||
"transform": {
|
||||
"transform_id": "sample",
|
||||
"schema_version": 7,
|
||||
"schedule": {
|
||||
"interval": {
|
||||
"start_time": 1621467964243,
|
||||
"period": 1,
|
||||
"unit": "Minutes"
|
||||
}
|
||||
},
|
||||
"metadata_id": null,
|
||||
"updated_at": 1621467964243,
|
||||
"enabled": true,
|
||||
"enabled_at": 1621467964243,
|
||||
"description": "Sample transform job",
|
||||
"source_index": "sample_index",
|
||||
"data_selection_query": {
|
||||
"match_all": {
|
||||
"boost": 1.0
|
||||
}
|
||||
},
|
||||
"target_index": "sample_target",
|
||||
"roles": [],
|
||||
"page_size": 1,
|
||||
"groups": [
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "customer_gender",
|
||||
"target_field": "gender"
|
||||
}
|
||||
},
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "day_of_week",
|
||||
"target_field": "day"
|
||||
}
|
||||
}
|
||||
],
|
||||
"aggregations": {
|
||||
"quantity": {
|
||||
"sum": {
|
||||
"field": "total_quantity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
You can specify the following options in the HTTP request body:
|
||||
|
||||
Option | Data Type | Description | Required
|
||||
:--- | :--- | :--- | :---
|
||||
enabled | Boolean | If true, the transform job is enabled at creation. | No
|
||||
schedule | JSON | The schedule the transform job runs on. | Yes
|
||||
start_time | Integer | The Unix epoch time of the transform job's start time. | Yes
|
||||
description | String | Describes the transform job. | No
|
||||
metadata_id | String | Any metadata to be associated with the transform job. | No
|
||||
source_index | String | The source index whose data to transform. | Yes
|
||||
target_index | String | The target index the newly transformed data is added into. You can create a new index or update an existing one. | Yes
|
||||
data_selection_query | JSON | The query DSL to use to filter a subset of the source index for the transform job. See [query DSL]({{site.url}}{{site.baseurl}}/opensearch/query-dsl) for more information. | Yes
|
||||
page_size | Integer | The number of fields to transform at a time. Higher number means higher performance but requires more memory and can cause higher latency. (Default: 1) | Yes
|
||||
groups | Array | Specifies the grouping(s) to use in the transform job. Supported groups are `terms`, `histogram`, and `date_histogram`. For more information, see [Bucket Aggregations]({{site.url}}{{site.baseurl}}/opensearch/bucket-agg). | Yes if not using aggregations
|
||||
source_field | String | The field(s) to transform | Yes
|
||||
aggregations | JSON | The aggregations to use in the transform job. Supported aggregations are: `sum`, `max`, `min`, `value_count`, `avg`, `scripted_metric`, and `percentiles`. For more information, see [Metric Aggregations]({{site.url}}{{site.baseurl}}/opensearch/metric-agg). | Yes if not using groups
|
||||
|
||||
## Update a transform job
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Updates a transform job if `transform_id` already exists.
|
||||
|
||||
**Sample Request**
|
||||
|
||||
```json
|
||||
PUT _plugins/_transform/<transform_id>
|
||||
|
||||
{
|
||||
"transform": {
|
||||
"enabled": true,
|
||||
"schedule": {
|
||||
"interval": {
|
||||
"period": 1,
|
||||
"unit": "Minutes",
|
||||
"start_time": 1602100553
|
||||
}
|
||||
},
|
||||
"description": "Sample transform job",
|
||||
"source_index": "sample_index",
|
||||
"target_index": "sample_target",
|
||||
"data_selection_query": {
|
||||
"match_all": {}
|
||||
},
|
||||
"page_size": 1,
|
||||
"groups": [
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "customer_gender",
|
||||
"target_field": "gender"
|
||||
}
|
||||
},
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "day_of_week",
|
||||
"target_field": "day"
|
||||
}
|
||||
}
|
||||
],
|
||||
"aggregations": {
|
||||
"quantity": {
|
||||
"sum": {
|
||||
"field": "total_quantity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Sample Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"_id": "sample",
|
||||
"_version": 2,
|
||||
"_seq_no": 14,
|
||||
"_primary_term": 1,
|
||||
"transform": {
|
||||
"transform_id": "sample",
|
||||
"schema_version": 7,
|
||||
"schedule": {
|
||||
"interval": {
|
||||
"start_time": 1602100553,
|
||||
"period": 1,
|
||||
"unit": "Minutes"
|
||||
}
|
||||
},
|
||||
"metadata_id": null,
|
||||
"updated_at": 1621889843874,
|
||||
"enabled": true,
|
||||
"enabled_at": 1621889843874,
|
||||
"description": "Sample transform job",
|
||||
"source_index": "sample_index",
|
||||
"data_selection_query": {
|
||||
"match_all": {
|
||||
"boost": 1.0
|
||||
}
|
||||
},
|
||||
"target_index": "sample_target",
|
||||
"roles": [],
|
||||
"page_size": 1,
|
||||
"groups": [
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "customer_gender",
|
||||
"target_field": "gender"
|
||||
}
|
||||
},
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "day_of_week",
|
||||
"target_field": "day"
|
||||
}
|
||||
}
|
||||
],
|
||||
"aggregations": {
|
||||
"quantity": {
|
||||
"sum": {
|
||||
"field": "total_quantity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `Update` operation supports the following URL parameters:
|
||||
|
||||
Parameter | Description | Required
|
||||
:---| :--- | :---
|
||||
`if_seq_no` | Only perform the transform operation if the last operation that changed the transform job has the specified sequence number. | No
|
||||
`if_primary_term` | Only perform the transform operation if the last operation that changed the transform job has the specified sequence term. | No
|
||||
|
||||
## Get a transform job's details
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Returns a transform job's details.
|
||||
|
||||
**Sample Request**
|
||||
|
||||
```json
|
||||
GET _plugins/_transform/<transform_id>
|
||||
```
|
||||
|
||||
**Sample Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"_id": "sample",
|
||||
"_version": 7,
|
||||
"_seq_no": 13,
|
||||
"_primary_term": 1,
|
||||
"transform": {
|
||||
"transform_id": "sample",
|
||||
"schema_version": 7,
|
||||
"schedule": {
|
||||
"interval": {
|
||||
"start_time": 1621467964243,
|
||||
"period": 1,
|
||||
"unit": "Minutes"
|
||||
}
|
||||
},
|
||||
"metadata_id": null,
|
||||
"updated_at": 1621467964243,
|
||||
"enabled": true,
|
||||
"enabled_at": 1621467964243,
|
||||
"description": "Sample transform job",
|
||||
"source_index": "sample_index",
|
||||
"data_selection_query": {
|
||||
"match_all": {
|
||||
"boost": 1.0
|
||||
}
|
||||
},
|
||||
"target_index": "sample_target",
|
||||
"roles": [],
|
||||
"page_size": 1,
|
||||
"groups": [
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "customer_gender",
|
||||
"target_field": "gender"
|
||||
}
|
||||
},
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "day_of_week",
|
||||
"target_field": "day"
|
||||
}
|
||||
}
|
||||
],
|
||||
"aggregations": {
|
||||
"quantity": {
|
||||
"sum": {
|
||||
"field": "total_quantity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can also get details of all transform jobs by omitting `transform_id`.
|
||||
|
||||
**Sample Request**
|
||||
|
||||
```json
|
||||
GET _plugins/_transform/
|
||||
```
|
||||
|
||||
**Sample Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"total_transforms": 1,
|
||||
"transforms": [
|
||||
{
|
||||
"_id": "sample",
|
||||
"_seq_no": 13,
|
||||
"_primary_term": 1,
|
||||
"transform": {
|
||||
"transform_id": "sample",
|
||||
"schema_version": 7,
|
||||
"schedule": {
|
||||
"interval": {
|
||||
"start_time": 1621467964243,
|
||||
"period": 1,
|
||||
"unit": "Minutes"
|
||||
}
|
||||
},
|
||||
"metadata_id": null,
|
||||
"updated_at": 1621467964243,
|
||||
"enabled": true,
|
||||
"enabled_at": 1621467964243,
|
||||
"description": "Sample transform job",
|
||||
"source_index": "sample_index",
|
||||
"data_selection_query": {
|
||||
"match_all": {
|
||||
"boost": 1.0
|
||||
}
|
||||
},
|
||||
"target_index": "sample_target",
|
||||
"roles": [],
|
||||
"page_size": 1,
|
||||
"groups": [
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "customer_gender",
|
||||
"target_field": "gender"
|
||||
}
|
||||
},
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "day_of_week",
|
||||
"target_field": "day"
|
||||
}
|
||||
}
|
||||
],
|
||||
"aggregations": {
|
||||
"quantity": {
|
||||
"sum": {
|
||||
"field": "total_quantity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
You can specify these options as the `GET` API operation’s URL parameters to filter results:
|
||||
|
||||
Parameter | Description | Required
|
||||
:--- | :--- | :---
|
||||
from | The starting index to search from. (Default: 0) | No
|
||||
size | Specifies the amount of results to return (Default: 10) | No
|
||||
search |The search term to use to filter results. | No
|
||||
sortField | The field to sort results with. | No
|
||||
sortDirection | Specifies the direction to sort results in. Can be `ASC` or `DESC`. (Default: ASC) | No
|
||||
|
||||
For example, this request returns two results starting from the eighth index.
|
||||
|
||||
**Sample Request**
|
||||
|
||||
```json
|
||||
GET _plugins/_transform?size=2&from=8
|
||||
```
|
||||
|
||||
**Sample Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"total_transforms": 18,
|
||||
"transforms": [
|
||||
{
|
||||
"_id": "sample8",
|
||||
"_seq_no": 93,
|
||||
"_primary_term": 1,
|
||||
"transform": {
|
||||
"transform_id": "sample8",
|
||||
"schema_version": 7,
|
||||
"schedule": {
|
||||
"interval": {
|
||||
"start_time": 1622063596812,
|
||||
"period": 1,
|
||||
"unit": "Minutes"
|
||||
}
|
||||
},
|
||||
"metadata_id": "y4hFAB2ZURQ2dzY7BAMxWA",
|
||||
"updated_at": 1622063657233,
|
||||
"enabled": false,
|
||||
"enabled_at": null,
|
||||
"description": "Sample transform job",
|
||||
"source_index": "sample_index3",
|
||||
"data_selection_query": {
|
||||
"match_all": {
|
||||
"boost": 1.0
|
||||
}
|
||||
},
|
||||
"target_index": "sample_target3",
|
||||
"roles": [],
|
||||
"page_size": 1,
|
||||
"groups": [
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "customer_gender",
|
||||
"target_field": "gender"
|
||||
}
|
||||
},
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "day_of_week",
|
||||
"target_field": "day"
|
||||
}
|
||||
}
|
||||
],
|
||||
"aggregations": {
|
||||
"quantity": {
|
||||
"sum": {
|
||||
"field": "total_quantity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "sample9",
|
||||
"_seq_no": 98,
|
||||
"_primary_term": 1,
|
||||
"transform": {
|
||||
"transform_id": "sample9",
|
||||
"schema_version": 7,
|
||||
"schedule": {
|
||||
"interval": {
|
||||
"start_time": 1622063598065,
|
||||
"period": 1,
|
||||
"unit": "Minutes"
|
||||
}
|
||||
},
|
||||
"metadata_id": "x8tCIiYMTE3veSbIJkit5A",
|
||||
"updated_at": 1622063658388,
|
||||
"enabled": false,
|
||||
"enabled_at": null,
|
||||
"description": "Sample transform job",
|
||||
"source_index": "sample_index4",
|
||||
"data_selection_query": {
|
||||
"match_all": {
|
||||
"boost": 1.0
|
||||
}
|
||||
},
|
||||
"target_index": "sample_target4",
|
||||
"roles": [],
|
||||
"page_size": 1,
|
||||
"groups": [
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "customer_gender",
|
||||
"target_field": "gender"
|
||||
}
|
||||
},
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "day_of_week",
|
||||
"target_field": "day"
|
||||
}
|
||||
}
|
||||
],
|
||||
"aggregations": {
|
||||
"quantity": {
|
||||
"sum": {
|
||||
"field": "total_quantity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Start a transform job
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Transform jobs created using the API are automatically enabled, but if you ever need to enable a job, you can use the `start` API operation.
|
||||
|
||||
**Sample Request**
|
||||
|
||||
```json
|
||||
POST _plugins/_transform/<transform_id>/_start
|
||||
```
|
||||
|
||||
**Sample Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"acknowledged": true
|
||||
}
|
||||
```
|
||||
|
||||
## Stop a transform job
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Stops/disables a transform job.
|
||||
|
||||
**Sample Request**
|
||||
|
||||
```json
|
||||
POST _plugins/_transform/<transform_id>/_stop
|
||||
```
|
||||
|
||||
**Sample Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"acknowledged": true
|
||||
}
|
||||
```
|
||||
|
||||
## Get the status of a transform job
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Returns the status and metadata of a transform job.
|
||||
|
||||
**Sample Request**
|
||||
|
||||
```json
|
||||
GET _plugins/_transform/<transform_id>/_explain
|
||||
```
|
||||
|
||||
**Sample Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"sample": {
|
||||
"metadata_id": "PzmjweME5xbgkenl9UpsYw",
|
||||
"transform_metadata": {
|
||||
"transform_id": "sample",
|
||||
"last_updated_at": 1621883525873,
|
||||
"status": "finished",
|
||||
"failure_reason": "null",
|
||||
"stats": {
|
||||
"pages_processed": 0,
|
||||
"documents_processed": 0,
|
||||
"documents_indexed": 0,
|
||||
"index_time_in_millis": 0,
|
||||
"search_time_in_millis": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Preview a transform job's results
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Returns a preview of what a transformed index would look like.
|
||||
|
||||
**Sample Request**
|
||||
|
||||
```json
|
||||
POST _plugins/_transform/_preview
|
||||
|
||||
{
|
||||
"transform": {
|
||||
"enabled": false,
|
||||
"schedule": {
|
||||
"interval": {
|
||||
"period": 1,
|
||||
"unit": "Minutes",
|
||||
"start_time": 1602100553
|
||||
}
|
||||
},
|
||||
"description": "test transform",
|
||||
"source_index": "sample_index",
|
||||
"target_index": "sample_target",
|
||||
"data_selection_query": {
|
||||
"match_all": {}
|
||||
},
|
||||
"page_size": 10,
|
||||
"groups": [
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "customer_gender",
|
||||
"target_field": "gender"
|
||||
}
|
||||
},
|
||||
{
|
||||
"terms": {
|
||||
"source_field": "day_of_week",
|
||||
"target_field": "day"
|
||||
}
|
||||
}
|
||||
],
|
||||
"aggregations": {
|
||||
"quantity": {
|
||||
"sum": {
|
||||
"field": "total_quantity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Sample Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"documents" : [
|
||||
{
|
||||
"quantity" : 862.0,
|
||||
"gender" : "FEMALE",
|
||||
"day" : "Friday"
|
||||
},
|
||||
{
|
||||
"quantity" : 682.0,
|
||||
"gender" : "FEMALE",
|
||||
"day" : "Monday"
|
||||
},
|
||||
{
|
||||
"quantity" : 772.0,
|
||||
"gender" : "FEMALE",
|
||||
"day" : "Saturday"
|
||||
},
|
||||
{
|
||||
"quantity" : 669.0,
|
||||
"gender" : "FEMALE",
|
||||
"day" : "Sunday"
|
||||
},
|
||||
{
|
||||
"quantity" : 887.0,
|
||||
"gender" : "FEMALE",
|
||||
"day" : "Thursday"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Delete a transform job
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Deletes a transform job. This operation does not delete the source or target indices.
|
||||
|
||||
**Sample Request**
|
||||
|
||||
```json
|
||||
DELETE _plugins/_transform/<transform_id>
|
||||
```
|
||||
|
||||
**Sample Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"took": 205,
|
||||
"errors": false,
|
||||
"items": [
|
||||
{
|
||||
"delete": {
|
||||
"_index": ".opensearch-ism-config",
|
||||
"_type": "_doc",
|
||||
"_id": "sample",
|
||||
"_version": 4,
|
||||
"result": "deleted",
|
||||
"forced_refresh": true,
|
||||
"_shards": {
|
||||
"total": 2,
|
||||
"successful": 1,
|
||||
"failed": 0
|
||||
},
|
||||
"_seq_no": 6,
|
||||
"_primary_term": 1,
|
||||
"status": 200
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: About Index Management
|
||||
nav_order: 1
|
||||
has_children: false
|
||||
redirect_from:
|
||||
- /im-plugin/
|
||||
---
|
||||
|
||||
# About Index Management
|
||||
OpenSearch Dashboards
|
||||
{: .label .label-yellow :}
|
||||
|
||||
The Index Management (IM) plugin lets you automate recurring index management activities and reduce storage costs.
|
||||
@@ -1,513 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: ISM API
|
||||
parent: Index State Management
|
||||
nav_order: 20
|
||||
---
|
||||
|
||||
# ISM API
|
||||
|
||||
Use the index state management operations to programmatically work with policies and managed indices.
|
||||
|
||||
---
|
||||
|
||||
#### Table of contents
|
||||
- TOC
|
||||
{:toc}
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Create policy
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Creates a policy.
|
||||
|
||||
#### Request
|
||||
|
||||
```json
|
||||
PUT _plugins/_ism/policies/policy_1
|
||||
{
|
||||
"policy": {
|
||||
"description": "ingesting logs",
|
||||
"default_state": "ingest",
|
||||
"states": [
|
||||
{
|
||||
"name": "ingest",
|
||||
"actions": [
|
||||
{
|
||||
"rollover": {
|
||||
"min_doc_count": 5
|
||||
}
|
||||
}
|
||||
],
|
||||
"transitions": [
|
||||
{
|
||||
"state_name": "search"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "search",
|
||||
"actions": [],
|
||||
"transitions": [
|
||||
{
|
||||
"state_name": "delete",
|
||||
"conditions": {
|
||||
"min_index_age": "5m"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "delete",
|
||||
"actions": [
|
||||
{
|
||||
"delete": {}
|
||||
}
|
||||
],
|
||||
"transitions": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"_id": "policy_1",
|
||||
"_version": 1,
|
||||
"_primary_term": 1,
|
||||
"_seq_no": 7,
|
||||
"policy": {
|
||||
"policy": {
|
||||
"policy_id": "policy_1",
|
||||
"description": "ingesting logs",
|
||||
"last_updated_time": 1577990761311,
|
||||
"schema_version": 1,
|
||||
"error_notification": null,
|
||||
"default_state": "ingest",
|
||||
"states": [
|
||||
{
|
||||
"name": "ingest",
|
||||
"actions": [
|
||||
{
|
||||
"rollover": {
|
||||
"min_doc_count": 5
|
||||
}
|
||||
}
|
||||
],
|
||||
"transitions": [
|
||||
{
|
||||
"state_name": "search"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "search",
|
||||
"actions": [],
|
||||
"transitions": [
|
||||
{
|
||||
"state_name": "delete",
|
||||
"conditions": {
|
||||
"min_index_age": "5m"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "delete",
|
||||
"actions": [
|
||||
{
|
||||
"delete": {}
|
||||
}
|
||||
],
|
||||
"transitions": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Add policy
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Adds a policy to an index. This operation does not change the policy if the index already has one.
|
||||
|
||||
#### Request
|
||||
|
||||
```json
|
||||
POST _plugins/_ism/add/index_1
|
||||
{
|
||||
"policy_id": "policy_1"
|
||||
}
|
||||
```
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"updated_indices": 1,
|
||||
"failures": false,
|
||||
"failed_indices": []
|
||||
}
|
||||
```
|
||||
|
||||
If you use a wildcard `*` while adding a policy to an index, the ISM plugin interprets `*` as all indices, including system indices like `.opendistro-security`, which stores users, roles, and tenants. A delete action in your policy might accidentally delete all user roles and tenants in your cluster.
|
||||
Don't use the broad `*` wildcard, and instead add a prefix, such as `my-logs*`, when specifying indices with the `_ism/add` API.
|
||||
{: .warning }
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Update policy
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Updates a policy. Use the `seq_no` and `primary_term` parameters to update an existing policy. If these numbers don't match the existing policy or the policy doesn't exist, ISM throws an error.
|
||||
|
||||
#### Request
|
||||
|
||||
```json
|
||||
PUT _plugins/_ism/policies/policy_1?if_seq_no=7&if_primary_term=1
|
||||
{
|
||||
"policy": {
|
||||
"description": "ingesting logs",
|
||||
"default_state": "ingest",
|
||||
"states": [
|
||||
{
|
||||
"name": "ingest",
|
||||
"actions": [
|
||||
{
|
||||
"rollover": {
|
||||
"min_doc_count": 5
|
||||
}
|
||||
}
|
||||
],
|
||||
"transitions": [
|
||||
{
|
||||
"state_name": "search"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "search",
|
||||
"actions": [],
|
||||
"transitions": [
|
||||
{
|
||||
"state_name": "delete",
|
||||
"conditions": {
|
||||
"min_index_age": "5m"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "delete",
|
||||
"actions": [
|
||||
{
|
||||
"delete": {}
|
||||
}
|
||||
],
|
||||
"transitions": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"_id": "policy_1",
|
||||
"_version": 2,
|
||||
"_primary_term": 1,
|
||||
"_seq_no": 10,
|
||||
"policy": {
|
||||
"policy": {
|
||||
"policy_id": "policy_1",
|
||||
"description": "ingesting logs",
|
||||
"last_updated_time": 1577990934044,
|
||||
"schema_version": 1,
|
||||
"error_notification": null,
|
||||
"default_state": "ingest",
|
||||
"states": [
|
||||
{
|
||||
"name": "ingest",
|
||||
"actions": [
|
||||
{
|
||||
"rollover": {
|
||||
"min_doc_count": 5
|
||||
}
|
||||
}
|
||||
],
|
||||
"transitions": [
|
||||
{
|
||||
"state_name": "search"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "search",
|
||||
"actions": [],
|
||||
"transitions": [
|
||||
{
|
||||
"state_name": "delete",
|
||||
"conditions": {
|
||||
"min_index_age": "5m"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "delete",
|
||||
"actions": [
|
||||
{
|
||||
"delete": {}
|
||||
}
|
||||
],
|
||||
"transitions": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Get policy
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Gets the policy by `policy_id`.
|
||||
|
||||
#### Request
|
||||
|
||||
```json
|
||||
GET _plugins/_ism/policies/policy_1
|
||||
```
|
||||
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"_id": "policy_1",
|
||||
"_version": 2,
|
||||
"_seq_no": 10,
|
||||
"_primary_term": 1,
|
||||
"policy": {
|
||||
"policy_id": "policy_1",
|
||||
"description": "ingesting logs",
|
||||
"last_updated_time": 1577990934044,
|
||||
"schema_version": 1,
|
||||
"error_notification": null,
|
||||
"default_state": "ingest",
|
||||
"states": [
|
||||
{
|
||||
"name": "ingest",
|
||||
"actions": [
|
||||
{
|
||||
"rollover": {
|
||||
"min_doc_count": 5
|
||||
}
|
||||
}
|
||||
],
|
||||
"transitions": [
|
||||
{
|
||||
"state_name": "search"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "search",
|
||||
"actions": [],
|
||||
"transitions": [
|
||||
{
|
||||
"state_name": "delete",
|
||||
"conditions": {
|
||||
"min_index_age": "5m"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "delete",
|
||||
"actions": [
|
||||
{
|
||||
"delete": {}
|
||||
}
|
||||
],
|
||||
"transitions": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Remove policy from index
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Removes any ISM policy from the index.
|
||||
|
||||
#### Request
|
||||
|
||||
```json
|
||||
POST _plugins/_ism/remove/index_1
|
||||
```
|
||||
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"updated_indices": 1,
|
||||
"failures": false,
|
||||
"failed_indices": []
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Update managed index policy
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Updates the managed index policy to a new policy (or to a new version of the policy). You can use an index pattern to update multiple indices at once. When updating multiple indices, you might want to include a state filter to only affect certain managed indices. The change policy filters out all the existing managed indices and only applies the change to the ones in the state that you specify. You can also explicitly specify the state that the managed index transitions to after the change policy takes effect.
|
||||
|
||||
A policy change is an asynchronous background process. The changes are queued and are not executed immediately by the background process. This delay in execution protects the currently running managed indices from being put into a broken state. If the policy you are changing to has only some small configuration changes, then the change takes place immediately. For example, if the policy changes the `min_index_age` parameter in a rollover condition from `1000d` to `100d`, this change takes place immediately in its next execution. If the change modifies the state, actions, or the order of actions of the current state the index is in, then the change happens at the end of its current state before transitioning to a new state.
|
||||
|
||||
In this example, the policy applied on the `index_1` index is changed to `policy_1`, which could either be a completely new policy or an updated version of its existing policy. The process only applies the change if the index is currently in the `searches` state. After this change in policy takes place, `index_1` transitions to the `delete` state.
|
||||
|
||||
#### Request
|
||||
|
||||
```json
|
||||
POST _plugins/_ism/change_policy/index_1
|
||||
{
|
||||
"policy_id": "policy_1",
|
||||
"state": "delete",
|
||||
"include": [
|
||||
{
|
||||
"state": "searches"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"updated_indices": 0,
|
||||
"failures": false,
|
||||
"failed_indices": []
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Retry failed index
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Retries the failed action for an index. For the retry call to succeed, ISM must manage the index, and the index must be in a failed state. You can use index patterns (`*`) to retry multiple failed indices.
|
||||
|
||||
#### Request
|
||||
|
||||
```json
|
||||
POST _plugins/_ism/retry/index_1
|
||||
{
|
||||
"state": "delete"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"updated_indices": 0,
|
||||
"failures": false,
|
||||
"failed_indices": []
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Explain index
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Gets the current state of the index. You can use index patterns to get the status of multiple indices.
|
||||
|
||||
#### Request
|
||||
|
||||
```json
|
||||
GET _plugins/_ism/explain/index_1
|
||||
```
|
||||
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"index_1": {
|
||||
"index.plugins.index_state_management.policy_id": "policy_1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `plugins.index_state_management.policy_id` setting is deprecated starting from ODFE version 1.13.0. We retain this field in the response API for consistency.
|
||||
|
||||
---
|
||||
|
||||
## Delete policy
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Deletes the policy by `policy_id`.
|
||||
|
||||
#### Request
|
||||
|
||||
```json
|
||||
DELETE _plugins/_ism/policies/policy_1
|
||||
```
|
||||
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"_index": ".opendistro-ism-config",
|
||||
"_type": "_doc",
|
||||
"_id": "policy_1",
|
||||
"_version": 3,
|
||||
"result": "deleted",
|
||||
"forced_refresh": true,
|
||||
"_shards": {
|
||||
"total": 2,
|
||||
"successful": 2,
|
||||
"failed": 0
|
||||
},
|
||||
"_seq_no": 15,
|
||||
"_primary_term": 1
|
||||
}
|
||||
```
|
||||
@@ -1,112 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Index State Management
|
||||
nav_order: 3
|
||||
has_children: true
|
||||
redirect_from:
|
||||
- /im-plugin/ism/
|
||||
has_toc: false
|
||||
---
|
||||
|
||||
# Index State Management
|
||||
OpenSearch Dashboards
|
||||
{: .label .label-yellow :}
|
||||
|
||||
If you analyze time-series data, you likely prioritize new data over old data. You might periodically perform certain operations on older indices, such as reducing replica count or deleting them.
|
||||
|
||||
Index State Management (ISM) is a plugin that lets you automate these periodic, administrative operations by triggering them based on changes in the index age, index size, or number of documents. Using the ISM plugin, you can define *policies* that automatically handle index rollovers or deletions to fit your use case.
|
||||
|
||||
For example, you can define a policy that moves your index into a `read_only` state after 30 days and then deletes it after a set period of 90 days. You can also set up the policy to send you a notification message when the index is deleted.
|
||||
|
||||
You might want to perform an index rollover after a certain amount of time or run a `force_merge` operation on an index during off-peak hours to improve search performance during peak hours.
|
||||
|
||||
To use the ISM plugin, your user role needs to be mapped to the `all_access` role that gives you full access to the cluster. To learn more, see [Users and roles]({{site.url}}{{site.baseurl}}/security-plugin/access-control/users-roles/).
|
||||
{: .note }
|
||||
|
||||
## Get started with ISM
|
||||
|
||||
To get started, choose **Index Management** in OpenSearch Dashboards.
|
||||
|
||||
### Step 1: Set up policies
|
||||
|
||||
A policy is a set of rules that describes how an index should be managed. For information about creating a policy, see [Policies]({{site.url}}{{site.baseurl}}/im-plugin/ism/policies/).
|
||||
|
||||
You can use the JSON editor or visual editor to create policies. Compared to the JSON editor, the visual editor offers a more structured way of defining policies by separating the process into creating error notifications, defining ISM templates, and adding states. We recommend using the visual editor if you want to see pre-defined fields, such as which actions you can assign to a state or under what conditions a state can transition into a destination state.
|
||||
|
||||
#### JSON editor
|
||||
|
||||
1. Choose the **Index Policies** tab.
|
||||
2. Choose **Create policy**.
|
||||
3. Choose **JSON editor**.
|
||||
4. In the **Name policy** section, enter a policy ID.
|
||||
5. In the **Define policy** section, enter your policy.
|
||||
6. Choose **Create**.
|
||||
|
||||
After you create a policy, your next step is to attach it to an index or indices.
|
||||
You can set up an `ism_template` in the policy so when an index that matches the ISM template pattern is created, the plugin automatically attaches the policy to the index.
|
||||
|
||||
The following example demonstrates how to create a policy that automatically gets attached to all indices whose names start with `index_name-`.
|
||||
|
||||
```json
|
||||
PUT _plugins/_ism/policies/policy_id
|
||||
{
|
||||
"policy": {
|
||||
"description": "Example policy.",
|
||||
"default_state": "...",
|
||||
"states": [...],
|
||||
"ism_template": {
|
||||
"index_patterns": ["index_name-*"],
|
||||
"priority": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you have more than one template that matches an index pattern, ISM uses the priority value to determine which template to apply.
|
||||
|
||||
For an example ISM template policy, see [Sample policy with ISM template]({{site.url}}{{site.baseurl}}/im-plugin/ism/policies#sample-policy-with-ism-template).
|
||||
|
||||
Older versions of the plugin include the `policy_id` in an index template, so when an index is created that matches the index template pattern, the index will have the policy attached to it:
|
||||
|
||||
```json
|
||||
PUT _index_template/<template_name>
|
||||
{
|
||||
"index_patterns": [
|
||||
"index_name-*"
|
||||
],
|
||||
"template": {
|
||||
"settings": {
|
||||
"opendistro.index_state_management.policy_id": "policy_id"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `opendistro.index_state_management.policy_id` setting is deprecated. You can continue to automatically manage newly created indices with the ISM template field.
|
||||
{: .note }
|
||||
|
||||
### Step 2: Attach policies to indices
|
||||
|
||||
1. Choose **Indices**.
|
||||
2. Choose the index or indices that you want to attach your policy to.
|
||||
3. Choose **Apply policy**.
|
||||
4. From the **Policy ID** menu, choose the policy that you created.
|
||||
You can see a preview of your policy.
|
||||
5. If your policy includes a rollover operation, specify a rollover alias.
|
||||
Make sure that the alias that you enter already exists. For more information about the rollover operation, see [rollover]({{site.url}}{{site.baseurl}}/im-plugin/ism/policies#rollover).
|
||||
6. Choose **Apply**.
|
||||
|
||||
After you attach a policy to an index, ISM creates a job that runs every 5 minutes by default to perform policy actions, check conditions, and transition the index into different states. To change the default time interval for this job, see [Settings]({{site.url}}{{site.baseurl}}/im-plugin/ism/settings/).
|
||||
|
||||
ISM does not run jobs if the cluster state is red.
|
||||
|
||||
### Step 3: Manage indices
|
||||
|
||||
1. Choose **Managed Indices**.
|
||||
2. To change your policy, see [Change Policy]({{site.url}}{{site.baseurl}}/im-plugin/ism/managedindices#change-policy).
|
||||
3. To attach a rollover alias to your index, select your policy and choose **Add rollover alias**.
|
||||
Make sure that the alias that you enter already exists. For more information about the rollover operation, see [rollover]({{site.url}}{{site.baseurl}}/im-plugin/ism/policies#rollover).
|
||||
4. To remove a policy, choose your policy, and then choose **Remove policy**.
|
||||
5. To retry a policy, choose your policy, and then choose **Retry policy**.
|
||||
|
||||
For information about managing your policies, see [Managed Indices]({{site.url}}{{site.baseurl}}/im-plugin/ism/managedindices/).
|
||||
@@ -1,73 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Managed Indices
|
||||
nav_order: 3
|
||||
parent: Index State Management
|
||||
has_children: false
|
||||
---
|
||||
|
||||
# Managed indices
|
||||
|
||||
You can change or update a policy using the managed index operations.
|
||||
|
||||
This table lists the fields of managed index operations.
|
||||
|
||||
Parameter | Description | Type | Required | Read Only
|
||||
:--- | :--- |:--- |:--- |
|
||||
`name` | The name of the managed index policy. | `string` | Yes | No
|
||||
`index` | The name of the managed index that this policy is managing. | `string` | Yes | No
|
||||
`index_uuid` | The uuid of the index. | `string` | Yes | No
|
||||
`enabled` | When `true`, the managed index is scheduled and run by the scheduler. | `boolean` | Yes | No
|
||||
`enabled_time` | The time the managed index was last enabled. If the managed index process is disabled, then this is null. | `timestamp` | Yes | Yes
|
||||
`last_updated_time` | The time the managed index was last updated. | `timestamp` | Yes | Yes
|
||||
`schedule` | The schedule of the managed index job. | `object` | Yes | No
|
||||
`policy_id` | The name of the policy used by this managed index. | `string` | Yes | No
|
||||
`policy_seq_no` | The sequence number of the policy used by this managed index. | `number` | Yes | No
|
||||
`policy_primary_term` | The primary term of the policy used by this managed index. | `number` | Yes | No
|
||||
`policy_version` | The version of the policy used by this managed index. | `number` | Yes | Yes
|
||||
`policy` | The cached JSON of the policy for the `policy_version` that's used during runs. If the policy is null, it means that this is the first execution of the job and the latest policy document is read in/saved. | `object` | No | No
|
||||
`change_policy` | The information regarding what policy and state to change to. | `object` | No | No
|
||||
`policy_name` | The name of the policy to update to. To update to the latest version, set this to be the same as the current `policy_name`. | `string` | No | Yes
|
||||
`state` | The state of the managed index after it finishes updating. If no state is specified, it's assumed that the policy structure did not change. | `string` | No | Yes
|
||||
|
||||
The following example shows a managed index policy:
|
||||
|
||||
```json
|
||||
{
|
||||
"managed_index": {
|
||||
"name": "my_index",
|
||||
"index": "my_index",
|
||||
"index_uuid": "sOKSOfkdsoSKeofjIS",
|
||||
"enabled": true,
|
||||
"enabled_time": 1553112384,
|
||||
"last_updated_time": 1553112384,
|
||||
"schedule": {
|
||||
"interval": {
|
||||
"period": 1,
|
||||
"unit": "MINUTES",
|
||||
"start_time": 1553112384
|
||||
}
|
||||
},
|
||||
"policy_id": "log_rotation",
|
||||
"policy_version": 1,
|
||||
"policy": {...},
|
||||
"change_policy": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Change policy
|
||||
|
||||
You can change any managed index policy, but ISM has a few constraints in place to make sure that policy changes don't break indices.
|
||||
|
||||
If an index is stuck in its current state, never proceeding, and you want to update its policy immediately, make sure that the new policy includes the same state---same name, same actions, same order---as the old policy. In this case, even if the policy is in the middle of executing an action, ISM applies the new policy.
|
||||
|
||||
If you update the policy without including an identical state, ISM updates the policy only after all actions in the current state finish executing. Alternately, you can choose a specific state in your old policy after which you want the new policy to take effect.
|
||||
|
||||
To change a policy using OpenSearch Dashboards, do the following:
|
||||
|
||||
- Under **Managed indices**, choose the indices that you want to attach the new policy to.
|
||||
- To attach the new policy to indices in specific states, choose **Choose state filters**, and then choose those states.
|
||||
- Under **Choose New Policy**, choose the new policy.
|
||||
- To start the new policy for indices in the current state, choose **Keep indices in their current state after the policy takes effect**.
|
||||
- To start the new policy in a specific state, choose **Start from a chosen state after changing policies**, and then choose the default start state in your new policy.
|
||||
@@ -1,672 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Policies
|
||||
nav_order: 1
|
||||
parent: Index State Management
|
||||
has_children: false
|
||||
---
|
||||
|
||||
# Policies
|
||||
|
||||
Policies are JSON documents that define the following:
|
||||
|
||||
- The *states* that an index can be in, including the default state for new indices. For example, you might name your states "hot," "warm," "delete," and so on. For more information, see [States](#states).
|
||||
- Any *actions* that you want the plugin to take when an index enters a state, such as performing a rollover. For more information, see [Actions](#actions).
|
||||
- The conditions that must be met for an index to move into a new state, known as *transitions*. For example, if an index is more than eight weeks old, you might want to move it to the "delete" state. For more information, see [Transitions](#transitions).
|
||||
|
||||
In other words, a policy defines the *states* that an index can be in, the *actions* to perform when in a state, and the conditions that must be met to *transition* between states.
|
||||
|
||||
You have complete flexibility in the way you can design your policies. You can create any state, transition to any other state, and specify any number of actions in each state.
|
||||
|
||||
This table lists the relevant fields of a policy.
|
||||
|
||||
Field | Description | Type | Required | Read Only
|
||||
:--- | :--- |:--- |:--- |
|
||||
`policy_id` | The name of the policy. | `string` | Yes | Yes
|
||||
`description` | A human-readable description of the policy. | `string` | Yes | No
|
||||
`ism_template` | Specify an ISM template pattern that matches the index to apply the policy. | `nested list of objects` | No | No
|
||||
`last_updated_time` | The time the policy was last updated. | `timestamp` | Yes | Yes
|
||||
`error_notification` | The destination and message template for error notifications. The destination could be Amazon Chime, Slack, or a webhook URL. | `object` | No | No
|
||||
`default_state` | The default starting state for each index that uses this policy. | `string` | Yes | No
|
||||
`states` | The states that you define in the policy. | `nested list of objects` | Yes | No
|
||||
|
||||
---
|
||||
|
||||
#### Table of contents
|
||||
1. TOC
|
||||
{:toc}
|
||||
|
||||
|
||||
---
|
||||
|
||||
## States
|
||||
|
||||
A state is the description of the status that the managed index is currently in. A managed index can be in only one state at a time. Each state has associated actions that are executed sequentially on entering a state and transitions that are checked after all the actions have been completed.
|
||||
|
||||
This table lists the parameters that you can define for a state.
|
||||
|
||||
Field | Description | Type | Required
|
||||
:--- | :--- |:--- |:--- |
|
||||
`name` | The name of the state. | `string` | Yes
|
||||
`actions` | The actions to execute after entering a state. For more information, see [Actions](#actions). | `nested list of objects` | Yes
|
||||
`transitions` | The next states and the conditions required to transition to those states. If no transitions exist, the policy assumes that it's complete and can now stop managing the index. For more information, see [Transitions](#transitions). | `nested list of objects` | Yes
|
||||
|
||||
---
|
||||
|
||||
## Actions
|
||||
|
||||
Actions are the steps that the policy sequentially executes on entering a specific state.
|
||||
|
||||
They are executed in the order in which they are defined.
|
||||
|
||||
This table lists the parameters that you can define for an action.
|
||||
|
||||
Parameter | Description | Type | Required | Default
|
||||
:--- | :--- |:--- |:--- |
|
||||
`timeout` | The timeout period for the action. Accepts time units for minutes, hours, and days. | `time unit` | No | -
|
||||
`retry` | The retry configuration for the action. | `object` | No | Specific to action
|
||||
|
||||
The `retry` operation has the following parameters:
|
||||
|
||||
Parameter | Description | Type | Required | Default
|
||||
:--- | :--- |:--- |:--- |
|
||||
`count` | The number of retry counts. | `number` | Yes | -
|
||||
`backoff` | The backoff policy type to use when retrying. | `string` | No | Exponential
|
||||
`delay` | The time to wait between retries. Accepts time units for minutes, hours, and days. | `time unit` | No | 1 minute
|
||||
|
||||
The following example action has a timeout period of one hour. The policy retries this action three times with an exponential backoff policy, with a delay of 10 minutes between each retry:
|
||||
|
||||
```json
|
||||
"actions": {
|
||||
"timeout": "1h",
|
||||
"retry": {
|
||||
"count": 3,
|
||||
"backoff": "exponential",
|
||||
"delay": "10m"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For a list of available unit types, see [Supported units]({{site.url}}{{site.baseurl}}/opensearch/units/).
|
||||
|
||||
## ISM supported operations
|
||||
|
||||
ISM supports the following operations:
|
||||
|
||||
- [force_merge](#force_merge)
|
||||
- [read_only](#read_only)
|
||||
- [read_write](#read_write)
|
||||
- [replica_count](#replica_count)
|
||||
- [close](#close)
|
||||
- [open](#open)
|
||||
- [delete](#delete)
|
||||
- [rollover](#rollover)
|
||||
- [notification](#notification)
|
||||
- [snapshot](#snapshot)
|
||||
- [index_priority](#index_priority)
|
||||
- [allocation](#allocation)
|
||||
|
||||
### force_merge
|
||||
|
||||
Reduces the number of Lucene segments by merging the segments of individual shards. This operation attempts to set the index to a `read-only` state before starting the merging process.
|
||||
|
||||
Parameter | Description | Type | Required
|
||||
:--- | :--- |:--- |:--- |
|
||||
`max_num_segments` | The number of segments to reduce the shard to. | `number` | Yes
|
||||
|
||||
```json
|
||||
{
|
||||
"force_merge": {
|
||||
"max_num_segments": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### read_only
|
||||
|
||||
Sets a managed index to be read only.
|
||||
|
||||
```json
|
||||
{
|
||||
"read_only": {}
|
||||
}
|
||||
```
|
||||
|
||||
### read_write
|
||||
|
||||
Sets a managed index to be writeable.
|
||||
|
||||
```json
|
||||
{
|
||||
"read_write": {}
|
||||
}
|
||||
```
|
||||
|
||||
### replica_count
|
||||
|
||||
Sets the number of replicas to assign to an index.
|
||||
|
||||
Parameter | Description | Type | Required
|
||||
:--- | :--- |:--- |:--- |
|
||||
`number_of_replicas` | Defines the number of replicas to assign to an index. | `number` | Yes
|
||||
|
||||
```json
|
||||
{
|
||||
"replica_count": {
|
||||
"number_of_replicas": 2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For information about setting replicas, see [Primary and replica shards]({{site.url}}{{site.baseurl}}/opensearch#primary-and-replica-shards).
|
||||
|
||||
### close
|
||||
|
||||
Closes the managed index.
|
||||
|
||||
```json
|
||||
{
|
||||
"close": {}
|
||||
}
|
||||
```
|
||||
|
||||
Closed indices remain on disk, but consume no CPU or memory. You can't read from, write to, or search closed indices.
|
||||
|
||||
Closing an index is a good option if you need to retain data for longer than you need to actively search it and have sufficient disk space on your data nodes. If you need to search the data again, reopening a closed index is simpler than restoring an index from a snapshot.
|
||||
|
||||
### open
|
||||
|
||||
Opens a managed index.
|
||||
|
||||
```json
|
||||
{
|
||||
"open": {}
|
||||
}
|
||||
```
|
||||
|
||||
### delete
|
||||
|
||||
Deletes a managed index.
|
||||
|
||||
```json
|
||||
{
|
||||
"delete": {}
|
||||
}
|
||||
```
|
||||
|
||||
### rollover
|
||||
|
||||
Rolls an alias over to a new index when the managed index meets one of the rollover conditions.
|
||||
|
||||
The index format must match the pattern: `^.*-\d+$`. For example, `(logs-000001)`.
|
||||
Set `index.plugins.index_state_management.rollover_alias` as the alias to rollover.
|
||||
|
||||
Parameter | Description | Type | Example | Required
|
||||
:--- | :--- |:--- |:--- |
|
||||
`min_size` | The minimum size of the total primary shard storage (not counting replicas) required to roll over the index. For example, if you set `min_size` to 100 GiB and your index has 5 primary shards and 5 replica shards of 20 GiB each, the total size of the primaries is 100 GiB, so the rollover occurs. ISM doesn't check indices continually, so it doesn't roll over indices at exactly 100 GiB. Instead, if an index is continuously growing, ISM might check it at 99 GiB, not perform the rollover, check again when the shards reach 105 GiB, and then perform the operation. | `string` | `20gb` or `5mb` | No
|
||||
`min_doc_count` | The minimum number of documents required to roll over the index. | `number` | `2000000` | No
|
||||
`min_index_age` | The minimum age required to roll over the index. Index age is the time between its creation and the present. | `string` | `5d` or `7h` | No
|
||||
|
||||
```json
|
||||
{
|
||||
"rollover": {
|
||||
"min_size": "50gb"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"rollover": {
|
||||
"min_doc_count": 100000000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"rollover": {
|
||||
"min_index_age": "30d"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### notification
|
||||
|
||||
Sends you a notification.
|
||||
|
||||
Parameter | Description | Type | Required
|
||||
:--- | :--- |:--- |:--- |
|
||||
`destination` | The destination URL. | `Slack, Amazon Chime, or webhook URL` | Yes
|
||||
`message_template` | The text of the message. You can add variables to your messages using [Mustache templates](https://mustache.github.io/mustache.5.html). | `object` | Yes
|
||||
|
||||
The destination system **must** return a response otherwise the notification operation throws an error.
|
||||
|
||||
#### Example 1: Chime notification
|
||||
|
||||
```json
|
||||
{
|
||||
"notification": {
|
||||
"destination": {
|
||||
"chime": {
|
||||
"url": "<url>"
|
||||
}
|
||||
},
|
||||
"message_template": {
|
||||
"source": "the index is {% raw %}{{ctx.index}}{% endraw %}"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Example 2: Custom webhook notification
|
||||
|
||||
```json
|
||||
{
|
||||
"notification": {
|
||||
"destination": {
|
||||
"custom_webhook": {
|
||||
"url": "https://<your_webhook>"
|
||||
}
|
||||
},
|
||||
"message_template": {
|
||||
"source": "the index is {% raw %}{{ctx.index}}{% endraw %}"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Example 3: Slack notification
|
||||
|
||||
```json
|
||||
{
|
||||
"notification": {
|
||||
"destination": {
|
||||
"slack": {
|
||||
"url": "https://hooks.slack.com/services/xxx/xxxxxx"
|
||||
}
|
||||
},
|
||||
"message_template": {
|
||||
"source": "the index is {% raw %}{{ctx.index}}{% endraw %}"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can use `ctx` variables in your message to represent a number of policy parameters based on the past executions of your policy. For example, if your policy has a rollover action, you can use `{% raw %}{{ctx.action.name}}{% endraw %}` in your message to represent the name of the rollover.
|
||||
|
||||
The following `ctx` variable options are available for every policy:
|
||||
|
||||
#### Guaranteed variables
|
||||
|
||||
Parameter | Description | Type
|
||||
:--- | :--- |:--- |:--- |
|
||||
`index` | The name of the index. | `string`
|
||||
`index_uuid` | The uuid of the index. | `string`
|
||||
`policy_id` | The name of the policy. | `string`
|
||||
|
||||
### snapshot
|
||||
|
||||
Backup your cluster’s indices and state. For more information about snapshots, see [Take and restore snapshots]({{site.url}}{{site.baseurl}}/opensearch/snapshot-restore/).
|
||||
|
||||
The `snapshot` operation has the following parameters:
|
||||
|
||||
Parameter | Description | Type | Required | Default
|
||||
:--- | :--- |:--- |:--- |
|
||||
`repository` | The repository name that you register through the native snapshot API operations. | `string` | Yes | -
|
||||
`snapshot` | The name of the snapshot. | `string` | Yes | -
|
||||
|
||||
```json
|
||||
{
|
||||
"snapshot": {
|
||||
"repository": "my_backup",
|
||||
"snapshot": "my_snapshot"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### index_priority
|
||||
|
||||
Set the priority for the index in a specific state. Unallocated shards of indices are recovered in the order of their priority, whenever possible. The indices with higher priority values are recovered first followed by the indices with lower priority values.
|
||||
|
||||
The `index_priority` operation has the following parameter:
|
||||
|
||||
Parameter | Description | Type | Required | Default
|
||||
:--- | :--- |:--- |:--- |:---
|
||||
`priority` | The priority for the index as soon as it enters a state. | `number` | Yes | 1
|
||||
|
||||
```json
|
||||
"actions": [
|
||||
{
|
||||
"index_priority": {
|
||||
"priority": 50
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### allocation
|
||||
|
||||
Allocate the index to a node with a specific attribute set [like this]({{site.url}}{{site.baseurl}}/opensearch/cluster/#advanced-step-7-set-up-a-hot-warm-architecture).
|
||||
For example, setting `require` to `warm` moves your data only to "warm" nodes.
|
||||
|
||||
The `allocation` operation has the following parameters:
|
||||
|
||||
Parameter | Description | Type | Required
|
||||
:--- | :--- |:--- |:---
|
||||
`require` | Allocate the index to a node with a specified attribute. | `string` | Yes
|
||||
`include` | Allocate the index to a node with any of the specified attributes. | `string` | Yes
|
||||
`exclude` | Don’t allocate the index to a node with any of the specified attributes. | `string` | Yes
|
||||
`wait_for` | Wait for the policy to execute before allocating the index to a node with a specified attribute. | `string` | Yes
|
||||
|
||||
```json
|
||||
"actions": [
|
||||
{
|
||||
"allocation": {
|
||||
"require": { "temp": "warm" }
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Transitions
|
||||
|
||||
Transitions define the conditions that need to be met for a state to change. After all actions in the current state are completed, the policy starts checking the conditions for transitions.
|
||||
|
||||
Transitions are evaluated in the order in which they are defined. For example, if the conditions for the first transition are met, then this transition takes place and the rest of the transitions are dismissed.
|
||||
|
||||
If you don't specify any conditions in a transition and leave it empty, then it's assumed to be the equivalent of always true. This means that the policy transitions the index to this state the moment it checks.
|
||||
|
||||
This table lists the parameters you can define for transitions.
|
||||
|
||||
Parameter | Description | Type | Required
|
||||
:--- | :--- |:--- |:--- |
|
||||
`state_name` | The name of the state to transition to if the conditions are met. | `string` | Yes
|
||||
`conditions` | List the conditions for the transition. | `list` | Yes
|
||||
|
||||
The `conditions` object has the following parameters:
|
||||
|
||||
Parameter | Description | Type | Required
|
||||
:--- | :--- |:--- |:--- |
|
||||
`min_index_age` | The minimum age of the index required to transition. | `string` | No
|
||||
`min_doc_count` | The minimum document count of the index required to transition. | `number` | No
|
||||
`min_size` | The minimum size of the index required to transition. | `string` | No
|
||||
`cron` | The `cron` job that triggers the transition if no other transition happens first. | `object` | No
|
||||
`cron.cron.expression` | The `cron` expression that triggers the transition. | `string` | Yes
|
||||
`cron.cron.timezone` | The timezone that triggers the transition. | `string` | Yes
|
||||
|
||||
The following example transitions the index to a `cold` state after a period of 30 days:
|
||||
|
||||
```json
|
||||
"transitions": [
|
||||
{
|
||||
"state_name": "cold",
|
||||
"conditions": {
|
||||
"min_index_age": "30d"
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
ISM checks the conditions on every execution of the policy based on the set interval.
|
||||
|
||||
This example uses the `cron` condition to transition indices every Saturday at 5:00 PT:
|
||||
|
||||
```json
|
||||
"transitions": [
|
||||
{
|
||||
"state_name": "cold",
|
||||
"conditions": {
|
||||
"cron": {
|
||||
"cron": {
|
||||
"expression": "* 17 * * SAT",
|
||||
"timezone": "America/Los_Angeles"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Note that this condition does not execute at exactly 5:00 PM; the job still executes based off the `job_interval` setting. Due to this variance in start time and the amount of time that it can take for actions to complete prior to checking transition conditions, we recommend against overly narrow cron expressions. For example, don't use `15 17 * * SAT` (5:15 PM on Saturday).
|
||||
|
||||
A window of an hour, which this example uses, is generally sufficient, but you might increase it to 2--3 hours to avoid missing the window and having to wait a week for the transition to occur. Alternately, you could use a broader expression such as `* * * * SAT,SUN` to have the transition occur at any time during the weekend.
|
||||
|
||||
For information on writing cron expressions, see [Cron expression reference]({{site.url}}{{site.baseurl}}/monitoring-plugins/alerting/cron/).
|
||||
|
||||
---
|
||||
|
||||
## Error notifications
|
||||
|
||||
The `error_notification` operation sends you a notification if your managed index fails.
|
||||
It notifies a single destination with a custom message.
|
||||
|
||||
Set up error notifications at the policy level:
|
||||
|
||||
```json
|
||||
{
|
||||
"policy": {
|
||||
"description": "hot warm delete workflow",
|
||||
"default_state": "hot",
|
||||
"schema_version": 1,
|
||||
"error_notification": { },
|
||||
"states": [ ]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Parameter | Description | Type | Required
|
||||
:--- | :--- |:--- |:--- |
|
||||
`destination` | The destination URL. | `Slack, Amazon Chime, or webhook URL` | Yes
|
||||
`message_template` | The text of the message. You can add variables to your messages using [Mustache templates](https://mustache.github.io/mustache.5.html). | `object` | Yes
|
||||
|
||||
The destination system **must** return a response otherwise the `error_notification` operation throws an error.
|
||||
|
||||
#### Example 1: Chime notification
|
||||
|
||||
```json
|
||||
{
|
||||
"error_notification": {
|
||||
"destination": {
|
||||
"chime": {
|
||||
"url": "<url>"
|
||||
}
|
||||
},
|
||||
"message_template": {
|
||||
"source": "The index {% raw %}{{ctx.index}}{% endraw %} failed during policy execution."
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Example 2: Custom webhook notification
|
||||
|
||||
```json
|
||||
{
|
||||
"error_notification": {
|
||||
"destination": {
|
||||
"custom_webhook": {
|
||||
"url": "https://<your_webhook>"
|
||||
}
|
||||
},
|
||||
"message_template": {
|
||||
"source": "The index {% raw %}{{ctx.index}}{% endraw %} failed during policy execution."
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Example 3: Slack notification
|
||||
|
||||
```json
|
||||
{
|
||||
"error_notification": {
|
||||
"destination": {
|
||||
"slack": {
|
||||
"url": "https://hooks.slack.com/services/xxx/xxxxxx"
|
||||
}
|
||||
},
|
||||
"message_template": {
|
||||
"source": "The index {% raw %}{{ctx.index}}{% endraw %} failed during policy execution."
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can use the same options for `ctx` variables as the [notification](#notification) operation.
|
||||
|
||||
## Sample policy with ISM template
|
||||
|
||||
The following sample template policy is for a rollover use case.
|
||||
|
||||
1. Create a policy with an `ism_template` field:
|
||||
|
||||
```json
|
||||
PUT _plugins/_ism/policies/rollover_policy
|
||||
{
|
||||
"policy": {
|
||||
"description": "Example rollover policy.",
|
||||
"default_state": "rollover",
|
||||
"states": [
|
||||
{
|
||||
"name": "rollover",
|
||||
"actions": [
|
||||
{
|
||||
"rollover": {
|
||||
"min_doc_count": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"transitions": []
|
||||
}
|
||||
],
|
||||
"ism_template": {
|
||||
"index_patterns": ["log*"],
|
||||
"priority": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You need to specify the `index_patterns` field. If you don't specify a value for `priority`, it defaults to 0.
|
||||
|
||||
2. Set up a template with the `rollover_alias` as `log` :
|
||||
|
||||
```json
|
||||
PUT _index_template/ism_rollover
|
||||
{
|
||||
"index_patterns": ["log*"],
|
||||
"template": {
|
||||
"settings": {
|
||||
"plugins.index_state_management.rollover_alias": "log"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. Create an index with the `log` alias:
|
||||
|
||||
```json
|
||||
PUT log-000001
|
||||
{
|
||||
"aliases": {
|
||||
"log": {
|
||||
"is_write_index": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
4. Index a document to trigger the rollover condition:
|
||||
|
||||
```json
|
||||
POST log/_doc
|
||||
{
|
||||
"message": "dummy"
|
||||
}
|
||||
```
|
||||
|
||||
5. Verify if the policy is attached to the `log-000001` index:
|
||||
|
||||
```json
|
||||
GET _plugins/_ism/explain/log-000001?pretty
|
||||
```
|
||||
|
||||
## Example policy
|
||||
|
||||
The following example policy implements a `hot`, `warm`, and `delete` workflow. You can use this policy as a template to prioritize resources to your indices based on their levels of activity.
|
||||
|
||||
In this case, an index is initially in a `hot` state. After a day, it changes to a `warm` state, where the number of replicas increases to 5 to improve the read performance.
|
||||
|
||||
After 30 days, the policy moves this index into a `delete` state. The service sends a notification to a Chime room that the index is being deleted, and then permanently deletes it.
|
||||
|
||||
```json
|
||||
{
|
||||
"policy": {
|
||||
"description": "hot warm delete workflow",
|
||||
"default_state": "hot",
|
||||
"schema_version": 1,
|
||||
"states": [
|
||||
{
|
||||
"name": "hot",
|
||||
"actions": [
|
||||
{
|
||||
"rollover": {
|
||||
"min_index_age": "1d"
|
||||
}
|
||||
}
|
||||
],
|
||||
"transitions": [
|
||||
{
|
||||
"state_name": "warm"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "warm",
|
||||
"actions": [
|
||||
{
|
||||
"replica_count": {
|
||||
"number_of_replicas": 5
|
||||
}
|
||||
}
|
||||
],
|
||||
"transitions": [
|
||||
{
|
||||
"state_name": "delete",
|
||||
"conditions": {
|
||||
"min_index_age": "30d"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "delete",
|
||||
"actions": [
|
||||
{
|
||||
"notification": {
|
||||
"destination": {
|
||||
"chime": {
|
||||
"url": "<URL>"
|
||||
}
|
||||
},
|
||||
"message_template": {
|
||||
"source": "The index {% raw %}{{ctx.index}}{% endraw %} is being deleted"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"delete": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This diagram shows the `states`, `transitions`, and `actions` of the above policy as a finite-state machine. For more information about finite-state machines, see [Wikipedia](https://en.wikipedia.org/wiki/Finite-state_machine).
|
||||
|
||||

|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Settings
|
||||
parent: Index State Management
|
||||
nav_order: 4
|
||||
---
|
||||
|
||||
# ISM settings
|
||||
|
||||
We don't recommend changing these settings; the defaults should work well for most use cases.
|
||||
|
||||
Index State Management (ISM) stores its configuration in the `.opendistro-ism-config` index. Don't modify this index without using the [ISM API operations]({{site.url}}{{site.baseurl}}/im-plugin/ism/api/).
|
||||
|
||||
All settings are available using the OpenSearch `_cluster/settings` operation. None require a restart, and all can be marked `persistent` or `transient`.
|
||||
|
||||
Setting | Default | Description
|
||||
:--- | :--- | :---
|
||||
`plugins.index_state_management.enabled` | True | Specifies whether ISM is enabled or not.
|
||||
`plugins.index_state_management.job_interval` | 5 minutes | The interval at which the managed index jobs are run.
|
||||
`plugins.index_state_management.coordinator.sweep_period` | 10 minutes | How often the routine background sweep is run.
|
||||
`plugins.index_state_management.coordinator.backoff_millis` | 50 milliseconds | The backoff time between retries for failures in the `ManagedIndexCoordinator` (such as when we update managed indices).
|
||||
`plugins.index_state_management.coordinator.backoff_count` | 2 | The count of retries for failures in the `ManagedIndexCoordinator`.
|
||||
`plugins.index_state_management.history.enabled` | True | Specifies whether audit history is enabled or not. The logs from ISM are automatically indexed to a logs document.
|
||||
`plugins.index_state_management.history.max_docs` | 2,500,000 | The maximum number of documents before rolling over the audit history index.
|
||||
`plugins.index_state_management.history.max_age` | 24 hours | The maximum age before rolling over the audit history index.
|
||||
`plugins.index_state_management.history.rollover_check_period` | 8 hours | The time between rollover checks for the audit history index.
|
||||
`plugins.index_state_management.history.rollover_retention_period` | 30 days | How long audit history indices are kept.
|
||||
`plugins.index_state_management.allow_list` | All actions | List of actions that you can use.
|
||||
|
||||
|
||||
## Audit history indices
|
||||
|
||||
If you don't want to disable ISM audit history or shorten the retention period, you can create an [index template]({{site.url}}{{site.baseurl}}/opensearch/index-templates/) to reduce the shard count of the history indices:
|
||||
|
||||
```json
|
||||
PUT _index_template/ism_history_indices
|
||||
{
|
||||
"index_patterns": [
|
||||
".opendistro-ism-managed-index-history-*"
|
||||
],
|
||||
"template": {
|
||||
"settings": {
|
||||
"number_of_shards": 1,
|
||||
"number_of_replicas": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Refresh search analyzer
|
||||
nav_order: 50
|
||||
has_children: false
|
||||
redirect_from: /im-plugin/refresh-analyzer/
|
||||
has_toc: false
|
||||
---
|
||||
|
||||
# Refresh search analyzer
|
||||
|
||||
With ISM installed, you can refresh search analyzers in real time with the following API:
|
||||
|
||||
```json
|
||||
POST /_plugins/_refresh_search_analyzers/<index or alias or wildcard>
|
||||
```
|
||||
For example, if you change the synonym list in your analyzer, the change takes effect without you needing to close and reopen the index.
|
||||
|
||||
To work, the token filter must have an `updateable` flag of `true`:
|
||||
|
||||
```json
|
||||
{
|
||||
"analyzer": {
|
||||
"my_synonyms": {
|
||||
"tokenizer": "whitespace",
|
||||
"filter": [
|
||||
"synonym"
|
||||
]
|
||||
}
|
||||
},
|
||||
"filter": {
|
||||
"synonym": {
|
||||
"type": "synonym_graph",
|
||||
"synonyms_path": "synonyms.txt",
|
||||
"updateable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -1,41 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Index management security
|
||||
nav_order: 40
|
||||
has_children: false
|
||||
---
|
||||
|
||||
# Index management security
|
||||
|
||||
Using the security plugin with index management lets you limit non-admin users to certain actions. For example, you might want to set up your security such that a group of users can only read ISM policies, while others can create, delete, or change policies.
|
||||
|
||||
All index management data are protected as system indices, and only a super admin or an admin with a Transport Layer Security (TLS) certificate can access system indices. For more information, see [System indices]({{site.url}}{{site.baseurl}}/security-plugin/configuration/system-indices).
|
||||
|
||||
## Basic permissions
|
||||
|
||||
The security plugin comes with one role that offers full access to index management: `index_management_full_access`. For a description of the role's permissions, see [Predefined roles]({{site.url}}{{site.baseurl}}/security-plugin/access-control/users-roles#predefined-roles).
|
||||
|
||||
With security enabled, users not only need the correct index management permissions, but they also need permissions to execute actions to involved indices. For example, if a user wants to use the REST API to attach a policy that executes a rollup job to an index named `system-logs`, they would need the permissions to attach a policy and execute a rollup job, as well as access to `system-logs`.
|
||||
|
||||
Finally, with the exceptions of Create Policy, Get Policy, and Delete Policy, users also need the `indices:admin/opensearch/ism/managedindex` permission to execute [ISM APIs]({{site.url}}{{site.baseurl}}/im-plugin/ism/api).
|
||||
|
||||
## (Advanced) Limit access by backend role
|
||||
|
||||
You can use backend roles to configure fine-grained access to index management policies and actions. For example, users of different departments in an organization might view different policies depending on what roles and permissions they are assigned.
|
||||
|
||||
First, ensure your users have the appropriate [backend roles]({{site.url}}{{site.baseurl}}/security-plugin/access-control/index/). Backend roles usually come from an [LDAP server]({{site.url}}{{site.baseurl}}/security-plugin/configuration/ldap/) or [SAML provider]({{site.url}}{{site.baseurl}}/security-plugin/configuration/saml/). However, if you use the internal user database, you can use the REST API to [add them manually]({{site.url}}{{site.baseurl}}/security-plugin/access-control/api#create-user).
|
||||
|
||||
Use the REST API to enable the following setting:
|
||||
|
||||
```json
|
||||
PUT _cluster/settings
|
||||
{
|
||||
"transient": {
|
||||
"plugins.index_management.filter_by_backend_roles": "true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
With security enabled, only users who share at least one backend role can see and execute the policies and actions relevant to their roles.
|
||||
|
||||
For example, consider a scenario with three users: `John` and `Jill`, who have the backend role `helpdesk_staff`, and `Jane`, who has the backend role `phone_operator`. `John` wants to create a policy that performs a rollup job on an index named `airline_data`, so `John` would need a backend role that has permissions to access that index, create relevant policies, and execute relevant actions, and `Jill` would be able to access the same index, policy, and job. However, `Jane` cannot access or edit those resources or actions.
|
||||
@@ -1,45 +0,0 @@
|
||||
|
||||
<div role="contentinfo">
|
||||
<div class="subfooter">
|
||||
<div class="container">
|
||||
<h1 class="visuallyhidden">OpenSearch Links</h1>
|
||||
|
||||
{% for column in site.data.footer.columns %}
|
||||
<div class="col {% if forloop.index > 2 %}last-child{% endif %}">
|
||||
|
||||
<h2>{{ column.title }}</h2>
|
||||
<ul>
|
||||
{% for link in column.links %}
|
||||
<li><a href="{{ link.url }}">{{ link.title}}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<div class="container">
|
||||
|
||||
<a href="{{ '/' | relative_url }}"><svg viewBox="0 0 64 64" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M61.7374 23.5C60.4878 23.5 59.4748 24.513 59.4748 25.7626C59.4748 44.3813 44.3813 59.4748 25.7626 59.4748C24.513 59.4748 23.5 60.4878 23.5 61.7374C23.5 62.987 24.513 64 25.7626 64C46.8805 64 64 46.8805 64 25.7626C64 24.513 62.987 23.5 61.7374 23.5Z" fill="currentColor" />
|
||||
<path d="M48.0814 38C50.2572 34.4505 52.3615 29.7178 51.9475 23.0921C51.0899 9.36725 38.6589 -1.04463 26.9206 0.0837327C22.3253 0.525465 17.6068 4.2712 18.026 10.9805C18.2082 13.8961 19.6352 15.6169 21.9544 16.9399C24.1618 18.1992 26.9978 18.9969 30.2128 19.9011C34.0962 20.9934 38.6009 22.2203 42.063 24.7717C46.2125 27.8295 49.0491 31.3743 48.0814 38Z" fill="currentColor" />
|
||||
<path d="M3.91861 14C1.74276 17.5495 -0.361506 22.2822 0.0524931 28.9079C0.910072 42.6327 13.3411 53.0446 25.0794 51.9163C29.6747 51.4745 34.3932 47.7288 33.974 41.0195C33.7918 38.1039 32.3647 36.3831 30.0456 35.0601C27.8382 33.8008 25.0022 33.0031 21.7872 32.0989C17.9038 31.0066 13.3991 29.7797 9.93694 27.2283C5.78746 24.1704 2.95092 20.6257 3.91861 14Z" fill="currentColor" />
|
||||
</svg></a>
|
||||
|
||||
<p class="copyright">© {{ 'now' | date: "%Y" }}
|
||||
<a href="https://aws.amazon.com/"> Amazon Web Services</a> and individual contributors. OpenSearch is a
|
||||
<a href="/trademark-usage.html">registered trademark</a> of Amazon Web Services.</a> <br /><br />
|
||||
|
||||
© 2005-2021
|
||||
<a href="https://www.djangoproject.com/foundation/"> Django Software
|
||||
Foundation</a> and individual contributors. Django is a
|
||||
<a href="https://www.djangoproject.com/trademarks/">registered
|
||||
trademark</a> of the Django Software Foundation.<br />
|
||||
This website was forked from the BSD-licensed <a href="https://github.com/django/djangoproject.com/">djangoproject.com</a> originally designed by <a href="https://www.threespot.com">Threespot</a> <span class="ampersand">&</span> <a href="http://andrevv.com/">andrevv</a>.<br /> We ♡ Django and the Django community. If you need a <a href="https://www.djangoproject.com/">high-level Python framework</a>, check it out.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,14 +0,0 @@
|
||||
{% if site.anchor_links != nil %}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/4.2.0/anchor.min.js"></script>
|
||||
{% endif %}
|
||||
|
||||
{% if page.has_math == true %}
|
||||
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
|
||||
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3.0.1/es5/tex-mml-chtml.js"></script>
|
||||
{% endif %}
|
||||
|
||||
{% if jekyll.environment == "development" %}
|
||||
<script src="{{ '/assets/js/version-selector.js' | relative_url }}"></script>
|
||||
{% else %}
|
||||
<script src="{{ '/docs/latest/assets/js/version-selector.js' }}"></script>
|
||||
{% endif %}
|
||||
@@ -1,41 +0,0 @@
|
||||
{% assign url_full = site.baseurl | append: page.url %}
|
||||
{% assign url_parts = url_full | split: "/" %}
|
||||
{%if page.alert %}
|
||||
<div role="banner" class="banner-alert">
|
||||
<div class="container">
|
||||
{{page.alert | markdownify}}
|
||||
</div>
|
||||
</div>
|
||||
{%endif%}
|
||||
{%if site.data.alert.message %}
|
||||
<div role="banner" class="banner-alert">
|
||||
<div class="container">
|
||||
{{site.data.alert.message | markdownify}}
|
||||
</div>
|
||||
</div>
|
||||
{%endif%}
|
||||
<div role="banner" id="top">
|
||||
<div class="container">
|
||||
<a class="logo" href="/">
|
||||
OpenSearch
|
||||
<svg viewBox="0 0 372 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M61.7374 26.5C60.4878 26.5 59.4748 27.513 59.4748 28.7626C59.4748 47.3814 44.3814 62.4748 25.7626 62.4748C24.513 62.4748 23.5 63.4878 23.5 64.7374C23.5 65.987 24.513 67 25.7626 67C46.8805 67 64 49.8805 64 28.7626C64 27.513 62.987 26.5 61.7374 26.5Z" fill="#00A3E0"/>
|
||||
<path d="M48.0814 41C50.2572 37.4505 52.3615 32.7178 51.9475 26.0921C51.0899 12.3673 38.6589 1.95537 26.9206 3.08373C22.3253 3.52547 17.6068 7.2712 18.026 13.9805C18.2082 16.8961 19.6352 18.6169 21.9544 19.9399C24.1618 21.1992 26.9978 21.9969 30.2128 22.9011C34.0962 23.9934 38.6009 25.2203 42.0631 27.7717C46.2125 30.8296 49.0491 34.3743 48.0814 41Z" fill="#B9D9EB"/>
|
||||
<path d="M3.91861 17C1.74276 20.5495 -0.361506 25.2822 0.0524931 31.9079C0.910072 45.6327 13.3411 56.0446 25.0794 54.9163C29.6747 54.4745 34.3932 50.7288 33.974 44.0195C33.7918 41.1039 32.3647 39.3831 30.0456 38.0601C27.8382 36.8008 25.0022 36.0031 21.7872 35.0989C17.9038 34.0066 13.3991 32.7797 9.93695 30.2283C5.78747 27.1704 2.95092 23.6257 3.91861 17Z" fill="#00A3E0"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M362.5 31V54H371.5V29C371.5 24.3927 370.6 20.9121 368.799 18.5511C366.998 16.1672 364.282 15 360.75 15C356.918 15 353.847 17.2408 352 21H351.5C351.636 19.0591 351.76 17.9472 351.85 17.1353C351.943 16.298 352 15.7797 352 15V0.5H343V54H352.5V35.5C352.5 31.3511 352.639 28.2815 353.493 26.081C354.347 23.8575 355.836 22.7458 357.96 22.7458C360.799 22.7458 362.5 25.3841 362.5 31ZM231.852 51.2289C234.284 48.7148 235.5 45.0936 235.5 40.3653C235.5 37.4129 234.834 34.7835 233.501 32.477C232.191 30.1705 229.865 27.9102 226.521 25.6959C224.042 24.0814 222.3 22.6398 221.294 21.3713C220.312 20.1027 219.821 18.615 219.821 16.9082C219.821 15.1783 220.23 13.8175 221.049 12.8257C221.891 11.8108 223.083 11.3034 224.627 11.3034C226.03 11.3034 227.339 11.5571 228.555 12.0645C229.794 12.572 230.975 13.1486 232.098 13.7944L235.254 6.25216C231.63 4.08405 227.854 3 223.925 3C219.809 3 216.524 4.26857 214.069 6.80572C211.637 9.34287 210.421 12.7796 210.421 17.1158C210.421 19.3761 210.725 21.3597 211.333 23.0665C211.964 24.7733 212.841 26.3187 213.964 27.7026C215.109 29.0634 216.781 30.4935 218.979 31.9927C221.505 33.6995 223.317 35.2564 224.416 36.6633C225.515 38.0472 226.065 39.5811 226.065 41.2648C226.065 42.9716 225.597 44.3209 224.662 45.3127C223.75 46.3045 222.382 46.8004 220.558 46.8004C217.354 46.8004 213.835 45.5664 210 43.0985V52.4052C213.133 54.1351 216.933 55 221.4 55C225.959 55 229.444 53.743 231.852 51.2289ZM241.674 49.8745C244.48 53.2915 248.306 55 253.152 55C257.303 55 260.862 54.1111 263.83 52.3333V44.7489C260.677 46.619 257.593 47.5541 254.578 47.5541C252.213 47.5541 250.358 46.7229 249.013 45.0606C247.668 43.3752 247.07 40.9401 247 37.5H265.5V32.4545C265.5 26.9365 264.283 22.6537 261.848 19.6061C259.413 16.5354 256.086 15 251.865 15C247.343 15 243.819 16.7893 241.291 20.368C238.764 23.9466 237.5 28.9221 237.5 35.2944C237.5 41.5743 238.891 46.4343 241.674 49.8745ZM248.526 24.2121C249.384 22.8038 250.474 22.0996 251.796 22.0996C253.21 22.0996 254.323 22.8268 255.135 24.2814C255.946 25.7359 256.454 28.1833 256.5 31H247C247.139 28.0678 247.668 25.5974 248.526 24.2121ZM288 54L286.5 49H286C284.622 51.2587 283.295 52.868 281.824 53.7208C280.352 54.5736 278.494 55 276.252 55C273.378 55 271.112 53.9398 269.453 51.8194C267.818 49.6989 267 46.7488 267 42.9689C267 38.9124 268.121 35.9046 270.364 33.9455C272.63 31.9634 276.006 30.8686 280.492 30.6612L285.678 30.4538V27.688C285.678 24.0925 284.101 22.2947 280.947 22.2947C278.611 22.2947 275.924 23.1936 272.887 24.9914L269.663 18.6301C273.541 16.21 277.694 15 282.25 15C286.385 15 289.592 16.1755 291.741 18.5264C293.914 20.8542 295 24.1616 295 28.4486V54H288ZM280.071 47.809C281.777 47.809 283.132 47.0599 284.136 45.5618C285.164 44.0406 285.678 42.0239 285.678 39.5117V36.2619L282.805 36.4002C280.679 36.5154 279.113 37.1147 278.109 38.1979C277.128 39.2812 276.637 40.8946 276.637 43.038C276.637 46.2187 277.782 47.809 280.071 47.809ZM318 15.75C316.93 15.405 315.337 15 314.222 15C312.651 15 311.273 15.5174 310.089 16.5523C308.905 17.5872 308.002 18.5853 307 21H306.5L305 16H298V54H307.463V34C307.463 30.6424 307.676 28.4763 308.86 26.7285C310.044 24.9577 311.74 24.0723 313.948 24.0723C314.973 24.0723 315.863 24.27 316.5 24.5L318 15.75ZM332 55C327.443 55 323.954 53.478 321.573 50.1302C319.191 46.7824 318 41.8647 318 35.377C318 28.5891 319.122 23.5213 321.366 20.1735C323.634 16.8257 327.017 15 331.735 15C333.154 15 334.752 15.3596 336.309 15.7752C337.866 16.1908 339.763 16.715 341 17.5L337.889 24.7449C335.989 23.6136 334.305 23.048 332.84 23.048C330.893 23.048 329.485 24.0754 328.614 26.1302C327.767 28.162 327.344 31.2211 327.344 35.3077C327.344 39.3019 327.767 42.2918 328.614 44.2774C329.462 46.2399 330.847 47.2211 332.771 47.2211C335.061 47.2211 337.454 46.413 339.95 44.7969V52.9008C337.546 54.4015 334.908 55 332 55Z" fill="#B9D9EB"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M107.777 48.2625C110.926 43.7708 112.5 37.3442 112.5 28.9827C112.5 20.6213 110.937 14.2062 107.812 9.73754C104.686 5.24585 100.194 3 94.3368 3C88.4098 3 83.8719 5.23433 80.7231 9.70299C77.5744 14.1486 76 20.5522 76 28.9136C76 37.3442 77.5744 43.8053 80.7231 48.297C83.8719 52.7657 88.3866 55 94.2674 55C100.125 55 104.628 52.7542 107.777 48.2625ZM87.8425 42.1468C86.3839 39.1293 85.6546 34.7413 85.6546 28.9827C85.6546 23.2011 86.3839 18.8131 87.8425 15.8186C89.3011 12.8011 91.4659 11.2924 94.3368 11.2924C99.986 11.2924 102.811 17.1891 102.811 28.9827C102.811 40.7763 99.9629 46.6731 94.2674 46.6731C91.4428 46.6731 89.3011 45.1643 87.8425 42.1468ZM128.186 53.9979C129.469 54.7387 130.85 55 132.5 55C136.03 55 138.9 53.3265 140.94 49.7612C142.98 46.196 144 41.2764 144 35.0025C144 28.6359 143.014 23.7164 141.043 20.2437C139.072 16.7479 136.345 15 132.861 15C129.24 15 126.402 17.1569 124.5 21H124L122.5 16H115.5V71.5H124.5V55C124.5 54.3518 124.367 52.1485 124 49H124.5C125.25 51.25 126.925 53.2339 128.186 53.9979ZM125.882 25.3832C126.685 23.6932 127.979 22.8482 129.767 22.8482C131.44 22.8482 132.666 23.8437 133.446 25.8347C134.248 27.8257 134.649 30.8353 134.649 34.8636C134.649 43.059 133.045 47.1567 129.836 47.1567C127.979 47.1567 126.65 46.1844 125.848 44.2397C125.046 42.295 124.645 39.1928 124.645 34.933V33.7176C124.691 29.8282 125.103 27.0501 125.882 25.3832ZM161.652 55C156.806 55 152.98 53.2915 150.174 49.8745C147.391 46.4343 146 41.5743 146 35.2944C146 28.9221 147.264 23.9466 149.791 20.368C152.319 16.7893 155.843 15 160.365 15C164.585 15 167.913 16.5354 170.348 19.6061C172.783 22.6537 174 26.9365 174 32.4545V37.5H155.5C155.57 40.9401 156.168 43.3752 157.513 45.0606C158.858 46.7229 160.713 47.5541 163.078 47.5541C166.093 47.5541 169.177 46.619 172.33 44.7489V52.3333C169.362 54.1111 165.803 55 161.652 55ZM160.296 22.0996C158.974 22.0996 157.884 22.8038 157.026 24.2121C156.168 25.5974 155.639 28.0678 155.5 31H165C164.954 28.1833 164.446 25.7359 163.635 24.2814C162.823 22.8268 161.71 22.0996 160.296 22.0996ZM196.5 31V54H205.5V29.1991C205.5 24.5589 204.623 21.0323 202.868 18.6194C201.137 16.2065 198.516 15 195.007 15C192.93 15 191.117 15.5104 189.57 16.5313C188.024 17.5289 186.831 19.2135 186 21H185.5L184.25 16H177V54H186.5V35.75C186.5 31.0402 186.673 27.8302 187.597 25.8582C188.52 23.8628 189.974 22.8652 191.96 22.8652C193.46 22.8652 194.546 23.5844 195.215 25.0229C195.885 26.4614 196.5 28.1927 196.5 31Z" fill="#00A3E0"/>
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<div class="menu-button"><i class="icon icon-reorder"></i><span>Menu</span></div>
|
||||
<div class="nav-menu-on" role="navigation">
|
||||
<ul class="small-nav">
|
||||
{%- include nav_item.html text="News" href="/blog" url_full="/blog/" url_fragment="blog" -%}
|
||||
{%- include nav_item.html text="Source" href="/source.html" url_full="/source.html" url_fragment="source" -%}
|
||||
{%- include nav_item.html text="Documentation" href="/docs" url_full="/docs/" url_fragment="docs" -%}
|
||||
{%- include nav_item.html text="Events" href="/events" url_full="/events/" url_fragment="events" -%}
|
||||
{%- include nav_item.html text="Get Started" href="/downloads.html" url_full="/downloads.html" url_fragment="downloads" -%}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,125 +0,0 @@
|
||||
<ul class="nav-list">
|
||||
{%- assign titled_pages = include.pages
|
||||
| where_exp:"item", "item.title != nil" -%}
|
||||
|
||||
{%- comment -%}
|
||||
The values of `title` and `nav_order` can be numbers or strings.
|
||||
Jekyll gives build failures when sorting on mixtures of different types,
|
||||
so numbers and strings need to be sorted separately.
|
||||
|
||||
Here, numbers are sorted by their values, and come before all strings.
|
||||
An omitted `nav_order` value is equivalent to the page's `title` value
|
||||
(except that a numerical `title` value is treated as a string).
|
||||
|
||||
The case-sensitivity of string sorting is determined by `site.nav_sort`.
|
||||
{%- endcomment -%}
|
||||
|
||||
{%- assign string_ordered_pages = titled_pages
|
||||
| where_exp:"item", "item.nav_order == nil" -%}
|
||||
{%- assign nav_ordered_pages = titled_pages
|
||||
| where_exp:"item", "item.nav_order != nil" -%}
|
||||
|
||||
{%- comment -%}
|
||||
The nav_ordered_pages have to be added to number_ordered_pages and
|
||||
string_ordered_pages, depending on the nav_order value.
|
||||
The first character of the jsonify result is `"` only for strings.
|
||||
{%- endcomment -%}
|
||||
{%- assign nav_ordered_groups = nav_ordered_pages
|
||||
| group_by_exp:"item", "item.nav_order | jsonify | slice: 0" -%}
|
||||
{%- assign number_ordered_pages = "" | split:"X" -%}
|
||||
{%- for group in nav_ordered_groups -%}
|
||||
{%- if group.name == '"' -%}
|
||||
{%- assign string_ordered_pages = string_ordered_pages | concat: group.items -%}
|
||||
{%- else -%}
|
||||
{%- assign number_ordered_pages = number_ordered_pages | concat: group.items -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
|
||||
{%- assign sorted_number_ordered_pages = number_ordered_pages | sort:"nav_order" -%}
|
||||
|
||||
{%- comment -%}
|
||||
The string_ordered_pages have to be sorted by nav_order, and otherwise title
|
||||
(where appending the empty string to a numeric title converts it to a string).
|
||||
After grouping them by those values, the groups are sorted, then the items
|
||||
of each group are concatenated.
|
||||
{%- endcomment -%}
|
||||
{%- assign string_ordered_groups = string_ordered_pages
|
||||
| group_by_exp:"item", "item.nav_order | default: item.title | append:''" -%}
|
||||
{%- if site.nav_sort == 'case_insensitive' -%}
|
||||
{%- assign sorted_string_ordered_groups = string_ordered_groups | sort_natural:"name" -%}
|
||||
{%- else -%}
|
||||
{%- assign sorted_string_ordered_groups = string_ordered_groups | sort:"name" -%}
|
||||
{%- endif -%}
|
||||
{%- assign sorted_string_ordered_pages = "" | split:"X" -%}
|
||||
{%- for group in sorted_string_ordered_groups -%}
|
||||
{%- assign sorted_string_ordered_pages = sorted_string_ordered_pages | concat: group.items -%}
|
||||
{%- endfor -%}
|
||||
|
||||
{%- assign pages_list = sorted_number_ordered_pages | concat: sorted_string_ordered_pages -%}
|
||||
|
||||
{%- for node in pages_list -%}
|
||||
{%- if node.parent == nil -%}
|
||||
{%- unless node.nav_exclude -%}
|
||||
<li class="nav-list-item{% if page.collection == include.key and page.url == node.url or page.parent == node.title or page.grand_parent == node.title %} active{% endif %}">
|
||||
{%- if node.has_children -%}
|
||||
<a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a>
|
||||
{%- endif -%}
|
||||
<a href="{{ node.url | absolute_url }}" class="nav-list-link{% if page.url == node.url %} active{% endif %}">{{ node.title }}</a>
|
||||
{%- if node.has_children -%}
|
||||
{%- assign children_list = pages_list | where: "parent", node.title -%}
|
||||
<ul class="nav-list ">
|
||||
{%- for child in children_list -%}
|
||||
{%- unless child.nav_exclude -%}
|
||||
<li class="nav-list-item {% if page.url == child.url or page.parent == child.title %} active{% endif %}">
|
||||
{%- if child.has_children -%}
|
||||
<a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a>
|
||||
{%- endif -%}
|
||||
<a href="{{ child.url | absolute_url }}" class="nav-list-link{% if page.url == child.url %} active{% endif %}">{{ child.title }}</a>
|
||||
{%- if child.has_children -%}
|
||||
{%- assign grand_children_list = pages_list | where: "parent", child.title | where: "grand_parent", node.title -%}
|
||||
<ul class="nav-list">
|
||||
{%- for grand_child in grand_children_list -%}
|
||||
{%- unless grand_child.nav_exclude -%}
|
||||
<li class="nav-list-item {% if page.url == grand_child.url %} active{% endif %}">
|
||||
<a href="{{ grand_child.url | absolute_url }}" class="nav-list-link{% if page.url == grand_child.url %} active{% endif %}">{{ grand_child.title }}</a>
|
||||
</li>
|
||||
{%- endunless -%}
|
||||
{%- endfor -%}
|
||||
</ul>
|
||||
{%- endif -%}
|
||||
</li>
|
||||
{%- endunless -%}
|
||||
{%- endfor -%}
|
||||
</ul>
|
||||
{%- endif -%}
|
||||
</li>
|
||||
{%- endunless -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
</ul>
|
||||
|
||||
{%- if page.collection == include.key -%}
|
||||
|
||||
{%- for node in pages_list -%}
|
||||
{%- if node.parent == nil -%}
|
||||
{%- if page.parent == node.title or page.grand_parent == node.title -%}
|
||||
{%- assign first_level_url = node.url | absolute_url -%}
|
||||
{%- endif -%}
|
||||
{%- if node.has_children -%}
|
||||
{%- assign children_list = pages_list | where: "parent", node.title -%}
|
||||
{%- for child in children_list -%}
|
||||
{%- if child.has_children -%}
|
||||
{%- if page.url == child.url or page.parent == child.title and page.grand_parent == child.parent -%}
|
||||
{%- assign second_level_url = child.url | absolute_url -%}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
|
||||
{% if page.has_children == true and page.has_toc != false %}
|
||||
{%- assign toc_list = pages_list | where: "parent", page.title | where: "grand_parent", page.parent -%}
|
||||
{%- endif -%}
|
||||
|
||||
{%- endif -%}
|
||||
@@ -1,7 +0,0 @@
|
||||
<li>
|
||||
{% if url_full == include.url_full %} {{ include.text }} {% else %}
|
||||
<a href="{{ include.href }}" {% if url_parts[1] == {{include.url_fragment}} %} class="in-category" {% endif %}>
|
||||
{{ include.text }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
@@ -1,182 +0,0 @@
|
||||
{% capture tocWorkspace %}
|
||||
{% comment %}
|
||||
Copyright (c) 2017 Vladimir "allejo" Jimenez
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
{% endcomment %}
|
||||
{% comment %}
|
||||
Version 1.1.0
|
||||
https://github.com/allejo/jekyll-toc
|
||||
|
||||
"...like all things liquid - where there's a will, and ~36 hours to spare, there's usually a/some way" ~jaybe
|
||||
|
||||
Usage:
|
||||
{% include toc.html html=content sanitize=true class="inline_toc" id="my_toc" h_min=2 h_max=3 %}
|
||||
|
||||
Parameters:
|
||||
* html (string) - the HTML of compiled markdown generated by kramdown in Jekyll
|
||||
|
||||
Optional Parameters:
|
||||
* sanitize (bool) : false - when set to true, the headers will be stripped of any HTML in the TOC
|
||||
* class (string) : '' - a CSS class assigned to the TOC
|
||||
* id (string) : '' - an ID to assigned to the TOC
|
||||
* h_min (int) : 1 - the minimum TOC header level to use; any header lower than this value will be ignored
|
||||
* h_max (int) : 6 - the maximum TOC header level to use; any header greater than this value will be ignored
|
||||
* ordered (bool) : false - when set to true, an ordered list will be outputted instead of an unordered list
|
||||
* item_class (string) : '' - add custom class(es) for each list item; has support for '%level%' placeholder, which is the current heading level
|
||||
* submenu_class (string) : '' - add custom class(es) for each child group of headings; has support for '%level%' placeholder which is the current "submenu" heading level
|
||||
* base_url (string) : '' - add a base url to the TOC links for when your TOC is on another page than the actual content
|
||||
* anchor_class (string) : '' - add custom class(es) for each anchor element
|
||||
* skip_no_ids (bool) : false - skip headers that do not have an `id` attribute
|
||||
|
||||
Output:
|
||||
An ordered or unordered list representing the table of contents of a markdown block. This snippet will only
|
||||
generate the table of contents and will NOT output the markdown given to it
|
||||
{% endcomment %}
|
||||
|
||||
{% capture newline %}
|
||||
{% endcapture %}
|
||||
{% assign newline = newline | rstrip %} <!-- Remove the extra spacing but preserve the newline -->
|
||||
|
||||
{% capture deprecation_warnings %}{% endcapture %}
|
||||
|
||||
{% if include.baseurl %}
|
||||
{% capture deprecation_warnings %}{{ deprecation_warnings }}<!-- jekyll-toc :: "baseurl" has been deprecated, use "base_url" instead -->{{ newline }}{% endcapture %}
|
||||
{% endif %}
|
||||
|
||||
{% if include.skipNoIDs %}
|
||||
{% capture deprecation_warnings %}{{ deprecation_warnings }}<!-- jekyll-toc :: "skipNoIDs" has been deprecated, use "skip_no_ids" instead -->{{ newline }}{% endcapture %}
|
||||
{% endif %}
|
||||
|
||||
{% capture jekyll_toc %}{% endcapture %}
|
||||
{% assign orderedList = include.ordered | default: false %}
|
||||
{% assign baseURL = include.base_url | default: include.baseurl | default: '' %}
|
||||
{% assign skipNoIDs = include.skip_no_ids | default: include.skipNoIDs | default: false %}
|
||||
{% assign minHeader = include.h_min | default: 1 %}
|
||||
{% assign maxHeader = include.h_max | default: 6 %}
|
||||
{% assign nodes = include.html | strip | split: '<h' %}
|
||||
|
||||
{% assign firstHeader = true %}
|
||||
{% assign currLevel = 0 %}
|
||||
{% assign lastLevel = 0 %}
|
||||
|
||||
{% capture listModifier %}{% if orderedList %}ol{% else %}ul{% endif %}{% endcapture %}
|
||||
|
||||
{% for node in nodes %}
|
||||
{% if node == "" %}
|
||||
{% continue %}
|
||||
{% endif %}
|
||||
|
||||
{% assign currLevel = node | replace: '"', '' | slice: 0, 1 | times: 1 %}
|
||||
|
||||
{% if currLevel < minHeader or currLevel > maxHeader %}
|
||||
{% continue %}
|
||||
{% endif %}
|
||||
|
||||
{% assign _workspace = node | split: '</h' %}
|
||||
|
||||
{% assign _idWorkspace = _workspace[0] | split: 'id="' %}
|
||||
{% assign _idWorkspace = _idWorkspace[1] | split: '"' %}
|
||||
{% assign htmlID = _idWorkspace[0] %}
|
||||
|
||||
{% assign _classWorkspace = _workspace[0] | split: 'class="' %}
|
||||
{% assign _classWorkspace = _classWorkspace[1] | split: '"' %}
|
||||
{% assign htmlClass = _classWorkspace[0] %}
|
||||
|
||||
{% if htmlClass contains "no_toc" %}
|
||||
{% continue %}
|
||||
{% endif %}
|
||||
|
||||
{% if firstHeader %}
|
||||
{% assign minHeader = currLevel %}
|
||||
{% endif %}
|
||||
|
||||
{% capture _hAttrToStrip %}{{ _workspace[0] | split: '>' | first }}>{% endcapture %}
|
||||
{% assign header = _workspace[0] | replace: _hAttrToStrip, '' %}
|
||||
|
||||
{% if include.item_class and include.item_class != blank %}
|
||||
{% capture listItemClass %} class="{{ include.item_class | replace: '%level%', currLevel | split: '.' | join: ' ' }}"{% endcapture %}
|
||||
{% endif %}
|
||||
|
||||
{% if include.submenu_class and include.submenu_class != blank %}
|
||||
{% assign subMenuLevel = currLevel | minus: 1 %}
|
||||
{% capture subMenuClass %} class="{{ include.submenu_class | replace: '%level%', subMenuLevel | split: '.' | join: ' ' }}"{% endcapture %}
|
||||
{% endif %}
|
||||
|
||||
{% capture anchorBody %}{% if include.sanitize %}{{ header | strip_html }}{% else %}{{ header }}{% endif %}{% endcapture %}
|
||||
|
||||
{% if htmlID %}
|
||||
{% capture anchorAttributes %} href="{% if baseURL %}{{ baseURL }}{% endif %}#{{ htmlID }}"{% endcapture %}
|
||||
|
||||
{% if include.anchor_class %}
|
||||
{% capture anchorAttributes %}{{ anchorAttributes }} class="{{ include.anchor_class | split: '.' | join: ' ' }}"{% endcapture %}
|
||||
{% endif %}
|
||||
|
||||
{% capture listItem %}<a{{ anchorAttributes }}>{{ anchorBody }}</a>{% endcapture %}
|
||||
{% elsif skipNoIDs == true %}
|
||||
{% continue %}
|
||||
{% else %}
|
||||
{% capture listItem %}{{ anchorBody }}{% endcapture %}
|
||||
{% endif %}
|
||||
|
||||
{% if currLevel > lastLevel %}
|
||||
{% capture jekyll_toc %}{{ jekyll_toc }}<{{ listModifier }}{{ subMenuClass }}>{% endcapture %}
|
||||
{% elsif currLevel < lastLevel %}
|
||||
{% assign repeatCount = lastLevel | minus: currLevel %}
|
||||
|
||||
{% for i in (1..repeatCount) %}
|
||||
{% capture jekyll_toc %}{{ jekyll_toc }}</li></{{ listModifier }}>{% endcapture %}
|
||||
{% endfor %}
|
||||
|
||||
{% capture jekyll_toc %}{{ jekyll_toc }}</li>{% endcapture %}
|
||||
{% else %}
|
||||
{% capture jekyll_toc %}{{ jekyll_toc }}</li>{% endcapture %}
|
||||
{% endif %}
|
||||
|
||||
{% capture jekyll_toc %}{{ jekyll_toc }}<li{{ listItemClass }}>{{ listItem }}{% endcapture %}
|
||||
|
||||
{% assign lastLevel = currLevel %}
|
||||
{% assign firstHeader = false %}
|
||||
{% endfor %}
|
||||
|
||||
{% assign repeatCount = minHeader | minus: 1 %}
|
||||
{% assign repeatCount = lastLevel | minus: repeatCount %}
|
||||
{% for i in (1..repeatCount) %}
|
||||
{% capture jekyll_toc %}{{ jekyll_toc }}</li></{{ listModifier }}>{% endcapture %}
|
||||
{% endfor %}
|
||||
|
||||
{% if jekyll_toc != '' %}
|
||||
{% assign rootAttributes = '' %}
|
||||
{% if include.class and include.class != blank %}
|
||||
{% capture rootAttributes %} class="{{ include.class | split: '.' | join: ' ' }}"{% endcapture %}
|
||||
{% endif %}
|
||||
|
||||
{% if include.id and include.id != blank %}
|
||||
{% capture rootAttributes %}{{ rootAttributes }} id="{{ include.id }}"{% endcapture %}
|
||||
{% endif %}
|
||||
|
||||
{% if rootAttributes %}
|
||||
{% assign nodes = jekyll_toc | split: '>' %}
|
||||
{% capture jekyll_toc %}<{{ listModifier }}{{ rootAttributes }}>{{ nodes | shift | join: '>' }}>{% endcapture %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endcapture %}{% assign tocWorkspace = '' %}{{ deprecation_warnings }}{{ jekyll_toc }}
|
||||
@@ -1,217 +0,0 @@
|
||||
---
|
||||
layout: table_wrappers
|
||||
---
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="{{ site.lang | default: 'en-US' }}">
|
||||
{% include head.html %}
|
||||
<body>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||||
<symbol id="svg-link" viewBox="0 0 24 24">
|
||||
<title>Link</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link">
|
||||
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-search" viewBox="0 0 24 24">
|
||||
<title>Search</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search">
|
||||
<circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-menu" viewBox="0 0 24 24">
|
||||
<title>Menu</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu">
|
||||
<line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
|
||||
<title>Expand</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right">
|
||||
<polyline points="9 18 15 12 9 6"></polyline>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-doc" viewBox="0 0 24 24">
|
||||
<title>Document</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file">
|
||||
<path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-grid" viewBox="0 0 24 24">
|
||||
<title>Documentation Menu</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="feather feather-grid">
|
||||
<rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="14" y="14" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect>
|
||||
</svg>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
||||
{% include header.html %}
|
||||
|
||||
<main>
|
||||
<div id="main-header"></div>
|
||||
<div class="side-bar">
|
||||
<div class="site-header">
|
||||
<a href="#" id="menu-button" class="site-button">
|
||||
Documentation <svg viewBox="0 0 24 24" class="icon"><use xlink:href="#svg-grid"></use></svg>
|
||||
</a>
|
||||
</div>
|
||||
<nav role="navigation" aria-label="Main" id="site-nav" class="site-nav">
|
||||
{% assign past_versions = site.data.versions.past | join: ";" %}
|
||||
<div class="version-wrapper">
|
||||
<version-selector selected="{{ site.data.versions.current }}"></version-selector>
|
||||
</div>
|
||||
{% assign pages_top_size = site.html_pages
|
||||
| where_exp:"item", "item.title != nil"
|
||||
| where_exp:"item", "item.parent == nil"
|
||||
| where_exp:"item", "item.nav_exclude != true"
|
||||
| size %}
|
||||
{% if pages_top_size > 0 %}
|
||||
{% include nav.html pages=site.html_pages key=nil %}
|
||||
{% endif %}
|
||||
{% if site.just_the_docs.collections %}
|
||||
{% assign collections_size = site.just_the_docs.collections | size %}
|
||||
{% for collection_entry in site.just_the_docs.collections %}
|
||||
{% assign collection_key = collection_entry[0] %}
|
||||
{% assign collection_value = collection_entry[1] %}
|
||||
{% assign collection = site[collection_key] %}
|
||||
{% if collection_value.nav_exclude != true %}
|
||||
{% if collections_size > 1 or pages_top_size > 0 %}
|
||||
{% if collection_value.nav_fold == true %}
|
||||
<ul class="nav-list nav-category-list">
|
||||
<li class="nav-list-item{% if page.collection == collection_key %} active{% endif %}">
|
||||
{%- if collection.size > 0 -%}
|
||||
<a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a>
|
||||
{%- endif -%}
|
||||
<div class="nav-category">{{ collection_value.name }}</div>
|
||||
{% include nav.html pages=collection key=collection_key %}
|
||||
</li>
|
||||
</ul>
|
||||
{% else %}
|
||||
<div class="nav-category">{{ collection_value.name }}</div>
|
||||
{% include nav.html pages=collection key=collection_key %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% include nav.html pages=collection key=collection_key %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</nav>
|
||||
<div class="site-footer">
|
||||
<p class="text-small text-grey-dk-100">See a problem? Submit <a href="https://github.com/opensearch-project/documentation-website/issues">issues</a> or <a href="https://github.com/opensearch-project/documentation-website/edit/main/{{ page.path }}">edit this page</a> on <a href="https://github.com/opensearch-project/documentation-website/">GitHub</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="copy-banner">
|
||||
<div class="container">
|
||||
<h1><a href="#">Documentation</a></h1>
|
||||
{% if site.search_enabled != false %}
|
||||
<div class="search">
|
||||
<div class="search-input-wrap">
|
||||
<input type="text" id="search-input" class="search-input" tabindex="0" placeholder="Search..." aria-label="Search {{ site.title }}" autocomplete="off">
|
||||
<label for="search-input" class="search-label"><svg viewBox="0 0 24 24" class="search-icon"><use xlink:href="#svg-search"></use></svg></label>
|
||||
</div>
|
||||
<div id="search-results" class="search-results"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="search-overlay"></div>
|
||||
</div>
|
||||
<div class="main" id="top">
|
||||
<div id="main-content-wrap" class="main-content-wrap">
|
||||
{% unless page.url == "/" %}
|
||||
{% if page.parent %}
|
||||
<nav aria-label="Breadcrumb" class="breadcrumb-nav">
|
||||
<ol class="breadcrumb-nav-list">
|
||||
{% if page.grand_parent %}
|
||||
<li class="breadcrumb-nav-list-item"><a href="{{ first_level_url }}">{{ page.grand_parent }}</a></li>
|
||||
<li class="breadcrumb-nav-list-item"><a href="{{ second_level_url }}">{{ page.parent }}</a></li>
|
||||
{% else %}
|
||||
<li class="breadcrumb-nav-list-item"><a href="{{ first_level_url }}">{{ page.parent }}</a></li>
|
||||
{% endif %}
|
||||
<li class="breadcrumb-nav-list-item"><span>{{ page.title }}</span></li>
|
||||
</ol>
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% endunless %}
|
||||
<div id="main-content" class="main-content" role="main">
|
||||
{% if site.heading_anchors != false %}
|
||||
{% include vendor/anchor_headings.html html=content beforeHeading="true" anchorBody="<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><use xlink:href=\"#svg-link\"></use></svg>" anchorClass="anchor-heading" anchorAttrs="aria-labelledby=\"%html_id%\"" %}
|
||||
{% else %}
|
||||
{{ content }}
|
||||
{% endif %}
|
||||
|
||||
{% if page.has_children == true and page.has_toc != false %}
|
||||
<hr>
|
||||
<h2 class="text-delta">Table of contents</h2>
|
||||
<ul>
|
||||
{% for child in toc_list %}
|
||||
<li>
|
||||
<a href="{{ child.url | absolute_url }}">{{ child.title }}</a>{% if child.summary %} - {{ child.summary }}{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% capture footer_custom %}
|
||||
{%- include footer_custom.html -%}
|
||||
{% endcapture %}
|
||||
{% if footer_custom != "" or site.last_edit_timestamp or site.gh_edit_link %}
|
||||
<hr>
|
||||
<footer>
|
||||
{% if site.back_to_top %}
|
||||
<p><a href="#top" id="back-to-top">{{ site.back_to_top_text }}</a></p>
|
||||
{% endif %}
|
||||
|
||||
{{ footer_custom }}
|
||||
|
||||
{% if site.last_edit_timestamp or site.gh_edit_link %}
|
||||
<div class="d-flex mt-2">
|
||||
{% if site.last_edit_timestamp and site.last_edit_time_format and page.last_modified_date %}
|
||||
<p class="text-small text-grey-dk-000 mb-0 mr-2">
|
||||
Page last modified: <span class="d-inline-block">{{ page.last_modified_date | date: site.last_edit_time_format }}</span>.
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if
|
||||
site.gh_edit_link and
|
||||
site.gh_edit_link_text and
|
||||
site.gh_edit_repository and
|
||||
site.gh_edit_branch and
|
||||
site.gh_edit_view_mode
|
||||
%}
|
||||
<p class="text-small text-grey-dk-000 mb-0">
|
||||
<a href="{{ site.gh_edit_repository }}/{{ site.gh_edit_view_mode }}/{{ site.gh_edit_branch }}{% if site.gh_edit_source %}/{{ site.gh_edit_source }}{% endif %}/{{ page.path }}" id="edit-this-page">{{ site.gh_edit_link_text }}</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</footer>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="toc-wrap">
|
||||
<div class="toc">
|
||||
{% include toc.html html=content h_min=2 h_max=2 class="toc-list" item_class="toc-item" sanitize=true %}
|
||||
</div>
|
||||
</div>
|
||||
{% if site.search_enabled != false %}
|
||||
{% if site.search.button %}
|
||||
<a href="#" id="search-button" class="search-button">
|
||||
<svg viewBox="0 0 24 24" class="icon"><use xlink:href="#svg-search"></use></svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{% include footer.html %}
|
||||
|
||||
{% if site.anchor_links != nil %}
|
||||
<script>
|
||||
anchors.add().remove('.subfooter h1, .subfooter h2');
|
||||
</script>
|
||||
{% endif %}
|
||||
<script src="{{ '/assets/js/header-nav.js' | relative_url }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,161 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Anomaly detection
|
||||
nav_order: 46
|
||||
has_children: true
|
||||
redirect_from:
|
||||
- /monitoring-plugins/ad/
|
||||
---
|
||||
|
||||
# Anomaly detection
|
||||
|
||||
An anomaly in OpenSearch is any unusual behavior change in your time-series data. Anomalies can provide valuable insights into your data. For example, for IT infrastructure data, an anomaly in the memory usage metric might help you uncover early signs of a system failure.
|
||||
|
||||
It can be challenging to discover anomalies using conventional methods such as creating visualizations and dashboards. You could configure an alert based on a static threshold, but this requires prior domain knowledge and isn't adaptive to data that exhibits organic growth or seasonal behavior.
|
||||
|
||||
Anomaly detection automatically detects anomalies in your OpenSearch data in near real-time using the Random Cut Forest (RCF) algorithm. RCF is an unsupervised machine learning algorithm that models a sketch of your incoming data stream to compute an `anomaly grade` and `confidence score` value for each incoming data point. These values are used to differentiate an anomaly from normal variations. For more information about how RCF works, see [Random Cut Forests](https://api.semanticscholar.org/CorpusID:927435).
|
||||
|
||||
You can pair the anomaly detection plugin with the [alerting plugin]({{site.url}}{{site.baseurl}}/monitoring-plugins/alerting/) to notify you as soon as an anomaly is detected.
|
||||
|
||||
To get started, choose **Anomaly Detection** in OpenSearch Dashboards.
|
||||
To first test with sample streaming data, you can try out one of the preconfigured detectors with one of the sample datasets.
|
||||
|
||||
## Step 1: Define a detector
|
||||
|
||||
A detector is an individual anomaly detection task. You can define multiple detectors, and all the detectors can run simultaneously, with each analyzing data from different sources.
|
||||
|
||||
1. Choose **Create detector**.
|
||||
1. Enter a name and brief description. Make sure the name is unique and descriptive enough to help you to identify the purpose of the detector.
|
||||
1. For **Data source**, choose the index you want to use as the data source. You can optionally use index patterns to choose multiple indices.
|
||||
1. (Optional) For **Data filter**, filter the index you chose as the data source. From the **Data filter** menu, choose **Add data filter**, and then design your filter query by selecting **Field**, **Operator**, and **Value**, or choose **Use query DSL** and add your own JSON filter query.
|
||||
1. Select the **Timestamp field** in your index.
|
||||
1. For **Operation settings**, define the **Detector interval**, which is the time interval at which the detector collects data.
|
||||
- The detector aggregates the data in this interval, then feeds the aggregated result into the anomaly detection model.
|
||||
The shorter you set this interval, the fewer data points the detector aggregates.
|
||||
The anomaly detection model uses a shingling process, a technique that uses consecutive data points to create a sample for the model. This process needs a certain number of aggregated data points from contiguous intervals.
|
||||
- We recommend setting the detector interval based on your actual data. If it's too long it might delay the results, and if it's too short it might miss some data. It also won't have a sufficient number of consecutive data points for the shingle process.
|
||||
1. (Optional) To add extra processing time for data collection, specify a **Window delay** value. This value tells the detector that the data is not ingested into OpenSearch in real time but with a certain delay.
|
||||
Set the window delay to shift the detector interval to account for this delay.
|
||||
- For example, say the detector interval is 10 minutes and data is ingested into your cluster with a general delay of 1 minute.
|
||||
Assume the detector runs at 2:00. The detector attempts to get the last 10 minutes of data from 1:50 to 2:00, but because of the 1-minute delay, it only gets 9 minutes of data and misses the data from 1:59 to 2:00.
|
||||
Setting the window delay to 1 minute shifts the interval window to 1:49 - 1:59, so the detector accounts for all 10 minutes of the detector interval time.
|
||||
1. Choose **Next**.
|
||||
|
||||
After you define the detector, the next step is to configure the model.
|
||||
|
||||
## Step 2: Configure the model
|
||||
|
||||
#### Add features to your detector
|
||||
|
||||
A feature is the field in your index that you want to check for anomalies. A detector can discover anomalies across one or more features. You must choose an aggregation method for each feature: `average()`, `count()`, `sum()`, `min()`, or `max()`. The aggregation method determines what constitutes an anomaly.
|
||||
|
||||
For example, if you choose `min()`, the detector focuses on finding anomalies based on the minimum values of your feature. If you choose `average()`, the detector finds anomalies based on the average values of your feature.
|
||||
|
||||
A multi-feature model correlates anomalies across all its features. The [curse of dimensionality](https://en.wikipedia.org/wiki/Curse_of_dimensionality) makes it less likely for multi-feature models to identify smaller anomalies as compared to a single-feature model. Adding more features might negatively impact the [precision and recall](https://en.wikipedia.org/wiki/Precision_and_recall) of a model. A higher proportion of noise in your data might further amplify this negative impact. Selecting the optimal feature set is usually an iterative process. By default, the maximum number of features for a detector is 5. You can adjust this limit with the `plugins.anomaly_detection.max_anomaly_features` setting.
|
||||
{: .note }
|
||||
|
||||
1. On the **Configure Model** page, enter the **Feature name** and check **Enable feature**.
|
||||
1. For **Find anomalies based on**, choose the method to find anomalies. For **Field Value**, choose the **aggregation method**. Or choose **Custom expression**, and add your own JSON aggregation query.
|
||||
1. Select a field.
|
||||
|
||||
#### (Optional) Set category fields for high cardinality
|
||||
|
||||
You can categorize anomalies based on a keyword or IP field type.
|
||||
|
||||
The category field categorizes or slices the source time series with a dimension like IP addresses, product IDs, country codes, and so on. This helps to see a granular view of anomalies within each entity of the category field to isolate and debug issues.
|
||||
|
||||
To set a category field, choose **Enable a category field** and select a field. You can’t change the category fields after you create the detector.
|
||||
|
||||
Only a certain number of unique entities are supported in the category field. Use the following equation to calculate the recommended total number of entities supported in a cluster:
|
||||
|
||||
```
|
||||
(data nodes * heap size * anomaly detection maximum memory percentage) / (entity model size of a detector)
|
||||
```
|
||||
|
||||
To get the entity model size of a detector, use the [profile detector API]({{site.url}}{{site.baseurl}}/monitoring-plugins/ad/api/#profile-detector). You can adjust the maximum memory percentage with the `plugins.anomaly_detection.model_max_size_percent` setting.
|
||||
|
||||
This formula provides a good starting point, but make sure to test with a representative workload.
|
||||
{: .note }
|
||||
|
||||
For example, for a cluster with three data nodes, each with 8 GB of JVM heap size, a maximum memory percentage of 10% (default), and the entity model size of the detector as 1MB: the total number of unique entities supported is (8.096 * 10^9 * 0.1 / 1 MB ) * 3 = 2429.
|
||||
|
||||
If the actual total number of unique entities higher than this number that you calculate (in this case: 2429), the anomaly detector makes its best effort to model the extra entities. The detector prioritizes entities that occur more often and are more recent.
|
||||
|
||||
#### (Advanced settings) Set a shingle size
|
||||
|
||||
Set the number of aggregation intervals from your data stream to consider in a detection window. It’s best to choose this value based on your actual data to see which one leads to the best results for your use case.
|
||||
|
||||
The anomaly detector expects the shingle size to be in the range of 1 and 60. The default shingle size is 8. We recommend that you don't choose 1 unless you have two or more features. Smaller values might increase [recall](https://en.wikipedia.org/wiki/Precision_and_recall) but also false positives. Larger values might be useful for ignoring noise in a signal.
|
||||
|
||||
#### Preview sample anomalies
|
||||
|
||||
Preview sample anomalies and adjust the feature settings if needed.
|
||||
For sample previews, the anomaly detection plugin selects a small number of data samples---for example, one data point every 30 minutes---and uses interpolation to estimate the remaining data points to approximate the actual feature data. It loads this sample dataset into the detector. The detector uses this sample dataset to generate a sample preview of anomaly results.
|
||||
|
||||
Examine the sample preview and use it to fine-tune your feature configurations (for example, enable or disable features) to get more accurate results.
|
||||
|
||||
1. Choose **Preview sample anomalies**.
|
||||
- If you don't see any sample anomaly result, check the detector interval and make sure you have more than 400 data points for some entities during the preview date range.
|
||||
1. Choose **Next**.
|
||||
|
||||
## Step 3: Set up detector jobs
|
||||
|
||||
To start a real-time detector to find anomalies in your data in near real-time, check **Start real-time detector automatically (recommended)**.
|
||||
|
||||
Alternatively, if you want to perform historical analysis and find patterns in long historical data windows (weeks or months), check **Run historical analysis detection** and select a date range (at least 128 detection intervals).
|
||||
|
||||
Analyzing historical data helps you get familiar with the anomaly detection plugin. You can also evaluate the performance of a detector with historical data to further fine-tune it.
|
||||
|
||||
We recommend experimenting with historical analysis with different feature sets and checking the precision before moving on to real-time detectors.
|
||||
|
||||
## Step 4: Review and create
|
||||
|
||||
Review your model configuration and select **Create detector**.
|
||||
|
||||
## Step 5: Observe the results
|
||||
|
||||
Choose the **Real-time results** or **Historical analysis** tab. For real-time results, you need to wait for some time to see the anomaly results. If the detector interval is 10 minutes, the detector might take more than an hour to start, as it's waiting for sufficient data to generate anomalies.
|
||||
|
||||
A shorter interval means the model passes the shingle process more quickly and starts to generate the anomaly results sooner.
|
||||
Use the [profile detector]({{site.url}}{{site.baseurl}}/monitoring-plugins/ad/api#profile-detector) operation to make sure you have sufficient data points.
|
||||
|
||||
If you see the detector pending in "initialization" for longer than a day, aggregate your existing data using the detector interval to check for any missing data points. If you find a lot of missing data points from the aggregated data, consider increasing the detector interval.
|
||||
|
||||

|
||||
|
||||
Analyze anomalies with the following visualizations:
|
||||
|
||||
- **Live anomalies** - displays live anomaly results for the last 60 intervals. For example, if the interval is 10, it shows results for the last 600 minutes. The chart refreshes every 30 seconds.
|
||||
- **Anomaly history** (for historical analysis) / **Anomaly overview** (for real-time results) - plots the anomaly grade with the corresponding measure of confidence.
|
||||
- **Anomaly occurrence** - shows the `Start time`, `End time`, `Data confidence`, and `Anomaly grade` for each detected anomaly.
|
||||
- **Feature breakdown** - plots the features based on the aggregation method. You can vary the date-time range of the detector.
|
||||
|
||||
`Anomaly grade` is a number between 0 and 1 that indicates how anomalous a data point is. An anomaly grade of 0 represents “not an anomaly,” and a non-zero value represents the relative severity of the anomaly.
|
||||
|
||||
`Data confidence` is an estimate of the probability that the reported anomaly grade matches the expected anomaly grade. Confidence increases as the model observes more data and learns the data behavior and trends. Note that confidence is distinct from model accuracy.
|
||||
|
||||
If you set the category field, you see an additional **Heat map** chart. The heat map correlates results for anomalous entities. This chart is empty until you select an anomalous entity. You also see the anomaly and feature line chart for the time period of the anomaly (`anomaly_grade` > 0).
|
||||
|
||||
Choose and drag over the anomaly line chart to zoom in and see a more detailed view of an anomaly.
|
||||
{: .note }
|
||||
|
||||
## Step 6: Set up alerts
|
||||
|
||||
Under **Real-time results**, choose **Set up alerts** and configure a monitor to notify you when anomalies are detected. For steps to create a monitor and set up notifications based on your anomaly detector, see [Monitors]({{site.url}}{{site.baseurl}}/monitoring-plugins/alerting/monitors/).
|
||||
|
||||
If you stop or delete a detector, make sure to delete any monitors associated with it.
|
||||
|
||||
## Step 7: Adjust the model
|
||||
|
||||
To see all the configuration settings for a detector, choose the **Detector configuration** tab.
|
||||
|
||||
1. To make any changes to the detector configuration, or fine tune the time interval to minimize any false positives, go to the **Detector configuration** section and choose **Edit**.
|
||||
- You need to stop real-time and historical analysis to change its configuration. Confirm that you want to stop the detector and proceed.
|
||||
1. To enable or disable features, in the **Features** section, choose **Edit** and adjust the feature settings as needed. After you make your changes, choose **Save and start detector**.
|
||||
|
||||
## Step 8: Manage your detectors
|
||||
|
||||
To start, stop, or delete a detector, go to the **Detectors** page.
|
||||
|
||||
1. Choose the detector name.
|
||||
2. Choose **Actions** and select **Start real-time detectors**, **Stop real-time detectors**, or **Delete detectors**.
|
||||
@@ -1,86 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Anomaly detection security
|
||||
nav_order: 10
|
||||
parent: Anomaly detection
|
||||
has_children: false
|
||||
---
|
||||
|
||||
# Anomaly detection security
|
||||
|
||||
You can use the security plugin with anomaly detection in OpenSearch to limit non-admin users to specific actions. For example, you might want some users to only be able to create, update, or delete detectors, while others to only view detectors.
|
||||
|
||||
All anomaly detection indices are protected as system indices. Only a super admin user or an admin user with a TLS certificate can access system indices. For more information, see [System indices]({{site.url}}{{site.baseurl}}/security-plugin/configuration/system-indices/).
|
||||
|
||||
|
||||
Security for anomaly detection works the same as [security for alerting]({{site.url}}{{site.baseurl}}/monitoring-plugins/alerting/security/).
|
||||
|
||||
## Basic permissions
|
||||
|
||||
As an admin user, you can use the security plugin to assign specific permissions to users based on which APIs they need access to. For a list of supported APIs, see [Anomaly detection API]({{site.url}}{{site.baseurl}}/monitoring-plugins/ad/api/).
|
||||
|
||||
The security plugin has two built-in roles that cover most anomaly detection use cases: `anomaly_full_access` and `anomaly_read_access`. For descriptions of each, see [Predefined roles]({{site.url}}{{site.baseurl}}/security-plugin/access-control/users-roles#predefined-roles).
|
||||
|
||||
If these roles don't meet your needs, mix and match individual anomaly detection [permissions]({{site.url}}{{site.baseurl}}/security-plugin/access-control/permissions/) to suit your use case. Each action corresponds to an operation in the REST API. For example, the `cluster:admin/opensearch/ad/detector/delete` permission lets you delete detectors.
|
||||
|
||||
## (Advanced) Limit access by backend role
|
||||
|
||||
Use backend roles to configure fine-grained access to individual detectors based on roles. For example, users of different departments in an organization can view detectors owned by their own department.
|
||||
|
||||
First, make sure your users have the appropriate [backend roles]({{site.url}}{{site.baseurl}}/security-plugin/access-control/index/). Backend roles usually come from an [LDAP server]({{site.url}}{{site.baseurl}}/security-plugin/configuration/ldap/) or [SAML provider]({{site.url}}{{site.baseurl}}/security-plugin/configuration/saml/), but if you use the internal user database, you can use the REST API to [add them manually]({{site.url}}{{site.baseurl}}/security-plugin/access-control/api#create-user).
|
||||
|
||||
Next, enable the following setting:
|
||||
|
||||
```json
|
||||
PUT _cluster/settings
|
||||
{
|
||||
"transient": {
|
||||
"plugins.anomaly_detection.filter_by_backend_roles": "true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now when users view anomaly detection resources in OpenSearch Dashboards (or make REST API calls), they only see detectors created by users who share at least one backend role.
|
||||
For example, consider two users: `alice` and `bob`.
|
||||
|
||||
`alice` has an analyst backend role:
|
||||
|
||||
```json
|
||||
PUT _plugins/_security/api/internalusers/alice
|
||||
{
|
||||
"password": "alice",
|
||||
"backend_roles": [
|
||||
"analyst"
|
||||
],
|
||||
"attributes": {}
|
||||
}
|
||||
```
|
||||
|
||||
`bob` has a human-resources backend role:
|
||||
|
||||
```json
|
||||
PUT _plugins/_security/api/internalusers/bob
|
||||
{
|
||||
"password": "bob",
|
||||
"backend_roles": [
|
||||
"human-resources"
|
||||
],
|
||||
"attributes": {}
|
||||
}
|
||||
```
|
||||
|
||||
Both `alice` and `bob` have full access to anomaly detection:
|
||||
|
||||
```json
|
||||
PUT _plugins/_security/api/rolesmapping/anomaly_full_access
|
||||
{
|
||||
"backend_roles": [],
|
||||
"hosts": [],
|
||||
"users": [
|
||||
"alice",
|
||||
"bob"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Because they have different backend roles, `alice` and `bob` cannot view each other's detectors or their results.
|
||||
@@ -1,47 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Settings
|
||||
parent: Anomaly detection
|
||||
nav_order: 4
|
||||
---
|
||||
|
||||
# Settings
|
||||
|
||||
The anomaly detection plugin adds several settings to the standard OpenSearch cluster settings.
|
||||
The settings are dynamic, so you can change the default behavior of the plugin without restarting your cluster.
|
||||
You can mark settings as `persistent` or `transient`.
|
||||
|
||||
For example, to update the retention period of the result index:
|
||||
|
||||
```json
|
||||
PUT _cluster/settings
|
||||
{
|
||||
"transient": {
|
||||
"plugins.anomaly_detection.ad_result_history_retention_period": "5m"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Setting | Default | Description
|
||||
:--- | :--- | :---
|
||||
plugins.anomaly_detection.enabled | True | Whether the anomaly detection plugin is enabled or not. If disabled, all detectors immediately stop running.
|
||||
plugins.anomaly_detection.max_anomaly_detectors | 1,000 | The maximum number of non-high cardinality detectors (no category field) users can create.
|
||||
plugins.anomaly_detection.max_multi_entity_anomaly_detectors | 10 | The maximum number of high cardinality detectors (with category field) in a cluster.
|
||||
plugins.anomaly_detection.max_anomaly_features | 5 | The maximum number of features for a detector.
|
||||
plugins.anomaly_detection.ad_result_history_rollover_period | 12h | How often the rollover condition is checked. If `true`, the anomaly detection plugin rolls over the result index to a new index.
|
||||
plugins.anomaly_detection.ad_result_history_max_docs_per_shard | 1,350,000,000 | The maximum number of documents in a single shard of the result index. The anomaly detection plugin only counts the refreshed documents in the primary shards.
|
||||
plugins.anomaly_detection.max_entities_per_query | 1,000,000 | The maximum unique values per detection interval for high cardinality detectors. By default, if the category field(s) have more than the configured unique values in a detector interval, the anomaly detection plugin orders them by the natural ordering of categorical values (for example, entity `ab` comes before `bc`) and then selects the top values.
|
||||
plugins.anomaly_detection.max_entities_for_preview | 5 | The maximum unique category field values displayed with the preview operation for high cardinality detectors. By default, if the category field(s) have more than the configured unique values in a detector interval, the anomaly detection plugin orders them by the natural ordering of categorical values (for example, entity `ab` comes before `bc`) and then selects the top values.
|
||||
plugins.anomaly_detection.max_primary_shards | 10 | The maximum number of primary shards an anomaly detection index can have.
|
||||
plugins.anomaly_detection.filter_by_backend_roles | False | When you enable the security plugin and set this to `true`, the anomaly detection plugin filters results based on the user's backend role(s).
|
||||
plugins.anomaly_detection.max_batch_task_per_node | 10 | Starting a historical analysis triggers a batch task. This setting is the number of batch tasks that you can run per data node. You can tune this setting from 1 to 1,000. If the data nodes can’t support all batch tasks and you’re not sure if the data nodes are capable of running more historical analysis, add more data nodes instead of changing this setting to a higher value. Increasing this value might bring more load on each data node.
|
||||
plugins.anomaly_detection.max_old_ad_task_docs_per_detector | 1 | You can run historical analysis for the same detector many times. For each run, the anomaly detection plugin creates a new task. This setting is the number of previous tasks the plugin keeps. Set this value to at least 1 to track its last run. You can keep a maximum of 1,000 old tasks to avoid overwhelming the cluster.
|
||||
plugins.anomaly_detection.batch_task_piece_size | 1,000 | The date range for a historical task is split into smaller pieces and the anomaly detection plugin runs the task piece by piece. Each piece contains 1,000 detection intervals by default. For example, if detector interval is 1 minute and one piece is 1,000 minutes, the feature data is queried every 1,000 minutes. You can change this setting from 1 to 10,000.
|
||||
plugins.anomaly_detection.batch_task_piece_interval_seconds | 5 | Add a time interval between two pieces of the same historical analysis task. This interval prevents the task from consuming too much of the available resources and starving other operations like search and bulk index. You can change this setting from 1 to 600 seconds.
|
||||
plugins.anomaly_detection.max_top_entities_for_historical_analysis | 1,000 | The maximum number of top entities that you run for a high cardinality detector historical analysis. The range is from 1 to 10,000.
|
||||
plugins.anomaly_detection.max_running_entities_per_detector_for_historical_analysis | 10 | The number of entity tasks that you can run in parallel for a high cardinality detector analysis. The task slots available on your cluster also impact how many entities run in parallel. If a cluster has 3 data nodes, each data node has 10 task slots by default. Say you already have two high cardinality detectors and each of them run 10 entities. If you start a single-entity detector that takes 1 task slot, the number of task slots available is 10 * 3 - 10 * 2 - 1 = 9. If you now start a new high cardinality detector, the detector can only run 9 entities in parallel and not 10. You can tune this value from 1 to 1,000 based on your cluster's capability. If you set a higher value, the anomaly detection plugin runs historical analysis faster but also consumes more resources.
|
||||
plugins.anomaly_detection.max_cached_deleted_tasks | 1,000 | You can rerun historical analysis for a single detector as many times as you like. The anomaly detection plugin only keeps a limited number of old tasks, by default 1 old task. If you run historical analysis three times for a detector, the oldest task is deleted. Because historical analysis generates a number of anomaly results in a short span of time, it's necessary to clean up anomaly results for a deleted task. With this field, you can configure how many deleted tasks you can cache at most. The plugin cleans up a task's results when it's deleted. If the plugin fails to do this cleanup, it adds the task's results into a cache and an hourly cron job performs the cleanup. You can use this setting to limit how many old tasks are put into cache to avoid a DDoS attack. After an hour, if still you find an old task result in the cache, use the [delete detector results API]({{site.url}}{{site.baseurl}}/monitoring-plugins/ad/api/#delete-detector-results) to delete the task result manually. You can tune this setting from 1 to 10,000.
|
||||
plugins.anomaly_detection.delete_anomaly_result_when_delete_detector | False | Whether the anomaly detection plugin deletes the anomaly result when you delete a detector. If you want to save some disk space, especially if you've high cardinality detectors generating a lot of results, set this field to true. Alternatively, you can use the [delete detector results API]({{site.url}}{{site.baseurl}}/monitoring-plugins/ad/api/#delete-detector-results) to manually delete the results.
|
||||
plugins.anomaly_detection.dedicated_cache_size | 10 | If the real-time analysis of a high cardinality detector starts successfully, the anomaly detection plugin guarantees keeping 10 (dynamically adjustable via this setting) entities' models in memory per node. If the number of entities exceeds this limit, the plugin puts the extra entities' models in a memory space shared by all detectors. The actual number of entities varies based on the memory that you've available and the frequencies of the entities. If you'd like the plugin to guarantee keeping more entities' models in memory and if you're cluster has sufficient memory, you can increase this setting value.
|
||||
plugins.anomaly_detection.max_concurrent_preview | 2 | The maximum number of concurrent previews. You can use this setting to limit resource usage.
|
||||
plugins.anomaly_detection.model_max_size_percent | 0.1 | The upper bound of the memory percentage for a model.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,64 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Cron
|
||||
nav_order: 20
|
||||
parent: Alerting
|
||||
has_children: false
|
||||
---
|
||||
|
||||
# Cron expression reference
|
||||
|
||||
Monitors can run at a variety of fixed intervals (e.g. hourly, daily, etc.), but you can also define custom cron expressions for when they should run. Monitors use the Unix cron syntax and support five fields:
|
||||
|
||||
Field | Valid values
|
||||
:--- | :---
|
||||
Minute | 0-59
|
||||
Hour | 0-23
|
||||
Day of month | 1-31
|
||||
Month | 1-12
|
||||
Day of week | 0-7 (0 and 7 are both Sunday) or SUN, MON, TUE, WED, THU, FRI, SAT
|
||||
|
||||
For example, the following expression translates to "every Monday through Friday at 11:30 AM":
|
||||
|
||||
```
|
||||
30 11 * * 1-5
|
||||
```
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
Feature | Description
|
||||
:--- | :---
|
||||
`*` | Wildcard. Specifies all valid values.
|
||||
`,` | List. Use to specify several values (e.g. `1,15,30`).
|
||||
`-` | Range. Use to specify a range of values (e.g. `1-15`).
|
||||
`/` | Step. Use after a wildcard or range to specify the "step" between values. For example, `0-11/2` is equivalent to `0,2,4,6,8,10`.
|
||||
|
||||
Note that you can specify the day using two fields: day of month and day of week. For most situations, we recommend that you use just one of these fields and leave the other as `*`.
|
||||
|
||||
If you use a non-wildcard value in both fields, the monitor runs when either field matches the time. For example, `15 2 1,15 * 1` causes the monitor to run at 2:15 AM on the 1st of the month, the 15th of the month, and every Monday.
|
||||
|
||||
|
||||
## Sample expressions
|
||||
|
||||
Every other day at 1:45 PM:
|
||||
|
||||
```
|
||||
45 13 1-31/2 * *
|
||||
```
|
||||
|
||||
Every 10 minutes on Saturday and Sunday:
|
||||
|
||||
```
|
||||
0/10 * * * 6-7
|
||||
```
|
||||
|
||||
Every three hours on the first day of every other month:
|
||||
|
||||
```
|
||||
0 0-23/3 1 1-12/2 *
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
For an example of how to use a custom cron expression in an API call, see the [create monitor API operation]({{site.url}}{{site.baseurl}}/monitoring-plugins/alerting/api#request-1).
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Alerting
|
||||
nav_order: 34
|
||||
has_children: true
|
||||
redirect_from:
|
||||
- /monitoring-plugins/alerting/
|
||||
---
|
||||
|
||||
# Alerting
|
||||
OpenSearch Dashboards
|
||||
{: .label .label-yellow :}
|
||||
|
||||
The alerting feature notifies you when data from one or more OpenSearch indices meets certain conditions. For example, you might want to notify a [Slack](https://slack.com/) channel if your application logs more than five HTTP 503 errors in one hour, or you might want to page a developer if no new documents have been indexed in the past 20 minutes.
|
||||
|
||||
To get started, choose **Alerting** in OpenSearch Dashboards.
|
||||
|
||||

|
||||
@@ -1,408 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Monitors
|
||||
nav_order: 1
|
||||
parent: Alerting
|
||||
has_children: false
|
||||
---
|
||||
|
||||
# Monitors
|
||||
|
||||
#### Table of contents
|
||||
- TOC
|
||||
{:toc}
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Key terms
|
||||
|
||||
Term | Definition
|
||||
:--- | :---
|
||||
Monitor | A job that runs on a defined schedule and queries OpenSearch indices. The results of these queries are then used as input for one or more *triggers*.
|
||||
Trigger | Conditions that, if met, generate *alerts*.
|
||||
Alert | An event associated with a trigger. When an alert is created, the trigger performs *actions*, which can include sending a notification.
|
||||
Action | The information that you want the monitor to send out after being triggered. Actions have a *destination*, a message subject, and a message body.
|
||||
Destination | A reusable location for an action. Supported locations are Amazon Chime, Email, Slack, or custom webhook.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Create destinations
|
||||
|
||||
1. Choose **Alerting**, **Destinations**, **Add destination**.
|
||||
1. Specify a name for the destination so that you can identify it later.
|
||||
1. For **Type**, choose Slack, Amazon Chime, custom webhook, or [email](#email-as-a-destination).
|
||||
|
||||
For Email, refer to the [Email as a destination](#email-as-a-destination) section below. For all other types, specify the webhook URL. See the documentation for [Slack](https://api.slack.com/incoming-webhooks) and [Amazon Chime](https://docs.aws.amazon.com/chime/latest/ug/webhooks.html) to learn more about webhooks.
|
||||
|
||||
If you're using custom webhooks, you must specify more information: parameters and headers. For example, if your endpoint requires basic authentication, you might need to add a header with a key of `Authorization` and a value of `Basic <Base64-encoded-credential-string>`. You might also need to change `Content-Type` to whatever your webhook requires. Popular values are `application/json`, `application/xml`, and `text/plain`.
|
||||
|
||||
This information is stored in plain text in the OpenSearch cluster. We will improve this design in the future, but for now, the encoded credentials (which are neither encrypted nor hashed) might be visible to other OpenSearch users.
|
||||
|
||||
|
||||
### Email as a destination
|
||||
|
||||
To send or receive an alert notification as an email, choose **Email** as the destination type. Next, add at least one sender and recipient. We recommend adding email groups if you want to notify more than a few people of an alert. You can configure senders and recipients using **Manage senders** and **Manage email groups**.
|
||||
|
||||
|
||||
#### Manage senders
|
||||
|
||||
Senders are email accounts from which the alerting plugin sends notifications.
|
||||
|
||||
To configure a sender email, do the following:
|
||||
|
||||
1. After you choose **Email** as the destination type, choose **Manage senders**.
|
||||
1. Choose **Add sender**, **New sender** and enter a unique name.
|
||||
1. Enter the email address, SMTP host (e.g. `smtp.gmail.com` for a Gmail account), and the port.
|
||||
1. Choose an encryption method, or use the default value of **None**. However, most email providers require SSL or TLS, which require a username and password in OpenSearch keystore. Refer to [Authenticate sender account](#authenticate-sender-account) to learn more.
|
||||
1. Choose **Save** to save the configuration and create the sender. You can create a sender even before you add your credentials to the OpenSearch keystore. However, you must [authenticate each sender account](#authenticate-sender-account) before you use the destination to send your alert.
|
||||
|
||||
You can reuse senders across many different destinations, but each destination only supports one sender.
|
||||
|
||||
|
||||
#### Manage email groups or recipients
|
||||
|
||||
Use email groups to create and manage reusable lists of email addresses. For example, one alert might email the DevOps team, whereas another might email the executive team and the engineering team.
|
||||
|
||||
You can enter individual email addresses or an email group in the **Recipients** field.
|
||||
|
||||
1. After you choose **Email** as the destination type, choose **Manage email groups**. Then choose **Add email group**, **New email group**.
|
||||
1. Enter a unique name.
|
||||
1. For recipient emails, enter any number of email addresses.
|
||||
1. Choose **Save**.
|
||||
|
||||
|
||||
#### Authenticate sender account
|
||||
|
||||
If your email provider requires SSL or TLS, you must authenticate each sender account before you can send an email. Enter these credentials in the OpenSearch keystore using the CLI. Run the following commands (in your OpenSearch directory) to enter your username and password. The `<sender_name>` is the name you entered for **Sender** earlier.
|
||||
|
||||
```bash
|
||||
./bin/opensearch-keystore add plugins.alerting.destination.email.<sender_name>.username
|
||||
./bin/opensearch-keystore add plugins.alerting.destination.email.<sender_name>.password
|
||||
```
|
||||
|
||||
Note: Keystore settings are node-specific. You must run these commands on each node.
|
||||
{: .note}
|
||||
|
||||
To change or update your credentials (after you've added them to the keystore on every node), call the reload API to automatically update those credentials without restarting OpenSearch:
|
||||
|
||||
```json
|
||||
POST _nodes/reload_secure_settings
|
||||
{
|
||||
"secure_settings_password": "1234"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Create monitors
|
||||
|
||||
1. Choose **Alerting**, **Monitors**, **Create monitor**.
|
||||
1. Specify a name for the monitor.
|
||||
1. Choose either **Per query monitor** or **Per bucket monitor**.
|
||||
|
||||
Whereas query-level monitors run your specified query and then check whether the query's results triggers any alerts, bucket-level monitors let you select fields to create buckets and categorize your results into those buckets. The alerting plugin runs each bucket's unique results against a script you define later, so you have finer control over which results should trigger alerts. Each of those buckets can trigger an alert, but query-level monitors can only trigger one alert at a time.
|
||||
|
||||
1. Define the monitor in one of three ways: visually, using a query, or using an anomaly detector.
|
||||
|
||||
- Visual definition works well for monitors that you can define as "some value is above or below some threshold for some amount of time."
|
||||
|
||||
- Query definition gives you flexibility in terms of what you query for (using [the OpenSearch query DSL]({{site.url}}{{site.baseurl}}/opensearch/query-dsl/full-text)) and how you evaluate the results of that query (Painless scripting).
|
||||
|
||||
This example averages the `cpu_usage` field:
|
||||
|
||||
```json
|
||||
{
|
||||
"size": 0,
|
||||
"query": {
|
||||
"match_all": {}
|
||||
},
|
||||
"aggs": {
|
||||
"avg_cpu": {
|
||||
"avg": {
|
||||
"field": "cpu_usage"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can even filter query results using `{% raw %}{{period_start}}{% endraw %}` and `{% raw %}{{period_end}}{% endraw %}`:
|
||||
|
||||
```json
|
||||
{
|
||||
"size": 0,
|
||||
"query": {
|
||||
"bool": {
|
||||
"filter": [{
|
||||
"range": {
|
||||
"timestamp": {
|
||||
"from": "{% raw %}{{period_end}}{% endraw %}||-1h",
|
||||
"to": "{% raw %}{{period_end}}{% endraw %}",
|
||||
"include_lower": true,
|
||||
"include_upper": true,
|
||||
"format": "epoch_millis",
|
||||
"boost": 1
|
||||
}
|
||||
}
|
||||
}],
|
||||
"adjust_pure_negative": true,
|
||||
"boost": 1
|
||||
}
|
||||
},
|
||||
"aggregations": {}
|
||||
}
|
||||
```
|
||||
|
||||
"Start" and "end" refer to the interval at which the monitor runs. See [Available variables](#available-variables).
|
||||
|
||||
To define a monitor visually, choose **Visual editor**. Then choose a source index, a timeframe, an aggregation (for example, `count()` or `average()`), a data filter if you want to monitor a subset of your source index, and a group-by field if you want to include an aggregation field in your query. At least one group-by field is required if you're defining a bucket-level monitor. Visual definition works well for most monitors.
|
||||
|
||||
If you use the security plugin, you can only choose indices that you have permission to access. For details, see [Alerting security]({{site.url}}{{site.baseurl}}/security-plugin/).
|
||||
|
||||
To use a query, choose **Extraction query editor**, add your query (using [the OpenSearch query DSL]({{site.url}}{{site.baseurl}}/opensearch/query-dsl/full-text/)), and test it using the **Run** button.
|
||||
|
||||
The monitor makes this query to OpenSearch as often as the schedule dictates; check the **Query Performance** section and make sure you're comfortable with the performance implications.
|
||||
|
||||
To use an anomaly detector, choose **Anomaly detector** and select your **Detector**.
|
||||
|
||||
The anomaly detection option is for pairing with the anomaly detection plugin. See [Anomaly Detection]({{site.url}}{{site.baseurl}}/monitoring-plugins/ad/).
|
||||
For anomaly detector, choose an appropriate schedule for the monitor based on the detector interval. Otherwise, the alerting monitor might miss reading the results.
|
||||
|
||||
For example, assume you set the monitor interval and the detector interval as 5 minutes, and you start the detector at 12:00. If an anomaly is detected at 12:05, it might be available at 12:06 because of the delay between writing the anomaly and it being available for queries. The monitor reads the anomaly results between 12:00 and 12:05, so it does not get the anomaly results available at 12:06.
|
||||
|
||||
To avoid this issue, make sure the alerting monitor is at least twice the detector interval.
|
||||
When you create a monitor using OpenSearch Dashboards, the anomaly detector plugin generates a default monitor schedule that's twice the detector interval.
|
||||
|
||||
Whenever you update a detector’s interval, make sure to update the associated monitor interval as well, as the anomaly detection plugin does not do this automatically.
|
||||
|
||||
**Note**: Anomaly detection is available only if you are defining a per query monitor.
|
||||
{: .note}
|
||||
|
||||
1. Choose a frequency and timezone for your monitor. Note that you can only pick a timezone if you choose Daily, Weekly, Monthly, or [custom cron expression]({{site.url}}{{site.baseurl}}/monitoring-plugins/alerting/cron/) for frequency.
|
||||
|
||||
1. Add a trigger to your monitor.
|
||||
|
||||
---
|
||||
|
||||
## Create triggers
|
||||
|
||||
Steps to create a trigger differ depending on whether you chose **Visual editor**, **Extraction query editor**, or **Anomaly detector** when you created the monitor.
|
||||
|
||||
You begin by specifying a name and severity level for the trigger. Severity levels help you manage alerts. A trigger with a high severity level (e.g. 1) might page a specific individual, whereas a trigger with a low severity level might message a chat room.
|
||||
|
||||
Remember that query-level monitors run your trigger's script just once against the query's results, but bucket-level monitors execute your trigger's script on each bucket, so you should create a trigger that best fits the monitor you chose. If you want to execute multiple scripts, you must create multiple triggers.
|
||||
|
||||
### Visual editor
|
||||
|
||||
For a query-level monitor's **Trigger condition**, specify a threshold for the aggregation and timeframe you chose earlier, such as "is below 1,000" or "is exactly 10."
|
||||
|
||||
The line moves up and down as you increase and decrease the threshold. Once this line is crossed, the trigger evaluates to true.
|
||||
|
||||
Bucket-level monitors also require you to specify a threshold and value for your aggregation and timeframe, but you can use a maximum of five conditions to better refine your trigger. Optionally, you can also use a keyword filter to filter for a specific field in your index.
|
||||
|
||||
|
||||
### Extraction query
|
||||
|
||||
If you're using a query-level monitor, specify a Painless script that returns true or false. Painless is the default OpenSearch scripting language and has a syntax similar to Groovy.
|
||||
|
||||
Trigger condition scripts revolve around the `ctx.results[0]` variable, which corresponds to the extraction query response. For example, your script might reference `ctx.results[0].hits.total.value` or `ctx.results[0].hits.hits[i]._source.error_code`.
|
||||
|
||||
A return value of true means the trigger condition has been met, and the trigger should execute its actions. Test your script using the **Run** button.
|
||||
|
||||
The **Info** link next to **Trigger condition** contains a useful summary of the variables and results available to your query.
|
||||
{: .tip }
|
||||
|
||||
Bucket-level monitors require you to specify more information in your trigger condition. At a minimum, you must have the following fields:
|
||||
|
||||
- `buckets_path`, which maps variable names to metrics to use in your script.
|
||||
- `parent_bucket_path`, which is a path to a multi-bucket aggregation. The path can include single-bucket aggregations, but the last aggregation must be multi-bucket. For example, if you have a pipeline such as `agg1>agg2>agg3`, `agg1` and `agg2` are single-bucket aggregations, but `agg3` must be a multi-bucket aggregation.
|
||||
- `script`, which is the script that OpenSearch runs to evaluate whether to trigger any alerts.
|
||||
|
||||
For example, you might have a script that looks like the following:
|
||||
|
||||
```json
|
||||
{
|
||||
"buckets_path": {
|
||||
"count_var": "_count"
|
||||
},
|
||||
"parent_bucket_path": "composite_agg",
|
||||
"script": {
|
||||
"source": "params.count_var > 5"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After mapping the `count_var` variable to the `_count` metric, you can use `count_var` in your script and reference `_count` data. Finally, `composite_agg` is a path to a multi-bucket aggregation.
|
||||
|
||||
### Anomaly detector
|
||||
|
||||
For **Trigger type**, choose **Anomaly detector grade and confidence**.
|
||||
|
||||
Specify the **Anomaly grade condition** for the aggregation and timeframe you chose earlier, "IS ABOVE 0.7" or "IS EXACTLY 0.5." The *anomaly grade* is a number between 0 and 1 that indicates the level of severity of how anomalous a data point is.
|
||||
|
||||
Specify the **Anomaly confidence condition** for the aggregation and timeframe you chose earlier, "IS ABOVE 0.7" or "IS EXACTLY 0.5." The *anomaly confidence* is an estimate of the probability that the reported anomaly grade matches the expected anomaly grade.
|
||||
|
||||
The line moves up and down as you increase and decrease the threshold. Once this line is crossed, the trigger evaluates to true.
|
||||
|
||||
|
||||
#### Sample scripts
|
||||
|
||||
{::comment}
|
||||
These scripts are Painless, not Groovy, but calling them Groovy in Jekyll gets us syntax highlighting in the generated HTML.
|
||||
{:/comment}
|
||||
|
||||
```groovy
|
||||
// Evaluates to true if the query returned any documents
|
||||
ctx.results[0].hits.total.value > 0
|
||||
```
|
||||
|
||||
```groovy
|
||||
// Returns true if the avg_cpu aggregation exceeds 90
|
||||
if (ctx.results[0].aggregations.avg_cpu.value > 90) {
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
```groovy
|
||||
// Performs some crude custom scoring and returns true if that score exceeds a certain value
|
||||
int score = 0;
|
||||
for (int i = 0; i < ctx.results[0].hits.hits.length; i++) {
|
||||
// Weighs 500 errors 10 times as heavily as 503 errors
|
||||
if (ctx.results[0].hits.hits[i]._source.http_status_code == "500") {
|
||||
score += 10;
|
||||
} else if (ctx.results[0].hits.hits[i]._source.http_status_code == "503") {
|
||||
score += 1;
|
||||
}
|
||||
}
|
||||
if (score > 99) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
```
|
||||
|
||||
Below are some variables you can include in your message using Mustache templates to see more information about your monitors.
|
||||
|
||||
### Available variables
|
||||
|
||||
#### Monitor variables
|
||||
|
||||
Variable | Data Type | Description
|
||||
:--- | :--- | :---
|
||||
`ctx.monitor` | Object | Includes `ctx.monitor.name`, `ctx.monitor.type`, `ctx.monitor.enabled`, `ctx.monitor.enabled_time`, `ctx.monitor.schedule`, `ctx.monitor.inputs`, `triggers` and `ctx.monitor.last_update_time`.
|
||||
`ctx.monitor.user` | Object | Includes information about the user who created the monitor. Includes `ctx.monitor.user.backend_roles` and `ctx.monitor.user.roles`, which are arrays that contain the backend roles and roles assigned to the user. See [alerting security]({{site.url}}{{site.baseurl}}/monitoring-plugins/alerting/security/) for more information.
|
||||
`ctx.monitor.enabled` | Boolean | Whether the monitor is enabled.
|
||||
`ctx.monitor.enabled_time` | Milliseconds | Unix epoch time of when the monitor was last enabled.
|
||||
`ctx.monitor.schedule` | Object | Contains a schedule of how often or when the monitor should run.
|
||||
`ctx.monitor.schedule.period.interval` | Integer | The interval at which the monitor runs.
|
||||
`ctx.monitor.schedule.period.unit` | String | The interval's unit of time.
|
||||
`ctx.monitor.inputs` | Array | An array that contains the indices and definition used to create the monitor.
|
||||
`ctx.monitor.inputs.search.indices` | Array | An array that contains the indices the monitor observes.
|
||||
`ctx.monitor.inputs.search.query` | N/A | The definition used to define the monitor.
|
||||
|
||||
#### Trigger variables
|
||||
|
||||
Variable | Data Type | Description
|
||||
:--- | :--- | : ---
|
||||
`ctx.trigger.id` | String | The trigger's ID.
|
||||
`ctx.trigger.name` | String | The trigger's name.
|
||||
`ctx.trigger.severity` | String | The trigger's severity.
|
||||
`ctx.trigger.condition`| Object | Contains the Painless script used when creating the monitor.
|
||||
`ctx.trigger.condition.script.source` | String | The language used to define the script. Must be painless.
|
||||
`ctx.trigger.condition.script.lang` | String | The script used to define the trigger.
|
||||
`ctx.trigger.actions`| Array | An array with one element that contains information about the action the monitor needs to trigger.
|
||||
|
||||
#### Action variables
|
||||
|
||||
Variable | Data Type | Description
|
||||
:--- | :--- | : ---
|
||||
`ctx.trigger.actions.id` | String | The action's ID.
|
||||
`ctx.trigger.actions.name` | String | The action's name.
|
||||
`ctx.trigger.actions.destination_id`| String | The alert destination's ID.
|
||||
`ctx.trigger.actions.message_template.source` | String | The message to send in the alert.
|
||||
`ctx.trigger.actions.message_template.lang` | String | The scripting language used to define the message. Must be Mustache.
|
||||
`ctx.trigger.actions.throttle_enabled` | Boolean | Whether throttling is enabled for this trigger. See [adding actions](#add-actions) for more information about throttling.
|
||||
`ctx.trigger.actions.subject_template.source` | String | The message's subject in the alert.
|
||||
`ctx.trigger.actions.subject_template.lang` | String | The scripting language used to define the subject. Must be mustache.
|
||||
|
||||
#### Other variables
|
||||
|
||||
Variable | Data Type | Description
|
||||
:--- | :--- : :---
|
||||
`ctx.results` | Array | An array with one element (i.e. `ctx.results[0]`). Contains the query results. This variable is empty if the trigger was unable to retrieve results. See `ctx.error`.
|
||||
`ctx.last_update_time` | Milliseconds | Unix epoch time of when the monitor was last updated.
|
||||
`ctx.periodStart` | String | Unix timestamp for the beginning of the period during which the alert triggered. For example, if a monitor runs every ten minutes, a period might begin at 10:40 and end at 10:50.
|
||||
`ctx.periodEnd` | String | The end of the period during which the alert triggered.
|
||||
`ctx.error` | String | The error message if the trigger was unable to retrieve results or unable to evaluate the trigger, typically due to a compile error or null pointer exception. Null otherwise.
|
||||
`ctx.alert` | Object | The current, active alert (if it exists). Includes `ctx.alert.id`, `ctx.alert.version`, and `ctx.alert.isAcknowledged`. Null if no alert is active. Only available with query-level monitors.
|
||||
`ctx.dedupedAlerts` | Object | Alerts that have already been triggered. OpenSearch keeps the existing alert to prevent the plugin from creating endless amounts of the same alerts. Only available with bucket-level monitors.
|
||||
`ctx.newAlerts` | Object | Newly created alerts. Only available with bucket-level monitors.
|
||||
`ctx.completedAlerts` | Object | Alerts that are no longer ongoing. Only available with bucket-level monitors.
|
||||
`bucket_keys` | String | Comma-separated list of the monitor's bucket key values. Available only for `ctx.dedupedAlerts`, `ctx.newAlerts`, and `ctx.completedAlerts`. Accessed through `ctx.dedupedAlerts[0].bucket_keys`.
|
||||
`parent_bucket_path` | String | The parent bucket path of the bucket that triggered the alert. Accessed through `ctx.dedupedAlerts[0].parent_bucket_path`.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Add actions
|
||||
|
||||
The final step in creating a monitor is to add one or more actions. Actions send notifications when trigger conditions are met and support [Slack](https://slack.com/), [Amazon Chime](https://aws.amazon.com/chime/), and webhooks.
|
||||
|
||||
If you don't want to receive notifications for alerts, you don't have to add actions to your triggers. Instead, you can periodically check OpenSearch Dashboards.
|
||||
{: .tip }
|
||||
|
||||
1. Specify a name for the action.
|
||||
1. Choose a destination.
|
||||
1. Add a subject and body for the message.
|
||||
|
||||
You can add variables to your messages using [Mustache templates](https://mustache.github.io/mustache.5.html). You have access to `ctx.action.name`, the name of the current action, as well as all [trigger variables](#available-variables).
|
||||
|
||||
If your destination is a custom webhook that expects a particular data format, you might need to include JSON (or even XML) directly in the message body:
|
||||
|
||||
```json
|
||||
{% raw %}{ "text": "Monitor {{ctx.monitor.name}} just entered alert status. Please investigate the issue. - Trigger: {{ctx.trigger.name}} - Severity: {{ctx.trigger.severity}} - Period start: {{ctx.periodStart}} - Period end: {{ctx.periodEnd}}" }{% endraw %}
|
||||
```
|
||||
|
||||
In this case, the message content must conform to the `Content-Type` header in the [custom webhook](#create-destinations).
|
||||
1. If you're using a bucket-level monitor, you can choose whether the monitor should perform an action for each execution or for each alert.
|
||||
|
||||
1. (Optional) Use action throttling to limit the number of notifications you receive within a given span of time.
|
||||
|
||||
For example, if a monitor checks a trigger condition every minute, you could receive one notification per minute. If you set action throttling to 60 minutes, you receive no more than one notification per hour, even if the trigger condition is met dozens of times in that hour.
|
||||
|
||||
1. Choose **Create**.
|
||||
|
||||
After an action sends a message, the content of that message has left the purview of the security plugin. Securing access to the message (e.g. access to the Slack channel) is your responsibility.
|
||||
|
||||
|
||||
#### Sample message
|
||||
|
||||
```mustache
|
||||
{% raw %}Monitor {{ctx.monitor.name}} just entered an alert state. Please investigate the issue.
|
||||
- Trigger: {{ctx.trigger.name}}
|
||||
- Severity: {{ctx.trigger.severity}}
|
||||
- Period start: {{ctx.periodStart}}
|
||||
- Period end: {{ctx.periodEnd}}{% endraw %}
|
||||
```
|
||||
|
||||
If you want to use the `ctx.results` variable in a message, use `{% raw %}{{ctx.results.0}}{% endraw %}` rather than `{% raw %}{{ctx.results[0]}}{% endraw %}`. This difference is due to how Mustache handles bracket notation.
|
||||
{: .note }
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Work with alerts
|
||||
|
||||
Alerts persist until you resolve the root cause and have the following states:
|
||||
|
||||
State | Description
|
||||
:--- | :---
|
||||
Active | The alert is ongoing and unacknowledged. Alerts remain in this state until you acknowledge them, delete the trigger associated with the alert, or delete the monitor entirely.
|
||||
Acknowledged | Someone has acknowledged the alert, but not fixed the root cause.
|
||||
Completed | The alert is no longer ongoing. Alerts enter this state after the corresponding trigger evaluates to false.
|
||||
Error | An error occurred while executing the trigger---usually the result of a a bad trigger or destination.
|
||||
Deleted | Someone deleted the monitor or trigger associated with this alert while the alert was ongoing.
|
||||
@@ -1,79 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Alerting security
|
||||
nav_order: 10
|
||||
parent: Alerting
|
||||
has_children: false
|
||||
---
|
||||
|
||||
# Alerting security
|
||||
|
||||
If you use the security plugin alongside alerting, you might want to limit certain users to certain actions. For example, you might want some users to only be able to view and acknowledge alerts, while others can modify monitors and destinations.
|
||||
|
||||
|
||||
## Basic permissions
|
||||
|
||||
The security plugin has three built-in roles that cover most alerting use cases: `alerting_read_access`, `alerting_ack_alerts`, and `alerting_full_access`. For descriptions of each, see [Predefined roles]({{site.url}}{{site.baseurl}}/security-plugin/access-control/users-roles#predefined-roles).
|
||||
|
||||
If these roles don't meet your needs, mix and match individual alerting [permissions]({{site.url}}{{site.baseurl}}/security-plugin/access-control/permissions/) to suit your use case. Each action corresponds to an operation in the REST API. For example, the `cluster:admin/opensearch/alerting/destination/delete` permission lets you delete destinations.
|
||||
|
||||
|
||||
## How monitors access data
|
||||
|
||||
Monitors run with the permissions of the user who created or last modified them. For example, consider the user `jdoe`, who works at a chain of retail stores. `jdoe` has two roles. Together, these two roles allow read access to three indices: `store1-returns`, `store2-returns`, and `store3-returns`.
|
||||
|
||||
`jdoe` creates a monitor that sends an email to management whenever the number of returns across all three indices exceeds 40 per hour.
|
||||
|
||||
Later, the user `psantos` wants to edit the monitor to run every two hours, but `psantos` only has access to `store1-returns`. To make the change, `psantos` has two options:
|
||||
|
||||
- Update the monitor so that it only checks `store1-returns`.
|
||||
- Ask an administrator for read access to the other two indices.
|
||||
|
||||
After making the change, the monitor now runs with the same permissions as `psantos`, including any [document-level security]({{site.url}}{{site.baseurl}}/security-plugin/access-control/document-level-security/) queries, [excluded fields]({{site.url}}{{site.baseurl}}/security-plugin/access-control/field-level-security/), and [masked fields]({{site.url}}{{site.baseurl}}/security-plugin/access-control/field-masking/). If you use an extraction query to define your monitor, use the **Run** button to ensure that the response includes the fields you need.
|
||||
|
||||
|
||||
## (Advanced) Limit access by backend role
|
||||
|
||||
Out of the box, the alerting plugin has no concept of ownership. For example, if you have the `cluster:admin/opensearch/alerting/monitor/write` permission, you can edit *all* monitors, regardless of whether you created them. If a small number of trusted users manage your monitors and destinations, this lack of ownership generally isn't a problem. A larger organization might need to segment access by backend role.
|
||||
|
||||
First, make sure that your users have the appropriate [backend roles]({{site.url}}{{site.baseurl}}/security-plugin/access-control/index/). Backend roles usually come from an [LDAP server]({{site.url}}{{site.baseurl}}/security-plugin/configuration/ldap/) or [SAML provider]({{site.url}}{{site.baseurl}}/security-plugin/configuration/saml/). However, if you use the internal user database, you can use the REST API to [add them manually]({{site.url}}{{site.baseurl}}/security-plugin/access-control/api#create-user).
|
||||
|
||||
Next, enable the following setting:
|
||||
|
||||
```json
|
||||
PUT _cluster/settings
|
||||
{
|
||||
"transient": {
|
||||
"plugins.alerting.filter_by_backend_roles": "true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now when users view alerting resources in OpenSearch Dashboards (or make REST API calls), they only see monitors and destinations that are created by users who share *at least one* backend role. For example, consider three users who all have full access to alerting: `jdoe`, `jroe`, and `psantos`.
|
||||
|
||||
`jdoe` and `jroe` are on the same team at work and both have the `analyst` backend role. `psantos` has the `human-resources` backend role.
|
||||
|
||||
If `jdoe` creates a monitor, `jroe` can see and modify it, but `psantos` can't. If that monitor generates an alert, the situation is the same: `jroe` can see and acknowledge it, but `psantos` can't. If `psantos` creates a destination, `jdoe` and `jroe` can't see or modify it.
|
||||
|
||||
|
||||
<!-- ## (Advanced) Limit access by individual
|
||||
|
||||
If you only want users to be able to see and modify their own monitors and destinations, duplicate the `alerting_full_access` role and add the following [DLS query]({{site.url}}{{site.baseurl}}/security-plugin/access-control/document-level-security/) to it:
|
||||
|
||||
```json
|
||||
{
|
||||
"bool": {
|
||||
"should": [{
|
||||
"match": {
|
||||
"monitor.created_by": "${user.name}"
|
||||
}
|
||||
}, {
|
||||
"match": {
|
||||
"destination.created_by": "${user.name}"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then, use this new role for all alerting users. -->
|
||||
@@ -1,59 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Management
|
||||
parent: Alerting
|
||||
nav_order: 5
|
||||
---
|
||||
|
||||
# Management
|
||||
|
||||
|
||||
## Alerting indices
|
||||
|
||||
The alerting feature creates several indices and one alias. The security plugin demo script configures them as [system indices]({{site.url}}{{site.baseurl}}/security-plugin/configuration/system-indices/) for an extra layer of protection. Don't delete these indices or modify their contents without using the alerting APIs.
|
||||
|
||||
Index | Purpose
|
||||
:--- | :---
|
||||
`.opendistro-alerting-alerts` | Stores ongoing alerts.
|
||||
`.opendistro-alerting-alert-history-<date>` | Stores a history of completed alerts.
|
||||
`.opendistro-alerting-config` | Stores monitors, triggers, and destinations. [Take a snapshot]({{site.url}}{{site.baseurl}}/opensearch/snapshot-restore) of this index to back up your alerting configuration.
|
||||
`.opendistro-alerting-alert-history-write` (alias) | Provides a consistent URI for the `.opendistro-alerting-alert-history-<date>` index.
|
||||
|
||||
All alerting indices are hidden by default. For a summary, make the following request:
|
||||
|
||||
```
|
||||
GET _cat/indices?expand_wildcards=open,hidden
|
||||
```
|
||||
|
||||
|
||||
## Alerting settings
|
||||
|
||||
We don't recommend changing these settings; the defaults should work well for most use cases.
|
||||
|
||||
All settings are available using the OpenSearch `_cluster/settings` API. None require a restart, and all can be marked `persistent` or `transient`.
|
||||
|
||||
Setting | Default | Description
|
||||
:--- | :--- | :---
|
||||
`plugins.scheduled_jobs.enabled` | true | Whether the alerting plugin is enabled or not. If disabled, all monitors immediately stop running.
|
||||
`plugins.alerting.index_timeout` | 60s | The timeout for creating monitors and destinations using the REST APIs.
|
||||
`plugins.alerting.request_timeout` | 10s | The timeout for miscellaneous requests from the plugin.
|
||||
`plugins.alerting.action_throttle_max_value` | 24h | The maximum amount of time you can set for action throttling. By default, this value displays as 1440 minutes in OpenSearch Dashboards.
|
||||
`plugins.alerting.input_timeout` | 30s | How long the monitor can take to issue the search request.
|
||||
`plugins.alerting.bulk_timeout` | 120s | How long the monitor can write alerts to the alert index.
|
||||
`plugins.alerting.alert_backoff_count` | 3 | The number of retries for writing alerts before the operation fails.
|
||||
`plugins.alerting.alert_backoff_millis` | 50ms | The amount of time to wait between retries---increases exponentially after each failed retry.
|
||||
`plugins.alerting.alert_history_rollover_period` | 12h | How frequently to check whether the `.opendistro-alerting-alert-history-write` alias should roll over to a new history index and whether the Alerting plugin should delete any history indices.
|
||||
`plugins.alerting.move_alerts_backoff_millis` | 250 | The amount of time to wait between retries---increases exponentially after each failed retry.
|
||||
`plugins.alerting.move_alerts_backoff_count` | 3 | The number of retries for moving alerts to a deleted state after their monitor or trigger has been deleted.
|
||||
`plugins.alerting.monitor.max_monitors` | 1000 | The maximum number of monitors users can create.
|
||||
`plugins.alerting.alert_history_max_age` | 30d | The oldest document to store in the `.opendistro-alert-history-<date>` index before creating a new index. If the number of alerts in this time period does not exceed `alert_history_max_docs`, alerting creates one history index per period (e.g. one index every 30 days).
|
||||
`plugins.alerting.alert_history_max_docs` | 1000 | The maximum number of alerts to store in the `.opendistro-alert-history-<date>` index before creating a new index.
|
||||
`plugins.alerting.alert_history_enabled` | true | Whether to create `.opendistro-alerting-alert-history-<date>` indices.
|
||||
`plugins.alerting.alert_history_retention_period` | 60d | The amount of time to keep history indices before automatically deleting them.
|
||||
`plugins.alerting.destination.allow_list` | ["chime", "slack", "custom_webhook", "email", "test_action"] | The list of allowed destinations. If you don't want to allow users to a certain type of destination, you can remove it from this list, but we recommend leaving this setting as-is.
|
||||
`plugins.alerting.filter_by_backend_roles` | "false" | Restricts access to monitors by backend role. See [Alerting security]({{site.url}}{{site.baseurl}}/monitoring-plugins/alerting/security/).
|
||||
`plugins.scheduled_jobs.sweeper.period` | 5m | The alerting feature uses its "job sweeper" component to periodically check for new or updated jobs. This setting is the rate at which the sweeper checks to see if any jobs (monitors) have changed and need to be rescheduled.
|
||||
`plugins.scheduled_jobs.sweeper.page_size` | 100 | The page size for the sweeper. You shouldn't need to change this value.
|
||||
`plugins.scheduled_jobs.sweeper.backoff_millis` | 50ms | The amount of time the sweeper waits between retries---increases exponentially after each failed retry.
|
||||
`plugins.scheduled_jobs.sweeper.retry_count` | 3 | The total number of times the sweeper should retry before throwing an error.
|
||||
`plugins.scheduled_jobs.request_timeout` | 10s | The timeout for the request that sweeps shards for jobs.
|
||||
@@ -1,198 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: API
|
||||
parent: Performance Analyzer
|
||||
nav_order: 1
|
||||
---
|
||||
|
||||
# Performance Analyzer API
|
||||
Introduced 1.0
|
||||
{: .label .label-purple }
|
||||
|
||||
Performance Analyzer uses a single HTTP method and URI for most requests:
|
||||
|
||||
```
|
||||
GET <endpoint>:9600/_plugins/_performanceanalyzer/metrics
|
||||
```
|
||||
|
||||
Note the use of port 9600. Provide parameters for metrics, aggregations, dimensions, and nodes (optional):
|
||||
|
||||
```
|
||||
?metrics=<metrics>&agg=<aggregations>&dim=<dimensions>&nodes=all"
|
||||
```
|
||||
|
||||
For a full list of metrics, see [Metrics reference]({{site.url}}{{site.baseurl}}/monitoring-plugins/pa/reference/). Performance Analyzer updates its data every five seconds. If you create a custom client, we recommend using that same interval for calls to the API.
|
||||
|
||||
|
||||
#### Sample request
|
||||
|
||||
```
|
||||
GET localhost:9600/_plugins/_performanceanalyzer/metrics?metrics=Latency,CPU_Utilization&agg=avg,max&dim=ShardID&nodes=all
|
||||
```
|
||||
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"keHlhQbbTpm1BYicficEQg": {
|
||||
"timestamp": 1554940530000,
|
||||
"data": {
|
||||
"fields": [{
|
||||
"name": "ShardID",
|
||||
"type": "VARCHAR"
|
||||
},
|
||||
{
|
||||
"name": "Latency",
|
||||
"type": "DOUBLE"
|
||||
},
|
||||
{
|
||||
"name": "CPU_Utilization",
|
||||
"type": "DOUBLE"
|
||||
}
|
||||
],
|
||||
"records": [
|
||||
[
|
||||
null,
|
||||
null,
|
||||
0.012552206029147535
|
||||
],
|
||||
[
|
||||
"1",
|
||||
4.8,
|
||||
0.0009780939762972104
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"bHdpbMJZTs-TKtZro2SmYA": {
|
||||
"timestamp": 1554940530000,
|
||||
"data": {
|
||||
"fields": [{
|
||||
"name": "ShardID",
|
||||
"type": "VARCHAR"
|
||||
},
|
||||
{
|
||||
"name": "Latency",
|
||||
"type": "DOUBLE"
|
||||
},
|
||||
{
|
||||
"name": "CPU_Utilization",
|
||||
"type": "DOUBLE"
|
||||
}
|
||||
],
|
||||
"records": [
|
||||
[
|
||||
null,
|
||||
18.2,
|
||||
0.011966493817311527
|
||||
],
|
||||
[
|
||||
"1",
|
||||
14.8,
|
||||
0.0007670829370071493
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In this case, each top-level object represents a node. The API returns names and data types for the metrics and dimensions that you specified, along with values from five seconds ago and current values (if different). Null values represent inactivity during that time period.
|
||||
|
||||
Performance Analyzer has one additional URI that returns the unit for each metric.
|
||||
|
||||
|
||||
#### Sample request
|
||||
|
||||
```
|
||||
GET localhost:9600/_plugins/_performanceanalyzer/metrics/units
|
||||
```
|
||||
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"Disk_Utilization": "%",
|
||||
"Cache_Request_Hit": "count",
|
||||
"TermVectors_Memory": "B",
|
||||
"Segments_Memory": "B",
|
||||
"HTTP_RequestDocs": "count",
|
||||
"Net_TCP_Lost": "segments/flow",
|
||||
"Refresh_Time": "ms",
|
||||
"GC_Collection_Event": "count",
|
||||
"Merge_Time": "ms",
|
||||
"Sched_CtxRate": "count/s",
|
||||
"Cache_Request_Size": "B",
|
||||
"ThreadPool_QueueSize": "count",
|
||||
"Sched_Runtime": "s/ctxswitch",
|
||||
"Disk_ServiceRate": "MB/s",
|
||||
"Heap_AllocRate": "B/s",
|
||||
"Heap_Max": "B",
|
||||
"Sched_Waittime": "s/ctxswitch",
|
||||
"ShardBulkDocs": "count",
|
||||
"Thread_Blocked_Time": "s/event",
|
||||
"VersionMap_Memory": "B",
|
||||
"Master_Task_Queue_Time": "ms",
|
||||
"Merge_CurrentEvent": "count",
|
||||
"Indexing_Buffer": "B",
|
||||
"Bitset_Memory": "B",
|
||||
"Norms_Memory": "B",
|
||||
"Net_PacketDropRate4": "packets/s",
|
||||
"Heap_Committed": "B",
|
||||
"Net_PacketDropRate6": "packets/s",
|
||||
"Thread_Blocked_Event": "count",
|
||||
"GC_Collection_Time": "ms",
|
||||
"Cache_Query_Miss": "count",
|
||||
"IO_TotThroughput": "B/s",
|
||||
"Latency": "ms",
|
||||
"Net_PacketRate6": "packets/s",
|
||||
"Cache_Query_Hit": "count",
|
||||
"IO_ReadSyscallRate": "count/s",
|
||||
"Net_PacketRate4": "packets/s",
|
||||
"Cache_Request_Miss": "count",
|
||||
"CB_ConfiguredSize": "B",
|
||||
"CB_TrippedEvents": "count",
|
||||
"ThreadPool_RejectedReqs": "count",
|
||||
"Disk_WaitTime": "ms",
|
||||
"Net_TCP_TxQ": "segments/flow",
|
||||
"Master_Task_Run_Time": "ms",
|
||||
"IO_WriteSyscallRate": "count/s",
|
||||
"IO_WriteThroughput": "B/s",
|
||||
"Flush_Event": "count",
|
||||
"Net_TCP_RxQ": "segments/flow",
|
||||
"Refresh_Event": "count",
|
||||
"Points_Memory": "B",
|
||||
"Flush_Time": "ms",
|
||||
"Heap_Init": "B",
|
||||
"CPU_Utilization": "cores",
|
||||
"HTTP_TotalRequests": "count",
|
||||
"ThreadPool_ActiveThreads": "count",
|
||||
"Cache_Query_Size": "B",
|
||||
"Paging_MinfltRate": "count/s",
|
||||
"Merge_Event": "count",
|
||||
"Net_TCP_SendCWND": "B/flow",
|
||||
"Cache_Request_Eviction": "count",
|
||||
"Segments_Total": "count",
|
||||
"Terms_Memory": "B",
|
||||
"DocValues_Memory": "B",
|
||||
"Heap_Used": "B",
|
||||
"Cache_FieldData_Eviction": "count",
|
||||
"IO_TotalSyscallRate": "count/s",
|
||||
"CB_EstimatedSize": "B",
|
||||
"Net_Throughput": "B/s",
|
||||
"Paging_RSS": "pages",
|
||||
"Indexing_ThrottleTime": "ms",
|
||||
"StoredFields_Memory": "B",
|
||||
"IndexWriter_Memory": "B",
|
||||
"Master_PendingQueueSize": "count",
|
||||
"Net_TCP_SSThresh": "B/flow",
|
||||
"Cache_FieldData_Size": "B",
|
||||
"Paging_MajfltRate": "count/s",
|
||||
"ThreadPool_TotalThreads": "count",
|
||||
"IO_ReadThroughput": "B/s",
|
||||
"ShardEvents": "count",
|
||||
"Net_TCP_NumFlows": "count"
|
||||
}
|
||||
```
|
||||
@@ -1,162 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Create PerfTop Dashboards
|
||||
parent: Performance Analyzer
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
# PerfTop dashboards
|
||||
|
||||
Dashboards are defined in JSON and composed of three main elements: tables, line graphs, and bar graphs. You define a grid of rows and columns and then place elements within that grid, with each element spanning as many rows and columns as you specify.
|
||||
|
||||
The best way to get started with building custom dashboards is to duplicate and modify one of the existing JSON files in the `dashboards` directory.
|
||||
{: .tip }
|
||||
|
||||
---
|
||||
|
||||
#### Table of contents
|
||||
1. TOC
|
||||
{:toc}
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Summary of elements
|
||||
|
||||
- Tables show metrics per dimension. For example, if your metric is `CPU_Utilization` and your dimension `ShardID`, a PerfTop table shows a row for each shard on each node.
|
||||
- Bar graphs are aggregated for the cluster, unless you add `nodeName` to the dashboard. See the [options for all elements](#all-elements).
|
||||
- Line graphs are aggregated for each node. Each line represents a node.
|
||||
|
||||
|
||||
## Position elements
|
||||
|
||||
PerfTop positions elements within a grid. For example, consider this 12 * 12 grid.
|
||||
|
||||

|
||||
|
||||
The upper-left of the grid represents row 0, column 0, so the starting positions for the three boxes are:
|
||||
|
||||
- Orange: row 0, column 0
|
||||
- Purple: row 2, column 2
|
||||
- Green: row 1, column 6
|
||||
|
||||
These boxes span a number of rows and columns. In this case:
|
||||
|
||||
- Orange: 2 rows, 4 columns
|
||||
- Purple: 1 row, 4 columns
|
||||
- Green: 3 rows, 2 columns
|
||||
|
||||
In JSON form, we have the following:
|
||||
|
||||
```json
|
||||
{
|
||||
"gridOptions": {
|
||||
"rows": 12,
|
||||
"cols": 12
|
||||
},
|
||||
"graphs": {
|
||||
"tables": [{
|
||||
"options": {
|
||||
"gridPosition": {
|
||||
"row": 0,
|
||||
"col": 0,
|
||||
"rowSpan": 2,
|
||||
"colSpan": 4
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"gridPosition": {
|
||||
"row": 2,
|
||||
"col": 2,
|
||||
"rowSpan": 1,
|
||||
"colSpan": 4
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"gridPosition": {
|
||||
"row": 1,
|
||||
"col": 6,
|
||||
"rowSpan": 3,
|
||||
"colSpan": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
At this point, however, all the JSON does is define the size and position of three tables. To fill elements with data, you specify a query.
|
||||
|
||||
|
||||
## Add queries
|
||||
|
||||
Queries use the same elements as the [REST API]({{site.url}}{{site.baseurl}}/monitoring-plugins/pa/api/), just in JSON form:
|
||||
|
||||
```json
|
||||
{
|
||||
"queryParams": {
|
||||
"metrics": "estimated,limitConfigured",
|
||||
"aggregates": "avg,avg",
|
||||
"dimensions": "type",
|
||||
"sortBy": "estimated"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For details on available metrics, see [Metrics reference]({{site.url}}{{site.baseurl}}/monitoring-plugins/pa/reference/).
|
||||
|
||||
|
||||
## Add options
|
||||
|
||||
Options include labels, colors, and a refresh interval. Different elements types have different options.
|
||||
|
||||
Dashboards support the 16 ANSI colors: black, red, green, yellow, blue, magenta, cyan, and white. For the "bright" variants of these colors, use the numbers 8--15. If your terminal supports 256 colors, you can also use hex codes (e.g. `#6D40ED`).
|
||||
{: .note }
|
||||
|
||||
|
||||
### All elements
|
||||
|
||||
Option | Type | Description
|
||||
:--- | :--- | :---
|
||||
`label` | String or integer | The text in the upper-left corner of the box.
|
||||
`labelColor` | String or integer | The color of the label.
|
||||
`refreshInterval` | Integer | The number of milliseconds between calls to the Performance Analyzer API for new data. Minimum value is 5000.
|
||||
`dimensionFilters` | String array | The dimension value to diplay for the graph. For example, if you query for `metric=Net_Throughput&agg=sum&dim=Direction` and the possible dimension values are `in` and `out`, you can define `dimensionFilters: ["in"]` to only display the metric data for `in` dimension
|
||||
`nodeName` | String | If non-null, lets you restrict elements to individual nodes. You can specify the node name directly in the dashboard file, but the better approach is to use `"nodeName": "#nodeName"` in the dashboard and include the `--nodename <node_name>` argument when starting PerfTop.
|
||||
|
||||
|
||||
### Tables
|
||||
|
||||
Option | Type | Description
|
||||
:--- | :--- | :---
|
||||
`bg` | String or integer | The background color.
|
||||
`fg` | String or integer | The text color.
|
||||
`selectedFg` | String or integer | The text color for focused text.
|
||||
`selectedBg` | String or integer | The background color for focused text.
|
||||
`columnSpacing` | Integer | The amount of space (measured in characters) between columns.
|
||||
`keys` | Boolean | Has no impact at this time.
|
||||
|
||||
|
||||
### Bars
|
||||
|
||||
Option | Type | Description
|
||||
:--- | :--- | :---
|
||||
`barWidth` | Integer | The width of each bar (measured in characters) in the graph.
|
||||
`xOffset` | Integer | The amount of space (measured in characters) between the y-axis and the first bar in the graph.
|
||||
`maxHeight` | Integer | The maximum height of each bar (measured in characters) in the graph.
|
||||
|
||||
|
||||
### Lines
|
||||
|
||||
Option | Type | Description
|
||||
:--- | :--- | :---
|
||||
`showNthLabel` | Integer | Which of the `xAxis` labels to show. For example, `"showNthLabel": 2` shows every other label.
|
||||
`showLegend` | Boolean | Whether or not to display a legend for the line graph.
|
||||
`legend.width` | Integer | The width of the legend (measured in characters) in the graph.
|
||||
`xAxis` | String array | Array of labels for the x-axis. For example, `["0:00", "0:10", "0:20", "0:30", "0:40", "0:50"]`.
|
||||
`colors` | String array | Array of line colors to choose from. For example, `["magenta", "cyan"]`. If you don't provide this value, PerfTop chooses random colors for each line.
|
||||
@@ -1,103 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Performance Analyzer
|
||||
nav_order: 58
|
||||
has_children: true
|
||||
redirect_from:
|
||||
- /monitoring-plugins/pa/
|
||||
---
|
||||
|
||||
# Performance Analyzer
|
||||
|
||||
Performance Analyzer is an agent and REST API that allows you to query numerous performance metrics for your cluster, including aggregations of those metrics, independent of the Java Virtual Machine (JVM). PerfTop is the default command line interface (CLI) for displaying those metrics.
|
||||
|
||||
To download PerfTop, see [Download](https://opensearch.org/downloads.html) on the OpenSearch website.
|
||||
|
||||
You can also install it using [npm](https://www.npmjs.com/):
|
||||
|
||||
```bash
|
||||
npm install -g @aws/opensearch-perftop
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
## Get started with PerfTop
|
||||
|
||||
The basic syntax is:
|
||||
|
||||
```bash
|
||||
./opensearch-perf-top-<operating_system> --dashboard <dashboard>.json --endpoint <endpoint>
|
||||
```
|
||||
|
||||
If you're using npm, the syntax is similar:
|
||||
|
||||
```bash
|
||||
opensearch-perf-top --dashboard <dashboard> --endpoint <endpoint>
|
||||
```
|
||||
|
||||
If you're running PerfTop from a node (i.e. locally), specify port 9600:
|
||||
|
||||
```bash
|
||||
./opensearch-perf-top-linux --dashboard dashboards/<dashboard>.json --endpoint localhost:9600
|
||||
```
|
||||
|
||||
Otherwise, just specify the OpenSearch endpoint:
|
||||
|
||||
```bash
|
||||
./opensearch-perf-top-macos --dashboard dashboards/<dashboard>.json --endpoint my-cluster.my-domain.com
|
||||
```
|
||||
|
||||
PerfTop has four pre-built dashboards in the `dashboards` directory, but you can also [create your own]({{site.url}}{{site.baseurl}}/monitoring-plugins/pa/dashboards/).
|
||||
|
||||
You can also load the pre-built dashboards (ClusterOverview, ClusterNetworkMemoryAnalysis, ClusterThreadAnalysis, or NodeAnalysis) without the JSON files, such as `--dashboard ClusterThreadAnalysis`.
|
||||
|
||||
PerfTop has no interactivity. Start the application, monitor the dashboard, and press Esc, Q, or Ctrl + C to quit.
|
||||
{: .note }
|
||||
|
||||
|
||||
### Other options
|
||||
|
||||
- For NodeAnalysis and similar custom dashboards, you can add the `--nodename <node_name>` argument if you want your dashboard to display metrics for only a single node.
|
||||
- For troubleshooting, add the `--logfile <log-file>.txt` argument.
|
||||
|
||||
|
||||
## Performance Analyzer configuration
|
||||
|
||||
### Storage
|
||||
|
||||
Performance Analyzer uses `/dev/shm` for temporary storage. During heavy workloads on a cluster, Performance Analyzer can use up to 1 GB of space.
|
||||
|
||||
Docker, however, has a default `/dev/shm` size of 64 MB. To change this value, you can use the `docker run --shm-size 1gb` flag or [a similar setting in Docker Compose](https://docs.docker.com/compose/compose-file#shm_size).
|
||||
|
||||
If you're not using Docker, check the size of `/dev/shm` using `df -h`. The default value is probably plenty, but if you need to change its size, add the following line to `/etc/fstab`:
|
||||
|
||||
```bash
|
||||
tmpfs /dev/shm tmpfs defaults,noexec,nosuid,size=1G 0 0
|
||||
```
|
||||
|
||||
Then remount the file system:
|
||||
|
||||
```bash
|
||||
mount -o remount /dev/shm
|
||||
```
|
||||
|
||||
|
||||
### Security
|
||||
|
||||
Performance Analyzer supports encryption in transit for requests. It currently does *not* support client or server authentication for requests. To enable encryption in transit, edit `performance-analyzer.properties` in your `$OPENSEARCH_HOME` directory:
|
||||
|
||||
```bash
|
||||
vi $OPENSEARCH_HOME/plugins/opensearch-performance-analyzer/pa_config/performance-analyzer.properties
|
||||
```
|
||||
|
||||
Change the following lines to configure encryption in transit. Note that `certificate-file-path` must be a certificate for the server, not a root CA:
|
||||
|
||||
```
|
||||
https-enabled = true
|
||||
|
||||
#Setup the correct path for certificates
|
||||
certificate-file-path = specify_path
|
||||
|
||||
private-key-file-path = specify_path
|
||||
```
|
||||
@@ -1,63 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: API
|
||||
parent: Root Cause Analysis
|
||||
grand_parent: Performance Analyzer
|
||||
nav_order: 1
|
||||
---
|
||||
|
||||
# RCA API
|
||||
|
||||
## Sample request
|
||||
|
||||
```
|
||||
# Request all available RCAs
|
||||
GET localhost:9600/_plugins/_performanceanalyzer/rca
|
||||
|
||||
# Request a specific RCA
|
||||
GET localhost:9600/_plugins/_performanceanalyzer/rca?name=HighHeapUsageClusterRca
|
||||
```
|
||||
|
||||
|
||||
## Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"HighHeapUsageClusterRca": [{
|
||||
"rca_name": "HighHeapUsageClusterRca",
|
||||
"state": "unhealthy",
|
||||
"timestamp": 1587426650942,
|
||||
"HotClusterSummary": [{
|
||||
"number_of_nodes": 2,
|
||||
"number_of_unhealthy_nodes": 1,
|
||||
"HotNodeSummary": [{
|
||||
"host_address": "192.168.144.2",
|
||||
"node_id": "JtlEoRowSI6iNpzpjlbp_Q",
|
||||
"HotResourceSummary": [{
|
||||
"resource_type": "old gen",
|
||||
"threshold": 0.65,
|
||||
"value": 0.81827232588145373,
|
||||
"avg": NaN,
|
||||
"max": NaN,
|
||||
"min": NaN,
|
||||
"unit_type": "heap usage in percentage",
|
||||
"time_period_seconds": 600,
|
||||
"TopConsumerSummary": [{
|
||||
"name": "CACHE_FIELDDATA_SIZE",
|
||||
"value": 590702564
|
||||
},
|
||||
{
|
||||
"name": "CACHE_REQUEST_SIZE",
|
||||
"value": 28375
|
||||
},
|
||||
{
|
||||
"name": "CACHE_QUERY_SIZE",
|
||||
"value": 12687
|
||||
}
|
||||
],
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
}
|
||||
```
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Root Cause Analysis
|
||||
nav_order: 50
|
||||
parent: Performance Analyzer
|
||||
has_children: true
|
||||
---
|
||||
|
||||
# Root Cause Analysis
|
||||
|
||||
The OpenSearch Performance Analyzer plugin (PA) captures OpenSearch and JVM activity, plus their lower-level resource usage (e.g. disk, network, CPU, and memory). Based on this instrumentation, Performance Analyzer computes and exposes diagnostic metrics so that administrators can measure and understand the bottlenecks in their OpenSearch clusters.
|
||||
|
||||
The Root Cause Analysis framework (RCA) uses the information from PA to alert administrators about the root cause of performance and availability issues that their clusters might be experiencing.
|
||||
|
||||
In broad strokes, the framework helps you access data streams from OpenSearch nodes running Performance Analyzer. You write snippets of Java to choose the streams that matter to you and evaluate the streams' PA metrics against certain thresholds. As RCA runs, you can access the state of each analysis using the REST API.
|
||||
|
||||
To learn more about Root Cause Analysis, see [its repository on GitHub](https://github.com/opensearch-project/performance-analyzer-rca).
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: RCA Reference
|
||||
parent: Root Cause Analysis
|
||||
grand_parent: Performance Analyzer
|
||||
nav_order: 3
|
||||
---
|
||||
|
||||
# RCA reference
|
||||
|
||||
You can find a reference of available RCAs and their purposes on [GitHub](https://github.com/opensearch-project/performance-analyzer-rca/tree/main/docs).
|
||||
@@ -1,560 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Metrics Reference
|
||||
parent: Performance Analyzer
|
||||
nav_order: 3
|
||||
---
|
||||
|
||||
# Metrics reference
|
||||
|
||||
This page contains all Performance Analyzer metrics. All metrics support the `avg`, `sum`, `min`, and `max` aggregations, although certain metrics measure only one thing, making the choice of aggregation irrelevant.
|
||||
|
||||
For information on dimensions, see the [dimensions reference](#dimensions-reference).
|
||||
|
||||
This list is extensive. We recommend using Ctrl/Cmd + F to find what you're looking for.
|
||||
{: .tip }
|
||||
|
||||
<table>
|
||||
<thead style="text-align: left">
|
||||
<tr>
|
||||
<th>Metric</th>
|
||||
<th>Dimensions</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>CPU_Utilization
|
||||
</td>
|
||||
<td rowspan="18">ShardID, IndexName, Operation, ShardRole
|
||||
</td>
|
||||
<td>CPU usage ratio. CPU time (in milliseconds) used by the associated thread(s) in the past five seconds, divided by 5000 milliseconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Paging_MajfltRate
|
||||
</td>
|
||||
<td>The number of major faults per second in the past five seconds. A major fault requires the process to load a memory page from disk.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Paging_MinfltRate
|
||||
</td>
|
||||
<td>The number of minor faults per second in the past five seconds. A minor fault does not requires the process to load a memory page from disk.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Paging_RSS
|
||||
</td>
|
||||
<td>The number of pages the process has in real memory---the pages that count towards text, data, or stack space. This number does not include pages that have not been demand-loaded in or swapped out.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sched_Runtime
|
||||
</td>
|
||||
<td>Time (seconds) spent executing on the CPU per context switch.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sched_Waittime
|
||||
</td>
|
||||
<td>Time (seconds) spent waiting on a run queue per context switch.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sched_CtxRate
|
||||
</td>
|
||||
<td>Number of times run on the CPU per second in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Heap_AllocRate
|
||||
</td>
|
||||
<td>An approximation of the heap memory allocated, in bytes, per second in the past five seconds
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IO_ReadThroughput
|
||||
</td>
|
||||
<td>Number of bytes read per second in the last five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IO_WriteThroughput
|
||||
</td>
|
||||
<td>Number of bytes written per second in the last five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IO_TotThroughput
|
||||
</td>
|
||||
<td>Number of bytes read or written per second in the last five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IO_ReadSyscallRate
|
||||
</td>
|
||||
<td>Read system calls per second in the last five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IO_WriteSyscallRate
|
||||
</td>
|
||||
<td>Write system calls per second in the last five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IO_TotalSyscallRate
|
||||
</td>
|
||||
<td>Read and write system calls per second in the last five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Thread_Blocked_Time
|
||||
</td>
|
||||
<td>Average time (seconds) that the associated thread(s) blocked to enter or reenter a monitor.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Thread_Blocked_Event
|
||||
</td>
|
||||
<td>The total number of times that the associated thread(s) blocked to enter or reenter a monitor (i.e. the number of times a thread has been in the blocked state).
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ShardEvents
|
||||
</td>
|
||||
<td>The total number of events executed on a shard in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ShardBulkDocs
|
||||
</td>
|
||||
<td>The total number of documents indexed in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Indexing_ThrottleTime
|
||||
</td>
|
||||
<td rowspan="30">ShardID, IndexName
|
||||
</td>
|
||||
<td>Time (milliseconds) that the index has been under merge throttling control in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cache_Query_Hit
|
||||
</td>
|
||||
<td>The number of successful lookups in the query cache in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cache_Query_Miss
|
||||
</td>
|
||||
<td>The number of lookups in the query cache that failed to retrieve a `DocIdSet` in the past five seconds. `DocIdSet` is a set of document IDs in Lucene.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cache_Query_Size
|
||||
</td>
|
||||
<td>Query cache memory size in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cache_FieldData_Eviction
|
||||
</td>
|
||||
<td>The number of times OpenSearch has evicted data from the fielddata heap space (occurs when the heap space is full) in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cache_FieldData_Size
|
||||
</td>
|
||||
<td>Fielddata memory size in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cache_Request_Hit
|
||||
</td>
|
||||
<td>The number of successful lookups in the shard request cache in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cache_Request_Miss
|
||||
</td>
|
||||
<td>The number of lookups in the request cache that failed to retrieve the results of search requests in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cache_Request_Eviction
|
||||
</td>
|
||||
<td>The number of times OpenSearch evicts data from shard request cache (occurs when the request cache is full) in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cache_Request_Size
|
||||
</td>
|
||||
<td>Shard request cache memory size in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Refresh_Event
|
||||
</td>
|
||||
<td>The total number of refreshes executed in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Refresh_Time
|
||||
</td>
|
||||
<td>The total time (milliseconds) spent executing refreshes in the past five seconds
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Flush_Event
|
||||
</td>
|
||||
<td>The total number of flushes executed in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Flush_Time
|
||||
</td>
|
||||
<td>The total time (milliseconds) spent executing flushes in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Merge_Event
|
||||
</td>
|
||||
<td>The total number of merges executed in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Merge_Time
|
||||
</td>
|
||||
<td>The total time (milliseconds) spent executing merges in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Merge_CurrentEvent
|
||||
</td>
|
||||
<td>The current number of merges executing.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Indexing_Buffer
|
||||
</td>
|
||||
<td>Index buffer memory size in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Segments_Total
|
||||
</td>
|
||||
<td>The number of segments.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Segments_Memory
|
||||
</td>
|
||||
<td>Estimated memory usage of segments in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Terms_Memory
|
||||
</td>
|
||||
<td>Estimated memory usage of terms dictionaries in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>StoredFields_Memory
|
||||
</td>
|
||||
<td>Estimated memory usage of stored fields in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TermVectors_Memory
|
||||
</td>
|
||||
<td>Estimated memory usage of term vectors in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Norms_Memory
|
||||
</td>
|
||||
<td>Estimated memory usage of norms (normalization factors) in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Points_Memory
|
||||
</td>
|
||||
<td>Estimated memory usage of points in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DocValues_Memory
|
||||
</td>
|
||||
<td>Estimated memory usage of doc values in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IndexWriter_Memory
|
||||
</td>
|
||||
<td>Estimated memory usage by the index writer in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Bitset_Memory
|
||||
</td>
|
||||
<td>Estimated memory usage for the cached bit sets in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>VersionMap_Memory
|
||||
</td>
|
||||
<td>Estimated memory usage of the version map in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Shard_Size_In_Bytes
|
||||
</td>
|
||||
<td>Estimated disk usage of the shard in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Latency
|
||||
</td>
|
||||
<td>Operation, Exception, Indices, HTTPRespCode, ShardID, IndexName, ShardRole
|
||||
</td>
|
||||
<td>Latency (milliseconds) of a request.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GC_Collection_Event
|
||||
</td>
|
||||
<td rowspan="6">MemType
|
||||
</td>
|
||||
<td>The number of garbage collections that have occurred in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GC_Collection_Time
|
||||
</td>
|
||||
<td>The approximate accumulated time (milliseconds) of all garbage collections that have occurred in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Heap_Committed
|
||||
</td>
|
||||
<td>The amount of memory (bytes) that is committed for the JVM to use.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Heap_Init
|
||||
</td>
|
||||
<td>The amount of memory (bytes) that the JVM initially requests from the operating system for memory management.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Heap_Max
|
||||
</td>
|
||||
<td>The maximum amount of memory (bytes) that can be used for memory management.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Heap_Used
|
||||
</td>
|
||||
<td>The amount of used memory in bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Disk_Utilization
|
||||
</td>
|
||||
<td rowspan="3">DiskName
|
||||
</td>
|
||||
<td>Disk utilization rate: percentage of disk time spent reading and writing by the OpenSearch process in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Disk_WaitTime
|
||||
</td>
|
||||
<td>Average duration (milliseconds) of read and write operations in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Disk_ServiceRate
|
||||
</td>
|
||||
<td>Service rate: MB read or written per second in the past five seconds. This metric assumes that each disk sector stores 512 bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Net_TCP_NumFlows
|
||||
</td>
|
||||
<td rowspan="6">DestAddr
|
||||
</td>
|
||||
<td>Number of samples collected. Performance Analyzer collects one sample every five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Net_TCP_TxQ
|
||||
</td>
|
||||
<td>Average number of TCP packets in the send buffer.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Net_TCP_RxQ
|
||||
</td>
|
||||
<td>Average number of TCP packets in the receive buffer.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Net_TCP_Lost
|
||||
</td>
|
||||
<td>Average number of unrecovered recurring timeouts. This number is reset when the recovery finishes or `SND.UNA` is advanced. `SND.UNA` is the sequence number of the first byte of data that has been sent, but not yet acknowledged.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Net_TCP_SendCWND
|
||||
</td>
|
||||
<td>Average size (bytes) of the sending congestion window.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Net_TCP_SSThresh
|
||||
</td>
|
||||
<td>Average size (bytes) of the slow start size threshold.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Net_PacketRate4
|
||||
</td>
|
||||
<td rowspan="5">Direction
|
||||
</td>
|
||||
<td>The total number of IPv4 datagrams transmitted/received from/by interfaces per second, including those transmitted or received in error
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Net_PacketDropRate4
|
||||
</td>
|
||||
<td>The total number of IPv4 datagrams transmitted or received in error per second.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Net_PacketRate6
|
||||
</td>
|
||||
<td>The total number of IPv6 datagrams transmitted or received from or by interfaces per second, including those transmitted or received in error.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Net_PacketDropRate6
|
||||
</td>
|
||||
<td>The total number of IPv6 datagrams transmitted or received in error per second.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Net_Throughput
|
||||
</td>
|
||||
<td>The number of bits transmitted or received per second by all network interfaces.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ThreadPool_QueueSize
|
||||
</td>
|
||||
<td rowspan="4">ThreadPoolType
|
||||
</td>
|
||||
<td>The size of the task queue.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ThreadPool_RejectedReqs
|
||||
</td>
|
||||
<td>The number of rejected executions.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ThreadPool_TotalThreads
|
||||
</td>
|
||||
<td>The current number of threads in the pool.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ThreadPool_ActiveThreads
|
||||
</td>
|
||||
<td>The approximate number of threads that are actively executing tasks.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Master_PendingQueueSize
|
||||
</td>
|
||||
<td>N/A
|
||||
</td>
|
||||
<td>The current number of pending tasks in the cluster state update thread. Each node has a cluster state update thread that submits cluster state update tasks (create index, update mapping, allocate shard, fail shard, etc.).
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>HTTP_RequestDocs
|
||||
</td>
|
||||
<td rowspan="2">Operation, Exception, Indices, HTTPRespCode
|
||||
</td>
|
||||
<td>The number of items in the request (only for `_bulk` request type).
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>HTTP_TotalRequests
|
||||
</td>
|
||||
<td>The number of finished requests in the past five seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CB_EstimatedSize
|
||||
</td>
|
||||
<td rowspan="3">CBType
|
||||
</td>
|
||||
<td>The current number of estimated bytes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CB_TrippedEvents
|
||||
</td>
|
||||
<td>The number of times the circuit breaker has tripped.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CB_ConfiguredSize
|
||||
</td>
|
||||
<td>The limit (bytes) for how much memory operations can use.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Master_Task_Queue_Time
|
||||
</td>
|
||||
<td rowspan="2">MasterTaskInsertOrder, MasterTaskPriority, MasterTaskType, MasterTaskMetadata
|
||||
</td>
|
||||
<td>The time (milliseconds) that a master task spent in the queue.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Master_Task_Run_Time
|
||||
</td>
|
||||
<td>The time (milliseconds) that a master task has been executed.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
## Dimensions reference
|
||||
|
||||
Dimension | Return values
|
||||
:--- | :---
|
||||
ShardID | ID for the shard (e.g. `1`).
|
||||
IndexName | Name of the index (e.g. `my-index`).
|
||||
Operation | Type of operation (e.g. `shardbulk`).
|
||||
ShardRole | `primary`, `replica`
|
||||
Exception | OpenSearch exceptions (e.g. `org.opensearch.index_not_found_exception`).
|
||||
Indices | The list of indices in the request URI.
|
||||
HTTPRespCode | Response code from OpenSearch (e.g. `200`).
|
||||
MemType | `totYoungGC`, `totFullGC`, `Survivor`, `PermGen`, `OldGen`, `Eden`, `NonHeap`, `Heap`
|
||||
DiskName | Name of the disk (e.g. `sda1`).
|
||||
DestAddr | Destination address (e.g. `010015AC`).
|
||||
Direction | `in`, `out`
|
||||
ThreadPoolType | The OpenSearch thread pools (e.g. `index`, `search`,`snapshot`).
|
||||
CBType | `accounting`, `fielddata`, `in_flight_requests`, `parent`, `request`
|
||||
MasterTaskInsertOrder | The order in which the task was inserted (e.g. `3691`).
|
||||
MasterTaskPriority | Priority of the task (e.g. `URGENT`). OpenSearch executes higher priority tasks before lower priority ones, regardless of `insert_order`.
|
||||
MasterTaskType | `shard-started`, `create-index`, `delete-index`, `refresh-mapping`, `put-mapping`, `CleanupSnapshotRestoreState`, `Update snapshot state`
|
||||
MasterTaskMetadata | Metadata for the task (if any).
|
||||
@@ -1,195 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Configuration reference
|
||||
parent: Trace analytics
|
||||
nav_order: 25
|
||||
---
|
||||
|
||||
# Data Prepper configuration reference
|
||||
|
||||
This page lists all supported Data Prepper sources, buffers, preppers, and sinks, along with their associated options. For example configuration files, see [Data Prepper]({{site.url}}{{site.baseurl}}/monitoring-plugins/trace/data-prepper/).
|
||||
|
||||
|
||||
## Data Prepper server options
|
||||
|
||||
Option | Required | Description
|
||||
:--- | :--- | :---
|
||||
ssl | No | Boolean, indicating whether TLS should be used for server APIs. Defaults to true.
|
||||
keyStoreFilePath | No | String, path to a .jks or .p12 keystore file. Required if ssl is true.
|
||||
keyStorePassword | No | String, password for keystore. Optional, defaults to empty string.
|
||||
privateKeyPassword | No | String, password for private key within keystore. Optional, defaults to empty string.
|
||||
serverPort | No | Integer, port number to use for server APIs. Defaults to 4900
|
||||
|
||||
|
||||
## General pipeline options
|
||||
|
||||
Option | Required | Description
|
||||
:--- | :--- | :---
|
||||
workers | No | Integer, default 1. Essentially the number of application threads. As a starting point for your use case, try setting this value to the number of CPU cores on the machine.
|
||||
delay | No | Integer (milliseconds), default 3,000. How long workers wait between buffer read attempts.
|
||||
|
||||
|
||||
## Sources
|
||||
|
||||
Sources define where your data comes from.
|
||||
|
||||
|
||||
### otel_trace_source
|
||||
|
||||
Source for the OpenTelemetry Collector.
|
||||
|
||||
Option | Required | Description
|
||||
:--- | :--- | :---
|
||||
port | No | Integer, the port OTel trace source is running on. Default is `21890`.
|
||||
request_timeout | No | Integer, the request timeout in millis. Default is `10_000`.
|
||||
health_check_service | No | Boolean, enables a gRPC health check service under `grpc.health.v1/Health/Check`. Default is `false`.
|
||||
proto_reflection_service | No | Boolean, enables a reflection service for Protobuf services (see [gRPC reflection](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md) and [gRPC Server Reflection Tutorial](https://github.com/grpc/grpc-java/blob/master/documentation/server-reflection-tutorial.md) docs). Default is `false`.
|
||||
unframed_requests | No | Boolean, enable requests not framed using the gRPC wire protocol.
|
||||
thread_count | No | Integer, the number of threads to keep in the ScheduledThreadPool. Default is `200`.
|
||||
max_connection_count | No | Integer, the maximum allowed number of open connections. Default is `500`.
|
||||
ssl | No | Boolean, enables connections to the OTel source port over TLS/SSL. Defaults to `true`.
|
||||
sslKeyCertChainFile | Conditionally | String, file-system path or AWS S3 path to the security certificate (e.g. `"config/demo-data-prepper.crt"` or `"s3://my-secrets-bucket/demo-data-prepper.crt"`). Required if ssl is set to `true`.
|
||||
sslKeyFile | Conditionally | String, file-system path or AWS S3 path to the security key (e.g. `"config/demo-data-prepper.key"` or `"s3://my-secrets-bucket/demo-data-prepper.key"`). Required if ssl is set to `true`.
|
||||
useAcmCertForSSL | No | Boolean, enables TLS/SSL using certificate and private key from AWS Certificate Manager (ACM). Default is `false`.
|
||||
acmCertificateArn | Conditionally | String, represents the ACM certificate ARN. ACM certificate take preference over S3 or local file system certificate. Required if `useAcmCertForSSL` is set to `true`.
|
||||
awsRegion | Conditionally | String, represents the AWS region to use ACM or S3. Required if `useAcmCertForSSL` is set to `true` or `sslKeyCertChainFile` and `sslKeyFile` are AWS S3 paths.
|
||||
|
||||
|
||||
### file
|
||||
|
||||
Source for flat file input.
|
||||
|
||||
Option | Required | Description
|
||||
:--- | :--- | :---
|
||||
path | Yes | String, path to the input file (e.g. `logs/my-log.log`).
|
||||
|
||||
|
||||
### pipeline
|
||||
|
||||
Source for reading from another pipeline.
|
||||
|
||||
Option | Required | Description
|
||||
:--- | :--- | :---
|
||||
name | Yes | String, name of the pipeline to read from.
|
||||
|
||||
|
||||
### stdin
|
||||
|
||||
Source for console input. Can be useful for testing. No options.
|
||||
|
||||
|
||||
## Buffers
|
||||
|
||||
Buffers store data as it passes through the pipeline. If you implement a custom buffer, it can be memory-based (better performance) or disk-based (larger).
|
||||
|
||||
|
||||
### bounded_blocking
|
||||
|
||||
The default buffer. Memory-based.
|
||||
|
||||
Option | Required | Description
|
||||
:--- | :--- | :---
|
||||
buffer_size | No | Integer, default 512. The maximum number of records the buffer accepts.
|
||||
batch_size | No | Integer, default 8. The maximum number of records the buffer drains after each read.
|
||||
|
||||
|
||||
## Preppers
|
||||
|
||||
Preppers perform some action on your data: filter, transform, enrich, etc.
|
||||
|
||||
|
||||
### otel_trace_raw_prepper
|
||||
|
||||
Converts OpenTelemetry data to OpenSearch-compatible JSON documents.
|
||||
|
||||
Option | Required | Description
|
||||
:--- | :--- | :---
|
||||
root_span_flush_delay | No | Integer, representing the time interval in seconds to flush all the root spans in the prepper together with their descendants. Defaults to 30.
|
||||
trace_flush_interval | No | Integer, representing the time interval in seconds to flush all the descendant spans without any root span. Defaults to 180.
|
||||
|
||||
|
||||
### service_map_stateful
|
||||
|
||||
Uses OpenTelemetry data to create a distributed service map for visualization in OpenSearch Dashboards.
|
||||
|
||||
Option | Required | Description
|
||||
:--- | :--- | :---
|
||||
window_duration | No | Integer, representing the fixed time window in seconds to evaluate service-map relationships. Defaults to 180.
|
||||
|
||||
### peer_forwarder
|
||||
|
||||
Forwards ExportTraceServiceRequests via gRPC to other Data Prepper instances. Required for operating Data Prepper in a clustered deployment.
|
||||
|
||||
Option | Required | Description
|
||||
:--- | :--- | :---
|
||||
time_out | No | Integer, forwarded request timeout in seconds. Defaults to 3 seconds.
|
||||
span_agg_count | No | Integer, batch size for number of spans per request. Defaults to 48.
|
||||
target_port | No | Integer, the destination port to forward requests to. Defaults to `21890`.
|
||||
discovery_mode | No | String, peer discovery mode to be used. Allowable values are `static`, `dns`, and `aws_cloud_map`. Defaults to `static`.
|
||||
static_endpoints | No | List, containing string endpoints of all Data Prepper instances.
|
||||
domain_name | No | String, single domain name to query DNS against. Typically used by creating multiple DNS A Records for the same domain.
|
||||
ssl | No | Boolean, indicating whether TLS should be used. Default is true.
|
||||
awsCloudMapNamespaceName | Conditionally | String, name of your CloudMap Namespace. Required if `discovery_mode` is set to `aws_cloud_map`.
|
||||
awsCloudMapServiceName | Conditionally | String, service name within your CloudMap Namespace. Required if `discovery_mode` is set to `aws_cloud_map`.
|
||||
sslKeyCertChainFile | Conditionally | String, represents the SSL certificate chain file path or AWS S3 path. S3 path example `s3://<bucketName>/<path>`. Required if `ssl` is set to `true`.
|
||||
useAcmCertForSSL | No | Boolean, enables TLS/SSL using certificate and private key from AWS Certificate Manager (ACM). Default is `false`.
|
||||
awsRegion | Conditionally | String, represents the AWS region to use ACM, S3, or CloudMap. Required if `useAcmCertForSSL` is set to `true` or `sslKeyCertChainFile` and `sslKeyFile` are AWS S3 paths.
|
||||
acmCertificateArn | Conditionally | String represents the ACM certificate ARN. ACM certificate take preference over S3 or local file system certificate. Required if `useAcmCertForSSL` is set to `true`.
|
||||
|
||||
### string_converter
|
||||
|
||||
Converts strings to uppercase or lowercase. Mostly useful as an example if you want to develop your own prepper.
|
||||
|
||||
Option | Required | Description
|
||||
:--- | :--- | :---
|
||||
upper_case | No | Boolean, whether to convert to uppercase (`true`) or lowercase (`false`).
|
||||
|
||||
|
||||
## Sinks
|
||||
|
||||
Sinks define where Data Prepper writes your data to.
|
||||
|
||||
|
||||
### opensearch
|
||||
|
||||
Sink for an OpenSearch cluster.
|
||||
|
||||
Option | Required | Description
|
||||
:--- | :--- | :---
|
||||
hosts | Yes | List of OpenSearch hosts to write to (e.g. `["https://localhost:9200", "https://remote-cluster:9200"]`).
|
||||
cert | No | String, path to the security certificate (e.g. `"config/root-ca.pem"`) if the cluster uses the OpenSearch security plugin.
|
||||
username | No | String, username for HTTP basic authentication.
|
||||
password | No | String, password for HTTP basic authentication.
|
||||
aws_sigv4 | No | Boolean, whether to use IAM signing to connect to an Amazon OpenSearch Service domain. For your access key, secret key, and optional session token, Data Prepper uses the default credential chain (environment variables, Java system properties, `~/.aws/credential`, etc.).
|
||||
aws_region | No | String, AWS region (e.g. `"us-east-1"`) for the domain if you are connecting to Amazon OpenSearch Service.
|
||||
aws_sts_role | No | String, IAM role which the sink plugin will assume to sign request to Amazon OpenSearch Service. If not provided the plugin will use the default credentials.
|
||||
trace_analytics_raw | No | Boolean, default false. Whether to export as trace data to the `otel-v1-apm-span-*` index pattern (alias `otel-v1-apm-span`) for use with the Trace Analytics OpenSearch Dashboards plugin.
|
||||
trace_analytics_service_map | No | Boolean, default false. Whether to export as trace data to the `otel-v1-apm-service-map` index for use with the service map component of the Trace Analytics OpenSearch Dashboards plugin.
|
||||
index | No | String, name of the index to export to. Only required if you don't use the `trace_analytics_raw` or `trace_analytics_service_map` presets.
|
||||
template_file | No | String, the path to a JSON [index template]({{site.url}}{{site.baseurl}}/opensearch/index-templates/) file (e.g. `/your/local/template-file.json` if you do not use the `trace_analytics_raw` or `trace_analytics_service_map`. See [otel-v1-apm-span-index-template.json](https://github.com/opensearch-project/data-prepper/blob/main/data-prepper-plugins/opensearch/src/main/resources/otel-v1-apm-span-index-template.json) for an example.
|
||||
document_id_field | No | String, the field from the source data to use for the OpenSearch document ID (e.g. `"my-field"`) if you don't use the `trace_analytics_raw` or `trace_analytics_service_map` presets.
|
||||
dlq_file | No | String, the path to your preferred dead letter queue file (e.g. `/your/local/dlq-file`). Data Prepper writes to this file when it fails to index a document on the OpenSearch cluster.
|
||||
bulk_size | No | Integer (long), default 5. The maximum size (in MiB) of bulk requests to the OpenSearch cluster. Values below 0 indicate an unlimited size. If a single document exceeds the maximum bulk request size, Data Prepper sends it individually.
|
||||
|
||||
|
||||
### file
|
||||
|
||||
Sink for flat file output.
|
||||
|
||||
Option | Required | Description
|
||||
:--- | :--- | :---
|
||||
path | Yes | String, path for the output file (e.g. `logs/my-transformed-log.log`).
|
||||
|
||||
|
||||
### pipeline
|
||||
|
||||
Sink for writing to another pipeline.
|
||||
|
||||
Option | Required | Description
|
||||
:--- | :--- | :---
|
||||
name | Yes | String, name of the pipeline to write to.
|
||||
|
||||
|
||||
### stdout
|
||||
|
||||
Sink for console output. Can be useful for testing. No options.
|
||||
@@ -1,135 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Data Prepper
|
||||
parent: Trace analytics
|
||||
nav_order: 20
|
||||
---
|
||||
|
||||
# Data Prepper
|
||||
|
||||
Data Prepper is an independent component, not an OpenSearch plugin, that converts data for use with OpenSearch. It's not bundled with the all-in-one OpenSearch installation packages.
|
||||
|
||||
|
||||
## Install Data Prepper
|
||||
|
||||
To use the Docker image, pull it like any other image:
|
||||
|
||||
```bash
|
||||
docker pull opensearchproject/data-prepper:latest
|
||||
```
|
||||
|
||||
Otherwise, [download](https://opensearch.org/downloads.html) the appropriate archive for your operating system and unzip it.
|
||||
|
||||
|
||||
## Configure pipelines
|
||||
|
||||
To use Data Prepper, you define pipelines in a configuration YAML file. Each pipeline is a combination of a source, a buffer, zero or more preppers, and one or more sinks:
|
||||
|
||||
```yml
|
||||
sample-pipeline:
|
||||
workers: 4 # the number of workers
|
||||
delay: 100 # in milliseconds, how long workers wait between read attempts
|
||||
source:
|
||||
otel_trace_source:
|
||||
ssl: true
|
||||
sslKeyCertChainFile: "config/demo-data-prepper.crt"
|
||||
sslKeyFile: "config/demo-data-prepper.key"
|
||||
buffer:
|
||||
bounded_blocking:
|
||||
buffer_size: 1024 # max number of records the buffer accepts
|
||||
batch_size: 256 # max number of records the buffer drains after each read
|
||||
prepper:
|
||||
- otel_trace_raw_prepper:
|
||||
sink:
|
||||
- opensearch:
|
||||
hosts: ["https:localhost:9200"]
|
||||
cert: "config/root-ca.pem"
|
||||
username: "ta-user"
|
||||
password: "ta-password"
|
||||
trace_analytics_raw: true
|
||||
```
|
||||
|
||||
- Sources define where your data comes from. In this case, the source is the OpenTelemetry Collector (`otel_trace_source`) with some optional SSL settings.
|
||||
|
||||
- Buffers store data as it passes through the pipeline.
|
||||
|
||||
By default, Data Prepper uses its one and only buffer, the `bounded_blocking` buffer, so you can omit this section unless you developed a custom buffer or need to tune the buffer settings.
|
||||
|
||||
- Preppers perform some action on your data: filter, transform, enrich, etc.
|
||||
|
||||
You can have multiple preppers, which run sequentially from top to bottom, not in parallel. The `otel_trace_raw_prepper` prepper converts OpenTelemetry data into OpenSearch-compatible JSON documents.
|
||||
|
||||
- Sinks define where your data goes. In this case, the sink is an OpenSearch cluster.
|
||||
|
||||
Pipelines can act as the source for other pipelines. In the following example, a pipeline takes data from the OpenTelemetry Collector and uses two other pipelines as sinks:
|
||||
|
||||
```yml
|
||||
entry-pipeline:
|
||||
delay: "100"
|
||||
source:
|
||||
otel_trace_source:
|
||||
ssl: true
|
||||
sslKeyCertChainFile: "config/demo-data-prepper.crt"
|
||||
sslKeyFile: "config/demo-data-prepper.key"
|
||||
sink:
|
||||
- pipeline:
|
||||
name: "raw-pipeline"
|
||||
- pipeline:
|
||||
name: "service-map-pipeline"
|
||||
raw-pipeline:
|
||||
source:
|
||||
pipeline:
|
||||
name: "entry-pipeline"
|
||||
prepper:
|
||||
- otel_trace_raw_prepper:
|
||||
sink:
|
||||
- opensearch:
|
||||
hosts: ["https://localhost:9200" ]
|
||||
cert: "config/root-ca.pem"
|
||||
username: "ta-user"
|
||||
password: "ta-password"
|
||||
trace_analytics_raw: true
|
||||
service-map-pipeline:
|
||||
delay: "100"
|
||||
source:
|
||||
pipeline:
|
||||
name: "entry-pipeline"
|
||||
prepper:
|
||||
- service_map_stateful:
|
||||
sink:
|
||||
- opensearch:
|
||||
hosts: ["https://localhost:9200"]
|
||||
cert: "config/root-ca.pem"
|
||||
username: "ta-user"
|
||||
password: "ta-password"
|
||||
trace_analytics_service_map: true
|
||||
```
|
||||
|
||||
To learn more, see the [Data Prepper configuration reference]({{site.url}}{{site.baseurl}}/monitoring-plugins/trace/data-prepper-reference/).
|
||||
|
||||
## Configure the Data Prepper server
|
||||
Data Prepper itself provides administrative HTTP endpoints such as `/list` to list pipelines and `/metrics/prometheus` to provide Prometheus-compatible metrics data. The port which serves these endpoints, as well as TLS configuration, is specified by a separate YAML file. Example:
|
||||
|
||||
```yml
|
||||
ssl: true
|
||||
keyStoreFilePath: "/usr/share/data-prepper/keystore.jks"
|
||||
keyStorePassword: "password"
|
||||
privateKeyPassword: "other_password"
|
||||
serverPort: 1234
|
||||
```
|
||||
|
||||
## Start Data Prepper
|
||||
|
||||
**Docker**
|
||||
|
||||
```bash
|
||||
docker run --name data-prepper --expose 21890 -v /full/path/to/pipelines.yaml:/usr/share/data-prepper/pipelines.yaml -v /full/path/to/data-prepper-config.yaml:/usr/share/data-prepper/data-prepper-config.yaml opensearchproject/opensearch-data-prepper:latest
|
||||
```
|
||||
|
||||
**macOS and Linux**
|
||||
|
||||
```bash
|
||||
./data-prepper-tar-install.sh config/pipelines.yaml config/data-prepper-config.yaml
|
||||
```
|
||||
|
||||
For production workloads, you likely want to run Data Prepper on a dedicated machine, which makes connectivity a concern. Data Prepper uses port 21890 and must be able to connect to both the OpenTelemetry Collector and the OpenSearch cluster. In the [sample applications](https://github.com/opensearch-project/Data-Prepper/tree/main/examples), you can see that all components use the same Docker network and expose the appropriate ports.
|
||||
@@ -1,83 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Get Started
|
||||
parent: Trace analytics
|
||||
nav_order: 1
|
||||
---
|
||||
|
||||
# Get started with Trace Analytics
|
||||
|
||||
OpenSearch Trace Analytics consists of two components---Data Prepper and the Trace Analytics OpenSearch Dashboards plugin---that fit into the OpenTelemetry and OpenSearch ecosystems. The Data Prepper repository has several [sample applications](https://github.com/opensearch-project/data-prepper/tree/main/examples) to help you get started.
|
||||
|
||||
|
||||
## Basic flow of data
|
||||
|
||||

|
||||
|
||||
1. Trace Analytics relies on you adding instrumentation to your application and generating trace data. The [OpenTelemetry documentation](https://opentelemetry.io/docs/) contains example applications for many programming languages that can help you get started, including Java, Python, Go, and JavaScript.
|
||||
|
||||
(In the [Jaeger HotROD](#jaeger-hotrod) example below, an extra component, the Jaeger agent, runs alongside the application and sends the data to the OpenTelemetry Collector, but the concept is similar.)
|
||||
|
||||
1. The [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/getting-started/) receives data from the application and formats it into OpenTelemetry data.
|
||||
|
||||
1. [Data Prepper]({{site.url}}{{site.baseurl}}/monitoring-plugins/trace/data-prepper/) processes the OpenTelemetry data, transforms it for use in OpenSearch, and indexes it on an OpenSearch cluster.
|
||||
|
||||
1. The [Trace Analytics OpenSearch Dashboards plugin]({{site.url}}{{site.baseurl}}/monitoring-plugins/trace/ta-dashboards/) displays the data in near real-time as a series of charts and tables, with an emphasis on service architecture, latency, error rate, and throughput.
|
||||
|
||||
|
||||
## Jaeger HotROD
|
||||
|
||||
One Trace Analytics sample application is the Jaeger HotROD demo, which mimics the flow of data through a distributed application.
|
||||
|
||||
Download or clone the [Data Prepper repository](https://github.com/opensearch-project/data-prepper). Then navigate to `examples/jaeger-hotrod/` and open `docker-compose.yml` in a text editor. This file contains a container for each element from [Basic flow of data](#basic-flow-of-data):
|
||||
|
||||
- A distributed application (`jaeger-hot-rod`) with the Jaeger agent (`jaeger-agent`)
|
||||
- The [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/getting-started/) (`otel-collector`)
|
||||
- Data Prepper (`data-prepper`)
|
||||
- A single-node OpenSearch cluster (`opensearch`)
|
||||
- OpenSearch Dashboards (`opensearch-dashboards`).
|
||||
|
||||
Close the file and run `docker-compose up --build`. After the containers start, navigate to `http://localhost:8080` in a web browser.
|
||||
|
||||

|
||||
|
||||
Click one of the buttons in the web interface to send a request to the application. Each request starts a series of operations across the services that make up the application. From the console logs, you can see that these operations share the same `trace-id`, which lets you track all of the operations in the request as a single *trace*:
|
||||
|
||||
```
|
||||
jaeger-hot-rod | http://0.0.0.0:8081/customer?customer=392
|
||||
jaeger-hot-rod | 2020-11-19T16:29:53.425Z INFO frontend/server.go:92 HTTP request received {"service": "frontend", "trace_id": "12091bd60f45ea2c", "span_id": "12091bd60f45ea2c", "method": "GET", "url": "/dispatch?customer=392&nonse=0.6509021735471818"}
|
||||
jaeger-hot-rod | 2020-11-19T16:29:53.426Z INFO customer/client.go:54 Getting customer{"service": "frontend", "component": "customer_client", "trace_id": "12091bd60f45ea2c", "span_id": "12091bd60f45ea2c", "customer_id": "392"}
|
||||
jaeger-hot-rod | 2020-11-19T16:29:53.430Z INFO customer/server.go:67 HTTP request received {"service": "customer", "trace_id": "12091bd60f45ea2c", "span_id": "252ff7d0e1ac533b", "method": "GET", "url": "/customer?customer=392"}
|
||||
jaeger-hot-rod | 2020-11-19T16:29:53.430Z INFO customer/database.go:73 Loading customer{"service": "customer", "component": "mysql", "trace_id": "12091bd60f45ea2c", "span_id": "252ff7d0e1ac533b", "customer_id": "392"}
|
||||
```
|
||||
|
||||
These operations also have a `span_id`. *Spans* are units of work from a single service. Each trace contains some number of spans. Shortly after the application starts processing the request, you can see the OpenTelemetry Collector starts exporting the spans:
|
||||
|
||||
```
|
||||
otel-collector | 2020-11-19T16:29:53.781Z INFO loggingexporter/logging_exporter.go:296 TraceExporter {"#spans": 1}
|
||||
otel-collector | 2020-11-19T16:29:53.787Z INFO loggingexporter/logging_exporter.go:296 TraceExporter {"#spans": 3}
|
||||
```
|
||||
|
||||
Then Data Prepper processes the data from the OpenTelemetry Collector and indexes it:
|
||||
|
||||
```
|
||||
data-prepper | 1031918 [service-map-pipeline-process-worker-2-thread-1] INFO com.amazon.dataprepper.pipeline.ProcessWorker – service-map-pipeline Worker: Processing 3 records from buffer
|
||||
data-prepper | 1031923 [entry-pipeline-process-worker-1-thread-1] INFO com.amazon.dataprepper.pipeline.ProcessWorker – entry-pipeline Worker: Processing 1 records from buffer
|
||||
```
|
||||
|
||||
Finally, you can see the OpenSearch node responding to the indexing request.
|
||||
|
||||
```
|
||||
node-0.example.com | [2020-11-19T16:29:55,064][INFO ][o.e.c.m.MetadataMappingService] [9fb4fb37a516] [otel-v1-apm-span-000001/NGYbmVD9RmmqnxjfTzBQsQ] update_mapping [_doc]
|
||||
node-0.example.com | [2020-11-19T16:29:55,267][INFO ][o.e.c.m.MetadataMappingService] [9fb4fb37a516] [otel-v1-apm-span-000001/NGYbmVD9RmmqnxjfTzBQsQ] update_mapping [_doc]
|
||||
```
|
||||
|
||||
In a new terminal window, run the following command to see one of the raw documents in the OpenSearch cluster:
|
||||
|
||||
```bash
|
||||
curl -X GET -u 'admin:admin' -k 'https://localhost:9200/otel-v1-apm-span-000001/_search?pretty&size=1'
|
||||
```
|
||||
|
||||
Navigate to `http://localhost:5601` in a web browser and choose **Trace Analytics**. You can see the results of your single click in the Jaeger HotROD web interface: the number of traces per API and HTTP method, latency trends, a color-coded map of the service architecture, and a list of trace IDs that you can use to drill down on individual operations.
|
||||
|
||||
If you don't see your trace, adjust the timeframe in OpenSearch Dashboards. For more information on using the plugin, see [OpenSearch Dashboards plugin]({{site.url}}{{site.baseurl}}/monitoring-plugins/trace/ta-dashboards/).
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Trace analytics
|
||||
nav_order: 48
|
||||
has_children: true
|
||||
has_toc: false
|
||||
redirect_from:
|
||||
- /monitoring-plugins/trace/
|
||||
---
|
||||
|
||||
# Trace Analytics
|
||||
|
||||
Trace Analytics provides a way to ingest and visualize [OpenTelemetry](https://opentelemetry.io/) data in OpenSearch. This data can help you find and fix performance problems in distributed applications.
|
||||
|
||||
A single operation, such as a user clicking a button, can trigger an extended series of events. The front end might call a back end service, which calls another service, which queries a database, processes the data, and sends it to the original service, which sends a confirmation to the front end.
|
||||
|
||||
Trace Analytics can help you visualize this flow of events and identify performance problems.
|
||||
|
||||

|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: OpenSearch Dashboards plugin
|
||||
parent: Trace analytics
|
||||
nav_order: 50
|
||||
---
|
||||
|
||||
# Trace Analytics OpenSearch Dashboards plugin
|
||||
|
||||
The Trace Analytics plugin for OpenSearch Dashboards provides at-a-glance visibility into your application performance, along with the ability to drill down on individual traces. For installation instructions, see [Standalone OpenSearch Dashboards plugin install]({{site.url}}{{site.baseurl}}/dashboards/install/plugins/).
|
||||
|
||||
The **Dashboard** view groups traces together by HTTP method and path so that you can see the average latency, error rate, and trends associated with a particular operation. For a more focused view, try filtering by trace group name.
|
||||
|
||||

|
||||
|
||||
To drill down on the traces that make up a trace group, choose the number of traces in righthand column. Then choose an individual trace for a detailed summary.
|
||||
|
||||

|
||||
|
||||
The **Services** view lists all services in the application, plus an interactive map that shows how the various services connect to each other. In contrast to the dashboard, which helps identify problems by operation, the service map helps identify problems by service. Try sorting by error rate or latency to get a sense of potential problem areas of your application.
|
||||
|
||||

|
||||
@@ -1,158 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Aggregations
|
||||
nav_order: 14
|
||||
has_children: true
|
||||
---
|
||||
|
||||
# Aggregations
|
||||
|
||||
OpenSearch isn’t just for search. Aggregations let you tap into OpenSearch's powerful analytics engine to analyze your data and extract statistics from it.
|
||||
|
||||
The use cases of aggregations vary from analyzing data in real time to take some action to using OpenSearch Dashboards to create a visualization dashboard.
|
||||
|
||||
OpenSearch can perform aggregations on massive datasets in milliseconds. Compared to queries, aggregations consume more CPU cycles and memory.
|
||||
|
||||
## Aggregations on text fields
|
||||
|
||||
By default, OpenSearch doesn't support aggregations on a text field. Because text fields are tokenized, an aggregation on a text field has to reverse the tokenization process back to its original string and then formulate an aggregation based on that. This kind of an operation consumes significant memory and degrades cluster performance.
|
||||
|
||||
While you can enable aggregations on text fields by setting the `fielddata` parameter to `true` in the mapping, the aggregations are still based on the tokenized words and not on the raw text.
|
||||
|
||||
We recommend keeping a raw version of the text field as a `keyword` field that you can aggregate on.
|
||||
|
||||
In this case, you can perform aggregations on the `title.raw` field, instead of on the `title` field:
|
||||
|
||||
```json
|
||||
PUT movies
|
||||
{
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "text",
|
||||
"fielddata": true,
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## General aggregation structure
|
||||
|
||||
The structure of an aggregation query is as follows:
|
||||
|
||||
```json
|
||||
GET _search
|
||||
{
|
||||
"size": 0,
|
||||
"aggs": {
|
||||
"NAME": {
|
||||
"AGG_TYPE": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you’re only interested in the aggregation result and not in the results of the query, set `size` to 0.
|
||||
|
||||
In the `aggs` property (you can use `aggregations` if you want), you can define any number of aggregations. Each aggregation is defined by its name and one of the types of aggregations that OpenSearch supports.
|
||||
|
||||
The name of the aggregation helps you to distinguish between different aggregations in the response. The `AGG_TYPE` property is where you specify the type of aggregation.
|
||||
|
||||
## Sample aggregation
|
||||
|
||||
This section uses the OpenSearch Dashboards sample ecommerce data and web log data. To add the sample data, log in to OpenSearch Dashboards, choose **Home**, and then choose **Try our sample data**. For **Sample eCommerce orders** and **Sample web logs**, choose **Add data**.
|
||||
|
||||
### avg
|
||||
|
||||
To find the average value of the `taxful_total_price` field:
|
||||
|
||||
```json
|
||||
GET opensearch_dashboards_sample_data_ecommerce/_search
|
||||
{
|
||||
"size": 0,
|
||||
"aggs": {
|
||||
"avg_taxful_total_price": {
|
||||
"avg": {
|
||||
"field": "taxful_total_price"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"took" : 1,
|
||||
"timed_out" : false,
|
||||
"_shards" : {
|
||||
"total" : 1,
|
||||
"successful" : 1,
|
||||
"skipped" : 0,
|
||||
"failed" : 0
|
||||
},
|
||||
"hits" : {
|
||||
"total" : {
|
||||
"value" : 4675,
|
||||
"relation" : "eq"
|
||||
},
|
||||
"max_score" : null,
|
||||
"hits" : [ ]
|
||||
},
|
||||
"aggregations" : {
|
||||
"avg_taxful_total_price" : {
|
||||
"value" : 75.05542864304813
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The aggregation block in the response shows the average value for the `taxful_total_price` field.
|
||||
|
||||
## Types of aggregations
|
||||
|
||||
There are three main types of aggregations:
|
||||
|
||||
- Metric aggregations - Calculate metrics such as `sum`, `min`, `max`, and `avg` on numeric fields.
|
||||
- Bucket aggregations - Sort query results into groups based on some criteria.
|
||||
- Pipeline aggregations - Pipe the output of one aggregation as an input to another.
|
||||
|
||||
## Nested aggregations
|
||||
|
||||
Aggregations within aggregations are called nested or subaggregations.
|
||||
|
||||
Metric aggregations produce simple results and can't contain nested aggregations.
|
||||
|
||||
Bucket aggregations produce buckets of documents that you can nest in other aggregations. You can perform complex analysis on your data by nesting metric and bucket aggregations within bucket aggregations.
|
||||
|
||||
### General nested aggregation syntax
|
||||
|
||||
```json
|
||||
{
|
||||
"aggs": {
|
||||
"name": {
|
||||
"type": {
|
||||
"data"
|
||||
},
|
||||
"aggs": {
|
||||
"nested": {
|
||||
"type": {
|
||||
"data"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The inner `aggs` keyword begins a new nested aggregation. The syntax of the parent aggregation and the nested aggregation is the same. Nested aggregations run in the context of the preceding parent aggregations.
|
||||
|
||||
You can also pair your aggregations with search queries to narrow down things you’re trying to analyze before aggregating. If you don't add a query, OpenSearch implicitly uses the `match_all` query.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,332 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Cluster formation
|
||||
nav_order: 7
|
||||
---
|
||||
|
||||
# Cluster formation
|
||||
|
||||
Before diving into OpenSearch and searching and aggregating data, you first need to create an OpenSearch cluster.
|
||||
|
||||
OpenSearch can operate as a single-node or multi-node cluster. The steps to configure both are, in general, quite similar. This page demonstrates how to create and configure a multi-node cluster, but with only a few minor adjustments, you can follow the same steps to create a single-node cluster.
|
||||
|
||||
To create and deploy an OpenSearch cluster according to your requirements, it’s important to understand how node discovery and cluster formation work and what settings govern them.
|
||||
|
||||
There are many ways to design a cluster. The following illustration shows a basic architecture:
|
||||
|
||||

|
||||
|
||||
This is a four-node cluster that has one dedicated master node, one dedicated coordinating node, and two data nodes that are master-eligible and also used for ingesting data.
|
||||
|
||||
The following table provides brief descriptions of the node types:
|
||||
|
||||
Node type | Description | Best practices for production
|
||||
:--- | :--- | :-- |
|
||||
`Master` | Manages the overall operation of a cluster and keeps track of the cluster state. This includes creating and deleting indices, keeping track of the nodes that join and leave the cluster, checking the health of each node in the cluster (by running ping requests), and allocating shards to nodes. | Three dedicated master nodes in three different zones is the right approach for almost all production use cases. This configuration ensures your cluster never loses quorum. Two nodes will be idle for most of the time except when one node goes down or needs some maintenance.
|
||||
`Master-eligible` | Elects one node among them as the master node through a voting process. | For production clusters, make sure you have dedicated master nodes. The way to achieve a dedicated node type is to mark all other node types as false. In this case, you have to mark all the other nodes as not master-eligible.
|
||||
`Data` | Stores and searches data. Performs all data-related operations (indexing, searching, aggregating) on local shards. These are the worker nodes of your cluster and need more disk space than any other node type. | As you add data nodes, keep them balanced between zones. For example, if you have three zones, add data nodes in multiples of three, one for each zone. We recommend using storage and RAM-heavy nodes.
|
||||
`Ingest` | Preprocesses data before storing it in the cluster. Runs an ingest pipeline that transforms your data before adding it to an index. | If you plan to ingest a lot of data and run complex ingest pipelines, we recommend you use dedicated ingest nodes. You can also optionally offload your indexing from the data nodes so that your data nodes are used exclusively for searching and aggregating.
|
||||
`Coordinating` | Delegates client requests to the shards on the data nodes, collects and aggregates the results into one final result, and sends this result back to the client. | A couple of dedicated coordinating-only nodes is appropriate to prevent bottlenecks for search-heavy workloads. We recommend using CPUs with as many cores as you can.
|
||||
|
||||
By default, each node is a master-eligible, data, ingest, and coordinating node. Deciding on the number of nodes, assigning node types, and choosing the hardware for each node type depends on your use case. You must take into account factors like the amount of time you want to hold on to your data, the average size of your documents, your typical workload (indexing, searches, aggregations), your expected price-performance ratio, your risk tolerance, and so on.
|
||||
|
||||
After you assess all these requirements, we recommend you use a benchmark testing tool like Rally to provision a small sample cluster and run tests with varying workloads and configurations. Compare and analyze the system and query metrics for these tests to design an optimum architecture. To get started with Rally, see the [Rally documentation](https://esrally.readthedocs.io/en/stable/).
|
||||
|
||||
This page demonstrates how to work with the different node types. It assumes that you have a four-node cluster similar to the preceding illustration.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you get started, you must install and configure OpenSearch on all of your nodes. For information about the available options, see [Install and configure OpenSearch]({{site.url}}{{site.baseurl}}/opensearch/install/).
|
||||
|
||||
After you're done, use SSH to connect to each node, then open the `config/opensearch.yml` file. You can set all configurations for your cluster in this file.
|
||||
|
||||
## Step 1: Name a cluster
|
||||
|
||||
Specify a unique name for the cluster. If you don't specify a cluster name, it's set to `opensearch` by default. Setting a descriptive cluster name is important, especially if you want to run multiple clusters inside a single network.
|
||||
|
||||
To specify the cluster name, change the following line:
|
||||
|
||||
```yml
|
||||
#cluster.name: my-application
|
||||
```
|
||||
|
||||
to
|
||||
|
||||
```yml
|
||||
cluster.name: opensearch-cluster
|
||||
```
|
||||
|
||||
Make the same change on all the nodes to make sure that they'll join to form a cluster.
|
||||
|
||||
|
||||
## Step 2: Set node attributes for each node in a cluster
|
||||
|
||||
After you name the cluster, set node attributes for each node in your cluster.
|
||||
|
||||
|
||||
#### Master node
|
||||
|
||||
Give your master node a name. If you don't specify a name, OpenSearch assigns a machine-generated name that makes the node difficult to monitor and troubleshoot.
|
||||
|
||||
```yml
|
||||
node.name: opensearch-master
|
||||
```
|
||||
|
||||
You can also explicitly specify that this node is a master node. This is already true by default, but adding it makes it easier to identify the master node:
|
||||
|
||||
```yml
|
||||
node.master: true
|
||||
```
|
||||
|
||||
Then make the node a dedicated master that won’t perform double-duty as a data node:
|
||||
|
||||
```yml
|
||||
node.data: false
|
||||
```
|
||||
|
||||
Specify that this node will not be used for ingesting data:
|
||||
|
||||
```yml
|
||||
node.ingest: false
|
||||
```
|
||||
|
||||
#### Data nodes
|
||||
|
||||
Change the name of two nodes to `opensearch-d1` and `opensearch-d2`, respectively:
|
||||
|
||||
```yml
|
||||
node.name: opensearch-d1
|
||||
```
|
||||
```yml
|
||||
node.name: opensearch-d2
|
||||
```
|
||||
|
||||
You can make them master-eligible data nodes that will also be used for ingesting data:
|
||||
|
||||
```yml
|
||||
node.master: true
|
||||
node.data: true
|
||||
node.ingest: true
|
||||
```
|
||||
|
||||
You can also specify any other attributes that you'd like to set for the data nodes.
|
||||
|
||||
#### Coordinating node
|
||||
|
||||
Change the name of the coordinating node to `opensearch-c1`:
|
||||
|
||||
```yml
|
||||
node.name: opensearch-c1
|
||||
```
|
||||
|
||||
Every node is a coordinating node by default, so to make this node a dedicated coordinating node, set `node.master`, `node.data`, and `node.ingest` to `false`:
|
||||
|
||||
```yml
|
||||
node.master: false
|
||||
node.data: false
|
||||
node.ingest: false
|
||||
```
|
||||
|
||||
## Step 3: Bind a cluster to specific IP addresses
|
||||
|
||||
`network_host` defines the IP address used to bind the node. By default, OpenSearch listens on a local host, which limits the cluster to a single node. You can also use `_local_` and `_site_` to bind to any loopback or site-local address, whether IPv4 or IPv6:
|
||||
|
||||
```yml
|
||||
network.host: [_local_, _site_]
|
||||
```
|
||||
|
||||
To form a multi-node cluster, specify the IP address of the node:
|
||||
|
||||
```yml
|
||||
network.host: <IP address of the node>
|
||||
```
|
||||
|
||||
|
||||
Make sure to configure these settings on all of your nodes.
|
||||
|
||||
|
||||
## Step 4: Configure discovery hosts for a cluster
|
||||
|
||||
Now that you've configured the network hosts, you need to configure the discovery hosts.
|
||||
|
||||
Zen Discovery is the built-in, default mechanism that uses [unicast](https://en.wikipedia.org/wiki/Unicast) to find other nodes in the cluster.
|
||||
|
||||
You can generally just add all your master-eligible nodes to the `discovery.seed_hosts` array. When a node starts up, it finds the other master-eligible nodes, determines which one is the master, and asks to join the cluster.
|
||||
|
||||
For example, for `opensearch-master` the line looks something like this:
|
||||
|
||||
```yml
|
||||
discovery.seed_hosts: ["<private IP of opensearch-d1>", "<private IP of opensearch-d2>", "<private IP of opensearch-c1>"]
|
||||
```
|
||||
|
||||
|
||||
## Step 5: Start the cluster
|
||||
|
||||
After you set the configurations, start OpenSearch on all nodes:
|
||||
|
||||
```bash
|
||||
sudo systemctl start opensearch.service
|
||||
```
|
||||
|
||||
Then go to the logs file to see the formation of the cluster:
|
||||
|
||||
```bash
|
||||
less /var/log/opensearch/opensearch-cluster.log
|
||||
```
|
||||
|
||||
Perform the following `_cat` query on any node to see all the nodes formed as a cluster:
|
||||
|
||||
```bash
|
||||
curl -XGET https://<private-ip>:9200/_cat/nodes?v -u 'admin:admin' --insecure
|
||||
```
|
||||
|
||||
```
|
||||
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
|
||||
x.x.x.x 13 61 0 0.02 0.04 0.05 mi * opensearch-master
|
||||
x.x.x.x 16 60 0 0.06 0.05 0.05 md - opensearch-d1
|
||||
x.x.x.x 34 38 0 0.12 0.07 0.06 md - opensearch-d2
|
||||
x.x.x.x 23 38 0 0.12 0.07 0.06 md - opensearch-c1
|
||||
```
|
||||
|
||||
To better understand and monitor your cluster, use the [cat API]({{site.url}}{{site.baseurl}}/opensearch/catapis/).
|
||||
|
||||
|
||||
## (Advanced) Step 6: Configure shard allocation awareness or forced awareness
|
||||
|
||||
If your nodes are spread across several geographical zones, you can configure shard allocation awareness to allocate all replica shards to a zone that’s different from their primary shard.
|
||||
|
||||
With shard allocation awareness, if the nodes in one of your zones fail, you can be assured that your replica shards are spread across your other zones. It adds a layer of fault tolerance to ensure your data survives a zone failure beyond just individual node failures.
|
||||
|
||||
To configure shard allocation awareness, add zone attributes to `opensearch-d1` and `opensearch-d2`, respectively:
|
||||
|
||||
```yml
|
||||
node.attr.zone: zoneA
|
||||
```
|
||||
```yml
|
||||
node.attr.zone: zoneB
|
||||
```
|
||||
|
||||
Update the cluster settings:
|
||||
|
||||
```json
|
||||
PUT _cluster/settings
|
||||
{
|
||||
"persistent": {
|
||||
"cluster.routing.allocation.awareness.attributes": "zone"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can either use `persistent` or `transient` settings. We recommend the `persistent` setting because it persists through a cluster reboot. Transient settings don't persist through a cluster reboot.
|
||||
|
||||
Shard allocation awareness attempts to separate primary and replica shards across multiple zones. However, if only one zone is available (such as after a zone failure), OpenSearch allocates replica shards to the only remaining zone.
|
||||
|
||||
Another option is to require that primary and replica shards are never allocated to the same zone. This is called forced awareness.
|
||||
|
||||
To configure forced awareness, specify all the possible values for your zone attributes:
|
||||
|
||||
```json
|
||||
PUT _cluster/settings
|
||||
{
|
||||
"persistent": {
|
||||
"cluster.routing.allocation.awareness.attributes": "zone",
|
||||
"cluster.routing.allocation.awareness.force.zone.values":["zoneA", "zoneB"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now, if a data node fails, forced awareness doesn't allocate the replicas to a node in the same zone. Instead, the cluster enters a yellow state and only allocates the replicas when nodes in another zone come online.
|
||||
|
||||
In our two-zone architecture, we can use allocation awareness if `opensearch-d1` and `opensearch-d2` are less than 50% utilized, so that each of them have the storage capacity to allocate replicas in the same zone.
|
||||
If that is not the case, and `opensearch-d1` and `opensearch-d2` do not have the capacity to contain all primary and replica shards, we can use forced awareness. This approach helps to make sure that, in the event of a failure, OpenSearch doesn't overload your last remaining zone and lock up your cluster due to lack of storage.
|
||||
|
||||
Choosing allocation awareness or forced awareness depends on how much space you might need in each zone to balance your primary and replica shards.
|
||||
|
||||
|
||||
## (Advanced) Step 7: Set up a hot-warm architecture
|
||||
|
||||
You can design a hot-warm architecture where you first index your data to hot nodes---fast and expensive---and after a certain period of time move them to warm nodes---slow and cheap.
|
||||
|
||||
If you analyze time series data that you rarely update and want the older data to go onto cheaper storage, this architecture can be a good fit.
|
||||
|
||||
This architecture helps save money on storage costs. Rather than increasing the number of hot nodes and using fast, expensive storage, you can add warm nodes for data that you don't access as frequently.
|
||||
|
||||
To configure a hot-warm storage architecture, add `temp` attributes to `opensearch-d1` and `opensearch-d2`, respectively:
|
||||
|
||||
```yml
|
||||
node.attr.temp: hot
|
||||
```
|
||||
```yml
|
||||
node.attr.temp: warm
|
||||
```
|
||||
|
||||
You can set the attribute name and value to whatever you want as long as it’s consistent for all your hot and warm nodes.
|
||||
|
||||
To add an index `newindex` to the hot node:
|
||||
|
||||
```json
|
||||
PUT newindex
|
||||
{
|
||||
"settings": {
|
||||
"index.routing.allocation.require.temp": "hot"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Take a look at the following shard allocation for `newindex`:
|
||||
|
||||
```json
|
||||
GET _cat/shards/newindex?v
|
||||
index shard prirep state docs store ip node
|
||||
new_index 2 p STARTED 0 230b 10.0.0.225 opensearch-d1
|
||||
new_index 2 r UNASSIGNED
|
||||
new_index 3 p STARTED 0 230b 10.0.0.225 opensearch-d1
|
||||
new_index 3 r UNASSIGNED
|
||||
new_index 4 p STARTED 0 230b 10.0.0.225 opensearch-d1
|
||||
new_index 4 r UNASSIGNED
|
||||
new_index 1 p STARTED 0 230b 10.0.0.225 opensearch-d1
|
||||
new_index 1 r UNASSIGNED
|
||||
new_index 0 p STARTED 0 230b 10.0.0.225 opensearch-d1
|
||||
new_index 0 r UNASSIGNED
|
||||
```
|
||||
|
||||
In this example, all primary shards are allocated to `opensearch-d1`, which is our hot node. All replica shards are unassigned, because we're forcing this index to allocate only to hot nodes.
|
||||
|
||||
To add an index `oldindex` to the warm node:
|
||||
|
||||
```json
|
||||
PUT oldindex
|
||||
{
|
||||
"settings": {
|
||||
"index.routing.allocation.require.temp": "warm"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The shard allocation for `oldindex`:
|
||||
|
||||
```json
|
||||
GET _cat/shards/oldindex?v
|
||||
index shard prirep state docs store ip node
|
||||
old_index 2 p STARTED 0 230b 10.0.0.74 opensearch-d2
|
||||
old_index 2 r UNASSIGNED
|
||||
old_index 3 p STARTED 0 230b 10.0.0.74 opensearch-d2
|
||||
old_index 3 r UNASSIGNED
|
||||
old_index 4 p STARTED 0 230b 10.0.0.74 opensearch-d2
|
||||
old_index 4 r UNASSIGNED
|
||||
old_index 1 p STARTED 0 230b 10.0.0.74 opensearch-d2
|
||||
old_index 1 r UNASSIGNED
|
||||
old_index 0 p STARTED 0 230b 10.0.0.74 opensearch-d2
|
||||
old_index 0 r UNASSIGNED
|
||||
```
|
||||
|
||||
In this case, all primary shards are allocated to `opensearch-d2`. Again, all replica shards are unassigned because we only have one warm node.
|
||||
|
||||
A popular approach is to configure your [index templates]({{site.url}}{{site.baseurl}}/opensearch/index-templates/) to set the `index.routing.allocation.require.temp` value to `hot`. This way, OpenSearch stores your most recent data on your hot nodes.
|
||||
|
||||
You can then use the [Index State Management (ISM)]({{site.url}}{{site.baseurl}}/im-plugin/) plugin to periodically check the age of an index and specify actions to take on it. For example, when the index reaches a specific age, change the `index.routing.allocation.require.temp` setting to `warm` to automatically move your data from hot nodes to warm nodes.
|
||||
|
||||
|
||||
## Next steps
|
||||
|
||||
If you are using the security plugin, the previous request to `_cat/nodes?v` might have failed with an initialization error. For full guidance around using the security plugin, see [Security configuration]({{site.url}}{{site.baseurl}}/security-plugin/configuration/index/).
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Common REST Parameters
|
||||
nav_order: 93
|
||||
---
|
||||
|
||||
# Common REST parameters
|
||||
|
||||
OpenSearch supports the following parameters for all REST operations:
|
||||
|
||||
Option | Description | Example
|
||||
:--- | :--- | :---
|
||||
Human-readable output | To convert output units to human-readable values (for example, `1h` for 1 hour and `1kb` for 1,024 bytes), add `?human=true` to the request URL. | `GET <index_name>/_search?human=true`
|
||||
Pretty result | To get back JSON responses in a readable format, add `?pretty=true` to the request URL. | `GET <index_name>/_search?pretty=true`
|
||||
Content type | To specify the type of content in the request body, use the `Content-Type` key name in the request header. Most operations support JSON, YAML, and CBOR formats. | `POST _scripts/<template_name> -H 'Content-Type: application/json`
|
||||
Request body in query string | If the client library does not accept a request body for non-POST requests, use the `source` query string parameter to pass the request body. Also, specify the `source_content_type` parameter with a supported media type such as `application/json`. | `GET _search?source_content_type=application/json&source={"query":{"match_all":{}}}`
|
||||
Stack traces | To include the error stack trace in the response when an exception is raised, add `error_trace=true` to the request URL. | `GET <index_name>/_search?error_trace=true`
|
||||
@@ -1,80 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Configuration
|
||||
nav_order: 5
|
||||
---
|
||||
|
||||
# OpenSearch configuration
|
||||
|
||||
Most OpenSearch configuration can take place in the cluster settings API. Certain operations require you to modify `opensearch.yml` and restart the cluster.
|
||||
|
||||
Whenever possible, use the cluster settings API instead; `opensearch.yml` is local to each node, whereas the API applies the setting to all nodes in the cluster. Certain settings, however, require `opensearch.yml`. In general, these settings relate to networking, cluster formation, and the local file system. To learn more, see [Cluster formation]({{site.url}}{{site.baseurl}}/opensearch/cluster/).
|
||||
|
||||
|
||||
## Update cluster settings using the API
|
||||
|
||||
The first step in changing a setting is to view the current settings:
|
||||
|
||||
```
|
||||
GET _cluster/settings?include_defaults=true
|
||||
```
|
||||
|
||||
For a more concise summary of non-default settings:
|
||||
|
||||
```
|
||||
GET _cluster/settings
|
||||
```
|
||||
|
||||
Three categories of setting exist in the cluster settings API: persistent, transient, and default. Persistent settings, well, persist after a cluster restart. After a restart, OpenSearch clears transient settings.
|
||||
|
||||
If you specify the same setting in multiple places, OpenSearch uses the following precedence:
|
||||
|
||||
1. Transient settings
|
||||
2. Persistent settings
|
||||
3. Settings from `opensearch.yml`
|
||||
4. Default settings
|
||||
|
||||
To change a setting, just specify the new one as either persistent or transient. This example shows the flat settings form:
|
||||
|
||||
```json
|
||||
PUT _cluster/settings
|
||||
{
|
||||
"persistent" : {
|
||||
"action.auto_create_index" : false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can also use the expanded form, which lets you copy and paste from the GET response and change existing values:
|
||||
|
||||
```json
|
||||
PUT _cluster/settings
|
||||
{
|
||||
"persistent": {
|
||||
"action": {
|
||||
"auto_create_index": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Configuration file
|
||||
|
||||
You can find `opensearch.yml` in `/usr/share/opensearch/config/opensearch.yml` (Docker) or `/etc/opensearch/opensearch.yml` (most Linux distributions) on each node.
|
||||
|
||||
You can edit the `OPENSEARCH_PATH_CONF=/etc/opensearch` to change the config directory location. This variable is sourced from `/etc/default/opensearch`(Debian package) and `/etc/sysconfig/opensearch`(RPM package).
|
||||
|
||||
If you set your customized `OPENSEARCH_PATH_CONF` variable, be aware that other default environment variables will not be loaded.
|
||||
|
||||
You don't mark settings in `opensearch.yml` as persistent or transient, and settings use the flat form:
|
||||
|
||||
```yml
|
||||
cluster.name: my-application
|
||||
action.auto_create_index: true
|
||||
compatibility.override_main_response_version: true
|
||||
```
|
||||
|
||||
The demo configuration includes a number of settings for the security plugin that you should modify before using OpenSearch for a production workload. To learn more, see [Security]({{site.url}}{{site.baseurl}}/security-plugin/).
|
||||
@@ -1,265 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Data streams
|
||||
nav_order: 13
|
||||
---
|
||||
|
||||
# Data streams
|
||||
|
||||
If you're ingesting continuously generated time-series data such as logs, events, and metrics into OpenSearch, you're likely in a scenario where the number of documents grows rapidly and you don't need to update older documents.
|
||||
|
||||
A typical workflow to manage time-series data involves multiple steps, such as creating a rollover index alias, defining a write index, and defining common mappings and settings for the backing indices.
|
||||
|
||||
Data streams simplify this process and enforce a setup that best suits time-series data, such as being designed primarily for append-only data and ensuring that each document has a timestamp field.
|
||||
|
||||
A data stream is internally composed of multiple backing indices. Search requests are routed to all the backing indices, while indexing requests are routed to the latest write index. [ISM]({{site.url}}{{site.baseurl}}/im-plugin/ism/index/) policies let you automatically handle index rollovers or deletions.
|
||||
|
||||
|
||||
## Get started with data streams
|
||||
|
||||
### Step 1: Create an index template
|
||||
|
||||
To create a data stream, you first need to create an index template that configures a set of indices as a data stream. The `data_stream` object indicates that it’s a data stream and not a regular index template. The index pattern matches with the name of the data stream:
|
||||
|
||||
```json
|
||||
PUT _index_template/logs-template
|
||||
{
|
||||
"index_patterns": [
|
||||
"my-data-stream",
|
||||
"logs-*"
|
||||
],
|
||||
"data_stream": {},
|
||||
"priority": 100
|
||||
}
|
||||
```
|
||||
|
||||
In this case, each ingested document must have an `@timestamp` field.
|
||||
You also have the ability to define your own custom timestamp field as a property in the `data_stream` object. You can also add index mappings and other settings here, just as you would for a regular index template.
|
||||
|
||||
```json
|
||||
PUT _index_template/logs-template-nginx
|
||||
{
|
||||
"index_patterns": "logs-nginx",
|
||||
"data_stream": {
|
||||
"timestamp_field": {
|
||||
"name": "request_time"
|
||||
}
|
||||
},
|
||||
"priority": 200,
|
||||
"template": {
|
||||
"settings": {
|
||||
"number_of_shards": 1,
|
||||
"number_of_replicas": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In this case, `logs-nginx` index matches both the `logs-template` and `logs-template-nginx` templates. When you have a tie, OpenSearch selects the matching index template with the higher priority value.
|
||||
|
||||
### Step 2: Create a data stream
|
||||
|
||||
After you create an index template, you can create a data stream.
|
||||
You can use the data stream API to explicitly create a data stream. The data stream API initializes the first backing index:
|
||||
|
||||
```json
|
||||
PUT _data_stream/logs-redis
|
||||
PUT _data_stream/logs-nginx
|
||||
```
|
||||
|
||||
You can also directly start ingesting data without creating a data stream.
|
||||
|
||||
Because we have a matching index template with a data_stream object, OpenSearch automatically creates the data stream:
|
||||
|
||||
```json
|
||||
POST logs-staging/_doc
|
||||
{
|
||||
"message": "login attempt failed",
|
||||
"@timestamp": "2013-03-01T00:00:00"
|
||||
}
|
||||
```
|
||||
|
||||
To see information about a specific data stream:
|
||||
|
||||
```json
|
||||
GET _data_stream/logs-nginx
|
||||
```
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"data_streams" : [
|
||||
{
|
||||
"name" : "logs-nginx",
|
||||
"timestamp_field" : {
|
||||
"name" : "request_time"
|
||||
},
|
||||
"indices" : [
|
||||
{
|
||||
"index_name" : ".ds-logs-nginx-000001",
|
||||
"index_uuid" : "-VhmuhrQQ6ipYCmBhn6vLw"
|
||||
}
|
||||
],
|
||||
"generation" : 1,
|
||||
"status" : "GREEN",
|
||||
"template" : "logs-template-nginx"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
You can see the name of the timestamp field, the list of the backing indices, and the template that's used to create the data stream. You can also see the health of the data stream, which represents the lowest status of all its backing indices.
|
||||
|
||||
To see more insights about the data stream, use the `_stats` endpoint:
|
||||
|
||||
```json
|
||||
GET _data_stream/logs-nginx/_stats
|
||||
```
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"_shards" : {
|
||||
"total" : 1,
|
||||
"successful" : 1,
|
||||
"failed" : 0
|
||||
},
|
||||
"data_stream_count" : 1,
|
||||
"backing_indices" : 1,
|
||||
"total_store_size_bytes" : 208,
|
||||
"data_streams" : [
|
||||
{
|
||||
"data_stream" : "logs-nginx",
|
||||
"backing_indices" : 1,
|
||||
"store_size_bytes" : 208,
|
||||
"maximum_timestamp" : 0
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: Ingest data into the data stream
|
||||
|
||||
To ingest data into a data stream, you can use the regular indexing APIs. Make sure every document that you index has a timestamp field. If you try to ingest a document that doesn't have a timestamp field, you get an error.
|
||||
|
||||
```json
|
||||
POST logs-redis/_doc
|
||||
{
|
||||
"message": "login attempt",
|
||||
"@timestamp": "2013-03-01T00:00:00"
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: Searching a data stream
|
||||
|
||||
You can search a data stream just like you search a regular index or an index alias.
|
||||
The search operation applies to all of the backing indices (all data present in the stream).
|
||||
|
||||
```json
|
||||
GET logs-redis/_search
|
||||
{
|
||||
"query": {
|
||||
"match": {
|
||||
"message": "login"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"took" : 514,
|
||||
"timed_out" : false,
|
||||
"_shards" : {
|
||||
"total" : 5,
|
||||
"successful" : 5,
|
||||
"skipped" : 0,
|
||||
"failed" : 0
|
||||
},
|
||||
"hits" : {
|
||||
"total" : {
|
||||
"value" : 1,
|
||||
"relation" : "eq"
|
||||
},
|
||||
"max_score" : 0.2876821,
|
||||
"hits" : [
|
||||
{
|
||||
"_index" : ".ds-logs-redis-000001",
|
||||
"_type" : "_doc",
|
||||
"_id" : "-rhVmXoBL6BAVWH3mMpC",
|
||||
"_score" : 0.2876821,
|
||||
"_source" : {
|
||||
"message" : "login attempt",
|
||||
"@timestamp" : "2013-03-01T00:00:00"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5: Rollover a data stream
|
||||
|
||||
A rollover operation creates a new backing index that becomes the data stream’s new write index.
|
||||
|
||||
To perform manual rollover operation on the data stream:
|
||||
|
||||
```json
|
||||
POST logs-redis/_rollover
|
||||
```
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"acknowledged" : true,
|
||||
"shards_acknowledged" : true,
|
||||
"old_index" : ".ds-logs-redis-000001",
|
||||
"new_index" : ".ds-logs-redis-000002",
|
||||
"rolled_over" : true,
|
||||
"dry_run" : false,
|
||||
"conditions" : { }
|
||||
}
|
||||
```
|
||||
|
||||
If you now perform a `GET` operation on the `logs-redis` data stream, you see that the generation ID is incremented from 1 to 2.
|
||||
|
||||
You can also set up an [Index State Management (ISM) policy]({{site.url}}{{site.baseurl}}/im-plugin/ism/policies/) to automate the rollover process for the data stream.
|
||||
The ISM policy is applied to the backing indices at the time of their creation. When you associate a policy to a data stream, it only affects the future backing indices of that data stream.
|
||||
|
||||
You also don’t need to provide the `rollover_alias` setting, because the ISM policy infers this information from the backing index.
|
||||
|
||||
### Step 6: Manage data streams in OpenSearch Dashboards
|
||||
|
||||
To manage data streams from OpenSearch Dashboards, open **OpenSearch Dashboards**, choose **Index Management**, select **Indices** or **Policy managed indices**.
|
||||
|
||||
You see a toggle switch for data streams that you can use to show or hide indices belonging to a data stream.
|
||||
|
||||
When you enable this switch, you see a data stream multi-select dropdown menu that you can use for filtering data streams.
|
||||
You also see a data stream column that shows you the name of the data stream the index is contained in.
|
||||
|
||||

|
||||
|
||||
You can select one or more data streams and apply an ISM policy on them. You can also apply a policy on any individual backing index.
|
||||
|
||||
You can performing visualizations on a data stream just like you would on a regular index or index alias.
|
||||
|
||||
### Step 7: Delete a data stream
|
||||
|
||||
The delete operation first deletes the backing indices of a data stream and then deletes the data stream itself.
|
||||
|
||||
To delete a data stream and all of its hidden backing indices:
|
||||
|
||||
```json
|
||||
DELETE _data_stream/<name_of_data_stream>
|
||||
```
|
||||
|
||||
You can use wildcards to delete more than one data stream.
|
||||
|
||||
We recommend deleting data from a data stream using an ISM policy.
|
||||
|
||||
You can also use [asynchronous search]({{site.url}}{{site.baseurl}}/search-plugins/async/index/) and [SQL]({{site.url}}{{site.baseurl}}/search-plugins/sql/index/) and [PPL]({{site.url}}{{site.baseurl}}/search-plugins/ppl/index/) to query your data stream directly. You can also use the security plugin to define granular permissions on the data stream name.
|
||||
@@ -1,202 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Index aliases
|
||||
nav_order: 12
|
||||
---
|
||||
|
||||
# Index aliases
|
||||
|
||||
An alias is a virtual index name that can point to one or more indices.
|
||||
|
||||
If your data is spread across multiple indices, rather than keeping track of which indices to query, you can create an alias and query it instead.
|
||||
|
||||
For example, if you’re storing logs into indices based on the month and you frequently query the logs for the previous two months, you can create a `last_2_months` alias and update the indices it points to each month.
|
||||
|
||||
Because you can change the indices an alias points to at any time, referring to indices using aliases in your applications allows you to reindex your data without any downtime.
|
||||
|
||||
---
|
||||
|
||||
#### Table of contents
|
||||
1. TOC
|
||||
{:toc}
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Create aliases
|
||||
|
||||
To create an alias, use a POST request:
|
||||
|
||||
```json
|
||||
POST _aliases
|
||||
```
|
||||
|
||||
Use the `actions` method to specify the list of actions that you want to perform. This command creates an alias named `alias1` and adds `index-1` to this alias:
|
||||
|
||||
```json
|
||||
POST _aliases
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"add": {
|
||||
"index": "index-1",
|
||||
"alias": "alias1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
You should see the following response:
|
||||
|
||||
```json
|
||||
{
|
||||
"acknowledged": true
|
||||
}
|
||||
```
|
||||
|
||||
If this request fails, make sure the index that you're adding to the alias already exists.
|
||||
|
||||
To check if `alias1` refers to `index-1`, run the following command:
|
||||
|
||||
```json
|
||||
GET alias1
|
||||
```
|
||||
|
||||
## Add or remove indices
|
||||
|
||||
You can perform multiple actions in the same `_aliases` operation.
|
||||
For example, the following command removes `index-1` and adds `index-2` to `alias1`:
|
||||
|
||||
```json
|
||||
POST _aliases
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"remove": {
|
||||
"index": "index-1",
|
||||
"alias": "alias1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"add": {
|
||||
"index": "index-2",
|
||||
"alias": "alias1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The `add` and `remove` actions occur atomically, which means that at no point will `alias1` point to both `index-1` and `index-2`.
|
||||
|
||||
You can also add indices based on an index pattern:
|
||||
|
||||
```json
|
||||
POST _aliases
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"add": {
|
||||
"index": "index*",
|
||||
"alias": "alias1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Manage aliases
|
||||
|
||||
To list the mapping of aliases to indices, run the following command:
|
||||
|
||||
```json
|
||||
GET _cat/aliases?v
|
||||
```
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
alias index filter routing.index routing.search
|
||||
alias1 index-1 * - -
|
||||
```
|
||||
|
||||
To check which indices an alias points to, run the following command:
|
||||
|
||||
```json
|
||||
GET _alias/alias1
|
||||
```
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"index-2": {
|
||||
"aliases": {
|
||||
"alias1": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Conversely, to find which alias points to a specific index, run the following command:
|
||||
|
||||
```json
|
||||
GET /index-2/_alias/*
|
||||
```
|
||||
|
||||
To check if an alias exists, run the following command:
|
||||
|
||||
```json
|
||||
HEAD /alias1/_alias/
|
||||
```
|
||||
|
||||
## Add aliases at index creation
|
||||
|
||||
You can add an index to an alias as you create the index:
|
||||
|
||||
```json
|
||||
PUT index-1
|
||||
{
|
||||
"aliases": {
|
||||
"alias1": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Create filtered aliases
|
||||
|
||||
You can create a filtered alias to access a subset of documents or fields from the underlying indices.
|
||||
|
||||
This command adds only a specific timestamp field to `alias1`:
|
||||
|
||||
```json
|
||||
POST _aliases
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"add": {
|
||||
"index": "index-1",
|
||||
"alias": "alias1",
|
||||
"filter": {
|
||||
"term": {
|
||||
"timestamp": "1574641891142"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Index alias options
|
||||
|
||||
You can specify the options shown in the following table.
|
||||
|
||||
Option | Valid values | Description | Required
|
||||
:--- | :--- | :---
|
||||
`index` | String | The name of the index that the alias points to. | Yes
|
||||
`alias` | String | The name of the alias. | No
|
||||
`filter` | Object | Add a filter to the alias. | No
|
||||
`routing` | String | Limit search to an associated shard value. You can specify `search_routing` and `index_routing` independently. | No
|
||||
`is_write_index` | String | Specify the index that accepts any write operations to the alias. If this value is not specified, then no write operations are allowed. | No
|
||||
@@ -1,271 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Index data
|
||||
nav_order: 10
|
||||
---
|
||||
|
||||
# Index data
|
||||
|
||||
You index data using the OpenSearch REST API. Two APIs exist: the index API and the `_bulk` API.
|
||||
|
||||
For situations in which new data arrives incrementally (for example, customer orders from a small business), you might use the index API to add documents individually as they arrive. For situations in which the flow of data is less frequent (for example, weekly updates to a marketing website), you might prefer to generate a file and send it to the `_bulk` API. For large numbers of documents, lumping requests together and using the `_bulk` API offers superior performance. If your documents are enormous, however, you might need to index them individually.
|
||||
|
||||
|
||||
## Introduction to indexing
|
||||
|
||||
Before you can search data, you must *index* it. Indexing is the method by which search engines organize data for fast retrieval. The resulting structure is called, fittingly, an index.
|
||||
|
||||
In OpenSearch, the basic unit of data is a JSON *document*. Within an index, OpenSearch identifies each document using a unique ID.
|
||||
|
||||
A request to the index API looks like this:
|
||||
|
||||
```json
|
||||
PUT <index>/_doc/<id>
|
||||
{ "A JSON": "document" }
|
||||
```
|
||||
|
||||
A request to the `_bulk` API looks a little different, because you specify the index and ID in the bulk data:
|
||||
|
||||
```json
|
||||
POST _bulk
|
||||
{ "index": { "_index": "<index>", "_id": "<id>" } }
|
||||
{ "A JSON": "document" }
|
||||
```
|
||||
|
||||
Bulk data must conform to a specific format, which requires a newline character (`\n`) at the end of every line, including the last line. This is the basic format:
|
||||
|
||||
```
|
||||
Action and metadata\n
|
||||
Optional document\n
|
||||
Action and metadata\n
|
||||
Optional document\n
|
||||
```
|
||||
|
||||
The document is optional, because `delete` actions don't require a document. The other actions (`index`, `create`, and `update`) all require a document. If you specifically want the action to fail if the document already exists, use the `create` action instead of the `index` action.
|
||||
{: .note }
|
||||
|
||||
To index bulk data using the `curl` command, navigate to the folder where you have your file saved and run the following command:
|
||||
|
||||
```json
|
||||
curl -H "Content-Type: application/x-ndjson" -POST https://localhost:9200/data/_bulk -u 'admin:admin' --insecure --data-binary "@data.json"
|
||||
```
|
||||
|
||||
If any one of the actions in the `_bulk` API fail, OpenSearch continues to execute the other actions. Examine the `items` array in the response to figure out what went wrong. The entries in the `items` array are in the same order as the actions specified in the request.
|
||||
|
||||
OpenSearch automatically creates an index when you add a document to an index that doesn't already exist. It also automatically generates an ID if you don't specify an ID in the request. This simple example automatically creates the movies index, indexes the document, and assigns it a unique ID:
|
||||
|
||||
```json
|
||||
POST movies/_doc
|
||||
{ "title": "Spirited Away" }
|
||||
```
|
||||
|
||||
Automatic ID generation has a clear downside: because the indexing request didn't specify a document ID, you can't easily update the document at a later time. Also, if you run this request 10 times, OpenSearch indexes this document as 10 different documents with unique IDs. To specify an ID of 1, use the following request (note the use of PUT instead of POST):
|
||||
|
||||
```json
|
||||
PUT movies/_doc/1
|
||||
{ "title": "Spirited Away" }
|
||||
```
|
||||
|
||||
Because you must specify an ID, if you run this command 10 times, you still have just one document indexed with the `_version` field incremented to 10.
|
||||
|
||||
Indices default to one primary shard and one replica. If you want to specify non-default settings, create the index before adding documents:
|
||||
|
||||
```json
|
||||
PUT more-movies
|
||||
{ "settings": { "number_of_shards": 6, "number_of_replicas": 2 } }
|
||||
```
|
||||
|
||||
## Naming restrictions for indices
|
||||
|
||||
OpenSearch indices have the following naming restrictions:
|
||||
|
||||
- All letters must be lowercase.
|
||||
- Index names can't begin with underscores (`_`) or hyphens (`-`).
|
||||
- Index names can't contain spaces, commas, or the following characters:
|
||||
|
||||
`:`, `"`, `*`, `+`, `/`, `\`, `|`, `?`, `#`, `>`, or `<`
|
||||
|
||||
## Read data
|
||||
|
||||
After you index a document, you can retrieve it by sending a GET request to the same endpoint that you used for indexing:
|
||||
|
||||
```json
|
||||
GET movies/_doc/1
|
||||
|
||||
{
|
||||
"_index" : "movies",
|
||||
"_type" : "_doc",
|
||||
"_id" : "1",
|
||||
"_version" : 1,
|
||||
"_seq_no" : 0,
|
||||
"_primary_term" : 1,
|
||||
"found" : true,
|
||||
"_source" : {
|
||||
"title" : "Spirited Away"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can see the document in the `_source` object. If the document is not found, the `found` key is `false` and the `_source` object is not part of the response.
|
||||
|
||||
To retrieve multiple documents with a single command, use the `_mget` operation.
|
||||
The format for retrieving multiple documents is similar to the `_bulk` operation, where you must specify the index and ID in the request body:
|
||||
|
||||
```json
|
||||
GET _mget
|
||||
{
|
||||
"docs": [
|
||||
{
|
||||
"_index": "<index>",
|
||||
"_id": "<id>"
|
||||
},
|
||||
{
|
||||
"_index": "<index>",
|
||||
"_id": "<id>"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
To only return specific fields in a document:
|
||||
|
||||
```json
|
||||
GET _mget
|
||||
{
|
||||
"docs": [
|
||||
{
|
||||
"_index": "<index>",
|
||||
"_id": "<id>",
|
||||
"_source": "field1"
|
||||
},
|
||||
{
|
||||
"_index": "<index>",
|
||||
"_id": "<id>",
|
||||
"_source": "field2"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
To check if a document exists:
|
||||
|
||||
```json
|
||||
HEAD movies/_doc/<doc-id>
|
||||
```
|
||||
|
||||
If the document exists, you get back a `200 OK` response, and if it doesn't, you get back a `404 - Not Found` error.
|
||||
|
||||
## Update data
|
||||
|
||||
To update existing fields or to add new fields, send a POST request to the `_update` operation with your changes in a `doc` object:
|
||||
|
||||
```json
|
||||
POST movies/_update/1
|
||||
{
|
||||
"doc": {
|
||||
"title": "Castle in the Sky",
|
||||
"genre": ["Animation", "Fantasy"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note the updated `title` field and new `genre` field:
|
||||
|
||||
```json
|
||||
GET movies/_doc/1
|
||||
|
||||
{
|
||||
"_index" : "movies",
|
||||
"_type" : "_doc",
|
||||
"_id" : "1",
|
||||
"_version" : 2,
|
||||
"_seq_no" : 1,
|
||||
"_primary_term" : 1,
|
||||
"found" : true,
|
||||
"_source" : {
|
||||
"title" : "Castle in the Sky",
|
||||
"genre" : [
|
||||
"Animation",
|
||||
"Fantasy"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The document also has an incremented `_version` field. Use this field to keep track of how many times a document is updated.
|
||||
|
||||
POST requests make partial updates to documents. To altogether replace a document, use a PUT request:
|
||||
|
||||
```json
|
||||
PUT movies/_doc/1
|
||||
{
|
||||
"title": "Spirited Away"
|
||||
}
|
||||
```
|
||||
|
||||
The document with ID of 1 will contain only the `title` field, because the entire document will be replaced with the document indexed in this PUT request.
|
||||
|
||||
Use the `upsert` object to conditionally update documents based on whether they already exist. Here, if the document exists, its `title` field changes to `Castle in the Sky`. If it doesn't, OpenSearch indexes the document in the `upsert` object.
|
||||
|
||||
```json
|
||||
POST movies/_update/2
|
||||
{
|
||||
"doc": {
|
||||
"title": "Castle in the Sky"
|
||||
},
|
||||
"upsert": {
|
||||
"title": "Only Yesterday",
|
||||
"genre": ["Animation", "Fantasy"],
|
||||
"date": 1993
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"_index" : "movies",
|
||||
"_type" : "_doc",
|
||||
"_id" : "2",
|
||||
"_version" : 2,
|
||||
"result" : "updated",
|
||||
"_shards" : {
|
||||
"total" : 2,
|
||||
"successful" : 1,
|
||||
"failed" : 0
|
||||
},
|
||||
"_seq_no" : 3,
|
||||
"_primary_term" : 1
|
||||
}
|
||||
```
|
||||
|
||||
Each update operation for a document has a unique combination of the `_seq_no` and `_primary_term` values.
|
||||
|
||||
OpenSearch first writes your updates to the primary shard and then sends this change to all the replica shards. An uncommon issue can occur if multiple users of your OpenSearch-based application make updates to existing documents in the same index. In this situation, another user can read and update a document from a replica before it receives your update from the primary shard. Your update operation then ends up updating an older version of the document. In the best case, you and the other user make the same changes, and the document remains accurate. In the worst case, the document now contains out-of-date information.
|
||||
|
||||
To prevent this situation, use the `_seq_no` and `_primary_term` values in the request header:
|
||||
|
||||
```json
|
||||
POST movies/_update/2?if_seq_no=3&if_primary_term=1
|
||||
{
|
||||
"doc": {
|
||||
"title": "Castle in the Sky",
|
||||
"genre": ["Animation", "Fantasy"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If the document is updated after we retrieved it, the `_seq_no` and `_primary_term` values are different and our update operation fails with a `409 — Conflict` error.
|
||||
|
||||
When using the `_bulk` API, specify the `_seq_no` and `_primary_term` values within the action metadata.
|
||||
|
||||
## Delete data
|
||||
|
||||
To delete a document from an index, use a DELETE request:
|
||||
|
||||
```json
|
||||
DELETE movies/_doc/1
|
||||
```
|
||||
|
||||
The DELETE operation increments the `_version` field. If you add the document back to the same ID, the `_version` field increments again. This behavior occurs because OpenSearch deletes the document `_source`, but retains its metadata.
|
||||
@@ -1,342 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Index templates
|
||||
nav_order: 15
|
||||
---
|
||||
|
||||
# Index templates
|
||||
|
||||
Index templates let you initialize new indices with predefined mappings and settings. For example, if you continuously index log data, you can define an index template so that all of these indices have the same number of shards and replicas.
|
||||
|
||||
### Create a template
|
||||
|
||||
To create an index template, use a POST request:
|
||||
|
||||
```json
|
||||
POST _index_template
|
||||
```
|
||||
|
||||
This command creates a template named `daily_logs` and applies it to any new index whose name matches the regular expression `logs-2020-01-*` and also adds it to the `my_logs` alias:
|
||||
|
||||
```json
|
||||
PUT _index_template/daily_logs
|
||||
{
|
||||
"index_patterns": [
|
||||
"logs-2020-01-*"
|
||||
],
|
||||
"template": {
|
||||
"aliases": {
|
||||
"my_logs": {}
|
||||
},
|
||||
"settings": {
|
||||
"number_of_shards": 2,
|
||||
"number_of_replicas": 1
|
||||
},
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"timestamp": {
|
||||
"type": "date",
|
||||
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
|
||||
},
|
||||
"value": {
|
||||
"type": "double"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You should see the following response:
|
||||
|
||||
```json
|
||||
{
|
||||
"acknowledged": true
|
||||
}
|
||||
```
|
||||
|
||||
If you create an index named `logs-2020-01-01`, you can see that it has the mappings and settings from the template:
|
||||
|
||||
```json
|
||||
PUT logs-2020-01-01
|
||||
GET logs-2020-01-01
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"logs-2020-01-01": {
|
||||
"aliases": {
|
||||
"my_logs": {}
|
||||
},
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"timestamp": {
|
||||
"type": "date",
|
||||
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
|
||||
},
|
||||
"value": {
|
||||
"type": "double"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"index": {
|
||||
"creation_date": "1578107970779",
|
||||
"number_of_shards": "2",
|
||||
"number_of_replicas": "1",
|
||||
"uuid": "U1vMDMOHSAuS2IzPcPHpOA",
|
||||
"version": {
|
||||
"created": "7010199"
|
||||
},
|
||||
"provided_name": "logs-2020-01-01"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Any additional indices that match this pattern---`logs-2020-01-02`, `logs-2020-01-03`, and so on---will inherit the same mappings and settings.
|
||||
|
||||
### Retrieve a template
|
||||
|
||||
To list all index templates:
|
||||
|
||||
```json
|
||||
GET _cat/templates
|
||||
```
|
||||
|
||||
To find a template by its name:
|
||||
|
||||
```json
|
||||
GET _index_template/daily_logs
|
||||
```
|
||||
|
||||
To get a list of all your templates:
|
||||
|
||||
```json
|
||||
GET _index_template/daily_logs
|
||||
```
|
||||
|
||||
To get a list of all templates that match a pattern:
|
||||
|
||||
```json
|
||||
GET _index_template/daily*
|
||||
```
|
||||
|
||||
To check if a specific template exists:
|
||||
|
||||
```json
|
||||
HEAD _index_template/<name>
|
||||
```
|
||||
|
||||
### Configure multiple templates
|
||||
|
||||
You can create multiple index templates for your indices. If the index name matches more than one template, OpenSearch merges all mappings and settings from all matching templates and applies them to the index.
|
||||
|
||||
The settings from the more recently created index templates override the settings of older index templates. So, you can first define a few common settings in a generic template that can act as a catch-all and then add more specialized settings as required.
|
||||
|
||||
An even better approach is to explicitly specify template priority using the `order` parameter. OpenSearch applies templates with lower priority numbers first and then overrides them with templates with higher priority numbers.
|
||||
|
||||
For example, say you have the following two templates that both match the `logs-2020-01-02` index and there’s a conflict in the `number_of_shards` field:
|
||||
|
||||
#### Template 1
|
||||
|
||||
```json
|
||||
PUT _index_template/template-01
|
||||
{
|
||||
"index_patterns": [
|
||||
"logs*"
|
||||
],
|
||||
"priority": 0,
|
||||
"template": {
|
||||
"settings": {
|
||||
"number_of_shards": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Template 2
|
||||
|
||||
```json
|
||||
PUT _index_template/template-02
|
||||
{
|
||||
"index_patterns": [
|
||||
"logs-2020-01-*"
|
||||
],
|
||||
"priority": 1,
|
||||
"template": {
|
||||
"settings": {
|
||||
"number_of_shards": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Because `template-02` has a higher `priority` value, it takes precedence over `template-01` . The `logs-2020-01-02` index would have the `number_of_shards` value as 3.
|
||||
|
||||
### Delete a template
|
||||
|
||||
You can delete an index template using its name:
|
||||
|
||||
```json
|
||||
DELETE _index_template/daily_logs
|
||||
```
|
||||
|
||||
## Composable index templates
|
||||
|
||||
Managing multiple index templates has the following challenges:
|
||||
|
||||
- If you have duplication between index templates, storing these index templates results in a bigger cluster state.
|
||||
- If you want to make a change across all your index templates, you have to manually make the change for each template.
|
||||
- If an index matches multiple templates, OpenSearch might merge the templates in an unexpected way that you discover only after an index is created.
|
||||
|
||||
You can use composable index templates to overcome these challenges. Composable index templates let you abstract common settings, mappings, and aliases into a reusable building block called a component template.
|
||||
|
||||
You can combine component templates to compose an index template.
|
||||
|
||||
Settings and mappings that you specify directly in the [create index]({{site.url}}{{site.baseurl}}/opensearch/rest-api/index-apis/create-index/) request override any settings or mappings specified in an index template and its component templates.
|
||||
{: .note }
|
||||
|
||||
### Create a component template
|
||||
|
||||
Let's define two component templates---`component_template_1` and `component_template_2`:
|
||||
|
||||
#### Component template 1
|
||||
|
||||
```json
|
||||
PUT _component_template/component_template_1
|
||||
{
|
||||
"template": {
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"@timestamp": {
|
||||
"type": "date"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Component template 2
|
||||
|
||||
```json
|
||||
PUT _component_template/component_template_2
|
||||
{
|
||||
"template": {
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"ip_address": {
|
||||
"type": "ip"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Use component templates to create an index template
|
||||
|
||||
When creating index templates, you need to include the component templates in a `composed_of` list.
|
||||
|
||||
OpenSearch applies the component templates in the order in which you specify them within the index template. The settings, mappings, and aliases that you specify inside the index template are applied last.
|
||||
|
||||
```json
|
||||
PUT _index_template/daily_logs
|
||||
{
|
||||
"index_patterns": [
|
||||
"logs-2020-01-*"
|
||||
],
|
||||
"template": {
|
||||
"aliases": {
|
||||
"my_logs": {}
|
||||
},
|
||||
"settings": {
|
||||
"number_of_shards": 2,
|
||||
"number_of_replicas": 1
|
||||
},
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"timestamp": {
|
||||
"type": "date",
|
||||
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
|
||||
},
|
||||
"value": {
|
||||
"type": "double"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"priority": 200,
|
||||
"composed_of": [
|
||||
"component_template_1",
|
||||
"component_template_2"
|
||||
],
|
||||
"version": 3,
|
||||
"_meta": {
|
||||
"description": "using component templates"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you create an index named `logs-2020-01-01`, you can see that it derives its mappings and settings from both the component templates:
|
||||
|
||||
```json
|
||||
PUT logs-2020-01-01
|
||||
GET logs-2020-01-01
|
||||
```
|
||||
|
||||
#### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"logs-2020-01-01": {
|
||||
"aliases": {
|
||||
"my_logs": {}
|
||||
},
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"@timestamp": {
|
||||
"type": "date"
|
||||
},
|
||||
"ip_address": {
|
||||
"type": "ip"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "date",
|
||||
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
|
||||
},
|
||||
"value": {
|
||||
"type": "double"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"index": {
|
||||
"creation_date": "1625382479459",
|
||||
"number_of_shards": "2",
|
||||
"number_of_replicas": "1",
|
||||
"uuid": "rYUlpOXDSUSuZifQLPfa5A",
|
||||
"version": {
|
||||
"created": "7100299"
|
||||
},
|
||||
"provided_name": "logs-2020-01-01"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Index template options
|
||||
|
||||
You can specify the following template options:
|
||||
|
||||
Option | Type | Description | Required
|
||||
:--- | :--- | :--- | :---
|
||||
`template` | `Object` | Specify index settings, mappings, and aliases. | No
|
||||
`priority` | `Integer` | The priority of the index template. | No
|
||||
`composed_of` | `String array` | The names of component templates applied on a new index together with the current template. | No
|
||||
`version` | `Integer` | Specify a version number to simplify template management. Default is `null`. | No
|
||||
`_meta ` | `Object` | Specify meta information about the template. | No
|
||||
@@ -1,96 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: About OpenSearch
|
||||
nav_order: 1
|
||||
has_children: false
|
||||
has_toc: false
|
||||
redirect_from:
|
||||
- /docs/opensearch/
|
||||
- /opensearch/
|
||||
---
|
||||
|
||||
{%- comment -%}The `/docs/opensearch/` redirect is specifically to support the UI links in OpenSearch Dashboards 1.0.0.{%- endcomment -%}
|
||||
|
||||
# Introduction to OpenSearch
|
||||
|
||||
OpenSearch is a distributed search and analytics engine based on [Apache Lucene](https://lucene.apache.org/). After adding your data to OpenSearch, you can perform full-text searches on it with all of the features you might expect: search by field, search multiple indices, boost fields, rank results by score, sort results by field, and aggregate results.
|
||||
|
||||
Unsurprisingly, people often use search engines like OpenSearch as the backend for a search application---think [Wikipedia](https://en.wikipedia.org/wiki/Wikipedia:FAQ/Technical#What_software_is_used_to_run_Wikipedia?) or an online store. It offers excellent performance and can scale up and down as the needs of the application grow or shrink.
|
||||
|
||||
An equally popular, but less obvious use case is log analytics, in which you take the logs from an application, feed them into OpenSearch, and use the rich search and visualization functionality to identify issues. For example, a malfunctioning web server might throw a 500 error 0.5% of the time, which can be hard to notice unless you have a real-time graph of all HTTP status codes that the server has thrown in the past four hours. You can use [OpenSearch Dashboards]({{site.url}}{{site.baseurl}}/dashboards/) to build these sorts of visualizations from data in OpenSearch.
|
||||
|
||||
|
||||
## Clusters and nodes
|
||||
|
||||
Its distributed design means that you interact with OpenSearch *clusters*. Each cluster is a collection of one or more *nodes*, servers that store your data and process search requests.
|
||||
|
||||
You can run OpenSearch locally on a laptop---its system requirements are minimal---but you can also scale a single cluster to hundreds of powerful machines in a data center.
|
||||
|
||||
In a single node cluster, such as a laptop, one machine has to do everything: manage the state of the cluster, index and search data, and perform any preprocessing of data prior to indexing it. As a cluster grows, however, you can subdivide responsibilities. Nodes with fast disks and plenty of RAM might be great at indexing and searching data, whereas a node with plenty of CPU power and a tiny disk could manage cluster state. For more information on setting node types, see [Cluster formation]({{site.url}}{{site.baseurl}}/opensearch/cluster/).
|
||||
|
||||
|
||||
## Indices and documents
|
||||
|
||||
OpenSearch organizes data into *indices*. Each index is a collection of JSON *documents*. If you have a set of raw encyclopedia articles or log lines that you want to add to OpenSearch, you must first convert them to [JSON](https://www.json.org/). A simple JSON document for a movie might look like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "The Wind Rises",
|
||||
"release_date": "2013-07-20"
|
||||
}
|
||||
```
|
||||
|
||||
When you add the document to an index, OpenSearch adds some metadata, such as the unique document *ID*:
|
||||
|
||||
```json
|
||||
{
|
||||
"_index": "<index-name>",
|
||||
"_type": "_doc",
|
||||
"_id": "<document-id>",
|
||||
"_version": 1,
|
||||
"_source": {
|
||||
"title": "The Wind Rises",
|
||||
"release_date": "2013-07-20"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Indices also contain mappings and settings:
|
||||
|
||||
- A *mapping* is the collection of *fields* that documents in the index have. In this case, those fields are `title` and `release_date`.
|
||||
- Settings include data like the index name, creation date, and number of shards.
|
||||
|
||||
## Primary and replica shards
|
||||
|
||||
OpenSearch splits indices into *shards* for even distribution across nodes in a cluster. For example, a 400 GB index might be too large for any single node in your cluster to handle, but split into ten shards, each one 40 GB, OpenSearch can distribute the shards across ten nodes and work with each shard individually.
|
||||
|
||||
By default, OpenSearch creates a *replica* shard for each *primary* shard. If you split your index into ten shards, for example, OpenSearch also creates ten replica shards. These replica shards act as backups in the event of a node failure---OpenSearch distributes replica shards to different nodes than their corresponding primary shards---but they also improve the speed and rate at which the cluster can process search requests. You might specify more than one replica per index for a search-heavy workload.
|
||||
|
||||
Despite being a piece of an OpenSearch index, each shard is actually a full Lucene index---confusing, we know. This detail is important, though, because each instance of Lucene is a running process that consumes CPU and memory. More shards is not necessarily better. Splitting a 400 GB index into 1,000 shards, for example, would place needless strain on your cluster. A good rule of thumb is to keep shard size between 10--50 GB.
|
||||
|
||||
|
||||
## REST API
|
||||
|
||||
You interact with OpenSearch clusters using the REST API, which offers a lot of flexibility. You can use clients like [curl](https://curl.haxx.se/) or any programming language that can send HTTP requests. To add a JSON document to an OpenSearch index (i.e. index a document), you send an HTTP request:
|
||||
|
||||
```json
|
||||
PUT https://<host>:<port>/<index-name>/_doc/<document-id>
|
||||
{
|
||||
"title": "The Wind Rises",
|
||||
"release_date": "2013-07-20"
|
||||
}
|
||||
```
|
||||
|
||||
To run a search for the document:
|
||||
|
||||
```
|
||||
GET https://<host>:<port>/<index-name>/_search?q=wind
|
||||
```
|
||||
|
||||
To delete the document:
|
||||
|
||||
```
|
||||
DELETE https://<host>:<port>/<index-name>/_doc/<document-id>
|
||||
```
|
||||
|
||||
You can change most OpenSearch settings using the REST API, modify indices, check the health of the cluster, get statistics---almost everything.
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Compatibility
|
||||
parent: Install OpenSearch
|
||||
nav_order: 2
|
||||
---
|
||||
|
||||
# Operating system and JVM compatibility
|
||||
|
||||
- We recommend installing OpenSearch on RHEL- or Debian-based Linux distributions that use [systemd](https://en.wikipedia.org/wiki/Systemd), such as CentOS, Amazon Linux 2, and Ubuntu (LTS). OpenSearch should work on many Linux distributions, but we only test a handful.
|
||||
- The OpenSearch tarball ships with a compatible version of Java in the `jdk` directory. To find its version, run `./jdk/bin/java -version`. For example, the OpenSearch 1.0.0 tarball ships with Java 15 (non-LTS).
|
||||
|
||||
{% comment %}`./jdk/bin/java -version` doesn't work on macOS with zsh at the moment, and I have no idea why. Maybe we need a macOS artifact. Regardless, the command works on Amazon Linux 2 with bash and presumably other distros. - aetter{% endcomment %}
|
||||
|
||||
To use a different Java installation, set the `OPENSEARCH_JAVA_HOME` environment variable to the Java install location. We recommend Java 11 (LTS), but OpenSearch also works with Java 8.
|
||||
|
||||
OpenSearch version | Compatible Java versions | Recommended operating systems
|
||||
:--- | :--- | :---
|
||||
1.x | 8, 11 | Red Hat Enterprise Linux 7, 8; CentOS 7, 8; Amazon Linux 2; Ubuntu 16.04, 18.04, 20.04
|
||||
@@ -1,179 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Docker security configuration
|
||||
parent: Install OpenSearch
|
||||
nav_order: 5
|
||||
---
|
||||
|
||||
# Docker security configuration
|
||||
|
||||
Before deploying to a production environment, you should replace the demo security certificates and configuration YAML files with your own. With the tarball, you have direct access to the file system, but the Docker image requires modifying the Docker storage volumes to include the replacement files.
|
||||
|
||||
Additionally, you can set the Docker environment variable `DISABLE_INSTALL_DEMO_CONFIG` to `true`. This change completely disables the demo installer.
|
||||
|
||||
|
||||
## Sample Docker Compose file
|
||||
|
||||
```yml
|
||||
version: '3'
|
||||
services:
|
||||
opensearch-node1:
|
||||
image: opensearchproject/opensearch:{{site.opensearch_version}}
|
||||
container_name: opensearch-node1
|
||||
environment:
|
||||
- cluster.name=opensearch-cluster
|
||||
- node.name=opensearch-node1
|
||||
- discovery.seed_hosts=opensearch-node1,opensearch-node2
|
||||
- cluster.initial_master_nodes=opensearch-node1,opensearch-node2
|
||||
- bootstrap.memory_lock=true # along with the memlock settings below, disables swapping
|
||||
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # minimum and maximum Java heap size, recommend setting both to 50% of system RAM
|
||||
- network.host=0.0.0.0 # required if not using the demo security configuration
|
||||
ulimits:
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
nofile:
|
||||
soft: 65536 # maximum number of open files for the OpenSearch user, set to at least 65536 on modern systems
|
||||
hard: 65536
|
||||
volumes:
|
||||
- opensearch-data1:/usr/share/opensearch/data
|
||||
- ./root-ca.pem:/usr/share/opensearch/config/root-ca.pem
|
||||
- ./node.pem:/usr/share/opensearch/config/node.pem
|
||||
- ./node-key.pem:/usr/share/opensearch/config/node-key.pem
|
||||
- ./admin.pem:/usr/share/opensearch/config/admin.pem
|
||||
- ./admin-key.pem:/usr/share/opensearch/config/admin-key.pem
|
||||
- ./custom-opensearch.yml:/usr/share/opensearch/config/opensearch.yml
|
||||
- ./internal_users.yml:/usr/share/opensearch/plugins/opensearch-security/securityconfig/internal_users.yml
|
||||
- ./roles_mapping.yml:/usr/share/opensearch/plugins/opensearch-security/securityconfig/roles_mapping.yml
|
||||
- ./tenants.yml:/usr/share/opensearch/plugins/opensearch-security/securityconfig/tenants.yml
|
||||
- ./roles.yml:/usr/share/opensearch/plugins/opensearch-security/securityconfig/roles.yml
|
||||
- ./action_groups.yml:/usr/share/opensearch/plugins/opensearch-security/securityconfig/action_groups.yml
|
||||
ports:
|
||||
- 9200:9200
|
||||
- 9600:9600 # required for Performance Analyzer
|
||||
networks:
|
||||
- opensearch-net
|
||||
opensearch-node2:
|
||||
image: opensearchproject/opensearch:{{site.opensearch_version}}
|
||||
container_name: opensearch-node2
|
||||
environment:
|
||||
- cluster.name=opensearch-cluster
|
||||
- node.name=opensearch-node2
|
||||
- discovery.seed_hosts=opensearch-node1,opensearch-node2
|
||||
- cluster.initial_master_nodes=opensearch-node1,opensearch-node2
|
||||
- bootstrap.memory_lock=true
|
||||
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
- network.host=0.0.0.0
|
||||
ulimits:
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
nofile:
|
||||
soft: 65536
|
||||
hard: 65536
|
||||
volumes:
|
||||
- opensearch-data2:/usr/share/opensearch/data
|
||||
- ./root-ca.pem:/usr/share/opensearch/config/root-ca.pem
|
||||
- ./node.pem:/usr/share/opensearch/config/node.pem
|
||||
- ./node-key.pem:/usr/share/opensearch/config/node-key.pem
|
||||
- ./admin.pem:/usr/share/opensearch/config/admin.pem
|
||||
- ./admin-key.pem:/usr/share/opensearch/config/admin-key.pem
|
||||
- ./custom-opensearch.yml:/usr/share/opensearch/config/opensearch.yml
|
||||
- ./internal_users.yml:/usr/share/opensearch/plugins/opensearch-security/securityconfig/internal_users.yml
|
||||
- ./roles_mapping.yml:/usr/share/opensearch/plugins/opensearch-security/securityconfig/roles_mapping.yml
|
||||
- ./tenants.yml:/usr/share/opensearch/plugins/opensearch-security/securityconfig/tenants.yml
|
||||
- ./roles.yml:/usr/share/opensearch/plugins/opensearch-security/securityconfig/roles.yml
|
||||
- ./action_groups.yml:/usr/share/opensearch/plugins/opensearch-security/securityconfig/action_groups.yml
|
||||
networks:
|
||||
- opensearch-net
|
||||
opensearch-dashboards
|
||||
image: opensearchproject/opensearch-dashboards:{{site.opensearch_version}}
|
||||
container_name: opensearch-dashboards
|
||||
ports:
|
||||
- 5601:5601
|
||||
expose:
|
||||
- "5601"
|
||||
environment:
|
||||
OPENSEARCH_HOSTS: '["https://opensearch-node1:9200","https://opensearch-node2:9200"]' # must be a string with no spaces when specified as an environment variable
|
||||
volumes:
|
||||
- ./custom-opensearch_dashboards.yml:/usr/share/opensearch-dashboards/config/opensearch_dashboards.yml
|
||||
networks:
|
||||
- opensearch-net
|
||||
|
||||
volumes:
|
||||
opensearch-data1:
|
||||
opensearch-data2:
|
||||
|
||||
networks:
|
||||
opensearch-net:
|
||||
```
|
||||
|
||||
Then make your changes to `opensearch.yml`. For a full list of settings, see [Security]({{site.url}}{{site.baseurl}}/security-plugin/configuration/index/). This example adds (extremely) verbose audit logging:
|
||||
|
||||
```yml
|
||||
plugins.security.ssl.transport.pemcert_filepath: node.pem
|
||||
plugins.security.ssl.transport.pemkey_filepath: node-key.pem
|
||||
plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
|
||||
plugins.security.ssl.transport.enforce_hostname_verification: false
|
||||
plugins.security.ssl.http.enabled: true
|
||||
plugins.security.ssl.http.pemcert_filepath: node.pem
|
||||
plugins.security.ssl.http.pemkey_filepath: node-key.pem
|
||||
plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem
|
||||
plugins.security.allow_default_init_securityindex: true
|
||||
plugins.security.authcz.admin_dn:
|
||||
- CN=A,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA
|
||||
plugins.security.nodes_dn:
|
||||
- 'CN=N,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA'
|
||||
plugins.security.audit.type: internal_opensearch
|
||||
plugins.security.enable_snapshot_restore_privilege: true
|
||||
plugins.security.check_snapshot_restore_write_privileges: true
|
||||
plugins.security.restapi.roles_enabled: ["all_access", "security_rest_api_access"]
|
||||
cluster.routing.allocation.disk.threshold_enabled: false
|
||||
opendistro_security.audit.config.disabled_rest_categories: NONE
|
||||
opendistro_security.audit.config.disabled_transport_categories: NONE
|
||||
```
|
||||
|
||||
Use this same override process to specify new [authentication settings]({{site.url}}{{site.baseurl}}/security-plugin/configuration/configuration/) in `/usr/share/opensearch/plugins/opensearch-security/securityconfig/config.yml`, as well as new default [internal users, roles, mappings, action groups, and tenants]({{site.url}}{{site.baseurl}}/security-plugin/configuration/yaml/).
|
||||
|
||||
To start the cluster, run `docker-compose up`.
|
||||
|
||||
If you encounter any `File /usr/share/opensearch/config/opensearch.yml has insecure file permissions (should be 0600)` messages, you can use `chmod` to set file permissions before running `docker-compose up`. Docker Compose passes files to the container as-is.
|
||||
{: .note }
|
||||
|
||||
Finally, you can reach OpenSearch Dashboards at http://localhost:5601, sign in, and use the **Security** panel to perform other management tasks.
|
||||
|
||||
|
||||
## Using certificates with Docker
|
||||
|
||||
To use your own certificates in your configuration, add all of the necessary certificates to the volumes section of the Docker Compose file:
|
||||
|
||||
```yml
|
||||
volumes:
|
||||
- ./root-ca.pem:/full/path/to/certificate.pem
|
||||
- ./admin.pem:/full/path/to/certificate.pem
|
||||
- ./admin-key.pem:/full/path/to/certificate.pem
|
||||
#Add other certificates
|
||||
```
|
||||
|
||||
After replacing the demo certificates with your own, you must also include a custom `opensearch.yml` in your setup, which you need to specify in the volumes section.
|
||||
|
||||
```yml
|
||||
volumes:
|
||||
#Add certificates here
|
||||
- ./custom-opensearch.yml: /full/path/to/custom-opensearch.yml
|
||||
```
|
||||
|
||||
Remember that the certificates you specify in your Docker Compose file must be the same as the certificates listed in your custom `opensearch.yml` file. At a minimum, you should replace the root, admin, and node certificates with your own. For more information about adding and using certificates, see [Configure TLS certificates]({{site.url}}{{site.baseurl}}/security-plugin/configuration/tls).
|
||||
|
||||
```yml
|
||||
plugins.security.ssl.transport.pemcert_filepath: new-node-cert.pem
|
||||
plugins.security.ssl.transport.pemkey_filepath: new-node-cert-key.pem
|
||||
plugins.security.ssl.transport.pemtrustedcas_filepath: new-root-ca.pem
|
||||
plugins.security.ssl.http.pemcert_filepath: new-node-cert.pem
|
||||
plugins.security.ssl.http.pemkey_filepath: new-node-cert-key.pem
|
||||
plugins.security.ssl.http.pemtrustedcas_filepath: new-root-ca.pem
|
||||
plugins.security.authcz.admin_dn:
|
||||
- CN=admin,OU=SSL,O=Test,L=Test,C=DE
|
||||
```
|
||||
|
||||
To start the cluster, run `docker-compose up` as usual.
|
||||
@@ -1,324 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Docker
|
||||
parent: Install OpenSearch
|
||||
nav_order: 3
|
||||
---
|
||||
|
||||
# Docker image
|
||||
|
||||
You can pull the OpenSearch Docker image just like any other image:
|
||||
|
||||
```bash
|
||||
docker pull opensearchproject/opensearch:{{site.opensearch_version}}
|
||||
docker pull opensearchproject/opensearch-dashboards:{{site.opensearch_version}}
|
||||
```
|
||||
|
||||
To check available versions, see [Docker Hub](https://hub.docker.com/u/opensearchproject).
|
||||
|
||||
OpenSearch images use `amazonlinux:2` as the base image. If you run Docker locally, set Docker to use at least 4 GB of RAM in **Preferences** > **Resources**.
|
||||
|
||||
|
||||
---
|
||||
|
||||
#### Table of contents
|
||||
1. TOC
|
||||
{:toc}
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Run the image
|
||||
|
||||
To run the image for local development:
|
||||
|
||||
```bash
|
||||
docker run -p 9200:9200 -p 9600:9600 -e "discovery.type=single-node" opensearchproject/opensearch:{{site.opensearch_version}}
|
||||
```
|
||||
|
||||
Then send requests to the server to verify that OpenSearch is up and running:
|
||||
|
||||
```bash
|
||||
curl -XGET https://localhost:9200 -u 'admin:admin' --insecure
|
||||
curl -XGET https://localhost:9200/_cat/nodes?v -u 'admin:admin' --insecure
|
||||
curl -XGET https://localhost:9200/_cat/plugins?v -u 'admin:admin' --insecure
|
||||
```
|
||||
|
||||
To find the container ID:
|
||||
|
||||
```bash
|
||||
docker ps
|
||||
```
|
||||
|
||||
Then you can stop the container using:
|
||||
|
||||
```bash
|
||||
docker stop <container-id>
|
||||
```
|
||||
|
||||
|
||||
## Start a cluster
|
||||
|
||||
To deploy multiple nodes and simulate a more realistic deployment, create a [docker-compose.yml](https://docs.docker.com/compose/compose-file/) file appropriate for your environment and run:
|
||||
|
||||
```bash
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
To stop the cluster, run:
|
||||
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
To stop the cluster and delete all data volumes, run:
|
||||
|
||||
```bash
|
||||
docker-compose down -v
|
||||
```
|
||||
|
||||
|
||||
#### Sample Docker Compose file
|
||||
|
||||
This sample file starts two data nodes and a container for OpenSearch Dashboards.
|
||||
|
||||
```yml
|
||||
version: '3'
|
||||
services:
|
||||
opensearch-node1:
|
||||
image: opensearchproject/opensearch:{{site.opensearch_version}}
|
||||
container_name: opensearch-node1
|
||||
environment:
|
||||
- cluster.name=opensearch-cluster
|
||||
- node.name=opensearch-node1
|
||||
- discovery.seed_hosts=opensearch-node1,opensearch-node2
|
||||
- cluster.initial_master_nodes=opensearch-node1,opensearch-node2
|
||||
- bootstrap.memory_lock=true # along with the memlock settings below, disables swapping
|
||||
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # minimum and maximum Java heap size, recommend setting both to 50% of system RAM
|
||||
ulimits:
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
nofile:
|
||||
soft: 65536 # maximum number of open files for the OpenSearch user, set to at least 65536 on modern systems
|
||||
hard: 65536
|
||||
volumes:
|
||||
- opensearch-data1:/usr/share/opensearch/data
|
||||
ports:
|
||||
- 9200:9200
|
||||
- 9600:9600 # required for Performance Analyzer
|
||||
networks:
|
||||
- opensearch-net
|
||||
opensearch-node2:
|
||||
image: opensearchproject/opensearch:{{site.opensearch_version}}
|
||||
container_name: opensearch-node2
|
||||
environment:
|
||||
- cluster.name=opensearch-cluster
|
||||
- node.name=opensearch-node2
|
||||
- discovery.seed_hosts=opensearch-node1,opensearch-node2
|
||||
- cluster.initial_master_nodes=opensearch-node1,opensearch-node2
|
||||
- bootstrap.memory_lock=true
|
||||
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
ulimits:
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
nofile:
|
||||
soft: 65536
|
||||
hard: 65536
|
||||
volumes:
|
||||
- opensearch-data2:/usr/share/opensearch/data
|
||||
networks:
|
||||
- opensearch-net
|
||||
opensearch-dashboards:
|
||||
image: opensearchproject/opensearch-dashboards:{{site.opensearch_version}}
|
||||
container_name: opensearch-dashboards
|
||||
ports:
|
||||
- 5601:5601
|
||||
expose:
|
||||
- "5601"
|
||||
environment:
|
||||
OPENSEARCH_HOSTS: '["https://opensearch-node1:9200","https://opensearch-node2:9200"]' # must be a string with no spaces when specified as an environment variable
|
||||
networks:
|
||||
- opensearch-net
|
||||
|
||||
volumes:
|
||||
opensearch-data1:
|
||||
opensearch-data2:
|
||||
|
||||
networks:
|
||||
opensearch-net:
|
||||
```
|
||||
|
||||
If you override `opensearch_dashboards.yml` settings using environment variables, as seen above, use all uppercase letters and periods in place of underscores (e.g. for `opensearch.hosts`, use `OPENSEARCH_HOSTS`).
|
||||
{: .note}
|
||||
|
||||
|
||||
## Configure OpenSearch
|
||||
|
||||
You can pass a custom `opensearch.yml` file to the Docker container using the [`-v` flag](https://docs.docker.com/engine/reference/commandline/run#mount-volume--v---read-only) for `docker run`:
|
||||
|
||||
```bash
|
||||
docker run \
|
||||
-p 9200:9200 -p 9600:9600 \
|
||||
-e "discovery.type=single-node" \
|
||||
-v /<full-path-to>/custom-opensearch.yml:/usr/share/opensearch/config/opensearch.yml \
|
||||
opensearchproject/opensearch:{{site.opensearch_version}}
|
||||
```
|
||||
|
||||
You can perform the same operation in `docker-compose.yml` using a relative path:
|
||||
|
||||
```yml
|
||||
services:
|
||||
opensearch-node1:
|
||||
volumes:
|
||||
- opensearch-data1:/usr/share/opensearch/data
|
||||
- ./custom-opensearch.yml:/usr/share/opensearch/config/opensearch.yml
|
||||
opensearch-node2:
|
||||
volumes:
|
||||
- opensearch-data2:/usr/share/opensearch/data
|
||||
- ./custom-opensearch.yml:/usr/share/opensearch/config/opensearch.yml
|
||||
opensearch-dashboards
|
||||
volumes:
|
||||
- ./custom-opensearch_dashboards.yml:/usr/share/opensearch-dashboards/config/opensearch_dashboards.yml
|
||||
```
|
||||
|
||||
You can also configure `docker-compose.yml` and `opensearch.yml` [to take your own certificates]({{site.url}}{{site.baseurl}}/opensearch/install/docker-security/) for use with the [Security]({{site.url}}{{site.baseurl}}/security-plugin/configuration/index/) plugin.
|
||||
|
||||
|
||||
### (Optional) Set up Performance Analyzer
|
||||
|
||||
1. Enable the Performance Analyzer plugin:
|
||||
|
||||
```bash
|
||||
curl -XPOST localhost:9200/_plugins/_performanceanalyzer/cluster/config -H 'Content-Type: application/json' -d '{"enabled": true}'
|
||||
```
|
||||
|
||||
If you receive the `curl: (52) Empty reply from server` error, you are likely protecting your cluster with the security plugin and you need to provide credentials. Modify the following command to use your username and password:
|
||||
|
||||
```bash
|
||||
curl -XPOST https://localhost:9200/_plugins/_performanceanalyzer/cluster/config -H 'Content-Type: application/json' -d '{"enabled": true}' -u 'admin:admin' -k
|
||||
```
|
||||
|
||||
1. Enable the Root Cause Analyzer (RCA) framework
|
||||
|
||||
```bash
|
||||
curl -XPOST localhost:9200/_plugins/_performanceanalyzer/rca/cluster/config -H 'Content-Type: application/json' -d '{"enabled": true}'
|
||||
```
|
||||
|
||||
Similar to step 1, if you run into `curl: (52) Empty reply from server`, run the command below to enable RCA
|
||||
|
||||
```bash
|
||||
curl -XPOST https://localhost:9200/_plugins/_performanceanalyzer/rca/cluster/config -H 'Content-Type: application/json' -d '{"enabled": true}' -u 'admin:admin' -k
|
||||
```
|
||||
|
||||
1. By default, Performance Analyzer's endpoints are not accessible from outside the Docker container.
|
||||
|
||||
To edit this behavior, open a shell session in the container and modify the configuration:
|
||||
|
||||
```bash
|
||||
docker ps # Look up the container id
|
||||
docker exec -it <container-id> /bin/bash
|
||||
# Inside container
|
||||
cd plugins/opensearch_performance_analyzer/pa_config/
|
||||
vi performance-analyzer.properties
|
||||
```
|
||||
|
||||
Uncomment the line `#webservice-bind-host` and set it to `0.0.0.0`:
|
||||
|
||||
```
|
||||
# ======================== OpenSearch performance analyzer plugin config =========================
|
||||
|
||||
# NOTE: this is an example for Linux. Please modify the config accordingly if you are using it under other OS.
|
||||
|
||||
# WebService bind host; default to all interfaces
|
||||
webservice-bind-host = 0.0.0.0
|
||||
|
||||
# Metrics data location
|
||||
metrics-location = /dev/shm/performanceanalyzer/
|
||||
|
||||
# Metrics deletion interval (minutes) for metrics data.
|
||||
# Interval should be between 1 to 60.
|
||||
metrics-deletion-interval = 1
|
||||
|
||||
# If set to true, the system cleans up the files behind it. So at any point, we should expect only 2
|
||||
# metrics-db-file-prefix-path files. If set to false, no files are cleaned up. This can be useful, if you are archiving
|
||||
# the files and wouldn't like for them to be cleaned up.
|
||||
cleanup-metrics-db-files = true
|
||||
|
||||
# WebService exposed by App's port
|
||||
webservice-listener-port = 9600
|
||||
|
||||
# Metric DB File Prefix Path location
|
||||
metrics-db-file-prefix-path = /tmp/metricsdb_
|
||||
|
||||
https-enabled = false
|
||||
|
||||
#Setup the correct path for certificates
|
||||
certificate-file-path = specify_path
|
||||
|
||||
private-key-file-path = specify_path
|
||||
|
||||
# Plugin Stats Metadata file name, expected to be in the same location
|
||||
plugin-stats-metadata = plugin-stats-metadata
|
||||
|
||||
# Agent Stats Metadata file name, expected to be in the same location
|
||||
agent-stats-metadata = agent-stats-metadata
|
||||
```
|
||||
|
||||
1. Then restart the Performance Analyzer agent:
|
||||
|
||||
```bash
|
||||
kill $(ps aux | grep -i 'PerformanceAnalyzerApp' | grep -v grep | awk '{print $2}')
|
||||
```
|
||||
|
||||
|
||||
## Bash access to containers
|
||||
|
||||
To create an interactive Bash session in a container, run `docker ps` to find the container ID. Then run:
|
||||
|
||||
```bash
|
||||
docker exec -it <container-id> /bin/bash
|
||||
```
|
||||
|
||||
|
||||
## Customize the Docker image
|
||||
|
||||
To run the image with a custom plugin, first create a [`Dockerfile`](https://docs.docker.com/engine/reference/builder/):
|
||||
|
||||
```
|
||||
FROM opensearchproject/opensearch:{{site.opensearch_version}}
|
||||
RUN /usr/share/opensearch/bin/opensearch-plugin install --batch <plugin-name-or-url>
|
||||
```
|
||||
|
||||
Then run the following commands:
|
||||
|
||||
```bash
|
||||
docker build --tag=opensearch-custom-plugin .
|
||||
docker run -p 9200:9200 -p 9600:9600 -v /usr/share/opensearch/data opensearch-custom-plugin
|
||||
```
|
||||
|
||||
You can also use a `Dockerfile` to pass your own certificates for use with the [security]({{site.url}}{{site.baseurl}}/security-plugin/) plugin, similar to the `-v` argument in [Configure OpenSearch](#configure-opensearch):
|
||||
|
||||
```
|
||||
FROM opensearchproject/opensearch:{{site.opensearch_version}}
|
||||
COPY --chown=opensearch:opensearch opensearch.yml /usr/share/opensearch/config/
|
||||
COPY --chown=opensearch:opensearch my-key-file.pem /usr/share/opensearch/config/
|
||||
COPY --chown=opensearch:opensearch my-certificate-chain.pem /usr/share/opensearch/config/
|
||||
COPY --chown=opensearch:opensearch my-root-cas.pem /usr/share/opensearch/config/
|
||||
```
|
||||
|
||||
Alternately, you might want to remove a plugin. This `Dockerfile` removes the security plugin:
|
||||
|
||||
```
|
||||
FROM opensearchproject/opensearch:{{site.opensearch_version}}
|
||||
RUN /usr/share/opensearch/bin/opensearch-plugin remove opensearch-security
|
||||
COPY --chown=opensearch:opensearch opensearch.yml /usr/share/opensearch/config/
|
||||
```
|
||||
|
||||
In this case, `opensearch.yml` is a "vanilla" version of the file with no plugin entries. It might look like this:
|
||||
|
||||
```yml
|
||||
cluster.name: "docker-cluster"
|
||||
network.host: 0.0.0.0
|
||||
```
|
||||
@@ -1,159 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Helm
|
||||
parent: Install OpenSearch
|
||||
nav_order: 6
|
||||
---
|
||||
|
||||
# Run OpenSearch using Helm
|
||||
|
||||
Helm is a package manager that allows you to easily install and manage OpenSearch in a Kubernetes cluster. You can define your OpenSearch configurations in a YAML file and use Helm to deploy your applications in a version-controlled and reproducible way.
|
||||
|
||||
The Helm chart contains the resources described in the following table.
|
||||
|
||||
Resource | Description
|
||||
:--- | :---
|
||||
`Chart.yaml` | Information about the chart.
|
||||
`values.yaml` | Default configuration values for the chart.
|
||||
`templates` | Templates that combine with values to generate the Kubernetes manifest files.
|
||||
|
||||
The specification in the default Helm chart supports many standard use cases and setups. You can modify the default chart to configure your desired specifications and set Transport Layer Security (TLS) and role-based access control (RBAC).
|
||||
|
||||
For information about the default configuration, steps to configure security, and configurable parameters, see the
|
||||
[README](https://github.com/opensearch-project/helm-charts/tree/main/charts).
|
||||
|
||||
The instructions here assume you have a Kubernetes cluster with Helm preinstalled. See the [Kubernetes documentation](https://kubernetes.io/docs/setup/) for steps to configure a Kubernetes cluster and the [Helm documentation](https://helm.sh/docs/intro/install/) to install Helm.
|
||||
{: .note }
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The default Helm chart deploys a three-node cluster. We recommend that you have at least 8 GiB of memory available for this deployment. You can expect the deployment to fail if, say, you have less than 4 GiB of memory available.
|
||||
|
||||
## Install OpenSearch using Helm
|
||||
|
||||
1. Add `opensearch` [helm-charts](https://github.com/opensearch-project/helm-charts) repository to Helm:
|
||||
|
||||
```bash
|
||||
helm repo add opensearch https://opensearch-project.github.io/helm-charts/
|
||||
```
|
||||
|
||||
1. Update the available charts locally from charts repositories:
|
||||
|
||||
```bash
|
||||
helm repo update
|
||||
```
|
||||
|
||||
1. To search for the OpenSearch-related Helm charts:
|
||||
|
||||
```bash
|
||||
helm search repo opensearch
|
||||
```
|
||||
|
||||
```bash
|
||||
NAME CHART VERSION APP VERSION DESCRIPTION
|
||||
opensearch/opensearch 1.0.7 1.0.0 A Helm chart for OpenSearch
|
||||
opensearch/opensearch-dashboards 1.0.4 1.0.0 A Helm chart for OpenSearch Dashboards
|
||||
```
|
||||
|
||||
1. Deploy OpenSearch:
|
||||
|
||||
```bash
|
||||
helm install my-deployment opensearch/opensearch
|
||||
```
|
||||
|
||||
You can also build the `opensearch-1.0.0.tgz` file manually:
|
||||
|
||||
1. Change to the `opensearch` directory:
|
||||
|
||||
```bash
|
||||
cd charts/opensearch
|
||||
```
|
||||
|
||||
1. Package the Helm chart:
|
||||
|
||||
```bash
|
||||
helm package .
|
||||
```
|
||||
|
||||
1. Deploy OpenSearch:
|
||||
|
||||
```bash
|
||||
helm install --generate-name opensearch-1.0.0.tgz
|
||||
```
|
||||
The output shows you the specifications instantiated from the install.
|
||||
To customize the deployment, pass in the values that you want to override with a custom YAML file:
|
||||
|
||||
```bash
|
||||
helm install --values=customvalues.yaml opensearch-1.0.0.tgz
|
||||
```
|
||||
|
||||
#### Sample output
|
||||
|
||||
```yaml
|
||||
NAME: opensearch-1-1629223146
|
||||
LAST DEPLOYED: Tue Aug 17 17:59:07 2021
|
||||
NAMESPACE: default
|
||||
STATUS: deployed
|
||||
REVISION: 1
|
||||
TEST SUITE: None
|
||||
NOTES:
|
||||
Watch all cluster members come up.
|
||||
$ kubectl get pods --namespace=default -l app=opensearch-cluster-master -w
|
||||
```
|
||||
|
||||
To make sure your OpenSearch pod is up and running, run the following command:
|
||||
|
||||
```bash
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
opensearch-cluster-master-0 1/1 Running 0 3m56s
|
||||
opensearch-cluster-master-1 1/1 Running 0 3m56s
|
||||
opensearch-cluster-master-2 1/1 Running 0 3m56s
|
||||
```
|
||||
|
||||
To access the OpenSearch shell:
|
||||
|
||||
```bash
|
||||
$ kubectl exec -it opensearch-cluster-master-0 -- /bin/bash
|
||||
```
|
||||
|
||||
You can send requests to the pod to verify that OpenSearch is up and running:
|
||||
|
||||
```json
|
||||
$ curl -XGET https://localhost:9200 -u 'admin:admin' --insecure
|
||||
{
|
||||
"name" : "opensearch-cluster-master-1",
|
||||
"cluster_name" : "opensearch-cluster",
|
||||
"cluster_uuid" : "hP2gq5bPS3SLp8Z7wXm8YQ",
|
||||
"version" : {
|
||||
"distribution" : "opensearch",
|
||||
"number" : "1.0.0",
|
||||
"build_type" : "tar",
|
||||
"build_hash" : "34550c5b17124ddc59458ef774f6b43a086522e3",
|
||||
"build_date" : "2021-07-02T23:22:21.383695Z",
|
||||
"build_snapshot" : false,
|
||||
"lucene_version" : "8.8.2",
|
||||
"minimum_wire_compatibility_version" : "6.8.0",
|
||||
"minimum_index_compatibility_version" : "6.0.0-beta1"
|
||||
},
|
||||
"tagline" : "The OpenSearch Project: https://opensearch.org/"
|
||||
}
|
||||
```
|
||||
|
||||
## Uninstall using Helm
|
||||
|
||||
To identify the OpenSearch deployment that you want to delete:
|
||||
|
||||
```bash
|
||||
$ helm list
|
||||
NAME NAMESPACEREVISIONUPDATED STATUS CHART APP VERSION
|
||||
opensearch-1-1629223146 default 1 2021-08-17 17:59:07.664498239 +0000 UTCdeployedopensearch-1.0.0 1.0.0
|
||||
```
|
||||
|
||||
To delete or uninstall a deployment, run the following command:
|
||||
|
||||
```bash
|
||||
helm delete opensearch-1-1629223146
|
||||
```
|
||||
|
||||
For steps to install OpenSearch Dashboards, see [Helm to install OpenSearch Dashboards]({{site.url}}{{site.baseurl}}/dashboards/install/helm/).
|
||||
@@ -1,40 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Important settings
|
||||
parent: Install OpenSearch
|
||||
nav_order: 70
|
||||
---
|
||||
|
||||
# Important settings
|
||||
|
||||
For production workloads, make sure the [Linux setting](https://www.kernel.org/doc/Documentation/sysctl/vm.txt) `vm.max_map_count` is set to at least 262144. Even if you use the Docker image, set this value on the *host machine*. To check the current value, run this command:
|
||||
|
||||
```bash
|
||||
cat /proc/sys/vm/max_map_count
|
||||
```
|
||||
|
||||
To increase the value, add the following line to `/etc/sysctl.conf`:
|
||||
|
||||
```
|
||||
vm.max_map_count=262144
|
||||
```
|
||||
|
||||
Then run `sudo sysctl -p` to reload.
|
||||
|
||||
The [sample docker-compose.yml]({{site.url}}{{site.baseurl}}/opensearch/install/docker#sample-docker-compose-file) file also contains several key settings:
|
||||
|
||||
- `bootstrap.memory_lock=true`
|
||||
|
||||
Disbles swapping (along with `memlock`). Swapping can dramatically decrease performance and stability, so you should ensure it is disabled on production clusters.
|
||||
|
||||
- `OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m`
|
||||
|
||||
Sets the size of the Java heap (we recommend half of system RAM).
|
||||
|
||||
- `nofile 65536`
|
||||
|
||||
Sets a limit of 65536 open files for the OpenSearch user.
|
||||
|
||||
- `port 9600`
|
||||
|
||||
Allows you to access Performance Analyzer on port 9600.
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Install OpenSearch
|
||||
nav_order: 2
|
||||
redirect_from:
|
||||
- /opensearch/install/
|
||||
has_children: true
|
||||
---
|
||||
|
||||
# Install and configure OpenSearch
|
||||
|
||||
OpenSearch has two installation options at this time: Docker images and tarballs.
|
||||
@@ -1,299 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: OpenSearch plugins
|
||||
parent: Install OpenSearch
|
||||
nav_order: 90
|
||||
---
|
||||
|
||||
# Standalone OpenSearch plugin installation
|
||||
|
||||
If you don't want to use the all-in-one OpenSearch installation options, you can install the individual plugins on a compatible OpenSearch cluster, just like any other plugin.
|
||||
|
||||
|
||||
---
|
||||
|
||||
#### Table of contents
|
||||
1. TOC
|
||||
{:toc}
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Plugin compatibility
|
||||
|
||||
<table>
|
||||
<thead style="text-align: left">
|
||||
<tr>
|
||||
<th>OpenSearch version</th>
|
||||
<th>Plugin versions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>1.1.0</td>
|
||||
<td>
|
||||
<pre>opensearch-alerting 1.1.0.0
|
||||
opensearch-anomaly-detection 1.1.0.0
|
||||
opensearch-asynchronous-search 1.1.0.0
|
||||
opensearch-cross-cluster-replication 1.1.0.0
|
||||
opensearch-index-management 1.1.0.0
|
||||
opensearch-job-scheduler 1.1.0.0
|
||||
opensearch-knn 1.1.0.0
|
||||
opensearch-notebooks 1.1.0.0
|
||||
opensearch-performance-analyzer 1.1.0.0
|
||||
opensearch-reports-scheduler 1.1.0.0
|
||||
opensearch-security 1.1.0.0
|
||||
opensearch-sql 1.1.0.0
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1.0.1</td>
|
||||
<td>
|
||||
<pre>opensearch-alerting 1.0.0.0
|
||||
opensearch-anomaly-detection 1.0.0.0
|
||||
opensearch-asynchronous-search 1.0.0.0
|
||||
opensearch-index-management 1.0.1.0
|
||||
opensearch-job-scheduler 1.0.0.0
|
||||
opensearch-knn 1.0.0.0
|
||||
opensearch-notebooks 1.0.0.0
|
||||
opensearch-performance-analyzer 1.0.1.0
|
||||
opensearch-reports-scheduler 1.0.0.0
|
||||
opensearch-security 1.0.1.0
|
||||
opensearch-sql 1.0.0.0
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1.0.0</td>
|
||||
<td>
|
||||
<pre>opensearch-alerting 1.0.0.0
|
||||
opensearch-anomaly-detection 1.0.0.0
|
||||
opensearch-asynchronous-search 1.0.0.0
|
||||
opensearch-index-management 1.0.0.0
|
||||
opensearch-job-scheduler 1.0.0.0
|
||||
opensearch-knn 1.0.0.0
|
||||
opensearch-notebooks 1.0.0.0
|
||||
opensearch-performance-analyzer 1.0.0.0
|
||||
opensearch-reports-scheduler 1.0.0.0
|
||||
opensearch-security 1.0.0.0
|
||||
opensearch-sql 1.0.0.0
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
To install plugins manually, you must have the exact version of OpenSearch installed, down to the minor version.
|
||||
|
||||
{% comment %}
|
||||
|
||||
To get a list of available OpenSearch versions on CentOS 7 and Amazon Linux 2, run the following command:
|
||||
|
||||
```bash
|
||||
sudo yum list opensearch-oss --showduplicates
|
||||
```
|
||||
|
||||
Then you can specify the version that you need:
|
||||
|
||||
```bash
|
||||
sudo yum install opensearch-oss-6.7.1
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## Install plugins
|
||||
|
||||
Navigate to the OpenSearch home directory (most likely, it is `/usr/share/opensearch`), and run the install command for each plugin.
|
||||
|
||||
|
||||
### Security
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-plugins/opensearch-security/opensearch-security-{{site.opensearch_major_minor_version}}.1.0.zip
|
||||
```
|
||||
|
||||
After installing the security plugin, you can run `sudo sh /usr/share/opensearch/plugins/opensearch-security/tools/install_demo_configuration.sh` to quickly get started with demo certificates. Otherwise, you must configure it manually and run [securityadmin.sh]({{site.url}}{{site.baseurl}}/security-plugin/configuration/security-admin/).
|
||||
|
||||
The security plugin has a corresponding [OpenSearch Dashboards plugin]({{site.url}}{{site.baseurl}}/opensearch-dashboards/install/plugins) that you probably want to install as well.
|
||||
|
||||
|
||||
### Job scheduler
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-plugins/opensearch-job-scheduler/opensearch-job-scheduler-{{site.opensearch_major_minor_version}}.0.0.zip
|
||||
```
|
||||
|
||||
|
||||
### Alerting
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-plugins/opensearch-alerting/opensearch-alerting-{{site.opensearch_major_minor_version}}.1.0.zip
|
||||
```
|
||||
|
||||
To install Alerting, you must first install the Job Scheduler plugin. Alerting has a corresponding [OpenSearch Dashboards plugin]({{site.url}}{{site.baseurl}}/opensearch-dashboards/install/plugins/) that you probably want to install as well.
|
||||
|
||||
|
||||
### SQL
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-plugins/opensearch-sql/opensearch-sql-{{site.opensearch_major_minor_version}}.2.0.zip
|
||||
```
|
||||
|
||||
|
||||
### Reports scheduler
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-plugins/opensearch-reports-scheduler/opensearch-reports-scheduler-{{site.opensearch_major_minor_version}}.0.0.zip
|
||||
```
|
||||
|
||||
|
||||
### Index State Management
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-plugins/opensearch-index-management/opensearch-index-management-{{site.opensearch_major_minor_version}}.2.0.zip
|
||||
```
|
||||
|
||||
To install Index State Management, you must first install the Job Scheduler plugin. ISM has a corresponding [OpenSearch Dashboards plugin]({{site.url}}{{site.baseurl}}/opensearch-dashboards/install/plugins/) that you probably want to install as well.
|
||||
|
||||
|
||||
### k-NN
|
||||
|
||||
k-NN is only available as part of the all-in-one installs: Docker, RPM, and Debian.
|
||||
|
||||
|
||||
### Anomaly detection
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-plugins/opensearch-anomaly-detection/opensearch-anomaly-detection-{{site.opensearch_major_minor_version}}.0.0.zip
|
||||
```
|
||||
|
||||
|
||||
### Asynchronous search
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-plugins/opensearch-asynchronous-search/opensearch-asynchronous-search-{{site.opensearch_major_minor_version}}.0.1.zip
|
||||
```
|
||||
|
||||
|
||||
### Performance Analyzer
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-plugin install https://d3g5vo6xdbdb9a.cloudfront.net/downloads/opensearch-plugins/performance-analyzer/opensearch-performance-analyzer-{{site.opensearch_major_minor_version}}.0.0.zip
|
||||
```
|
||||
|
||||
Performance Analyzer requires some manual configuration after installing the plugin:
|
||||
|
||||
1. Create `/usr/lib/systemd/system/opensearch-performance-analyzer.service` based on [this file](https://github.com/opensearch-project/performance-analyzer/blob/master/packaging/opensearch-performance-analyzer.service).
|
||||
|
||||
1. Make the CLI executable:
|
||||
|
||||
```bash
|
||||
sudo chmod +x /usr/share/opensearch/bin/performance-analyzer-agent-cli
|
||||
```
|
||||
|
||||
1. Run the appropriate `postinst` script for your Linux distribution:
|
||||
|
||||
```bash
|
||||
# Debian-based distros
|
||||
sudo sh /usr/share/opensearch/plugins/opensearch-performance-analyzer/install/deb/postinst.sh 1
|
||||
|
||||
# RPM distros
|
||||
sudo sh /usr/share/opensearch/plugins/opensearch-performance-analyzer/install/rpm/postinst.sh 1
|
||||
```
|
||||
|
||||
1. Make Performance Analyzer accessible outside of the host machine
|
||||
|
||||
```bash
|
||||
cd /usr/share/opensearch # navigate to the OpenSearch home directory
|
||||
cd plugins/opensearch_performance_analyzer/pa_config/
|
||||
vi performance-analyzer.properties
|
||||
```
|
||||
|
||||
Uncomment the line `#webservice-bind-host` and set it to `0.0.0.0`:
|
||||
|
||||
```bash
|
||||
# ======================== OpenSearch performance analyzer plugin config =========================
|
||||
|
||||
# NOTE: this is an example for Linux. Please modify the config accordingly if you are using it under other OS.
|
||||
|
||||
# WebService bind host; default to all interfaces
|
||||
webservice-bind-host = 0.0.0.0
|
||||
|
||||
# Metrics data location
|
||||
metrics-location = /dev/shm/performanceanalyzer/
|
||||
|
||||
# Metrics deletion interval (minutes) for metrics data.
|
||||
# Interval should be between 1 to 60.
|
||||
metrics-deletion-interval = 1
|
||||
|
||||
# If set to true, the system cleans up the files behind it. So at any point, we should expect only 2
|
||||
# metrics-db-file-prefix-path files. If set to false, no files are cleaned up. This can be useful, if you are archiving
|
||||
# the files and wouldn't like for them to be cleaned up.
|
||||
cleanup-metrics-db-files = true
|
||||
|
||||
# WebService exposed by App's port
|
||||
webservice-listener-port = 9600
|
||||
|
||||
# Metric DB File Prefix Path location
|
||||
metrics-db-file-prefix-path = /tmp/metricsdb_
|
||||
|
||||
https-enabled = false
|
||||
|
||||
#Setup the correct path for certificates
|
||||
certificate-file-path = specify_path
|
||||
|
||||
private-key-file-path = specify_path
|
||||
|
||||
# Plugin Stats Metadata file name, expected to be in the same location
|
||||
plugin-stats-metadata = plugin-stats-metadata
|
||||
|
||||
# Agent Stats Metadata file name, expected to be in the same location
|
||||
agent-stats-metadata = agent-stats-metadata
|
||||
```
|
||||
|
||||
1. Start the OpenSearch service:
|
||||
|
||||
```bash
|
||||
sudo systemctl start opensearch.service
|
||||
```
|
||||
|
||||
1. Send a test request:
|
||||
|
||||
```bash
|
||||
curl -XGET "localhost:9600/_plugins/_performanceanalyzer/metrics?metrics=Latency,CPU_Utilization&agg=avg,max&dim=ShardID&nodes=all"
|
||||
```
|
||||
{% endcomment %}
|
||||
|
||||
## List installed plugins
|
||||
|
||||
To check your installed plugins:
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-plugin list
|
||||
```
|
||||
|
||||
|
||||
## Remove plugins
|
||||
|
||||
If you are removing Performance Analyzer, see below. Otherwise, you can remove the plugin with a single command:
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-plugin remove <plugin-name>
|
||||
```
|
||||
|
||||
Then restart OpenSearch on the node:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart opensearch.service
|
||||
```
|
||||
|
||||
## Update plugins
|
||||
|
||||
OpenSearch doesn't update plugins. Instead, you have to remove and reinstall them:
|
||||
|
||||
```bash
|
||||
sudo bin/opensearch-plugin remove <plugin-name>
|
||||
sudo bin/opensearch-plugin install <plugin-name>
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user