diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..07a6101c --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,52 @@ +--- +version: 2.1 +orbs: + prometheus: prometheus/prometheus@0.17.1 +executors: + # This must match .promu.yml. + golang: + docker: + - image: cimg/go:1.23 +jobs: + test: + executor: golang + steps: + - prometheus/setup_environment + - run: make + - prometheus/store_artifact: + file: elasticsearch_exporter +workflows: + version: 2 + elasticsearch_exporter: + jobs: + - test: + filters: + tags: + only: /.*/ + - prometheus/build: + name: build + filters: + tags: + only: /.*/ + - prometheus/publish_master: + context: org-context + docker_hub_organization: prometheuscommunity + quay_io_organization: prometheuscommunity + requires: + - test + - build + filters: + branches: + only: master + - prometheus/publish_release: + context: org-context + docker_hub_organization: prometheuscommunity + quay_io_organization: prometheuscommunity + requires: + - test + - build + filters: + tags: + only: /^v.*/ + branches: + ignore: /.*/ diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..202ae236 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "monthly" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..64d02488 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,102 @@ +--- +name: CI +on: + pull_request: + push: + +jobs: + test_go: + name: Go tests + runs-on: ubuntu-latest + container: + # Whenever the Go version is updated here, .promu.yml + # should also be updated. + image: quay.io/prometheus/golang-builder:1.23-base + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: prometheus/promci@52c7012f5f0070d7281b8db4a119e21341d43c91 # v0.4.5 + - uses: ./.github/promci/actions/setup_environment + - run: make GO_ONLY=1 SKIP_GOLANGCI_LINT=1 + + build: + name: Build Prometheus for common architectures + runs-on: ubuntu-latest + if: | + !(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) + && + !(github.event_name == 'pull_request' && startsWith(github.event.pull_request.base.ref, 'release-')) + && + !(github.event_name == 'push' && github.event.ref == 'refs/heads/main') + && + !(github.event_name == 'push' && github.event.ref == 'refs/heads/master') + strategy: + matrix: + thread: [ 0, 1, 2 ] + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: prometheus/promci@52c7012f5f0070d7281b8db4a119e21341d43c91 # v0.4.5 + - uses: ./.github/promci/actions/build + with: + promu_opts: "-p linux/amd64 -p windows/amd64 -p linux/arm64 -p darwin/amd64 -p darwin/arm64 -p linux/386" + parallelism: 3 + thread: ${{ matrix.thread }} + + build_all: + name: Build Prometheus for all architectures + runs-on: ubuntu-latest + if: | + (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) + || + (github.event_name == 'pull_request' && startsWith(github.event.pull_request.base.ref, 'release-')) + || + (github.event_name == 'push' && github.event.ref == 'refs/heads/main') + || + (github.event_name == 'push' && github.event.ref == 'refs/heads/master') + strategy: + matrix: + thread: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + + # Whenever the Go version is updated here, .promu.yml + # should also be updated. + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: prometheus/promci@52c7012f5f0070d7281b8db4a119e21341d43c91 # v0.4.5 + - uses: ./.github/promci/actions/build + with: + parallelism: 12 + thread: ${{ matrix.thread }} + + publish_main: + name: Publish main branch artifacts + runs-on: ubuntu-latest + needs: [test_go, build_all] + if: | + (github.event_name == 'push' && github.event.ref == 'refs/heads/main') + || + (github.event_name == 'push' && github.event.ref == 'refs/heads/master') + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: prometheus/promci@52c7012f5f0070d7281b8db4a119e21341d43c91 # v0.4.5 + - uses: ./.github/promci/actions/publish_main + with: + docker_hub_login: ${{ secrets.docker_hub_login }} + docker_hub_password: ${{ secrets.docker_hub_password }} + quay_io_login: ${{ secrets.quay_io_login }} + quay_io_password: ${{ secrets.quay_io_password }} + + publish_release: + name: Publish release artefacts + runs-on: ubuntu-latest + needs: [test_go, build_all] + if: | + (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: prometheus/promci@52c7012f5f0070d7281b8db4a119e21341d43c91 # v0.4.5 + - uses: ./.github/promci/actions/publish_release + with: + docker_hub_login: ${{ secrets.docker_hub_login }} + docker_hub_password: ${{ secrets.docker_hub_password }} + quay_io_login: ${{ secrets.quay_io_login }} + quay_io_password: ${{ secrets.quay_io_password }} + github_token: ${{ secrets.PROMBOT_GITHUB_TOKEN }} diff --git a/.github/workflows/container_description.yml b/.github/workflows/container_description.yml new file mode 100644 index 00000000..dcca16ff --- /dev/null +++ b/.github/workflows/container_description.yml @@ -0,0 +1,57 @@ +--- +name: Push README to Docker Hub +on: + push: + paths: + - "README.md" + - "README-containers.md" + - ".github/workflows/container_description.yml" + branches: [ main, master ] + +permissions: + contents: read + +jobs: + PushDockerHubReadme: + runs-on: ubuntu-latest + name: Push README to Docker Hub + if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks. + steps: + - name: git checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Set docker hub repo name + run: echo "DOCKER_REPO_NAME=$(make docker-repo-name)" >> $GITHUB_ENV + - name: Push README to Dockerhub + uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8 # v1 + env: + DOCKER_USER: ${{ secrets.DOCKER_HUB_LOGIN }} + DOCKER_PASS: ${{ secrets.DOCKER_HUB_PASSWORD }} + with: + destination_container_repo: ${{ env.DOCKER_REPO_NAME }} + provider: dockerhub + short_description: ${{ env.DOCKER_REPO_NAME }} + # Empty string results in README-containers.md being pushed if it + # exists. Otherwise, README.md is pushed. + readme_file: '' + + PushQuayIoReadme: + runs-on: ubuntu-latest + name: Push README to quay.io + if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks. + steps: + - name: git checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Set quay.io org name + run: echo "DOCKER_REPO=$(echo quay.io/${GITHUB_REPOSITORY_OWNER} | tr -d '-')" >> $GITHUB_ENV + - name: Set quay.io repo name + run: echo "DOCKER_REPO_NAME=$(make docker-repo-name)" >> $GITHUB_ENV + - name: Push README to quay.io + uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8 # v1 + env: + DOCKER_APIKEY: ${{ secrets.QUAY_IO_API_TOKEN }} + with: + destination_container_repo: ${{ env.DOCKER_REPO_NAME }} + provider: quay + # Empty string results in README-containers.md being pushed if it + # exists. Otherwise, README.md is pushed. + readme_file: '' diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 00000000..01b943b9 --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,39 @@ +--- +# This action is synced from https://github.com/prometheus/prometheus +name: golangci-lint +on: + push: + paths: + - "go.sum" + - "go.mod" + - "**.go" + - "scripts/errcheck_excludes.txt" + - ".github/workflows/golangci-lint.yml" + - ".golangci.yml" + pull_request: + +permissions: # added using https://github.com/step-security/secure-repo + contents: read + +jobs: + golangci: + permissions: + contents: read # for actions/checkout to fetch code + pull-requests: read # for golangci/golangci-lint-action to fetch pull requests + name: lint + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Install Go + uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 + with: + go-version: 1.23.x + - name: Install snmp_exporter/generator dependencies + run: sudo apt-get update && sudo apt-get -y install libsnmp-dev + if: github.repository == 'prometheus/snmp_exporter' + - name: Lint + uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 + with: + args: --verbose + version: v1.62.0 diff --git a/.github/workflows/mixin.yml b/.github/workflows/mixin.yml new file mode 100644 index 00000000..840dd07b --- /dev/null +++ b/.github/workflows/mixin.yml @@ -0,0 +1,34 @@ +--- +name: mixin +on: + pull_request: + paths: + - "elasticsearch-mixin/**" + +jobs: + check-mixin: + name: check + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: 1.22.5 + - name: Install dependencies + run: | + go install github.com/google/go-jsonnet/cmd/jsonnet@v0.20.0 + go install github.com/google/go-jsonnet/cmd/jsonnetfmt@v0.20.0 + go install github.com/google/go-jsonnet/cmd/jsonnet-lint@v0.20.0 + go install github.com/monitoring-mixins/mixtool/cmd/mixtool@16dc166166d91e93475b86b9355a4faed2400c18 + go install github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb@v0.5.1 + - name: Lint + run: bash ./scripts/lint-jsonnet.sh + - name: Compile mixin + run: bash ./scripts/compile-mixin.sh + - name: Verify compiled mixin matches repo + run: | + git diff --exit-code -- ./elasticsearch-mixin || (echo "Compiled mixin does not match repo" && exit 1) + # Check if there are any new untracked files + test -z "$(git status --porcelain)" || (echo "Untracked files found, please run ./scripts/compile-mixin.sh" && exit 1) diff --git a/.gitignore b/.gitignore index cedc197b..9687f990 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ elasticsearch_exporter *.tar.gz *-stamp -.idea -*~ +.tarballs +/vendor +vendor/ diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..c6fdefb0 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,21 @@ +--- +linters: + enable: + - revive + - sloglint + +issues: + exclude-rules: + - path: _test.go + linters: + - errcheck + +linters-settings: + errcheck: + exclude-functions: scripts/errcheck_excludes.txt + revive: + rules: + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-parameter + - name: unused-parameter + severity: warning + disabled: true diff --git a/.gometalinter.json b/.gometalinter.json deleted file mode 100644 index 9748f80d..00000000 --- a/.gometalinter.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Cyclo": 40, - "Deadline": "6m", - "EnableGC": true, - "Exclude": ["TLS InsecureSkipVerify set true.", "Potential file inclusion via variable", "Errors unhandled.,LOW,HIGH"], - "Sort": ["linter", "severity", "path", "line"], - "Vendor": true -} diff --git a/.promu.yml b/.promu.yml index 9a17044b..db8843ab 100644 --- a/.promu.yml +++ b/.promu.yml @@ -1,16 +1,18 @@ go: - cgo: false + # This must match .circle/config.yml. + version: 1.23 repository: - path: github.com/justwatchcom/elasticsearch_exporter + path: github.com/prometheus-community/elasticsearch_exporter build: - flags: -a -tags netgo + binaries: + - name: elasticsearch_exporter ldflags: | -s - -X {{repoPath}}/vendor/github.com/prometheus/common/version.Version={{.Version}} - -X {{repoPath}}/vendor/github.com/prometheus/common/version.Revision={{.Revision}} - -X {{repoPath}}/vendor/github.com/prometheus/common/version.Branch={{.Branch}} - -X {{repoPath}}/vendor/github.com/prometheus/common/version.BuildUser={{user}}@{{host}} - -X {{repoPath}}/vendor/github.com/prometheus/common/version.BuildDate={{date "20060102-15:04:05"}} + -X github.com/prometheus/common/version.Version={{.Version}} + -X github.com/prometheus/common/version.Revision={{.Revision}} + -X github.com/prometheus/common/version.Branch={{.Branch}} + -X github.com/prometheus/common/version.BuildUser={{user}}@{{host}} + -X github.com/prometheus/common/version.BuildDate={{date "20060102-15:04:05"}} tarball: files: - LICENSE @@ -19,27 +21,3 @@ tarball: - examples/grafana/dashboard.json - examples/kubernetes/deployment.yml - examples/prometheus/elasticsearch.rules -crossbuild: - platforms: - - linux/amd64 - - linux/386 - - darwin/amd64 - - darwin/386 - - windows/amd64 - - windows/386 - - freebsd/amd64 - - freebsd/386 - - openbsd/amd64 - - openbsd/386 - - netbsd/amd64 - - netbsd/386 - - dragonfly/amd64 - - linux/arm - - linux/arm64 - - freebsd/arm - - openbsd/arm - - netbsd/arm - - linux/ppc64 - - linux/ppc64le - - linux/mips64 - - linux/mips64le diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 038bd324..00000000 --- a/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: go - -go: - - 1.10.x - - 1.11.x - - tip - -script: - - make style - - make vet - - make gometalinter - - make build - - make test - -matrix: - allow_failures: - - go: tip diff --git a/.yamllint b/.yamllint new file mode 100644 index 00000000..8d09c375 --- /dev/null +++ b/.yamllint @@ -0,0 +1,25 @@ +--- +extends: default +ignore: | + **/node_modules + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + commas: disable + comments: disable + comments-indentation: disable + document-start: disable + indentation: + spaces: consistent + indent-sequences: consistent + key-duplicates: + ignore: | + config/testdata/section_key_dup.bad.yml + line-length: disable + truthy: + check-keys: false diff --git a/CHANGELOG.md b/CHANGELOG.md index a4656591..940dfe9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,140 @@ +## master / unreleased + +BREAKING CHANGES: + +The flag `--es.slm` has been renamed to `--collector.slm`. + +The logging system has been replaced with log/slog from the stdlib. This change is being made across the prometheus ecosystem. The logging output has changed, but the messages and levels remain the same. The `ts` label for the timestamp has bewen replaced with `time`, the accuracy is less, and the timezone is not forced to UTC. The `caller` field has been replaced by the `source` field, which now includes the full path to the source file. The `level` field now exposes the log level in capital letters. + +* [CHANGE] Rename --es.slm to --collector.slm #932 +* [CHANGE] Replace logging system #942 + +## 1.8.0 / 2024-09-14 + +* [FEATURE] Add tasks action collector. Enable using `--collector.tasks.actions`. #778 +* [FEATURE] Add additional nodes metrics for indexing pressure monitoring. #904 + +## 1.7.0 / 2023-12-02 + +BREAKING CHANGES: + +The flag `--es.snapshots` has been renamed to `--collector.snapshots`. + +* [CHANGE] Rename --es.snapshots to --collector.snapshots #789 +* [CHANGE] Add cluster label to `elasticsearch_node_shards_total` metric #639 +* [FEATURE] Add watermark metrics #611 +* [FEATURE] Add `elasticsearch_indices_settings_creation_timestamp_seconds` metric #816 + +## 1.6.0 / 2023-06-22 + +BREAKING CHANGES: + +The flag `--es.cluster_settings` has been renamed to `--collector.clustersettings`. + +* [CHANGE] Rename --es.cluster_settings to --collector.clustersettings +* [FEATURE] Add ILM metrics #513 +* [ENHANCEMENT] Add ElasticCloud node roles to role label #652 +* [ENHANCEMENT] Add ability to use AWS IAM role for authentication #653 +* [ENHANCEMENT] Add metric for index replica count #483 +* [BUGFIX] Set elasticsearch_clusterinfo_version_info guage to 1 #728 +* [BUGFIX] Fix index field counts with nested fields #675 + + +## 1.5.0 / 2022-07-28 + +* [FEATURE] Add metrics collection for data stream statistics #592 +* [FEATURE] Support for AWS Elasticsearch using AWS SDK v2 #597 +* [BUGFIX] Fix cluster settings collection when max_shards_per_node is manually set. #603 + +## 1.4.0 / 2022-06-29 + +* [BREAKING] Remove ENV var support for most non-sensitive options. #518 +* [BREAKING] Rename elasticsearch_process_cpu_time_seconds_sum to elasticsearch_process_cpu_seconds_total #520 +* [FEATURE] Add metric for index aliases #563 +* [FEATURE] Add metric for number of shards on a node #535 +* [FEATURE] Add metrics for SLM (snapshot lifecycle management) #558 +* [FEATURE] Add metric for JVM uptime #537 +* [FEATURE] Add metrics for current searches and current indexing documents #485 +* [BUGFIX] Remove the elasticsearch_process_cpu_time_seconds_sum metric as it was never used #498 + +## 1.3.0 / 2021-10-21 + +* [FEATURE] Add support for passing elasticsearch credentials via the ES_USERNAME and ES_PASSWORD environment varialbes #461 +* [FEATURE] Add support for API keys for elasticsearch authentication (Elastic cloud) #459 +* [BUGFIX] Fix index stats when shards are unavailable #445 + +## 1.2.1 / 2021-06-29 + +* [BUGFIX] Fixed elasticsearch 7.13 node stats metrics #439 +* [BUGFIX] Fixed snapshot stats metrics for some snapshot repository types #442 + +## 1.2.0 / 2021-06-10 + +This release marks the first release under the prometheus-community organization. + +* [FEATURE] Added elasticsearch_clustersettings_stats_max_shards_per_node metric. #277 +* [FEATURE] Added elasticsearch_indices_shards_store_size_in_bytes metric. #292 +* [FEATURE] Added --es.indices_mappings flag to scrape elasticsearch index mapping stats and elasticsearch_indices_mappings_stats collector. #411 +* [FEATURE] Added elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds metric. #318 +* [ENHANCEMENT] Added support for reloading the tls client certificate in case it changes on disk. #414 +* [BUGFIX] Fixed the elasticsearch_indices_shards_docs metric name. #291 + +## 1.1.0 + +repeating the breaking changes introduced in 1.1.0rc1: +* [BREAKING] uses the registered exporter port 9114 instead of 9118. If you need to stick to the old port, you can specify the listen port with --web.listen-address +* [BREAKING] commandline flags are now POSIX flags with double dashes -- + +new changes in 1.1.0: +* [FEATURE] add checksum promu command to Makefile +* [FEATURE] add healthz handler +* [BUGFIX] json parse error if the snapshot json contains failures (#269) +* [BUGFIX] Remove credentials from URL in clusterinfo metrics +* [FEATURE] Add indices_segment_term_vectors_memory_bytes_{primary,total} metrics +* [FEATURE] Add indices_segments_{points,term_vectors,version_map}_memory_in_bytes metrics +* [BUGFIX] Kubernetes yml file fixes +* [FEATURE] Add index_stats_query_cache_caches_total metric +* [FEATURE] Rename query_cache_cache_count metric to query_cache_cache_total +* [BUGFIX] Change type for indices_query_cache_cache_count metric to counter +* [BUGFIX]/ [BREAKING] Add _total prefix to indices_warmer_time_seconds metric +* [FEATURE] Add indices_warmer_{time_seconds,total} metrics +* [BUGFIX] exporter doesn't exit 1 if port is already in use (#241) +* [BUGFIX] parse clusterinfo.build_date as string, not time.Time +* [BUGFIX] Various Documentation Fixes +* [FEATURE] add node_roles metric (#207) +* [FEATURE] Extend nodes metrics. added indices.merges.current_size +build fix: remove unnecessary conversion +* [FEATURE] Extend nodes metrics. added overhead of circuit breakers +* [BUGFIX] fix nodes metrics name indices.query_cache_miss_count, indices.request_cache_miss_count +* [FEATURE] Extend nodes search metrics. added scroll_total, scroll_time +* [FEATURE] Extend indices.indexing nodes metrics. added is_throttled, throttle_time +* [FEATURE]/ [BUGFIX] #212 remove misleading metric + +## 1.1.0rc1 + +* [BREAKING] uses the registered exporter port 9114 instead of 9118. If you need to stick to the old port, you can specify the listen port with --web.listen-address +* [BREAKING] commandline flags are now POSIX flags with double dashes -- +* [FEATURE] new collector for snapshot metrics +* [FEATURE] added os memory stats metrics +* [FEATURE] enable querying ES via proxy +* [FEATURE] new collector for cluster settings +* [FEATURE] new collector for indices settings +* [FEATURE] cluster info collector. The collector periodically queries the / endpoints and provides the other collectors with a semi up-to-date cluster label +* +* [FEATURE]/ [BUGFIX] grafana dashboard improvements and fixes +* [BUGFIX] Fixed createTLSConfig function. Return full tls configuration when ca, crt, key and insecure flag are set +* +* [INTERNAL] added code linting to build pipeline + +## 1.0.4rc1 + +* [DOCUMENTATION] documentation updates +* [FEATURE] add more index metrics +* [FEATURE] add filesystem metrics +* [FEATURE] add jvm buffer pool metrics +* [FEATURE] add support for using the exporter behind reverse proxy (URL-prefixing) +* [ENHANCEMENT] add linting to build chain and make project lint clean + ## 1.0.3rc1 * [BUGFIX] update prometheus alerting rule example to v2 format diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..d325872b --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,3 @@ +# Prometheus Community Code of Conduct + +Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). diff --git a/Dockerfile b/Dockerfile index 5ba6f65a..dd1b9fd3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,12 @@ -FROM quay.io/prometheus/golang-builder as builder +ARG ARCH="amd64" +ARG OS="linux" +FROM quay.io/prometheus/busybox-${OS}-${ARCH}:glibc +LABEL maintainer="The Prometheus Authors " -ADD . /go/src/github.com/justwatchcom/elasticsearch_exporter -WORKDIR /go/src/github.com/justwatchcom/elasticsearch_exporter +ARG ARCH="amd64" +ARG OS="linux" +COPY .build/${OS}-${ARCH}/elasticsearch_exporter /bin/elasticsearch_exporter -RUN make - -FROM quay.io/prometheus/busybox:latest -MAINTAINER The Prometheus Authors - -COPY --from=builder /go/src/github.com/justwatchcom/elasticsearch_exporter/elasticsearch_exporter /bin/elasticsearch_exporter - -EXPOSE 9114 +EXPOSE 7979 +USER nobody ENTRYPOINT [ "/bin/elasticsearch_exporter" ] diff --git a/MAINTAINERS.md b/MAINTAINERS.md new file mode 100644 index 00000000..bb40820a --- /dev/null +++ b/MAINTAINERS.md @@ -0,0 +1,2 @@ +* Ben Kochie @SuperQ +* Joe Adams @sysadmind diff --git a/Makefile b/Makefile index 85aa7d3d..fab02136 100644 --- a/Makefile +++ b/Makefile @@ -1,78 +1,10 @@ -# Copyright 2016 The Prometheus Authors -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Ensure that 'all' is the default target otherwise it will be the first target from Makefile.common. +all:: -GO := GO15VENDOREXPERIMENT=1 go -PROMU := $(GOPATH)/bin/promu -GOLINTER ?= $(GOPATH)/bin/gometalinter -pkgs = $(shell $(GO) list ./... | grep -v /vendor/) +# Needs to be defined before including Makefile.common to auto-generate targets +DOCKER_ARCHS ?= amd64 armv7 arm64 ppc64le +DOCKER_REPO ?= prometheuscommunity -PREFIX ?= $(shell pwd) -BIN_DIR ?= $(shell pwd) -DOCKER_IMAGE_NAME ?= elasticsearch-exporter -DOCKER_IMAGE_TAG ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD)) - - -all: format build test - -style: - @echo ">> checking code style" - @! gofmt -d $(shell find . -path ./vendor -prune -o -name '*.go' -print) | grep '^' - -test: - @echo ">> running tests" - @$(GO) test -short $(pkgs) - -format: - @echo ">> formatting code" - @$(GO) fmt $(pkgs) - -vet: - @echo ">> vetting code" - @$(GO) vet $(pkgs) - -build: promu - @echo ">> building binaries" - @$(PROMU) build --prefix $(PREFIX) +include Makefile.common -crossbuild: promu - @echo ">> cross-building binaries" - @$(PROMU) crossbuild - -tarball: promu - @echo ">> building release tarball" - @$(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR) - -tarballs: promu - @echo ">> building release tarballs" - @$(PROMU) crossbuild tarballs $(BIN_DIR) - -docker: - @echo ">> building docker image" - @docker build -t "$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" . - -promu: - @GOOS=$(shell uname -s | tr A-Z a-z) \ - GOARCH=$(subst x86_64,amd64,$(patsubst i%86,386,$(shell uname -m))) \ - $(GO) get -u github.com/prometheus/promu - -gometalinter: $(GOLINTER) - @echo ">> linting code" - @$(GOLINTER) --install > /dev/null - @$(GOLINTER) --config=./.gometalinter.json ./... - -$(GOPATH)/bin/gometalinter lint: - @GOOS=$(shell uname -s | tr A-Z a-z) \ - GOARCH=$(subst x86_64,amd64,$(patsubst i%86,386,$(shell uname -m))) \ - $(GO) get -u github.com/alecthomas/gometalinter - -.PHONY: all style format build test vet tarball docker promu $(GOPATH)/bin/gometalinter lint +DOCKER_IMAGE_NAME ?= elasticsearch-exporter diff --git a/Makefile.common b/Makefile.common new file mode 100644 index 00000000..fc47bdbb --- /dev/null +++ b/Makefile.common @@ -0,0 +1,283 @@ +# Copyright 2018 The Prometheus Authors +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# A common Makefile that includes rules to be reused in different prometheus projects. +# !!! Open PRs only against the prometheus/prometheus/Makefile.common repository! + +# Example usage : +# Create the main Makefile in the root project directory. +# include Makefile.common +# customTarget: +# @echo ">> Running customTarget" +# + +# Ensure GOBIN is not set during build so that promu is installed to the correct path +unexport GOBIN + +GO ?= go +GOFMT ?= $(GO)fmt +FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH))) +GOOPTS ?= +GOHOSTOS ?= $(shell $(GO) env GOHOSTOS) +GOHOSTARCH ?= $(shell $(GO) env GOHOSTARCH) + +GO_VERSION ?= $(shell $(GO) version) +GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION)) +PRE_GO_111 ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.') + +PROMU := $(FIRST_GOPATH)/bin/promu +pkgs = ./... + +ifeq (arm, $(GOHOSTARCH)) + GOHOSTARM ?= $(shell GOARM= $(GO) env GOARM) + GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)v$(GOHOSTARM) +else + GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH) +endif + +GOTEST := $(GO) test +GOTEST_DIR := +ifneq ($(CIRCLE_JOB),) +ifneq ($(shell command -v gotestsum 2> /dev/null),) + GOTEST_DIR := test-results + GOTEST := gotestsum --junitfile $(GOTEST_DIR)/unit-tests.xml -- +endif +endif + +PROMU_VERSION ?= 0.17.0 +PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz + +SKIP_GOLANGCI_LINT := +GOLANGCI_LINT := +GOLANGCI_LINT_OPTS ?= +GOLANGCI_LINT_VERSION ?= v1.62.0 +# golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64. +# windows isn't included here because of the path separator being different. +ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) + ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386 arm64)) + # If we're in CI and there is an Actions file, that means the linter + # is being run in Actions, so we don't need to run it here. + ifneq (,$(SKIP_GOLANGCI_LINT)) + GOLANGCI_LINT := + else ifeq (,$(CIRCLE_JOB)) + GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint + else ifeq (,$(wildcard .github/workflows/golangci-lint.yml)) + GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint + endif + endif +endif + +PREFIX ?= $(shell pwd) +BIN_DIR ?= $(shell pwd) +DOCKER_IMAGE_TAG ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD)) +DOCKERFILE_PATH ?= ./Dockerfile +DOCKERBUILD_CONTEXT ?= ./ +DOCKER_REPO ?= prom + +DOCKER_ARCHS ?= amd64 + +BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS)) +PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS)) +TAG_DOCKER_ARCHS = $(addprefix common-docker-tag-latest-,$(DOCKER_ARCHS)) + +SANITIZED_DOCKER_IMAGE_TAG := $(subst +,-,$(DOCKER_IMAGE_TAG)) + +ifeq ($(GOHOSTARCH),amd64) + ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux freebsd darwin windows)) + # Only supported on amd64 + test-flags := -race + endif +endif + +# This rule is used to forward a target like "build" to "common-build". This +# allows a new "build" target to be defined in a Makefile which includes this +# one and override "common-build" without override warnings. +%: common-% ; + +.PHONY: common-all +common-all: precheck style check_license lint yamllint unused build test + +.PHONY: common-style +common-style: + @echo ">> checking code style" + @fmtRes=$$($(GOFMT) -d $$(find . -path ./vendor -prune -o -name '*.go' -print)); \ + if [ -n "$${fmtRes}" ]; then \ + echo "gofmt checking failed!"; echo "$${fmtRes}"; echo; \ + echo "Please ensure you are using $$($(GO) version) for formatting code."; \ + exit 1; \ + fi + +.PHONY: common-check_license +common-check_license: + @echo ">> checking license header" + @licRes=$$(for file in $$(find . -type f -iname '*.go' ! -path './vendor/*') ; do \ + awk 'NR<=3' $$file | grep -Eq "(Copyright|generated|GENERATED)" || echo $$file; \ + done); \ + if [ -n "$${licRes}" ]; then \ + echo "license header checking failed:"; echo "$${licRes}"; \ + exit 1; \ + fi + +.PHONY: common-deps +common-deps: + @echo ">> getting dependencies" + $(GO) mod download + +.PHONY: update-go-deps +update-go-deps: + @echo ">> updating Go dependencies" + @for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \ + $(GO) get -d $$m; \ + done + $(GO) mod tidy + +.PHONY: common-test-short +common-test-short: $(GOTEST_DIR) + @echo ">> running short tests" + $(GOTEST) -short $(GOOPTS) $(pkgs) + +.PHONY: common-test +common-test: $(GOTEST_DIR) + @echo ">> running all tests" + $(GOTEST) $(test-flags) $(GOOPTS) $(pkgs) + +$(GOTEST_DIR): + @mkdir -p $@ + +.PHONY: common-format +common-format: + @echo ">> formatting code" + $(GO) fmt $(pkgs) + +.PHONY: common-vet +common-vet: + @echo ">> vetting code" + $(GO) vet $(GOOPTS) $(pkgs) + +.PHONY: common-lint +common-lint: $(GOLANGCI_LINT) +ifdef GOLANGCI_LINT + @echo ">> running golangci-lint" + $(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs) +endif + +.PHONY: common-lint-fix +common-lint-fix: $(GOLANGCI_LINT) +ifdef GOLANGCI_LINT + @echo ">> running golangci-lint fix" + $(GOLANGCI_LINT) run --fix $(GOLANGCI_LINT_OPTS) $(pkgs) +endif + +.PHONY: common-yamllint +common-yamllint: + @echo ">> running yamllint on all YAML files in the repository" +ifeq (, $(shell command -v yamllint 2> /dev/null)) + @echo "yamllint not installed so skipping" +else + yamllint . +endif + +# For backward-compatibility. +.PHONY: common-staticcheck +common-staticcheck: lint + +.PHONY: common-unused +common-unused: + @echo ">> running check for unused/missing packages in go.mod" + $(GO) mod tidy + @git diff --exit-code -- go.sum go.mod + +.PHONY: common-build +common-build: promu + @echo ">> building binaries" + $(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES) + +.PHONY: common-tarball +common-tarball: promu + @echo ">> building release tarball" + $(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR) + +.PHONY: common-docker-repo-name +common-docker-repo-name: + @echo "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)" + +.PHONY: common-docker $(BUILD_DOCKER_ARCHS) +common-docker: $(BUILD_DOCKER_ARCHS) +$(BUILD_DOCKER_ARCHS): common-docker-%: + docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \ + -f $(DOCKERFILE_PATH) \ + --build-arg ARCH="$*" \ + --build-arg OS="linux" \ + $(DOCKERBUILD_CONTEXT) + +.PHONY: common-docker-publish $(PUBLISH_DOCKER_ARCHS) +common-docker-publish: $(PUBLISH_DOCKER_ARCHS) +$(PUBLISH_DOCKER_ARCHS): common-docker-publish-%: + docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" + +DOCKER_MAJOR_VERSION_TAG = $(firstword $(subst ., ,$(shell cat VERSION))) +.PHONY: common-docker-tag-latest $(TAG_DOCKER_ARCHS) +common-docker-tag-latest: $(TAG_DOCKER_ARCHS) +$(TAG_DOCKER_ARCHS): common-docker-tag-latest-%: + docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest" + docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)" + +.PHONY: common-docker-manifest +common-docker-manifest: + DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(SANITIZED_DOCKER_IMAGE_TAG)) + DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" + +.PHONY: promu +promu: $(PROMU) + +$(PROMU): + $(eval PROMU_TMP := $(shell mktemp -d)) + curl -s -L $(PROMU_URL) | tar -xvzf - -C $(PROMU_TMP) + mkdir -p $(FIRST_GOPATH)/bin + cp $(PROMU_TMP)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM)/promu $(FIRST_GOPATH)/bin/promu + rm -r $(PROMU_TMP) + +.PHONY: proto +proto: + @echo ">> generating code from proto files" + @./scripts/genproto.sh + +ifdef GOLANGCI_LINT +$(GOLANGCI_LINT): + mkdir -p $(FIRST_GOPATH)/bin + curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_LINT_VERSION)/install.sh \ + | sed -e '/install -d/d' \ + | sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION) +endif + +.PHONY: precheck +precheck:: + +define PRECHECK_COMMAND_template = +precheck:: $(1)_precheck + +PRECHECK_COMMAND_$(1) ?= $(1) $$(strip $$(PRECHECK_OPTIONS_$(1))) +.PHONY: $(1)_precheck +$(1)_precheck: + @if ! $$(PRECHECK_COMMAND_$(1)) 1>/dev/null 2>&1; then \ + echo "Execution of '$$(PRECHECK_COMMAND_$(1))' command failed. Is $(1) installed?"; \ + exit 1; \ + fi +endef + +govulncheck: install-govulncheck + govulncheck ./... + +install-govulncheck: + command -v govulncheck > /dev/null || go install golang.org/x/vuln/cmd/govulncheck@latest diff --git a/NOTICE b/NOTICE new file mode 100644 index 00000000..e9201a02 --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright 2015 Eric Richardson +Copyright 2017 JustWatch +Copyright 2021 The Prometheus Authors diff --git a/README.md b/README.md index b40da3c3..64948429 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,29 @@ -# Elasticsearch Exporter [![Build Status](https://travis-ci.org/justwatchcom/elasticsearch_exporter.svg?branch=master)](https://travis-ci.org/justwatchcom/elasticsearch_exporter) -[![Docker Pulls](https://img.shields.io/docker/pulls/justwatch/elasticsearch_exporter.svg?maxAge=604800)](https://hub.docker.com/r/justwatch/elasticsearch_exporter) -[![Go Report Card](https://goreportcard.com/badge/github.com/justwatchcom/elasticsearch_exporter)](https://goreportcard.com/report/github.com/justwatchcom/elasticsearch_exporter) +# Elasticsearch Exporter -Prometheus exporter for various metrics about ElasticSearch, written in Go. +[![CircleCI](https://circleci.com/gh/prometheus-community/elasticsearch_exporter.svg?style=svg)](https://circleci.com/gh/prometheus-community/elasticsearch_exporter) +[![Go Report Card](https://goreportcard.com/badge/github.com/prometheus-community/elasticsearch_exporter)](https://goreportcard.com/report/github.com/prometheus-community/elasticsearch_exporter) + +Prometheus exporter for various metrics about Elasticsearch, written in Go. ### Installation For pre-built binaries please take a look at the releases. -https://github.com/justwatchcom/elasticsearch_exporter/releases + #### Docker ```bash -docker pull justwatch/elasticsearch_exporter:1.0.2 -docker run --rm -p 9114:9114 justwatch/elasticsearch_exporter:1.0.2 +docker pull quay.io/prometheuscommunity/elasticsearch-exporter:latest +docker run --rm -p 9114:9114 quay.io/prometheuscommunity/elasticsearch-exporter:latest ``` Example `docker-compose.yml`: ```yaml elasticsearch_exporter: - image: justwatch/elasticsearch_exporter:1.0.2 + image: quay.io/prometheuscommunity/elasticsearch-exporter:latest command: - - '-es.uri=http://elasticsearch:9200' + - '--es.uri=http://elasticsearch:9200' restart: always ports: - "127.0.0.1:9114:9114" @@ -30,166 +31,248 @@ elasticsearch_exporter: #### Kubernetes -You can find a helm chart in the stable charts repository at https://github.com/kubernetes/charts/tree/master/stable/elasticsearch-exporter. +You can find a helm chart in the prometheus-community charts repository at + +```bash +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm install [RELEASE_NAME] prometheus-community/prometheus-elasticsearch-exporter +``` ### Configuration -**NOTE:** The exporter fetches information from an ElasticSearch cluster on every scrape, therefore having a too short scrape interval can impose load on ES master nodes, particularly if you run with `-es.all` and `-es.indices`. We suggest you measure how long fetching `/_nodes/stats` and `/_all/_stats` takes for your ES cluster to determine whether your scraping interval is too short. As a last resort, you can scrape this exporter using a dedicated job with its own scraping interval. +**NOTE:** The exporter fetches information from an Elasticsearch cluster on every scrape, therefore having a too short scrape interval can impose load on ES master nodes, particularly if you run with `--es.all` and `--es.indices`. We suggest you measure how long fetching `/_nodes/stats` and `/_all/_stats` takes for your ES cluster to determine whether your scraping interval is too short. As a last resort, you can scrape this exporter using a dedicated job with its own scraping interval. Below is the command line options summary: + ```bash elasticsearch_exporter --help ``` -| Argument | Introduced in Version | Description | Default | -| -------- | --------------------- | ----------- | ----------- | -| es.uri | 1.0.2 | Address (host and port) of the Elasticsearch node we should connect to. This could be a local node (`localhost:9200`, for instance), or the address of a remote Elasticsearch server. When basic auth is needed, specify as: `://:@:`. E.G., `http://admin:pass@localhost:9200`. | http://localhost:9200 | -| es.all | 1.0.2 | If true, query stats for all nodes in the cluster, rather than just the node we connect to. | false | -| es.cluster_settings | 1.1.0rc1 | If true, query stats for cluster settings. | false | -| es.indices | 1.0.2 | If true, query stats for all indices in the cluster. | false | -| es.indices_settings | 1.0.4rc1 | If true, query settings stats for all indices in the cluster. | false | -| es.shards | 1.0.3rc1 | If true, query stats for all indices in the cluster, including shard-level stats (implies `es.indices=true`). | false | -| es.snapshots | 1.0.4rc1 | If true, query stats for the cluster snapshots. | false | -| es.timeout | 1.0.2 | Timeout for trying to get stats from Elasticsearch. (ex: 20s) | 5s | -| es.ca | 1.0.2 | Path to PEM file that contains trusted Certificate Authorities for the Elasticsearch connection. | | -| es.client-private-key | 1.0.2 | Path to PEM file that contains the private key for client auth when connecting to Elasticsearch. | | -| es.client-cert | 1.0.2 | Path to PEM file that contains the corresponding cert for the private key to connect to Elasticsearch. | | -| es.clusterinfo.interval | 1.1.0rc1 | Cluster info update interval for the cluster label | 5m | -| es.ssl-skip-verify | 1.0.4rc1 | Skip SSL verification when connecting to Elasticsearch. | false | -| web.listen-address | 1.0.2 | Address to listen on for web interface and telemetry. | :9114 | -| web.telemetry-path | 1.0.2 | Path under which to expose metrics. | /metrics | -| version | 1.0.2 | Show version info on stdout and exit. | | - -Commandline parameters start with a single `-` for versions less than `1.1.0rc1`. -For versions greater than `1.1.0rc1`, commandline parameters are specified with `--`. Also, all commandline parameters can be provided as environment variables. The environment variable name is derived from the parameter name -by replacing `.` and `-` with `_` and upper-casing the parameter name. - +| Argument | Introduced in Version | Description | Default | +| ----------------------- | --------------------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ----------- | +| collector.clustersettings| 1.6.0 | If true, query stats for cluster settings (As of v1.6.0, this flag has replaced "es.cluster_settings"). | false | +| es.uri | 1.0.2 | Address (host and port) of the Elasticsearch node we should connect to. This could be a local node (`localhost:9200`, for instance), or the address of a remote Elasticsearch server. When basic auth is needed, specify as: `://:@:`. E.G., `http://admin:pass@localhost:9200`. Special characters in the user credentials need to be URL-encoded. | | +| es.all | 1.0.2 | If true, query stats for all nodes in the cluster, rather than just the node we connect to. | false | +| es.indices | 1.0.2 | If true, query stats for all indices in the cluster. | false | +| es.indices_settings | 1.0.4rc1 | If true, query settings stats for all indices in the cluster. | false | +| es.indices_mappings | 1.2.0 | If true, query stats for mappings of all indices of the cluster. | false | +| es.aliases | 1.0.4rc1 | If true, include informational aliases metrics. | true | +| es.shards | 1.0.3rc1 | If true, query stats for all indices in the cluster, including shard-level stats (implies `es.indices=true`). | false | +| collector.snapshots | 1.0.4rc1 | If true, query stats for the cluster snapshots. (As of v1.7.0, this flag has replaced "es.snapshots"). | false | +| es.slm | | If true, query stats for SLM. | false | +| es.data_stream | | If true, query state for Data Steams. | false | +| es.timeout | 1.0.2 | Timeout for trying to get stats from Elasticsearch. (ex: 20s) | 5s | +| es.ca | 1.0.2 | Path to PEM file that contains trusted Certificate Authorities for the Elasticsearch connection. | | +| es.client-private-key | 1.0.2 | Path to PEM file that contains the private key for client auth when connecting to Elasticsearch. | | +| es.client-cert | 1.0.2 | Path to PEM file that contains the corresponding cert for the private key to connect to Elasticsearch. | | +| es.clusterinfo.interval | 1.1.0rc1 | Cluster info update interval for the cluster label | 5m | +| es.ssl-skip-verify | 1.0.4rc1 | Skip SSL verification when connecting to Elasticsearch. | false | +| web.listen-address | 1.0.2 | Address to listen on for web interface and telemetry. | :9114 | +| web.telemetry-path | 1.0.2 | Path under which to expose metrics. | /metrics | +| aws.region | 1.5.0 | Region for AWS elasticsearch | | +| aws.role-arn | 1.6.0 | Role ARN of an IAM role to assume. | | +| version | 1.0.2 | Show version info on stdout and exit. | | + +Commandline parameters start with a single `-` for versions less than `1.1.0rc1`. +For versions greater than `1.1.0rc1`, commandline parameters are specified with `--`. + +The API key used to connect can be set with the `ES_API_KEY` environment variable. + +#### Logging + +Logging by the exporter is handled by the `log/slog` package. The output format can be customized with the `--log.format` flag which defaults to logfmt. The log level can be set with the `--log.level` flag which defaults to info. The output can be set to either stdout (default) or stderr with the `--log.output` flag. + +#### Elasticsearch 7.x security privileges + +Username and password can be passed either directly in the URI or through the `ES_USERNAME` and `ES_PASSWORD` environment variables. +Specifying those two environment variables will override authentication passed in the URI (if any). + +ES 7.x supports RBACs. The following security privileges are required for the elasticsearch_exporter. + +Setting | Privilege Required | Description +:---- | :---- | :---- +collector.clustersettings| `cluster` `monitor` | +exporter defaults | `cluster` `monitor` | All cluster read-only operations, like cluster health and state, hot threads, node info, node and cluster stats, and pending cluster tasks. | +es.indices | `indices` `monitor` (per index or `*`) | All actions that are required for monitoring (recovery, segments info, index stats and status) +es.indices_settings | `indices` `monitor` (per index or `*`) | +es.indices_mappings | `indices` `view_index_metadata` (per index or `*`) | +es.shards | not sure if `indices` or `cluster` `monitor` or both | +collector.snapshots | `cluster:admin/snapshot/status` and `cluster:admin/repository/get` | [ES Forum Post](https://discuss.elastic.co/t/permissions-for-backup-user-with-x-pack/88057) +es.slm | `manage_slm` +es.data_stream | `monitor` or `manage` (per index or `*`) | + +Further Information + +- [Built in Users](https://www.elastic.co/guide/en/elastic-stack-overview/7.3/built-in-users.html) +- [Defining Roles](https://www.elastic.co/guide/en/elastic-stack-overview/7.3/defining-roles.html) +- [Privileges](https://www.elastic.co/guide/en/elastic-stack-overview/7.3/security-privileges.html) + ### Metrics -|Name |Type |Cardinality |Help -|---- |---- |----------- |---- -| elasticsearch_breakers_estimated_size_bytes | gauge | 4 | Estimated size in bytes of breaker -| elasticsearch_breakers_limit_size_bytes | gauge | 4 | Limit size in bytes for breaker -| elasticsearch_breakers_tripped | counter | 4 | tripped for breaker -| elasticsearch_cluster_health_active_primary_shards | gauge | 1 | The number of primary shards in your cluster. This is an aggregate total across all indices. -| elasticsearch_cluster_health_active_shards | gauge | 1 | Aggregate total of all shards across all indices, which includes replica shards. -| elasticsearch_cluster_health_delayed_unassigned_shards | gauge | 1 | Shards delayed to reduce reallocation overhead -| elasticsearch_cluster_health_initializing_shards | gauge | 1 | Count of shards that are being freshly created. -| elasticsearch_cluster_health_number_of_data_nodes | gauge | 1 | Number of data nodes in the cluster. -| elasticsearch_cluster_health_number_of_in_flight_fetch | gauge | 1 | The number of ongoing shard info requests. -| elasticsearch_cluster_health_number_of_nodes | gauge | 1 | Number of nodes in the cluster. -| elasticsearch_cluster_health_number_of_pending_tasks | gauge | 1 | Cluster level changes which have not yet been executed -| elasticsearch_cluster_health_task_max_waiting_in_queue_millis | gauge | 1 | Max time in millis that a task is waiting in queue. -| elasticsearch_cluster_health_relocating_shards | gauge | 1 | The number of shards that are currently moving from one node to another node. -| elasticsearch_cluster_health_status | gauge | 3 | Whether all primary and replica shards are allocated. -| elasticsearch_cluster_health_timed_out | gauge | 1 | Number of cluster health checks timed out -| elasticsearch_cluster_health_unassigned_shards | gauge | 1 | The number of shards that exist in the cluster state, but cannot be found in the cluster itself. -| elasticsearch_filesystem_data_available_bytes | gauge | 1 | Available space on block device in bytes -| elasticsearch_filesystem_data_free_bytes | gauge | 1 | Free space on block device in bytes -| elasticsearch_filesystem_data_size_bytes | gauge | 1 | Size of block device in bytes -| elasticsearch_filesystem_io_stats_device_operations_count | gauge | 1 | Count of disk operations -| elasticsearch_filesystem_io_stats_device_read_operations_count | gauge | 1 | Count of disk read operations -| elasticsearch_filesystem_io_stats_device_write_operations_count | gauge | 1 | Count of disk write operations -| elasticsearch_filesystem_io_stats_device_read_size_kilobytes_sum | gauge | 1 | Total kilobytes read from disk -| elasticsearch_filesystem_io_stats_device_write_size_kilobytes_sum | gauge | 1 | Total kilobytes written to disk -| elasticsearch_indices_docs | gauge | 1 | Count of documents on this node -| elasticsearch_indices_docs_deleted | gauge | 1 | Count of deleted documents on this node -| elasticsearch_indices_docs_primary | gauge | | Count of documents with only primary shards on all nodes -| elasticsearch_indices_fielddata_evictions | counter | 1 | Evictions from field data -| elasticsearch_indices_fielddata_memory_size_bytes | gauge | 1 | Field data cache memory usage in bytes -| elasticsearch_indices_filter_cache_evictions | counter | 1 | Evictions from filter cache -| elasticsearch_indices_filter_cache_memory_size_bytes | gauge | 1 | Filter cache memory usage in bytes -| elasticsearch_indices_flush_time_seconds | counter | 1 | Cumulative flush time in seconds -| elasticsearch_indices_flush_total | counter | 1 | Total flushes -| elasticsearch_indices_get_exists_time_seconds | counter | 1 | Total time get exists in seconds -| elasticsearch_indices_get_exists_total | counter | 1 | Total get exists operations -| elasticsearch_indices_get_missing_time_seconds | counter | 1 | Total time of get missing in seconds -| elasticsearch_indices_get_missing_total | counter | 1 | Total get missing -| elasticsearch_indices_get_time_seconds | counter | 1 | Total get time in seconds -| elasticsearch_indices_get_total | counter | 1 | Total get -| elasticsearch_indices_indexing_delete_time_seconds_total | counter | 1 | Total time indexing delete in seconds -| elasticsearch_indices_indexing_delete_total | counter | 1 | Total indexing deletes -| elasticsearch_indices_indexing_index_time_seconds_total | counter | 1 | Cumulative index time in seconds -| elasticsearch_indices_indexing_index_total | counter | 1 | Total index calls -| elasticsearch_indices_merges_docs_total | counter | 1 | Cumulative docs merged -| elasticsearch_indices_merges_total | counter | 1 | Total merges -| elasticsearch_indices_merges_total_size_bytes_total | counter | 1 | Total merge size in bytes -| elasticsearch_indices_merges_total_time_seconds_total | counter | 1 | Total time spent merging in seconds -| elasticsearch_indices_query_cache_cache_total | counter | 1 | Count of query cache -| elasticsearch_indices_query_cache_cache_size | gauge | 1 | Size of query cache -| elasticsearch_indices_query_cache_count | counter | 2 | Count of query cache hit/miss -| elasticsearch_indices_query_cache_evictions | counter | 1 | Evictions from query cache -| elasticsearch_indices_query_cache_memory_size_bytes | gauge | 1 | Query cache memory usage in bytes -| elasticsearch_indices_query_cache_total | counter | 1 | Size of query cache total -| elasticsearch_indices_refresh_time_seconds_total | counter | 1 | Total time spent refreshing in seconds -| elasticsearch_indices_refresh_total | counter | 1 | Total refreshes -| elasticsearch_indices_request_cache_count | counter | 2 | Count of request cache hit/miss -| elasticsearch_indices_request_cache_evictions | counter | 1 | Evictions from request cache -| elasticsearch_indices_request_cache_memory_size_bytes | gauge | 1 | Request cache memory usage in bytes -| elasticsearch_indices_search_fetch_time_seconds | counter | 1 | Total search fetch time in seconds -| elasticsearch_indices_search_fetch_total | counter | 1 | Total number of fetches -| elasticsearch_indices_search_query_time_seconds | counter | 1 | Total search query time in seconds -| elasticsearch_indices_search_query_total | counter | 1 | Total number of queries -| elasticsearch_indices_segments_count | gauge | 1 | Count of index segments on this node -| elasticsearch_indices_segments_memory_bytes | gauge | 1 | Current memory size of segments in bytes -| elasticsearch_indices_settings_stats_read_only_indices | gauge | 1 | Count of indices that have read_only_allow_delete=true -| elasticsearch_indices_shards_docs | gauge | 3 | Count of documents on this shard -| elasticsearch_indices_shards_docs_deleted | gauge | 3 | Count of deleted documents on each shard -| elasticsearch_indices_store_size_bytes | gauge | 1 | Current size of stored index data in bytes -| elasticsearch_indices_store_size_bytes_primary | gauge | | Current size of stored index data in bytes with only primary shards on all nodes -| elasticsearch_indices_store_size_bytes_total | gauge | | Current size of stored index data in bytes with all shards on all nodes -| elasticsearch_indices_store_throttle_time_seconds_total | counter | 1 | Throttle time for index store in seconds -| elasticsearch_indices_translog_operations | counter | 1 | Total translog operations -| elasticsearch_indices_translog_size_in_bytes | counter | 1 | Total translog size in bytes -| elasticsearch_indices_warmer_time_seconds_total | counter | 1 | Total warmer time in seconds -| elasticsearch_indices_warmer_total | counter | 1 | Total warmer count -| elasticsearch_jvm_gc_collection_seconds_count | counter | 2 | Count of JVM GC runs -| elasticsearch_jvm_gc_collection_seconds_sum | counter | 2 | GC run time in seconds -| elasticsearch_jvm_memory_committed_bytes | gauge | 2 | JVM memory currently committed by area -| elasticsearch_jvm_memory_max_bytes | gauge | 1 | JVM memory max -| elasticsearch_jvm_memory_used_bytes | gauge | 2 | JVM memory currently used by area -| elasticsearch_jvm_memory_pool_used_bytes | gauge | 3 | JVM memory currently used by pool -| elasticsearch_jvm_memory_pool_max_bytes | counter | 3 | JVM memory max by pool -| elasticsearch_jvm_memory_pool_peak_used_bytes | counter | 3 | JVM memory peak used by pool -| elasticsearch_jvm_memory_pool_peak_max_bytes | counter | 3 | JVM memory peak max by pool -| elasticsearch_os_cpu_percent | gauge | 1 | Percent CPU used by the OS -| elasticsearch_os_load1 | gauge | 1 | Shortterm load average -| elasticsearch_os_load5 | gauge | 1 | Midterm load average -| elasticsearch_os_load15 | gauge | 1 | Longterm load average -| elasticsearch_process_cpu_percent | gauge | 1 | Percent CPU used by process -| elasticsearch_process_cpu_time_seconds_sum | counter | 3 | Process CPU time in seconds -| elasticsearch_process_mem_resident_size_bytes | gauge | 1 | Resident memory in use by process in bytes -| elasticsearch_process_mem_share_size_bytes | gauge | 1 | Shared memory in use by process in bytes -| elasticsearch_process_mem_virtual_size_bytes | gauge | 1 | Total virtual memory used in bytes -| elasticsearch_process_open_files_count | gauge | 1 | Open file descriptors -| elasticsearch_snapshot_stats_number_of_snapshots | gauge | 1 | Total number of snapshots -| elasticsearch_snapshot_stats_oldest_snapshot_timestamp | gauge | 1 | Oldest snapshot timestamp -| elasticsearch_snapshot_stats_snapshot_start_time_timestamp | gauge | 1 | Last snapshot start timestamp -| elasticsearch_snapshot_stats_snapshot_end_time_timestamp | gauge | 1 | Last snapshot end timestamp -| elasticsearch_snapshot_stats_snapshot_number_of_failures | gauge | 1 | Last snapshot number of failures -| elasticsearch_snapshot_stats_snapshot_number_of_indices | gauge | 1 | Last snapshot number of indices -| elasticsearch_snapshot_stats_snapshot_failed_shards | gauge | 1 | Last snapshot failed shards -| elasticsearch_snapshot_stats_snapshot_successful_shards | gauge | 1 | Last snapshot successful shards -| elasticsearch_snapshot_stats_snapshot_total_shards | gauge | 1 | Last snapshot total shard -| elasticsearch_thread_pool_active_count | gauge | 14 | Thread Pool threads active -| elasticsearch_thread_pool_completed_count | counter | 14 | Thread Pool operations completed -| elasticsearch_thread_pool_largest_count | gauge | 14 | Thread Pool largest threads count -| elasticsearch_thread_pool_queue_count | gauge | 14 | Thread Pool operations queued -| elasticsearch_thread_pool_rejected_count | counter | 14 | Thread Pool operations rejected -| elasticsearch_thread_pool_threads_count | gauge | 14 | Thread Pool current threads count -| elasticsearch_transport_rx_packets_total | counter | 1 | Count of packets received -| elasticsearch_transport_rx_size_bytes_total | counter | 1 | Total number of bytes received -| elasticsearch_transport_tx_packets_total | counter | 1 | Count of packets sent -| elasticsearch_transport_tx_size_bytes_total | counter | 1 | Total number of bytes sent -| elasticsearch_clusterinfo_last_retrieval_success_ts | gauge | 1 | Timestamp of the last successful cluster info retrieval -| elasticsearch_clusterinfo_up | gauge | 1 | Up metric for the cluster info collector -| elasticsearch_clusterinfo_version_info | gauge | 6 | Constant metric with ES version information as labels +| Name | Type | Cardinality | Help | +|----------------------------------------------------------------------|------------|-------------|-----------------------------------------------------------------------------------------------------| +| elasticsearch_breakers_estimated_size_bytes | gauge | 4 | Estimated size in bytes of breaker | +| elasticsearch_breakers_limit_size_bytes | gauge | 4 | Limit size in bytes for breaker | +| elasticsearch_breakers_tripped | counter | 4 | tripped for breaker | +| elasticsearch_cluster_health_active_primary_shards | gauge | 1 | The number of primary shards in your cluster. This is an aggregate total across all indices. | +| elasticsearch_cluster_health_active_shards | gauge | 1 | Aggregate total of all shards across all indices, which includes replica shards. | +| elasticsearch_cluster_health_delayed_unassigned_shards | gauge | 1 | Shards delayed to reduce reallocation overhead | +| elasticsearch_cluster_health_initializing_shards | gauge | 1 | Count of shards that are being freshly created. | +| elasticsearch_cluster_health_number_of_data_nodes | gauge | 1 | Number of data nodes in the cluster. | +| elasticsearch_cluster_health_number_of_in_flight_fetch | gauge | 1 | The number of ongoing shard info requests. | +| elasticsearch_cluster_health_number_of_nodes | gauge | 1 | Number of nodes in the cluster. | +| elasticsearch_cluster_health_number_of_pending_tasks | gauge | 1 | Cluster level changes which have not yet been executed | +| elasticsearch_cluster_health_task_max_waiting_in_queue_millis | gauge | 1 | Max time in millis that a task is waiting in queue. | +| elasticsearch_cluster_health_relocating_shards | gauge | 1 | The number of shards that are currently moving from one node to another node. | +| elasticsearch_cluster_health_status | gauge | 3 | Whether all primary and replica shards are allocated. | +| elasticsearch_cluster_health_unassigned_shards | gauge | 1 | The number of shards that exist in the cluster state, but cannot be found in the cluster itself. | +| elasticsearch_clustersettings_stats_max_shards_per_node | gauge | 0 | Current maximum number of shards per node setting. | +| elasticsearch_clustersettings_allocation_threshold_enabled | gauge | 0 | Is disk allocation decider enabled. | +| elasticsearch_clustersettings_allocation_watermark_flood_stage_bytes | gauge | 0 | Flood stage watermark as in bytes. | +| elasticsearch_clustersettings_allocation_watermark_high_bytes | gauge | 0 | High watermark for disk usage in bytes. | +| elasticsearch_clustersettings_allocation_watermark_low_bytes | gauge | 0 | Low watermark for disk usage in bytes. | +| elasticsearch_clustersettings_allocation_watermark_flood_stage_ratio | gauge | 0 | Flood stage watermark as a ratio. | +| elasticsearch_clustersettings_allocation_watermark_high_ratio | gauge | 0 | High watermark for disk usage as a ratio. | +| elasticsearch_clustersettings_allocation_watermark_low_ratio | gauge | 0 | Low watermark for disk usage as a ratio. | +| elasticsearch_filesystem_data_available_bytes | gauge | 1 | Available space on block device in bytes | +| elasticsearch_filesystem_data_free_bytes | gauge | 1 | Free space on block device in bytes | +| elasticsearch_filesystem_data_size_bytes | gauge | 1 | Size of block device in bytes | +| elasticsearch_filesystem_io_stats_device_operations_count | gauge | 1 | Count of disk operations | +| elasticsearch_filesystem_io_stats_device_read_operations_count | gauge | 1 | Count of disk read operations | +| elasticsearch_filesystem_io_stats_device_write_operations_count | gauge | 1 | Count of disk write operations | +| elasticsearch_filesystem_io_stats_device_read_size_kilobytes_sum | gauge | 1 | Total kilobytes read from disk | +| elasticsearch_filesystem_io_stats_device_write_size_kilobytes_sum | gauge | 1 | Total kilobytes written to disk | +| elasticsearch_indices_active_queries | gauge | 1 | The number of currently active queries | +| elasticsearch_indices_docs | gauge | 1 | Count of documents on this node | +| elasticsearch_indices_docs_deleted | gauge | 1 | Count of deleted documents on this node | +| elasticsearch_indices_deleted_docs_primary | gauge | 1 | Count of deleted documents with only primary shards | +| elasticsearch_indices_docs_primary | gauge | 1 | Count of documents with only primary shards on all nodes | +| elasticsearch_indices_docs_total | gauge | | Count of documents with shards on all nodes | +| elasticsearch_indices_fielddata_evictions | counter | 1 | Evictions from field data | +| elasticsearch_indices_fielddata_memory_size_bytes | gauge | 1 | Field data cache memory usage in bytes | +| elasticsearch_indices_filter_cache_evictions | counter | 1 | Evictions from filter cache | +| elasticsearch_indices_filter_cache_memory_size_bytes | gauge | 1 | Filter cache memory usage in bytes | +| elasticsearch_indices_flush_time_seconds | counter | 1 | Cumulative flush time in seconds | +| elasticsearch_indices_flush_total | counter | 1 | Total flushes | +| elasticsearch_indices_get_exists_time_seconds | counter | 1 | Total time get exists in seconds | +| elasticsearch_indices_get_exists_total | counter | 1 | Total get exists operations | +| elasticsearch_indices_get_missing_time_seconds | counter | 1 | Total time of get missing in seconds | +| elasticsearch_indices_get_missing_total | counter | 1 | Total get missing | +| elasticsearch_indices_get_time_seconds | counter | 1 | Total get time in seconds | +| elasticsearch_indices_get_total | counter | 1 | Total get | +| elasticsearch_indices_indexing_delete_time_seconds_total | counter | 1 | Total time indexing delete in seconds | +| elasticsearch_indices_indexing_delete_total | counter | 1 | Total indexing deletes | +| elasticsearch_indices_index_current | gauge | 1 | The number of documents currently being indexed to an index | +| elasticsearch_indices_indexing_index_time_seconds_total | counter | 1 | Cumulative index time in seconds | +| elasticsearch_indices_indexing_index_total | counter | 1 | Total index calls | +| elasticsearch_indices_mappings_stats_fields | gauge | 1 | Count of fields currently mapped by index | +| elasticsearch_indices_mappings_stats_json_parse_failures_total | counter | 0 | Number of errors while parsing JSON | +| elasticsearch_indices_mappings_stats_scrapes_total | counter | 0 | Current total Elasticsearch Indices Mappings scrapes | +| elasticsearch_indices_mappings_stats_up | gauge | 0 | Was the last scrape of the Elasticsearch Indices Mappings endpoint successful | +| elasticsearch_indices_merges_docs_total | counter | 1 | Cumulative docs merged | +| elasticsearch_indices_merges_total | counter | 1 | Total merges | +| elasticsearch_indices_merges_total_size_bytes_total | counter | 1 | Total merge size in bytes | +| elasticsearch_indices_merges_total_time_seconds_total | counter | 1 | Total time spent merging in seconds | +| elasticsearch_indices_query_cache_cache_total | counter | 1 | Count of query cache | +| elasticsearch_indices_query_cache_cache_size | gauge | 1 | Size of query cache | +| elasticsearch_indices_query_cache_count | counter | 2 | Count of query cache hit/miss | +| elasticsearch_indices_query_cache_evictions | counter | 1 | Evictions from query cache | +| elasticsearch_indices_query_cache_memory_size_bytes | gauge | 1 | Query cache memory usage in bytes | +| elasticsearch_indices_query_cache_total | counter | 1 | Size of query cache total | +| elasticsearch_indices_refresh_time_seconds_total | counter | 1 | Total time spent refreshing in seconds | +| elasticsearch_indices_refresh_total | counter | 1 | Total refreshes | +| elasticsearch_indices_request_cache_count | counter | 2 | Count of request cache hit/miss | +| elasticsearch_indices_request_cache_evictions | counter | 1 | Evictions from request cache | +| elasticsearch_indices_request_cache_memory_size_bytes | gauge | 1 | Request cache memory usage in bytes | +| elasticsearch_indices_search_fetch_time_seconds | counter | 1 | Total search fetch time in seconds | +| elasticsearch_indices_search_fetch_total | counter | 1 | Total number of fetches | +| elasticsearch_indices_search_query_time_seconds | counter | 1 | Total search query time in seconds | +| elasticsearch_indices_search_query_total | counter | 1 | Total number of queries | +| elasticsearch_indices_segments_count | gauge | 1 | Count of index segments on this node | +| elasticsearch_indices_segments_memory_bytes | gauge | 1 | Current memory size of segments in bytes | +| elasticsearch_indices_settings_creation_timestamp_seconds | gauge | 1 | Timestamp of the index creation in seconds | +| elasticsearch_indices_settings_stats_read_only_indices | gauge | 1 | Count of indices that have read_only_allow_delete=true | +| elasticsearch_indices_settings_total_fields | gauge | | Index setting value for index.mapping.total_fields.limit (total allowable mapped fields in a index) | +| elasticsearch_indices_settings_replicas | gauge | | Index setting value for index.replicas | +| elasticsearch_indices_shards_docs | gauge | 3 | Count of documents on this shard | +| elasticsearch_indices_shards_docs_deleted | gauge | 3 | Count of deleted documents on each shard | +| elasticsearch_indices_store_size_bytes | gauge | 1 | Current size of stored index data in bytes | +| elasticsearch_indices_store_size_bytes_primary | gauge | | Current size of stored index data in bytes with only primary shards on all nodes | +| elasticsearch_indices_store_size_bytes_total | gauge | | Current size of stored index data in bytes with all shards on all nodes | +| elasticsearch_indices_store_throttle_time_seconds_total | counter | 1 | Throttle time for index store in seconds | +| elasticsearch_indices_translog_operations | counter | 1 | Total translog operations | +| elasticsearch_indices_translog_size_in_bytes | counter | 1 | Total translog size in bytes | +| elasticsearch_indices_warmer_time_seconds_total | counter | 1 | Total warmer time in seconds | +| elasticsearch_indices_warmer_total | counter | 1 | Total warmer count | +| elasticsearch_jvm_gc_collection_seconds_count | counter | 2 | Count of JVM GC runs | +| elasticsearch_jvm_gc_collection_seconds_sum | counter | 2 | GC run time in seconds | +| elasticsearch_jvm_memory_committed_bytes | gauge | 2 | JVM memory currently committed by area | +| elasticsearch_jvm_memory_max_bytes | gauge | 1 | JVM memory max | +| elasticsearch_jvm_memory_used_bytes | gauge | 2 | JVM memory currently used by area | +| elasticsearch_jvm_memory_pool_used_bytes | gauge | 3 | JVM memory currently used by pool | +| elasticsearch_jvm_memory_pool_max_bytes | counter | 3 | JVM memory max by pool | +| elasticsearch_jvm_memory_pool_peak_used_bytes | counter | 3 | JVM memory peak used by pool | +| elasticsearch_jvm_memory_pool_peak_max_bytes | counter | 3 | JVM memory peak max by pool | +| elasticsearch_os_cpu_percent | gauge | 1 | Percent CPU used by the OS | +| elasticsearch_os_load1 | gauge | 1 | Shortterm load average | +| elasticsearch_os_load5 | gauge | 1 | Midterm load average | +| elasticsearch_os_load15 | gauge | 1 | Longterm load average | +| elasticsearch_process_cpu_percent | gauge | 1 | Percent CPU used by process | +| elasticsearch_process_cpu_seconds_total | counter | 1 | Process CPU time in seconds | +| elasticsearch_process_mem_resident_size_bytes | gauge | 1 | Resident memory in use by process in bytes | +| elasticsearch_process_mem_share_size_bytes | gauge | 1 | Shared memory in use by process in bytes | +| elasticsearch_process_mem_virtual_size_bytes | gauge | 1 | Total virtual memory used in bytes | +| elasticsearch_process_open_files_count | gauge | 1 | Open file descriptors | +| elasticsearch_snapshot_stats_number_of_snapshots | gauge | 1 | Total number of snapshots | +| elasticsearch_snapshot_stats_oldest_snapshot_timestamp | gauge | 1 | Oldest snapshot timestamp | +| elasticsearch_snapshot_stats_snapshot_start_time_timestamp | gauge | 1 | Last snapshot start timestamp | +| elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds | gauge | 1 | Timestamp of the latest SUCCESS or PARTIAL snapshot | +| elasticsearch_snapshot_stats_snapshot_end_time_timestamp | gauge | 1 | Last snapshot end timestamp | +| elasticsearch_snapshot_stats_snapshot_number_of_failures | gauge | 1 | Last snapshot number of failures | +| elasticsearch_snapshot_stats_snapshot_number_of_indices | gauge | 1 | Last snapshot number of indices | +| elasticsearch_snapshot_stats_snapshot_failed_shards | gauge | 1 | Last snapshot failed shards | +| elasticsearch_snapshot_stats_snapshot_successful_shards | gauge | 1 | Last snapshot successful shards | +| elasticsearch_snapshot_stats_snapshot_total_shards | gauge | 1 | Last snapshot total shard | +| elasticsearch_thread_pool_active_count | gauge | 14 | Thread Pool threads active | +| elasticsearch_thread_pool_completed_count | counter | 14 | Thread Pool operations completed | +| elasticsearch_thread_pool_largest_count | gauge | 14 | Thread Pool largest threads count | +| elasticsearch_thread_pool_queue_count | gauge | 14 | Thread Pool operations queued | +| elasticsearch_thread_pool_rejected_count | counter | 14 | Thread Pool operations rejected | +| elasticsearch_thread_pool_threads_count | gauge | 14 | Thread Pool current threads count | +| elasticsearch_transport_rx_packets_total | counter | 1 | Count of packets received | +| elasticsearch_transport_rx_size_bytes_total | counter | 1 | Total number of bytes received | +| elasticsearch_transport_tx_packets_total | counter | 1 | Count of packets sent | +| elasticsearch_transport_tx_size_bytes_total | counter | 1 | Total number of bytes sent | +| elasticsearch_clusterinfo_last_retrieval_success_ts | gauge | 1 | Timestamp of the last successful cluster info retrieval | +| elasticsearch_clusterinfo_up | gauge | 1 | Up metric for the cluster info collector | +| elasticsearch_clusterinfo_version_info | gauge | 6 | Constant metric with ES version information as labels | +| elasticsearch_slm_stats_up | gauge | 0 | Up metric for SLM collector | +| elasticsearch_slm_stats_total_scrapes | counter | 0 | Number of scrapes for SLM collector | +| elasticsearch_slm_stats_json_parse_failures | counter | 0 | JSON parse failures for SLM collector | +| elasticsearch_slm_stats_retention_runs_total | counter | 0 | Total retention runs | +| elasticsearch_slm_stats_retention_failed_total | counter | 0 | Total failed retention runs | +| elasticsearch_slm_stats_retention_timed_out_total | counter | 0 | Total retention run timeouts | +| elasticsearch_slm_stats_retention_deletion_time_seconds | gauge | 0 | Retention run deletion time | +| elasticsearch_slm_stats_total_snapshots_taken_total | counter | 0 | Total snapshots taken | +| elasticsearch_slm_stats_total_snapshots_failed_total | counter | 0 | Total snapshots failed | +| elasticsearch_slm_stats_total_snapshots_deleted_total | counter | 0 | Total snapshots deleted | +| elasticsearch_slm_stats_total_snapshots_failed_total | counter | 0 | Total snapshots failed | +| elasticsearch_slm_stats_snapshots_taken_total | counter | 1 | Snapshots taken by policy | +| elasticsearch_slm_stats_snapshots_failed_total | counter | 1 | Snapshots failed by policy | +| elasticsearch_slm_stats_snapshots_deleted_total | counter | 1 | Snapshots deleted by policy | +| elasticsearch_slm_stats_snapshot_deletion_failures_total | counter | 1 | Snapshot deletion failures by policy | +| elasticsearch_slm_stats_operation_mode | gauge | 1 | SLM operation mode (Running, stopping, stopped) | +| elasticsearch_data_stream_stats_up | gauge | 0 | Up metric for Data Stream collection | +| elasticsearch_data_stream_stats_total_scrapes | counter | 0 | Total scrapes for Data Stream stats | +| elasticsearch_data_stream_stats_json_parse_failures | counter | 0 | Number of parsing failures for Data Stream stats | +| elasticsearch_data_stream_backing_indices_total | gauge | 1 | Number of backing indices for Data Stream | +| elasticsearch_data_stream_store_size_bytes | gauge | 1 | Current size of data stream backing indices in bytes | ### Alerts & Recording Rules We provide examples for [Prometheus](http://prometheus.io) [alerts and recording rules](examples/prometheus/elasticsearch.rules) as well as an [Grafana](http://www.grafana.org) [Dashboard](examples/grafana/dashboard.json) and a [Kubernetes](http://kubernetes.io) [Deployment](examples/kubernetes/deployment.yml). -The example dashboard needs the [node_exporter](https://github.com/prometheus/node_exporter) installed. In order to select the nodes that belong to the ElasticSearch cluster, we rely on a label `cluster`. +The example dashboard needs the [node_exporter](https://github.com/prometheus/node_exporter) installed. In order to select the nodes that belong to the Elasticsearch cluster, we rely on a label `cluster`. Depending on your setup, it can derived from the platform metadata: For example on [GCE](https://cloud.google.com) @@ -207,15 +290,17 @@ Please refer to the [Prometheus SD documentation](https://prometheus.io/docs/ope ## Credit & License -`elasticsearch_exporter` is maintained by the nice folks from [JustWatch](https://www.justwatch.com/) -and licensed under the terms of the Apache license. +`elasticsearch_exporter` is maintained by the [Prometheus Community](https://www.prometheus.io/community/). + +`elasticsearch_exporter` was then maintained by the nice folks from [JustWatch](https://www.justwatch.com/). +Then transferred this repository to the Prometheus Community in May 2021. This package was originally created and maintained by [Eric Richardson](https://github.com/ewr), who transferred this repository to us in January 2017. Maintainers of this repository: -* Christoph Oelmüller @zwopir +- Christoph Oelmüller @zwopir Please refer to the Git commit log for a complete list of contributors. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..fed02d85 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,6 @@ +# Reporting a security issue + +The Prometheus security policy, including how to report vulnerabilities, can be +found here: + + diff --git a/VERSION b/VERSION index 686366e4..27f9cd32 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.0rc1 +1.8.0 diff --git a/collector/cluster_health.go b/collector/cluster_health.go index 5321adce..303838e8 100644 --- a/collector/cluster_health.go +++ b/collector/cluster_health.go @@ -1,21 +1,30 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector import ( "encoding/json" "fmt" + "io" + "log/slog" "net/http" "net/url" "path" - "github.com/go-kit/kit/log" - "github.com/go-kit/kit/log/level" "github.com/prometheus/client_golang/prometheus" ) -const ( - namespace = "elasticsearch" -) - var ( colors = []string{"green", "yellow", "red"} defaultClusterHealthLabels = []string{"cluster"} @@ -36,19 +45,16 @@ type clusterHealthStatusMetric struct { // ClusterHealth type defines the collector struct type ClusterHealth struct { - logger log.Logger + logger *slog.Logger client *http.Client url *url.URL - up prometheus.Gauge - totalScrapes, jsonParseFailures prometheus.Counter - metrics []*clusterHealthMetric statusMetric *clusterHealthStatusMetric } // NewClusterHealth returns a new Collector exposing ClusterHealth stats. -func NewClusterHealth(logger log.Logger, client *http.Client, url *url.URL) *ClusterHealth { +func NewClusterHealth(logger *slog.Logger, client *http.Client, url *url.URL) *ClusterHealth { subsystem := "cluster_health" return &ClusterHealth{ @@ -56,19 +62,6 @@ func NewClusterHealth(logger log.Logger, client *http.Client, url *url.URL) *Clu client: client, url: url, - up: prometheus.NewGauge(prometheus.GaugeOpts{ - Name: prometheus.BuildFQName(namespace, subsystem, "up"), - Help: "Was the last scrape of the ElasticSearch cluster health endpoint successful.", - }), - totalScrapes: prometheus.NewCounter(prometheus.CounterOpts{ - Name: prometheus.BuildFQName(namespace, subsystem, "total_scrapes"), - Help: "Current total ElasticSearch cluster health scrapes.", - }), - jsonParseFailures: prometheus.NewCounter(prometheus.CounterOpts{ - Name: prometheus.BuildFQName(namespace, subsystem, "json_parse_failures"), - Help: "Number of errors while parsing JSON.", - }), - metrics: []*clusterHealthMetric{ { Type: prometheus.GaugeValue, @@ -215,10 +208,6 @@ func (c *ClusterHealth) Describe(ch chan<- *prometheus.Desc) { ch <- metric.Desc } ch <- c.statusMetric.Desc - - ch <- c.up.Desc() - ch <- c.totalScrapes.Desc() - ch <- c.jsonParseFailures.Desc() } func (c *ClusterHealth) fetchAndDecodeClusterHealth() (clusterHealthResponse, error) { @@ -235,8 +224,8 @@ func (c *ClusterHealth) fetchAndDecodeClusterHealth() (clusterHealthResponse, er defer func() { err = res.Body.Close() if err != nil { - _ = level.Warn(c.logger).Log( - "msg", "failed to close http.Client", + c.logger.Warn( + "failed to close http.Client", "err", err, ) } @@ -246,8 +235,12 @@ func (c *ClusterHealth) fetchAndDecodeClusterHealth() (clusterHealthResponse, er return chr, fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) } - if err := json.NewDecoder(res.Body).Decode(&chr); err != nil { - c.jsonParseFailures.Inc() + bts, err := io.ReadAll(res.Body) + if err != nil { + return chr, err + } + + if err := json.Unmarshal(bts, &chr); err != nil { return chr, err } @@ -256,24 +249,14 @@ func (c *ClusterHealth) fetchAndDecodeClusterHealth() (clusterHealthResponse, er // Collect collects ClusterHealth metrics. func (c *ClusterHealth) Collect(ch chan<- prometheus.Metric) { - var err error - c.totalScrapes.Inc() - defer func() { - ch <- c.up - ch <- c.totalScrapes - ch <- c.jsonParseFailures - }() - clusterHealthResp, err := c.fetchAndDecodeClusterHealth() if err != nil { - c.up.Set(0) - _ = level.Warn(c.logger).Log( - "msg", "failed to fetch and decode cluster health", + c.logger.Warn( + "failed to fetch and decode cluster health", "err", err, ) return } - c.up.Set(1) for _, metric := range c.metrics { ch <- prometheus.MustNewConstMetric( diff --git a/collector/cluster_health_response.go b/collector/cluster_health_response.go index 11c42c6e..1cc8051d 100644 --- a/collector/cluster_health_response.go +++ b/collector/cluster_health_response.go @@ -1,3 +1,16 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector type clusterHealthResponse struct { diff --git a/collector/cluster_health_test.go b/collector/cluster_health_test.go index 598eab19..fd3e887e 100644 --- a/collector/cluster_health_test.go +++ b/collector/cluster_health_test.go @@ -1,13 +1,29 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector import ( - "fmt" + "io" "net/http" "net/http/httptest" "net/url" + "os" + "strings" "testing" - "github.com/go-kit/kit/log" + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/promslog" ) func TestClusterHealth(t *testing.T) { @@ -15,46 +31,172 @@ func TestClusterHealth(t *testing.T) { // docker run -d -p 9200:9200 elasticsearch:VERSION-alpine // curl -XPUT http://localhost:9200/twitter // curl http://localhost:9200/_cluster/health - tcs := map[string]string{ - "1.7.6": `{"cluster_name":"elasticsearch","status":"yellow","timed_out":false,"number_of_nodes":1,"number_of_data_nodes":1,"active_primary_shards":5,"active_shards":5,"relocating_shards":0,"initializing_shards":0,"unassigned_shards":5,"delayed_unassigned_shards":0,"number_of_pending_tasks":0,"number_of_in_flight_fetch":0}`, - "2.4.5": `{"cluster_name":"elasticsearch","status":"yellow","timed_out":false,"number_of_nodes":1,"number_of_data_nodes":1,"active_primary_shards":5,"active_shards":5,"relocating_shards":0,"initializing_shards":0,"unassigned_shards":5,"delayed_unassigned_shards":0,"number_of_pending_tasks":0,"number_of_in_flight_fetch":0,"task_max_waiting_in_queue_millis":12,"active_shards_percent_as_number":50.0}`, - "5.4.2": `{"cluster_name":"elasticsearch","status":"yellow","timed_out":false,"number_of_nodes":1,"number_of_data_nodes":1,"active_primary_shards":5,"active_shards":5,"relocating_shards":0,"initializing_shards":0,"unassigned_shards":5,"delayed_unassigned_shards":0,"number_of_pending_tasks":0,"number_of_in_flight_fetch":0,"task_max_waiting_in_queue_millis":12,"active_shards_percent_as_number":50.0}`, + + tests := []struct { + name string + file string + want string + }{ + { + name: "1.7.6", + file: "../fixtures/clusterhealth/1.7.6.json", + want: ` + # HELP elasticsearch_cluster_health_active_primary_shards The number of primary shards in your cluster. This is an aggregate total across all indices. + # TYPE elasticsearch_cluster_health_active_primary_shards gauge + elasticsearch_cluster_health_active_primary_shards{cluster="elasticsearch"} 5 + # HELP elasticsearch_cluster_health_active_shards Aggregate total of all shards across all indices, which includes replica shards. + # TYPE elasticsearch_cluster_health_active_shards gauge + elasticsearch_cluster_health_active_shards{cluster="elasticsearch"} 5 + # HELP elasticsearch_cluster_health_delayed_unassigned_shards Shards delayed to reduce reallocation overhead + # TYPE elasticsearch_cluster_health_delayed_unassigned_shards gauge + elasticsearch_cluster_health_delayed_unassigned_shards{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_initializing_shards Count of shards that are being freshly created. + # TYPE elasticsearch_cluster_health_initializing_shards gauge + elasticsearch_cluster_health_initializing_shards{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_number_of_data_nodes Number of data nodes in the cluster. + # TYPE elasticsearch_cluster_health_number_of_data_nodes gauge + elasticsearch_cluster_health_number_of_data_nodes{cluster="elasticsearch"} 1 + # HELP elasticsearch_cluster_health_number_of_in_flight_fetch The number of ongoing shard info requests. + # TYPE elasticsearch_cluster_health_number_of_in_flight_fetch gauge + elasticsearch_cluster_health_number_of_in_flight_fetch{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_number_of_nodes Number of nodes in the cluster. + # TYPE elasticsearch_cluster_health_number_of_nodes gauge + elasticsearch_cluster_health_number_of_nodes{cluster="elasticsearch"} 1 + # HELP elasticsearch_cluster_health_number_of_pending_tasks Cluster level changes which have not yet been executed + # TYPE elasticsearch_cluster_health_number_of_pending_tasks gauge + elasticsearch_cluster_health_number_of_pending_tasks{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_relocating_shards The number of shards that are currently moving from one node to another node. + # TYPE elasticsearch_cluster_health_relocating_shards gauge + elasticsearch_cluster_health_relocating_shards{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_status Whether all primary and replica shards are allocated. + # TYPE elasticsearch_cluster_health_status gauge + elasticsearch_cluster_health_status{cluster="elasticsearch",color="green"} 0 + elasticsearch_cluster_health_status{cluster="elasticsearch",color="red"} 0 + elasticsearch_cluster_health_status{cluster="elasticsearch",color="yellow"} 1 + # HELP elasticsearch_cluster_health_task_max_waiting_in_queue_millis Tasks max time waiting in queue. + # TYPE elasticsearch_cluster_health_task_max_waiting_in_queue_millis gauge + elasticsearch_cluster_health_task_max_waiting_in_queue_millis{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_unassigned_shards The number of shards that exist in the cluster state, but cannot be found in the cluster itself. + # TYPE elasticsearch_cluster_health_unassigned_shards gauge + elasticsearch_cluster_health_unassigned_shards{cluster="elasticsearch"} 5 + `, + }, + { + name: "2.4.5", + file: "../fixtures/clusterhealth/2.4.5.json", + want: ` + # HELP elasticsearch_cluster_health_active_primary_shards The number of primary shards in your cluster. This is an aggregate total across all indices. + # TYPE elasticsearch_cluster_health_active_primary_shards gauge + elasticsearch_cluster_health_active_primary_shards{cluster="elasticsearch"} 5 + # HELP elasticsearch_cluster_health_active_shards Aggregate total of all shards across all indices, which includes replica shards. + # TYPE elasticsearch_cluster_health_active_shards gauge + elasticsearch_cluster_health_active_shards{cluster="elasticsearch"} 5 + # HELP elasticsearch_cluster_health_delayed_unassigned_shards Shards delayed to reduce reallocation overhead + # TYPE elasticsearch_cluster_health_delayed_unassigned_shards gauge + elasticsearch_cluster_health_delayed_unassigned_shards{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_initializing_shards Count of shards that are being freshly created. + # TYPE elasticsearch_cluster_health_initializing_shards gauge + elasticsearch_cluster_health_initializing_shards{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_number_of_data_nodes Number of data nodes in the cluster. + # TYPE elasticsearch_cluster_health_number_of_data_nodes gauge + elasticsearch_cluster_health_number_of_data_nodes{cluster="elasticsearch"} 1 + # HELP elasticsearch_cluster_health_number_of_in_flight_fetch The number of ongoing shard info requests. + # TYPE elasticsearch_cluster_health_number_of_in_flight_fetch gauge + elasticsearch_cluster_health_number_of_in_flight_fetch{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_number_of_nodes Number of nodes in the cluster. + # TYPE elasticsearch_cluster_health_number_of_nodes gauge + elasticsearch_cluster_health_number_of_nodes{cluster="elasticsearch"} 1 + # HELP elasticsearch_cluster_health_number_of_pending_tasks Cluster level changes which have not yet been executed + # TYPE elasticsearch_cluster_health_number_of_pending_tasks gauge + elasticsearch_cluster_health_number_of_pending_tasks{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_relocating_shards The number of shards that are currently moving from one node to another node. + # TYPE elasticsearch_cluster_health_relocating_shards gauge + elasticsearch_cluster_health_relocating_shards{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_status Whether all primary and replica shards are allocated. + # TYPE elasticsearch_cluster_health_status gauge + elasticsearch_cluster_health_status{cluster="elasticsearch",color="green"} 0 + elasticsearch_cluster_health_status{cluster="elasticsearch",color="red"} 0 + elasticsearch_cluster_health_status{cluster="elasticsearch",color="yellow"} 1 + # HELP elasticsearch_cluster_health_task_max_waiting_in_queue_millis Tasks max time waiting in queue. + # TYPE elasticsearch_cluster_health_task_max_waiting_in_queue_millis gauge + elasticsearch_cluster_health_task_max_waiting_in_queue_millis{cluster="elasticsearch"} 12 + # HELP elasticsearch_cluster_health_unassigned_shards The number of shards that exist in the cluster state, but cannot be found in the cluster itself. + # TYPE elasticsearch_cluster_health_unassigned_shards gauge + elasticsearch_cluster_health_unassigned_shards{cluster="elasticsearch"} 5 + `, + }, + { + name: "5.4.2", + file: "../fixtures/clusterhealth/5.4.2.json", + want: ` + # HELP elasticsearch_cluster_health_active_primary_shards The number of primary shards in your cluster. This is an aggregate total across all indices. + # TYPE elasticsearch_cluster_health_active_primary_shards gauge + elasticsearch_cluster_health_active_primary_shards{cluster="elasticsearch"} 5 + # HELP elasticsearch_cluster_health_active_shards Aggregate total of all shards across all indices, which includes replica shards. + # TYPE elasticsearch_cluster_health_active_shards gauge + elasticsearch_cluster_health_active_shards{cluster="elasticsearch"} 5 + # HELP elasticsearch_cluster_health_delayed_unassigned_shards Shards delayed to reduce reallocation overhead + # TYPE elasticsearch_cluster_health_delayed_unassigned_shards gauge + elasticsearch_cluster_health_delayed_unassigned_shards{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_initializing_shards Count of shards that are being freshly created. + # TYPE elasticsearch_cluster_health_initializing_shards gauge + elasticsearch_cluster_health_initializing_shards{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_number_of_data_nodes Number of data nodes in the cluster. + # TYPE elasticsearch_cluster_health_number_of_data_nodes gauge + elasticsearch_cluster_health_number_of_data_nodes{cluster="elasticsearch"} 1 + # HELP elasticsearch_cluster_health_number_of_in_flight_fetch The number of ongoing shard info requests. + # TYPE elasticsearch_cluster_health_number_of_in_flight_fetch gauge + elasticsearch_cluster_health_number_of_in_flight_fetch{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_number_of_nodes Number of nodes in the cluster. + # TYPE elasticsearch_cluster_health_number_of_nodes gauge + elasticsearch_cluster_health_number_of_nodes{cluster="elasticsearch"} 1 + # HELP elasticsearch_cluster_health_number_of_pending_tasks Cluster level changes which have not yet been executed + # TYPE elasticsearch_cluster_health_number_of_pending_tasks gauge + elasticsearch_cluster_health_number_of_pending_tasks{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_relocating_shards The number of shards that are currently moving from one node to another node. + # TYPE elasticsearch_cluster_health_relocating_shards gauge + elasticsearch_cluster_health_relocating_shards{cluster="elasticsearch"} 0 + # HELP elasticsearch_cluster_health_status Whether all primary and replica shards are allocated. + # TYPE elasticsearch_cluster_health_status gauge + elasticsearch_cluster_health_status{cluster="elasticsearch",color="green"} 0 + elasticsearch_cluster_health_status{cluster="elasticsearch",color="red"} 0 + elasticsearch_cluster_health_status{cluster="elasticsearch",color="yellow"} 1 + # HELP elasticsearch_cluster_health_task_max_waiting_in_queue_millis Tasks max time waiting in queue. + # TYPE elasticsearch_cluster_health_task_max_waiting_in_queue_millis gauge + elasticsearch_cluster_health_task_max_waiting_in_queue_millis{cluster="elasticsearch"} 12 + # HELP elasticsearch_cluster_health_unassigned_shards The number of shards that exist in the cluster state, but cannot be found in the cluster itself. + # TYPE elasticsearch_cluster_health_unassigned_shards gauge + elasticsearch_cluster_health_unassigned_shards{cluster="elasticsearch"} 5 + `, + }, } - for ver, out := range tcs { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, out) - })) - defer ts.Close() - - u, err := url.Parse(ts.URL) - if err != nil { - t.Fatalf("Failed to parse URL: %s", err) - } - c := NewClusterHealth(log.NewNopLogger(), http.DefaultClient, u) - chr, err := c.fetchAndDecodeClusterHealth() - if err != nil { - t.Fatalf("Failed to fetch or decode cluster health: %s", err) - } - t.Logf("[%s] Cluster Health Response: %+v", ver, chr) - if chr.ClusterName != "elasticsearch" { - t.Errorf("Invalid cluster health response") - } - if chr.Status != "yellow" { - t.Errorf("Invalid cluster status") - } - if chr.TimedOut { - t.Errorf("Check didn't time out") - } - if chr.NumberOfNodes != 1 { - t.Errorf("Wrong number of nodes") - } - if chr.NumberOfDataNodes != 1 { - t.Errorf("Wrong number of data nodes") - } - if ver != "1.7.6" { - if chr.TaskMaxWaitingInQueueMillis != 12 { - t.Errorf("Wrong task max waiting time in millis") + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f, err := os.Open(tt.file) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.Copy(w, f) + })) + defer ts.Close() + + u, err := url.Parse(ts.URL) + if err != nil { + t.Fatal(err) + } + + c := NewClusterHealth(promslog.NewNopLogger(), http.DefaultClient, u) + if err != nil { + t.Fatal(err) + } + + if err := testutil.CollectAndCompare(c, strings.NewReader(tt.want)); err != nil { + t.Fatal(err) } - } + }) } } diff --git a/collector/cluster_info.go b/collector/cluster_info.go new file mode 100644 index 00000000..5dafb9b9 --- /dev/null +++ b/collector/cluster_info.go @@ -0,0 +1,109 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "context" + "encoding/json" + "io" + "log/slog" + "net/http" + "net/url" + + "github.com/blang/semver/v4" + "github.com/prometheus/client_golang/prometheus" +) + +func init() { + registerCollector("cluster-info", defaultEnabled, NewClusterInfo) +} + +type ClusterInfoCollector struct { + logger *slog.Logger + u *url.URL + hc *http.Client +} + +func NewClusterInfo(logger *slog.Logger, u *url.URL, hc *http.Client) (Collector, error) { + return &ClusterInfoCollector{ + logger: logger, + u: u, + hc: hc, + }, nil +} + +var clusterInfoDesc = map[string]*prometheus.Desc{ + "version": prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "version"), + "Elasticsearch version information.", + []string{ + "cluster", + "cluster_uuid", + "build_date", + "build_hash", + "version", + "lucene_version", + }, + nil, + ), +} + +// ClusterInfoResponse is the cluster info retrievable from the / endpoint +type ClusterInfoResponse struct { + Name string `json:"name"` + ClusterName string `json:"cluster_name"` + ClusterUUID string `json:"cluster_uuid"` + Version VersionInfo `json:"version"` + Tagline string `json:"tagline"` +} + +// VersionInfo is the version info retrievable from the / endpoint, embedded in ClusterInfoResponse +type VersionInfo struct { + Number semver.Version `json:"number"` + BuildHash string `json:"build_hash"` + BuildDate string `json:"build_date"` + BuildSnapshot bool `json:"build_snapshot"` + LuceneVersion semver.Version `json:"lucene_version"` +} + +func (c *ClusterInfoCollector) Update(_ context.Context, ch chan<- prometheus.Metric) error { + resp, err := c.hc.Get(c.u.String()) + if err != nil { + return err + } + defer resp.Body.Close() + b, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + var info ClusterInfoResponse + err = json.Unmarshal(b, &info) + if err != nil { + return err + } + + ch <- prometheus.MustNewConstMetric( + clusterInfoDesc["version"], + prometheus.GaugeValue, + 1, + info.ClusterName, + info.ClusterUUID, + info.Version.BuildDate, + info.Version.BuildHash, + info.Version.Number.String(), + info.Version.LuceneVersion.String(), + ) + + return nil +} diff --git a/collector/cluster_info_test.go b/collector/cluster_info_test.go new file mode 100644 index 00000000..d7d12bc2 --- /dev/null +++ b/collector/cluster_info_test.go @@ -0,0 +1,93 @@ +// Copyright 2023 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "io" + "net/http" + "net/http/httptest" + "net/url" + "os" + "strings" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/promslog" +) + +func TestClusterInfo(t *testing.T) { + // Testcases created using: + // docker run -p 9200:9200 -e "discovery.type=single-node" elasticsearch:${VERSION} + // curl http://localhost:9200/ > fixtures/cluster_info/${VERSION}.json + + tests := []struct { + name string + file string + want string + }{ + { + name: "2.4.5", + file: "../fixtures/clusterinfo/2.4.5.json", + want: `# HELP elasticsearch_version Elasticsearch version information. + # TYPE elasticsearch_version gauge + elasticsearch_version{build_date="",build_hash="c849dd13904f53e63e88efc33b2ceeda0b6a1276",cluster="elasticsearch",cluster_uuid="3qps7bcWTqyzV49ApmPVfw",lucene_version="5.5.4",version="2.4.5"} 1 + `, + }, + { + name: "5.4.2", + file: "../fixtures/clusterinfo/5.4.2.json", + want: `# HELP elasticsearch_version Elasticsearch version information. + # TYPE elasticsearch_version gauge + elasticsearch_version{build_date="2017-06-15T02:29:28.122Z",build_hash="929b078",cluster="elasticsearch",cluster_uuid="kbqi7yhQT-WlPdGL2m0xJg",lucene_version="6.5.1",version="5.4.2"} 1 + `, + }, + { + name: "7.13.1", + file: "../fixtures/clusterinfo/7.13.1.json", + want: `# HELP elasticsearch_version Elasticsearch version information. + # TYPE elasticsearch_version gauge + elasticsearch_version{build_date="2021-05-28T17:40:59.346932922Z",build_hash="9a7758028e4ea59bcab41c12004603c5a7dd84a9",cluster="docker-cluster",cluster_uuid="aCMrCY1VQpqJ6U4Sw_xdiw",lucene_version="8.8.2",version="7.13.1"} 1 + `, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f, err := os.Open(tt.file) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.Copy(w, f) + })) + defer ts.Close() + + u, err := url.Parse(ts.URL) + if err != nil { + t.Fatal(err) + } + + c, err := NewClusterInfo(promslog.NewNopLogger(), u, http.DefaultClient) + if err != nil { + t.Fatal(err) + } + + if err := testutil.CollectAndCompare(wrapCollector{c}, strings.NewReader(tt.want)); err != nil { + t.Fatal(err) + } + }) + } +} diff --git a/collector/cluster_settings.go b/collector/cluster_settings.go index 978abddd..35ee97f5 100644 --- a/collector/cluster_settings.go +++ b/collector/cluster_settings.go @@ -1,140 +1,201 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector import ( + "context" "encoding/json" "fmt" + "io" + "log/slog" "net/http" "net/url" - "path" + "strconv" + "strings" - "github.com/go-kit/kit/log" - "github.com/go-kit/kit/log/level" "github.com/imdario/mergo" "github.com/prometheus/client_golang/prometheus" ) -// ClusterSettings information struct -type ClusterSettings struct { - logger log.Logger - client *http.Client - url *url.URL +func init() { + registerCollector("clustersettings", defaultDisabled, NewClusterSettings) +} - up prometheus.Gauge - shardAllocationEnabled prometheus.Gauge - totalScrapes, jsonParseFailures prometheus.Counter +type ClusterSettingsCollector struct { + logger *slog.Logger + u *url.URL + hc *http.Client } -// NewClusterSettings defines Cluster Settings Prometheus metrics -func NewClusterSettings(logger log.Logger, client *http.Client, url *url.URL) *ClusterSettings { - return &ClusterSettings{ +func NewClusterSettings(logger *slog.Logger, u *url.URL, hc *http.Client) (Collector, error) { + return &ClusterSettingsCollector{ logger: logger, - client: client, - url: url, - - up: prometheus.NewGauge(prometheus.GaugeOpts{ - Name: prometheus.BuildFQName(namespace, "clustersettings_stats", "up"), - Help: "Was the last scrape of the ElasticSearch cluster settings endpoint successful.", - }), - totalScrapes: prometheus.NewCounter(prometheus.CounterOpts{ - Name: prometheus.BuildFQName(namespace, "clustersettings_stats", "total_scrapes"), - Help: "Current total ElasticSearch cluster settings scrapes.", - }), - shardAllocationEnabled: prometheus.NewGauge(prometheus.GaugeOpts{ - Name: prometheus.BuildFQName(namespace, "clustersettings_stats", "shard_allocation_enabled"), - Help: "Current mode of cluster wide shard routing allocation settings.", - }), - jsonParseFailures: prometheus.NewCounter(prometheus.CounterOpts{ - Name: prometheus.BuildFQName(namespace, "clustersettings_stats", "json_parse_failures"), - Help: "Number of errors while parsing JSON.", - }), - } + u: u, + hc: hc, + }, nil } -// Describe add Snapshots metrics descriptions -func (cs *ClusterSettings) Describe(ch chan<- *prometheus.Desc) { - ch <- cs.up.Desc() - ch <- cs.totalScrapes.Desc() - ch <- cs.shardAllocationEnabled.Desc() - ch <- cs.jsonParseFailures.Desc() +var clusterSettingsDesc = map[string]*prometheus.Desc{ + "shardAllocationEnabled": prometheus.NewDesc( + prometheus.BuildFQName(namespace, "clustersettings_stats", "shard_allocation_enabled"), + "Current mode of cluster wide shard routing allocation settings.", + nil, nil, + ), + + "maxShardsPerNode": prometheus.NewDesc( + prometheus.BuildFQName(namespace, "clustersettings_stats", "max_shards_per_node"), + "Current maximum number of shards per node setting.", + nil, nil, + ), + + "thresholdEnabled": prometheus.NewDesc( + prometheus.BuildFQName(namespace, "clustersettings_allocation", "threshold_enabled"), + "Is disk allocation decider enabled.", + nil, nil, + ), + + "floodStageRatio": prometheus.NewDesc( + prometheus.BuildFQName(namespace, "clustersettings_allocation_watermark", "flood_stage_ratio"), + "Flood stage watermark as a ratio.", + nil, nil, + ), + + "highRatio": prometheus.NewDesc( + prometheus.BuildFQName(namespace, "clustersettings_allocation_watermark", "high_ratio"), + "High watermark for disk usage as a ratio.", + nil, nil, + ), + + "lowRatio": prometheus.NewDesc( + prometheus.BuildFQName(namespace, "clustersettings_allocation_watermark", "low_ratio"), + "Low watermark for disk usage as a ratio.", + nil, nil, + ), + + "floodStageBytes": prometheus.NewDesc( + prometheus.BuildFQName(namespace, "clustersettings_allocation_watermark", "flood_stage_bytes"), + "Flood stage watermark as in bytes.", + nil, nil, + ), + + "highBytes": prometheus.NewDesc( + prometheus.BuildFQName(namespace, "clustersettings_allocation_watermark", "high_bytes"), + "High watermark for disk usage in bytes.", + nil, nil, + ), + + "lowBytes": prometheus.NewDesc( + prometheus.BuildFQName(namespace, "clustersettings_allocation_watermark", "low_bytes"), + "Low watermark for disk usage in bytes.", + nil, nil, + ), } -func (cs *ClusterSettings) getAndParseURL(u *url.URL, data interface{}) error { - res, err := cs.client.Get(u.String()) - if err != nil { - return fmt.Errorf("failed to get from %s://%s:%s%s: %s", - u.Scheme, u.Hostname(), u.Port(), u.Path, err) - } +// clusterSettingsResponse is a representation of a Elasticsearch Cluster Settings +type clusterSettingsResponse struct { + Defaults clusterSettingsSection `json:"defaults"` + Persistent clusterSettingsSection `json:"persistent"` + Transient clusterSettingsSection `json:"transient"` +} - defer func() { - err = res.Body.Close() - if err != nil { - _ = level.Warn(cs.logger).Log( - "msg", "failed to close http.Client", - "err", err, - ) - } - }() +// clusterSettingsSection is a representation of a Elasticsearch Cluster Settings +type clusterSettingsSection struct { + Cluster clusterSettingsCluster `json:"cluster"` +} - if res.StatusCode != http.StatusOK { - return fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) - } +// clusterSettingsCluster is a representation of a Elasticsearch clusterSettingsCluster Settings +type clusterSettingsCluster struct { + Routing clusterSettingsRouting `json:"routing"` + // This can be either a JSON object (which does not contain the value we are interested in) or a string + MaxShardsPerNode interface{} `json:"max_shards_per_node"` +} - if err := json.NewDecoder(res.Body).Decode(data); err != nil { - cs.jsonParseFailures.Inc() - return err - } - return nil +// clusterSettingsRouting is a representation of a Elasticsearch Cluster shard routing configuration +type clusterSettingsRouting struct { + Allocation clusterSettingsAllocation `json:"allocation"` +} + +// clusterSettingsAllocation is a representation of a Elasticsearch Cluster shard routing allocation settings +type clusterSettingsAllocation struct { + Enabled string `json:"enable"` + Disk clusterSettingsDisk `json:"disk"` } -func (cs *ClusterSettings) fetchAndDecodeClusterSettingsStats() (ClusterSettingsResponse, error) { +// clusterSettingsDisk is a representation of a Elasticsearch Cluster shard routing disk allocation settings +type clusterSettingsDisk struct { + ThresholdEnabled string `json:"threshold_enabled"` + Watermark clusterSettingsWatermark `json:"watermark"` +} + +// clusterSettingsWatermark is representation of Elasticsearch Cluster shard routing disk allocation watermark settings +type clusterSettingsWatermark struct { + FloodStage string `json:"flood_stage"` + High string `json:"high"` + Low string `json:"low"` +} - u := *cs.url - u.Path = path.Join(u.Path, "/_cluster/settings") +func (c *ClusterSettingsCollector) Update(ctx context.Context, ch chan<- prometheus.Metric) error { + u := c.u.ResolveReference(&url.URL{Path: "_cluster/settings"}) q := u.Query() q.Set("include_defaults", "true") - u.RawPath = q.Encode() - var csfr ClusterSettingsFullResponse - var csr ClusterSettingsResponse - err := cs.getAndParseURL(&u, &csfr) + u.RawQuery = q.Encode() + + req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) if err != nil { - return csr, err + return err } - err = mergo.Merge(&csr, csfr.Defaults, mergo.WithOverride) + + resp, err := c.hc.Do(req) if err != nil { - return csr, err + return err } - err = mergo.Merge(&csr, csfr.Persistent, mergo.WithOverride) + defer resp.Body.Close() + b, err := io.ReadAll(resp.Body) if err != nil { - return csr, err + return err + } + var data clusterSettingsResponse + err = json.Unmarshal(b, &data) + if err != nil { + return err } - err = mergo.Merge(&csr, csfr.Transient, mergo.WithOverride) - - return csr, err -} - -// Collect gets cluster settings metric values -func (cs *ClusterSettings) Collect(ch chan<- prometheus.Metric) { - cs.totalScrapes.Inc() - defer func() { - ch <- cs.up - ch <- cs.totalScrapes - ch <- cs.jsonParseFailures - ch <- cs.shardAllocationEnabled - }() + // Merge all settings into one struct + merged := data.Defaults - csr, err := cs.fetchAndDecodeClusterSettingsStats() + err = mergo.Merge(&merged, data.Persistent, mergo.WithOverride) if err != nil { - cs.shardAllocationEnabled.Set(0) - cs.up.Set(0) - _ = level.Warn(cs.logger).Log( - "msg", "failed to fetch and decode cluster settings stats", - "err", err, - ) - return + return err + } + err = mergo.Merge(&merged, data.Transient, mergo.WithOverride) + if err != nil { + return err } - cs.up.Set(1) + // Max shards per node + if maxShardsPerNodeString, ok := merged.Cluster.MaxShardsPerNode.(string); ok { + maxShardsPerNode, err := strconv.ParseInt(maxShardsPerNodeString, 10, 64) + if err == nil { + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["maxShardsPerNode"], + prometheus.GaugeValue, + float64(maxShardsPerNode), + ) + } + } + + // Shard allocation enabled shardAllocationMap := map[string]int{ "all": 0, "primaries": 1, @@ -142,5 +203,143 @@ func (cs *ClusterSettings) Collect(ch chan<- prometheus.Metric) { "none": 3, } - cs.shardAllocationEnabled.Set(float64(shardAllocationMap[csr.Cluster.Routing.Allocation.Enabled])) + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["shardAllocationEnabled"], + prometheus.GaugeValue, + float64(shardAllocationMap[merged.Cluster.Routing.Allocation.Enabled]), + ) + + // Threshold enabled + thresholdMap := map[string]int{ + "false": 0, + "true": 1, + } + + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["thresholdEnabled"], + prometheus.GaugeValue, + float64(thresholdMap[merged.Cluster.Routing.Allocation.Disk.ThresholdEnabled]), + ) + + // Watermark bytes or ratio metrics + if strings.HasSuffix(merged.Cluster.Routing.Allocation.Disk.Watermark.High, "b") { + flooodStageBytes, err := getValueInBytes(merged.Cluster.Routing.Allocation.Disk.Watermark.FloodStage) + if err != nil { + c.logger.Error("failed to parse flood_stage bytes", "err", err) + } else { + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["floodStageBytes"], + prometheus.GaugeValue, + flooodStageBytes, + ) + } + + highBytes, err := getValueInBytes(merged.Cluster.Routing.Allocation.Disk.Watermark.High) + if err != nil { + c.logger.Error("failed to parse high bytes", "err", err) + } else { + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["highBytes"], + prometheus.GaugeValue, + highBytes, + ) + } + + lowBytes, err := getValueInBytes(merged.Cluster.Routing.Allocation.Disk.Watermark.Low) + if err != nil { + c.logger.Error("failed to parse low bytes", "err", err) + } else { + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["lowBytes"], + prometheus.GaugeValue, + lowBytes, + ) + } + + return nil + } + + // Watermark ratio metrics + floodRatio, err := getValueAsRatio(merged.Cluster.Routing.Allocation.Disk.Watermark.FloodStage) + if err != nil { + c.logger.Error("failed to parse flood_stage ratio", "err", err) + } else { + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["floodStageRatio"], + prometheus.GaugeValue, + floodRatio, + ) + } + + highRatio, err := getValueAsRatio(merged.Cluster.Routing.Allocation.Disk.Watermark.High) + if err != nil { + c.logger.Error("failed to parse high ratio", "err", err) + } else { + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["highRatio"], + prometheus.GaugeValue, + highRatio, + ) + } + + lowRatio, err := getValueAsRatio(merged.Cluster.Routing.Allocation.Disk.Watermark.Low) + if err != nil { + c.logger.Error("failed to parse low ratio", "err", err) + } else { + ch <- prometheus.MustNewConstMetric( + clusterSettingsDesc["lowRatio"], + prometheus.GaugeValue, + lowRatio, + ) + } + + return nil +} + +func getValueInBytes(value string) (float64, error) { + type UnitValue struct { + unit string + val float64 + } + + unitValues := []UnitValue{ + {"pb", 1024 * 1024 * 1024 * 1024 * 1024}, + {"tb", 1024 * 1024 * 1024 * 1024}, + {"gb", 1024 * 1024 * 1024}, + {"mb", 1024 * 1024}, + {"kb", 1024}, + {"b", 1}, + } + + for _, uv := range unitValues { + if strings.HasSuffix(value, uv.unit) { + numberStr := strings.TrimSuffix(value, uv.unit) + + number, err := strconv.ParseFloat(numberStr, 64) + if err != nil { + return 0, err + } + return number * uv.val, nil + } + } + + return 0, fmt.Errorf("failed to convert unit %s to bytes", value) +} + +func getValueAsRatio(value string) (float64, error) { + if strings.HasSuffix(value, "%") { + percentValue, err := strconv.Atoi(strings.TrimSpace(strings.TrimSuffix(value, "%"))) + if err != nil { + return 0, err + } + + return float64(percentValue) / 100, nil + } + + ratio, err := strconv.ParseFloat(value, 64) + if err != nil { + return 0, err + } + + return ratio, nil } diff --git a/collector/cluster_settings_response.go b/collector/cluster_settings_response.go deleted file mode 100644 index 1ef3cc5d..00000000 --- a/collector/cluster_settings_response.go +++ /dev/null @@ -1,28 +0,0 @@ -package collector - -// ClusterSettingsFullResponse is a representation of a Elasticsearch Cluster Settings -type ClusterSettingsFullResponse struct { - Defaults ClusterSettingsResponse `json:"defaults"` - Persistent ClusterSettingsResponse `json:"persistent"` - Transient ClusterSettingsResponse `json:"transient"` -} - -// ClusterSettingsResponse is a representation of a Elasticsearch Cluster Settings -type ClusterSettingsResponse struct { - Cluster Cluster `json:"cluster"` -} - -// Cluster is a representation of a Elasticsearch Cluster Settings -type Cluster struct { - Routing Routing `json:"routing"` -} - -// Routing is a representation of a Elasticsearch Cluster shard routing configuration -type Routing struct { - Allocation Allocation `json:"allocation"` -} - -// Allocation is a representation of a Elasticsearch Cluster shard routing allocation settings -type Allocation struct { - Enabled string `json:"enable"` -} diff --git a/collector/cluster_settings_test.go b/collector/cluster_settings_test.go index 3a10aac5..52c41a1e 100644 --- a/collector/cluster_settings_test.go +++ b/collector/cluster_settings_test.go @@ -1,44 +1,203 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector import ( - "fmt" + "io" "net/http" "net/http/httptest" "net/url" + "os" + "strings" "testing" - "github.com/go-kit/kit/log" + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/promslog" ) func TestClusterSettingsStats(t *testing.T) { // Testcases created using: // docker run -d -p 9200:9200 elasticsearch:VERSION-alpine // curl http://localhost:9200/_cluster/settings/?include_defaults=true - tcs := map[string]string{ - "5.4.2": `{"persistent":{},"transient":{},"defaults":{"cluster":{"routing":{"rebalance":{"enable":"ALL"},"allocation":{"node_concurrent_incoming_recoveries":"2","node_initial_primaries_recoveries":"4","same_shard":{"host":"false"},"total_shards_per_node":"-1","type":"balanced","disk":{"threshold_enabled":"true","watermark":{"low":"85%","high":"90%"},"include_relocations":"true","reroute_interval":"60s"},"awareness":{"attributes":""},"balance":{"index":"0.55","threshold":"1.0","shard":"0.45"},"enable":"ALL","node_concurrent_outgoing_recoveries":"2","allow_rebalance":"indices_all_active","cluster_concurrent_rebalance":"2","node_concurrent_recoveries":"2","snapshot":{"relocation_enabled":"false"}}},"indices":{"close":{"enable":"true"}},"nodes":{"reconnect_interval":"10s"},"blocks":{"read_only":"false"},"service":{"slow_task_logging_threshold":"30s"},"name":"elasticsearch","info":{"update":{"interval":"30s","timeout":"15s"}}},"logger":{"level":"INFO"},"bootstrap":{"ctrlhandler":"true","memory_lock":"false","system_call_filter":"true","seccomp":"true"},"processors":"4","network":{"host":["_local_"],"tcp":{"reuse_address":"true","connect_timeout":"30s","blocking":"false","blocking_server":"false","no_delay":"true","blocking_client":"false","keep_alive":"true","receive_buffer_size":"-1b","send_buffer_size":"-1b"},"bind_host":["_local_"],"server":"true","breaker":{"inflight_requests":{"limit":"100%","overhead":"1.0"}},"publish_host":["_local_"]},"pidfile":"","path":{"conf":"","scripts":"","logs":"/usr/share/elasticsearch/logs","shared_data":"","home":"/usr/share/elasticsearch"},"default":{"path":{"logs":"","conf":""}},"search":{"default_search_timeout":"-1","highlight":{"term_vector_multi_value":"true"},"low_level_cancellation":"false","keep_alive_interval":"1m","remote":{"node":{"attr":""},"initial_connect_timeout":"30s","connect":"true","connections_per_cluster":"3"},"default_keep_alive":"5m"},"security":{"manager":{"filter_bad_defaults":"true"}},"repositories":{"fs":{"compress":"false","chunk_size":"-1b","location":""},"url":{"supported_protocols":["http","https","ftp","file","jar"],"url":"http:"}},"action":{"auto_create_index":"true","search":{"shard_count":{"limit":"9223372036854775807"}},"destructive_requires_name":"false","master":{"force_local":"false"}},"client":{"type":"node","transport":{"ignore_cluster_name":"false","nodes_sampler_interval":"5s","sniff":"false","ping_timeout":"5s"}},"rest":{"action":{"multi":{"allow_explicit_index":"true"}}},"cache":{"recycler":{"page":{"limit":{"heap":"10%"},"type":"CONCURRENT","weight":{"longs":"1.0","ints":"1.0","bytes":"1.0","objects":"0.1"}}}},"resource":{"reload":{"enabled":"true","interval":{"low":"60s","high":"5s","medium":"30s"}}},"thread_pool":{"force_merge":{"queue_size":"-1","size":"1"},"fetch_shard_started":{"core":"1","max":"8","keep_alive":"5m"},"listener":{"queue_size":"-1","size":"2"},"index":{"queue_size":"200","size":"4"},"refresh":{"core":"1","max":"2","keep_alive":"5m"},"generic":{"core":"4","max":"128","keep_alive":"30s"},"warmer":{"core":"1","max":"2","keep_alive":"5m"},"search":{"queue_size":"1000","size":"7"},"fetch_shard_store":{"core":"1","max":"8","keep_alive":"5m"},"flush":{"core":"1","max":"2","keep_alive":"5m"},"management":{"core":"1","max":"5","keep_alive":"5m"},"get":{"queue_size":"1000","size":"4"},"bulk":{"queue_size":"200","size":"4"},"estimated_time_interval":"200ms","snapshot":{"core":"1","max":"2","keep_alive":"5m"}},"index":{"codec":"default","store":{"type":"","fs":{"fs_lock":"native"}}},"monitor":{"jvm":{"gc":{"enabled":"true","overhead":{"warn":"50","debug":"10","info":"25"},"refresh_interval":"1s"},"refresh_interval":"1s"},"process":{"refresh_interval":"1s"},"os":{"refresh_interval":"1s"},"fs":{"refresh_interval":"1s"}},"transport":{"tcp":{"reuse_address":"true","connect_timeout":"30s","compress":"false","port":"9300-9400","blocking_server":"false","blocking_client":"false","keep_alive":"true","receive_buffer_size":"-1b","send_buffer_size":"-1b"},"ping_schedule":"-1","publish_port":"-1","connections_per_node":{"recovery":"2","state":"1","bulk":"3","reg":"6","ping":"1"},"tcp_no_delay":"true","tracer":{"exclude":["internal:discovery/zen/fd*","cluster:monitor/nodes/liveness"]},"type":"","netty":{"max_composite_buffer_components":"-1","worker_count":"8","receive_predictor_size":"512kb","receive_predictor_max":"512kb","receive_predictor_min":"512kb","boss_count":"1","max_cumulation_buffer_capacity":"-1b"},"type.default":"netty4"},"script":{"cache":{"max_size":"100","expire":"0ms"},"painless":{"regex":{"enabled":"false"}},"legacy":{"default_lang":"groovy"},"max_size_in_bytes":"65535","update":"false","max_compilations_per_minute":"15","ingest":"false","search":"false","file":"true","inline":"false","auto_reload_enabled":"true","engine":{"painless":{"file.ingest":"true","file.update":"true","file.aggs":"true","inline.ingest":"true","file":"true","inline":"true","inline.update":"true","stored.search":"true","inline.aggs":"true","file.search":"true","stored":"true","stored.ingest":"true","stored.aggs":"true","stored.update":"true","inline.search":"true"},"expression":{"file.ingest":"true","file.update":"true","file.aggs":"true","inline.ingest":"true","file":"true","inline":"true","inline.update":"true","stored.search":"true","inline.aggs":"true","file.search":"true","stored":"true","stored.ingest":"true","stored.aggs":"true","stored.update":"true","inline.search":"true"},"groovy":{"file.ingest":"true","file.update":"true","file.aggs":"true","inline.ingest":"false","file":"true","inline":"false","inline.update":"false","stored.search":"false","inline.aggs":"false","file.search":"true","stored":"false","stored.ingest":"false","stored.aggs":"false","stored.update":"false","inline.search":"false"},"mustache":{"file.ingest":"true","file.update":"true","file.aggs":"true","inline.ingest":"true","file":"true","inline":"true","inline.update":"true","stored.search":"true","inline.aggs":"true","file.search":"true","stored":"true","stored.ingest":"true","stored.aggs":"true","stored.update":"true","inline.search":"true"}},"stored":"false","aggs":"false"},"node":{"data":"true","enable_lucene_segment_infos_trace":"false","local_storage":"true","max_local_storage_nodes":"1","name":"DK8-2Lc","id":{"seed":"0"},"add_lock_id_to_custom_path":"true","portsfile":"false","ingest":"true","master":"true"},"indices":{"cache":{"cleanup_interval":"1m"},"mapping":{"dynamic_timeout":"30s"},"memory":{"interval":"5s","max_index_buffer_size":"-1b","shard_inactive_time":"5m","index_buffer_size":"10%","min_index_buffer_size":"48mb"},"breaker":{"request":{"limit":"60%","type":"memory","overhead":"1.0"},"total":{"limit":"70%"},"fielddata":{"limit":"60%","type":"memory","overhead":"1.03"},"type":"hierarchy"},"fielddata":{"cache":{"size":"-1b"}},"query":{"bool":{"max_clause_count":"1024"},"query_string":{"analyze_wildcard":"false","allowLeadingWildcard":"true"}},"recovery":{"recovery_activity_timeout":"1800000ms","retry_delay_network":"5s","internal_action_timeout":"15m","retry_delay_state_sync":"500ms","internal_action_long_timeout":"1800000ms","max_bytes_per_sec":"40mb"},"requests":{"cache":{"size":"1%","expire":"0ms"}},"store":{"delete":{"shard":{"timeout":"30s"}},"throttle":{"type":"NONE","max_bytes_per_sec":"0b"}},"analysis":{"hunspell":{"dictionary":{"ignore_case":"false","lazy":"false"}}},"queries":{"cache":{"count":"10000","size":"10%","all_segments":"false"}},"ttl":{"interval":"60s"}},"discovery":{"type":"zen","zen":{"commit_timeout":"30s","no_master_block":"write","join_retry_delay":"100ms","join_retry_attempts":"3","ping":{"unicast":{"concurrent_connects":"10","hosts":{"resolve_timeout":"5s"}}},"master_election":{"ignore_non_master_pings":"false","wait_for_joins_timeout":"30000ms"},"send_leave_request":"true","ping_timeout":"3s","join_timeout":"60000ms","publish_diff":{"enable":"true"},"minimum_master_nodes":"-1","hosts_provider":null,"publish_timeout":"30s","fd":{"connect_on_network_disconnect":"false","ping_interval":"1s","ping_retries":"3","register_connection_listener":"true","ping_timeout":"30s"},"max_pings_from_another_master":"3"},"initial_state_timeout":"30s"},"tribe":{"name":"","on_conflict":"any","blocks":{"write":"false","metadata":"false"}},"http":{"tcp":{"reuse_address":"true","keep_alive":"true","blocking_server":"false","receive_buffer_size":"-1b","send_buffer_size":"-1b"},"bind_host":["0.0.0.0"],"cors":{"max-age":"1728000","allow-origin":"","allow-headers":"X-Requested-With,Content-Type,Content-Length","allow-credentials":"false","allow-methods":"OPTIONS,HEAD,GET,POST,PUT,DELETE","enabled":"false"},"max_chunk_size":"8kb","compression_level":"3","reset_cookies":"false","max_initial_line_length":"4kb","type":"","pipelining":"true","enabled":"true","type.default":"netty4","detailed_errors":{"enabled":"true"},"content_type":{"required":"false"},"port":"9200-9300","host":["0.0.0.0"],"publish_port":"-1","max_header_size":"8kb","pipelining.max_events":"10000","tcp_no_delay":"true","compression":"true","publish_host":["0.0.0.0"],"max_content_length":"100mb","netty":{"receive_predictor_size":"64kb","max_composite_buffer_components":"-1","receive_predictor_max":"64kb","worker_count":"8","receive_predictor_min":"64kb","max_cumulation_buffer_capacity":"-1b"}},"gateway":{"recover_after_master_nodes":"0","expected_nodes":"-1","recover_after_data_nodes":"-1","initial_shards":"quorum","expected_data_nodes":"-1","recover_after_time":"0ms","expected_master_nodes":"-1","recover_after_nodes":"-1"}}}`, - "5.4.2-merge": `{"persistent":{},"transient":{"cluster":{"routing":{"allocation":{"enable":"ALL"}}}},"defaults":{"cluster":{"routing":{"rebalance":{"enable":"ALL"},"none":{"node_concurrent_incoming_recoveries":"2","node_initial_primaries_recoveries":"4","same_shard":{"host":"false"},"total_shards_per_node":"-1","type":"balanced","disk":{"threshold_enabled":"true","watermark":{"low":"85%","high":"90%"},"include_relocations":"true","reroute_interval":"60s"},"awareness":{"attributes":""},"balance":{"index":"0.55","threshold":"1.0","shard":"0.45"},"node_concurrent_outgoing_recoveries":"2","allow_rebalance":"indices_all_active","cluster_concurrent_rebalance":"2","node_concurrent_recoveries":"2","snapshot":{"relocation_enabled":"false"}}},"indices":{"close":{"enable":"true"}},"nodes":{"reconnect_interval":"10s"},"blocks":{"read_only":"false"},"service":{"slow_task_logging_threshold":"30s"},"name":"elasticsearch","info":{"update":{"interval":"30s","timeout":"15s"}}},"logger":{"level":"INFO"},"bootstrap":{"ctrlhandler":"true","memory_lock":"false","system_call_filter":"true","seccomp":"true"},"processors":"4","network":{"host":["_local_"],"tcp":{"reuse_address":"true","connect_timeout":"30s","blocking":"false","blocking_server":"false","no_delay":"true","blocking_client":"false","keep_alive":"true","receive_buffer_size":"-1b","send_buffer_size":"-1b"},"bind_host":["_local_"],"server":"true","breaker":{"inflight_requests":{"limit":"100%","overhead":"1.0"}},"publish_host":["_local_"]},"pidfile":"","path":{"conf":"","scripts":"","logs":"/usr/share/elasticsearch/logs","shared_data":"","home":"/usr/share/elasticsearch"},"default":{"path":{"logs":"","conf":""}},"search":{"default_search_timeout":"-1","highlight":{"term_vector_multi_value":"true"},"low_level_cancellation":"false","keep_alive_interval":"1m","remote":{"node":{"attr":""},"initial_connect_timeout":"30s","connect":"true","connections_per_cluster":"3"},"default_keep_alive":"5m"},"security":{"manager":{"filter_bad_defaults":"true"}},"repositories":{"fs":{"compress":"false","chunk_size":"-1b","location":""},"url":{"supported_protocols":["http","https","ftp","file","jar"],"url":"http:"}},"action":{"auto_create_index":"true","search":{"shard_count":{"limit":"9223372036854775807"}},"destructive_requires_name":"false","master":{"force_local":"false"}},"client":{"type":"node","transport":{"ignore_cluster_name":"false","nodes_sampler_interval":"5s","sniff":"false","ping_timeout":"5s"}},"rest":{"action":{"multi":{"allow_explicit_index":"true"}}},"cache":{"recycler":{"page":{"limit":{"heap":"10%"},"type":"CONCURRENT","weight":{"longs":"1.0","ints":"1.0","bytes":"1.0","objects":"0.1"}}}},"resource":{"reload":{"enabled":"true","interval":{"low":"60s","high":"5s","medium":"30s"}}},"thread_pool":{"force_merge":{"queue_size":"-1","size":"1"},"fetch_shard_started":{"core":"1","max":"8","keep_alive":"5m"},"listener":{"queue_size":"-1","size":"2"},"index":{"queue_size":"200","size":"4"},"refresh":{"core":"1","max":"2","keep_alive":"5m"},"generic":{"core":"4","max":"128","keep_alive":"30s"},"warmer":{"core":"1","max":"2","keep_alive":"5m"},"search":{"queue_size":"1000","size":"7"},"fetch_shard_store":{"core":"1","max":"8","keep_alive":"5m"},"flush":{"core":"1","max":"2","keep_alive":"5m"},"management":{"core":"1","max":"5","keep_alive":"5m"},"get":{"queue_size":"1000","size":"4"},"bulk":{"queue_size":"200","size":"4"},"estimated_time_interval":"200ms","snapshot":{"core":"1","max":"2","keep_alive":"5m"}},"index":{"codec":"default","store":{"type":"","fs":{"fs_lock":"native"}}},"monitor":{"jvm":{"gc":{"enabled":"true","overhead":{"warn":"50","debug":"10","info":"25"},"refresh_interval":"1s"},"refresh_interval":"1s"},"process":{"refresh_interval":"1s"},"os":{"refresh_interval":"1s"},"fs":{"refresh_interval":"1s"}},"transport":{"tcp":{"reuse_address":"true","connect_timeout":"30s","compress":"false","port":"9300-9400","blocking_server":"false","blocking_client":"false","keep_alive":"true","receive_buffer_size":"-1b","send_buffer_size":"-1b"},"ping_schedule":"-1","publish_port":"-1","connections_per_node":{"recovery":"2","state":"1","bulk":"3","reg":"6","ping":"1"},"tcp_no_delay":"true","tracer":{"exclude":["internal:discovery/zen/fd*","cluster:monitor/nodes/liveness"]},"type":"","netty":{"max_composite_buffer_components":"-1","worker_count":"8","receive_predictor_size":"512kb","receive_predictor_max":"512kb","receive_predictor_min":"512kb","boss_count":"1","max_cumulation_buffer_capacity":"-1b"},"type.default":"netty4"},"script":{"cache":{"max_size":"100","expire":"0ms"},"painless":{"regex":{"enabled":"false"}},"legacy":{"default_lang":"groovy"},"max_size_in_bytes":"65535","update":"false","max_compilations_per_minute":"15","ingest":"false","search":"false","file":"true","inline":"false","auto_reload_enabled":"true","engine":{"painless":{"file.ingest":"true","file.update":"true","file.aggs":"true","inline.ingest":"true","file":"true","inline":"true","inline.update":"true","stored.search":"true","inline.aggs":"true","file.search":"true","stored":"true","stored.ingest":"true","stored.aggs":"true","stored.update":"true","inline.search":"true"},"expression":{"file.ingest":"true","file.update":"true","file.aggs":"true","inline.ingest":"true","file":"true","inline":"true","inline.update":"true","stored.search":"true","inline.aggs":"true","file.search":"true","stored":"true","stored.ingest":"true","stored.aggs":"true","stored.update":"true","inline.search":"true"},"groovy":{"file.ingest":"true","file.update":"true","file.aggs":"true","inline.ingest":"false","file":"true","inline":"false","inline.update":"false","stored.search":"false","inline.aggs":"false","file.search":"true","stored":"false","stored.ingest":"false","stored.aggs":"false","stored.update":"false","inline.search":"false"},"mustache":{"file.ingest":"true","file.update":"true","file.aggs":"true","inline.ingest":"true","file":"true","inline":"true","inline.update":"true","stored.search":"true","inline.aggs":"true","file.search":"true","stored":"true","stored.ingest":"true","stored.aggs":"true","stored.update":"true","inline.search":"true"}},"stored":"false","aggs":"false"},"node":{"data":"true","enable_lucene_segment_infos_trace":"false","local_storage":"true","max_local_storage_nodes":"1","name":"DK8-2Lc","id":{"seed":"0"},"add_lock_id_to_custom_path":"true","portsfile":"false","ingest":"true","master":"true"},"indices":{"cache":{"cleanup_interval":"1m"},"mapping":{"dynamic_timeout":"30s"},"memory":{"interval":"5s","max_index_buffer_size":"-1b","shard_inactive_time":"5m","index_buffer_size":"10%","min_index_buffer_size":"48mb"},"breaker":{"request":{"limit":"60%","type":"memory","overhead":"1.0"},"total":{"limit":"70%"},"fielddata":{"limit":"60%","type":"memory","overhead":"1.03"},"type":"hierarchy"},"fielddata":{"cache":{"size":"-1b"}},"query":{"bool":{"max_clause_count":"1024"},"query_string":{"analyze_wildcard":"false","allowLeadingWildcard":"true"}},"recovery":{"recovery_activity_timeout":"1800000ms","retry_delay_network":"5s","internal_action_timeout":"15m","retry_delay_state_sync":"500ms","internal_action_long_timeout":"1800000ms","max_bytes_per_sec":"40mb"},"requests":{"cache":{"size":"1%","expire":"0ms"}},"store":{"delete":{"shard":{"timeout":"30s"}},"throttle":{"type":"NONE","max_bytes_per_sec":"0b"}},"analysis":{"hunspell":{"dictionary":{"ignore_case":"false","lazy":"false"}}},"queries":{"cache":{"count":"10000","size":"10%","all_segments":"false"}},"ttl":{"interval":"60s"}},"discovery":{"type":"zen","zen":{"commit_timeout":"30s","no_master_block":"write","join_retry_delay":"100ms","join_retry_attempts":"3","ping":{"unicast":{"concurrent_connects":"10","hosts":{"resolve_timeout":"5s"}}},"master_election":{"ignore_non_master_pings":"false","wait_for_joins_timeout":"30000ms"},"send_leave_request":"true","ping_timeout":"3s","join_timeout":"60000ms","publish_diff":{"enable":"true"},"minimum_master_nodes":"-1","hosts_provider":null,"publish_timeout":"30s","fd":{"connect_on_network_disconnect":"false","ping_interval":"1s","ping_retries":"3","register_connection_listener":"true","ping_timeout":"30s"},"max_pings_from_another_master":"3"},"initial_state_timeout":"30s"},"tribe":{"name":"","on_conflict":"any","blocks":{"write":"false","metadata":"false"}},"http":{"tcp":{"reuse_address":"true","keep_alive":"true","blocking_server":"false","receive_buffer_size":"-1b","send_buffer_size":"-1b"},"bind_host":["0.0.0.0"],"cors":{"max-age":"1728000","allow-origin":"","allow-headers":"X-Requested-With,Content-Type,Content-Length","allow-credentials":"false","allow-methods":"OPTIONS,HEAD,GET,POST,PUT,DELETE","enabled":"false"},"max_chunk_size":"8kb","compression_level":"3","reset_cookies":"false","max_initial_line_length":"4kb","type":"","pipelining":"true","enabled":"true","type.default":"netty4","detailed_errors":{"enabled":"true"},"content_type":{"required":"false"},"port":"9200-9300","host":["0.0.0.0"],"publish_port":"-1","max_header_size":"8kb","pipelining.max_events":"10000","tcp_no_delay":"true","compression":"true","publish_host":["0.0.0.0"],"max_content_length":"100mb","netty":{"receive_predictor_size":"64kb","max_composite_buffer_components":"-1","receive_predictor_max":"64kb","worker_count":"8","receive_predictor_min":"64kb","max_cumulation_buffer_capacity":"-1b"}},"gateway":{"recover_after_master_nodes":"0","expected_nodes":"-1","recover_after_data_nodes":"-1","initial_shards":"quorum","expected_data_nodes":"-1","recover_after_time":"0ms","expected_master_nodes":"-1","recover_after_nodes":"-1"}}}`} - for ver, out := range tcs { - for hn, handler := range map[string]http.Handler{ - "plain": http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, out) - }), - } { - ts := httptest.NewServer(handler) + + tests := []struct { + name string + file string + want string + }{ + // MaxShardsPerNode is empty in older versions + { + name: "5.4.2", + file: "../fixtures/settings-5.4.2.json", + want: ` +# HELP elasticsearch_clustersettings_stats_shard_allocation_enabled Current mode of cluster wide shard routing allocation settings. +# TYPE elasticsearch_clustersettings_stats_shard_allocation_enabled gauge +elasticsearch_clustersettings_stats_shard_allocation_enabled 0 +# HELP elasticsearch_clustersettings_allocation_threshold_enabled Is disk allocation decider enabled. +# TYPE elasticsearch_clustersettings_allocation_threshold_enabled gauge +elasticsearch_clustersettings_allocation_threshold_enabled 1 +# HELP elasticsearch_clustersettings_allocation_watermark_high_ratio High watermark for disk usage as a ratio. +# TYPE elasticsearch_clustersettings_allocation_watermark_high_ratio gauge +elasticsearch_clustersettings_allocation_watermark_high_ratio 0.9 +# HELP elasticsearch_clustersettings_allocation_watermark_low_ratio Low watermark for disk usage as a ratio. +# TYPE elasticsearch_clustersettings_allocation_watermark_low_ratio gauge +elasticsearch_clustersettings_allocation_watermark_low_ratio 0.85 +`, + }, + + { + name: "5.4.2-merge", + file: "../fixtures/settings-merge-5.4.2.json", + want: ` +# HELP elasticsearch_clustersettings_stats_shard_allocation_enabled Current mode of cluster wide shard routing allocation settings. +# TYPE elasticsearch_clustersettings_stats_shard_allocation_enabled gauge +elasticsearch_clustersettings_stats_shard_allocation_enabled 0 +# HELP elasticsearch_clustersettings_allocation_threshold_enabled Is disk allocation decider enabled. +# TYPE elasticsearch_clustersettings_allocation_threshold_enabled gauge +elasticsearch_clustersettings_allocation_threshold_enabled 0 +`, + }, + { + name: "7.3.0", + file: "../fixtures/settings-7.3.0.json", + want: ` +# HELP elasticsearch_clustersettings_stats_max_shards_per_node Current maximum number of shards per node setting. +# TYPE elasticsearch_clustersettings_stats_max_shards_per_node gauge +elasticsearch_clustersettings_stats_max_shards_per_node 1000 +# HELP elasticsearch_clustersettings_stats_shard_allocation_enabled Current mode of cluster wide shard routing allocation settings. +# TYPE elasticsearch_clustersettings_stats_shard_allocation_enabled gauge +elasticsearch_clustersettings_stats_shard_allocation_enabled 0 +# HELP elasticsearch_clustersettings_allocation_threshold_enabled Is disk allocation decider enabled. +# TYPE elasticsearch_clustersettings_allocation_threshold_enabled gauge +elasticsearch_clustersettings_allocation_threshold_enabled 0 +# HELP elasticsearch_clustersettings_allocation_watermark_flood_stage_ratio Flood stage watermark as a ratio. +# TYPE elasticsearch_clustersettings_allocation_watermark_flood_stage_ratio gauge +elasticsearch_clustersettings_allocation_watermark_flood_stage_ratio 0.95 +# HELP elasticsearch_clustersettings_allocation_watermark_high_ratio High watermark for disk usage as a ratio. +# TYPE elasticsearch_clustersettings_allocation_watermark_high_ratio gauge +elasticsearch_clustersettings_allocation_watermark_high_ratio 0.9 +# HELP elasticsearch_clustersettings_allocation_watermark_low_ratio Low watermark for disk usage as a ratio. +# TYPE elasticsearch_clustersettings_allocation_watermark_low_ratio gauge +elasticsearch_clustersettings_allocation_watermark_low_ratio 0.85 +`, + }, + { + name: "7.17.5-persistent-clustermaxshardspernode", + file: "../fixtures/settings-persistent-clustermaxshardspernode-7.17.5.json", + want: ` +# HELP elasticsearch_clustersettings_stats_max_shards_per_node Current maximum number of shards per node setting. +# TYPE elasticsearch_clustersettings_stats_max_shards_per_node gauge +elasticsearch_clustersettings_stats_max_shards_per_node 1000 +# HELP elasticsearch_clustersettings_stats_shard_allocation_enabled Current mode of cluster wide shard routing allocation settings. +# TYPE elasticsearch_clustersettings_stats_shard_allocation_enabled gauge +elasticsearch_clustersettings_stats_shard_allocation_enabled 0 +# HELP elasticsearch_clustersettings_allocation_threshold_enabled Is disk allocation decider enabled. +# TYPE elasticsearch_clustersettings_allocation_threshold_enabled gauge +elasticsearch_clustersettings_allocation_threshold_enabled 1 +# HELP elasticsearch_clustersettings_allocation_watermark_flood_stage_bytes Flood stage watermark as in bytes. +# TYPE elasticsearch_clustersettings_allocation_watermark_flood_stage_bytes gauge +elasticsearch_clustersettings_allocation_watermark_flood_stage_bytes 100 +# HELP elasticsearch_clustersettings_allocation_watermark_high_bytes High watermark for disk usage in bytes. +# TYPE elasticsearch_clustersettings_allocation_watermark_high_bytes gauge +elasticsearch_clustersettings_allocation_watermark_high_bytes 2.147483648e+11 +# HELP elasticsearch_clustersettings_allocation_watermark_low_bytes Low watermark for disk usage in bytes. +# TYPE elasticsearch_clustersettings_allocation_watermark_low_bytes gauge +elasticsearch_clustersettings_allocation_watermark_low_bytes 5.24288e+07 +`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f, err := os.Open(tt.file) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.Copy(w, f) + })) defer ts.Close() u, err := url.Parse(ts.URL) if err != nil { - t.Fatalf("Failed to parse URL: %s", err) + t.Fatal(err) } - c := NewClusterSettings(log.NewNopLogger(), http.DefaultClient, u) - nsr, err := c.fetchAndDecodeClusterSettingsStats() + + c, err := NewClusterSettings(promslog.NewNopLogger(), u, http.DefaultClient) if err != nil { - t.Fatalf("Failed to fetch or decode cluster settings stats: %s", err) + t.Fatal(err) + } + + if err := testutil.CollectAndCompare(wrapCollector{c}, strings.NewReader(tt.want)); err != nil { + t.Fatal(err) + } + }) + } +} + +func Test_getValueInBytes(t *testing.T) { + tests := []struct { + name string + input string + want float64 + wantErr bool + }{ + {name: "Bytes", input: "100b", want: 100}, + {name: "Kibibytes", input: "200kb", want: 204800}, + {name: "Mebibytes", input: "300mb", want: 314572800}, + {name: "Gibibytes", input: "400gb", want: 429496729600}, + {name: "Tebibytes", input: "500tb", want: 549755813888000}, + {name: "Pebibytes", input: "600pb", want: 675539944105574400}, + {name: "Unknown", input: "9ab", wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := getValueInBytes(tt.input) + if (err != nil) != tt.wantErr { + t.Fatalf("getValueInBytes() error = %v, wantErr %v", err, tt.wantErr) + } + + if got != tt.want { + t.Errorf("getValueInBytes() = %v, want %v", got, tt.want) } - t.Logf("[%s/%s] Cluster Settings Stats Response: %+v", hn, ver, nsr) - if nsr.Cluster.Routing.Allocation.Enabled != "ALL" { - t.Errorf("Wrong setting for cluster routing allocation enabled") + }) + } +} + +func Test_getValueAsRatio(t *testing.T) { + tests := []struct { + name string + input string + want float64 + wantErr bool + }{ + {name: "Ratio", input: "0.5", want: 0.5}, + {name: "Percentage", input: "50%", want: 0.5}, + {name: "Invalid", input: "500b", wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := getValueAsRatio(tt.input) + if (err != nil) != tt.wantErr { + t.Fatalf("getValueAsRatio() error = %v, wantErr %v", err, tt.wantErr) + } + + if got != tt.want { + t.Errorf("getValueAsRatio() = %v, want %v", got, tt.want) } - } + }) } } diff --git a/collector/collector.go b/collector/collector.go new file mode 100644 index 00000000..38de96ce --- /dev/null +++ b/collector/collector.go @@ -0,0 +1,216 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package collector includes all individual collectors to gather and export elasticsearch metrics. +package collector + +import ( + "context" + "errors" + "fmt" + "log/slog" + "net/http" + "net/url" + "sync" + "time" + + "github.com/alecthomas/kingpin/v2" + "github.com/prometheus/client_golang/prometheus" +) + +const ( + // Namespace defines the common namespace to be used by all metrics. + namespace = "elasticsearch" + + defaultEnabled = true + defaultDisabled = false +) + +type factoryFunc func(logger *slog.Logger, u *url.URL, hc *http.Client) (Collector, error) + +var ( + factories = make(map[string]factoryFunc) + initiatedCollectorsMtx = sync.Mutex{} + initiatedCollectors = make(map[string]Collector) + collectorState = make(map[string]*bool) + forcedCollectors = map[string]bool{} // collectors which have been explicitly enabled or disabled +) + +var ( + scrapeDurationDesc = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "scrape", "duration_seconds"), + "elasticsearch_exporter: Duration of a collector scrape.", + []string{"collector"}, + nil, + ) + scrapeSuccessDesc = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "scrape", "success"), + "elasticsearch_exporter: Whether a collector succeeded.", + []string{"collector"}, + nil, + ) +) + +// Collector is the interface a collector has to implement. +type Collector interface { + // Get new metrics and expose them via prometheus registry. + Update(context.Context, chan<- prometheus.Metric) error +} + +func registerCollector(name string, isDefaultEnabled bool, createFunc factoryFunc) { + var helpDefaultState string + if isDefaultEnabled { + helpDefaultState = "enabled" + } else { + helpDefaultState = "disabled" + } + + // Create flag for this collector + flagName := fmt.Sprintf("collector.%s", name) + flagHelp := fmt.Sprintf("Enable the %s collector (default: %s).", name, helpDefaultState) + defaultValue := fmt.Sprintf("%v", isDefaultEnabled) + + flag := kingpin.Flag(flagName, flagHelp).Default(defaultValue).Action(collectorFlagAction(name)).Bool() + collectorState[name] = flag + + // Register the create function for this collector + factories[name] = createFunc +} + +type ElasticsearchCollector struct { + Collectors map[string]Collector + logger *slog.Logger + esURL *url.URL + httpClient *http.Client +} + +type Option func(*ElasticsearchCollector) error + +// NewElasticsearchCollector creates a new ElasticsearchCollector +func NewElasticsearchCollector(logger *slog.Logger, filters []string, options ...Option) (*ElasticsearchCollector, error) { + e := &ElasticsearchCollector{logger: logger} + // Apply options to customize the collector + for _, o := range options { + if err := o(e); err != nil { + return nil, err + } + } + + f := make(map[string]bool) + for _, filter := range filters { + enabled, exist := collectorState[filter] + if !exist { + return nil, fmt.Errorf("missing collector: %s", filter) + } + if !*enabled { + return nil, fmt.Errorf("disabled collector: %s", filter) + } + f[filter] = true + } + collectors := make(map[string]Collector) + initiatedCollectorsMtx.Lock() + defer initiatedCollectorsMtx.Unlock() + for key, enabled := range collectorState { + if !*enabled || (len(f) > 0 && !f[key]) { + continue + } + if collector, ok := initiatedCollectors[key]; ok { + collectors[key] = collector + } else { + collector, err := factories[key](logger.With("collector", key), e.esURL, e.httpClient) + if err != nil { + return nil, err + } + collectors[key] = collector + initiatedCollectors[key] = collector + } + } + + e.Collectors = collectors + + return e, nil +} + +func WithElasticsearchURL(esURL *url.URL) Option { + return func(e *ElasticsearchCollector) error { + e.esURL = esURL + return nil + } +} + +func WithHTTPClient(hc *http.Client) Option { + return func(e *ElasticsearchCollector) error { + e.httpClient = hc + return nil + } +} + +// Describe implements the prometheus.Collector interface. +func (e ElasticsearchCollector) Describe(ch chan<- *prometheus.Desc) { + ch <- scrapeDurationDesc + ch <- scrapeSuccessDesc +} + +// Collect implements the prometheus.Collector interface. +func (e ElasticsearchCollector) Collect(ch chan<- prometheus.Metric) { + wg := sync.WaitGroup{} + ctx := context.TODO() + wg.Add(len(e.Collectors)) + for name, c := range e.Collectors { + go func(name string, c Collector) { + execute(ctx, name, c, ch, e.logger) + wg.Done() + }(name, c) + } + wg.Wait() +} + +func execute(ctx context.Context, name string, c Collector, ch chan<- prometheus.Metric, logger *slog.Logger) { + begin := time.Now() + err := c.Update(ctx, ch) + duration := time.Since(begin) + var success float64 + + if err != nil { + if IsNoDataError(err) { + logger.Debug("collector returned no data", "name", name, "duration_seconds", duration.Seconds(), "err", err) + } else { + logger.Error("collector failed", "name", name, "duration_seconds", duration.Seconds(), "err", err) + } + success = 0 + } else { + logger.Debug("collector succeeded", "name", name, "duration_seconds", duration.Seconds()) + success = 1 + } + ch <- prometheus.MustNewConstMetric(scrapeDurationDesc, prometheus.GaugeValue, duration.Seconds(), name) + ch <- prometheus.MustNewConstMetric(scrapeSuccessDesc, prometheus.GaugeValue, success, name) +} + +// collectorFlagAction generates a new action function for the given collector +// to track whether it has been explicitly enabled or disabled from the command line. +// A new action function is needed for each collector flag because the ParseContext +// does not contain information about which flag called the action. +// See: https://github.com/alecthomas/kingpin/issues/294 +func collectorFlagAction(collector string) func(ctx *kingpin.ParseContext) error { + return func(ctx *kingpin.ParseContext) error { + forcedCollectors[collector] = true + return nil + } +} + +// ErrNoData indicates the collector found no data to collect, but had no other error. +var ErrNoData = errors.New("collector returned no data") + +func IsNoDataError(err error) bool { + return err == ErrNoData +} diff --git a/collector/collector_test.go b/collector/collector_test.go new file mode 100644 index 00000000..80c7fa5d --- /dev/null +++ b/collector/collector_test.go @@ -0,0 +1,36 @@ +// Copyright 2023 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "context" + + "github.com/prometheus/client_golang/prometheus" +) + +// wrapCollector is a util to let you test your Collector implementation. +// +// Use this with prometheus/client_golang/prometheus/testutil to test metric output, for example: +// +// testutil.CollectAndCompare(wrapCollector{c}, strings.NewReader(want)) +type wrapCollector struct { + c Collector +} + +func (w wrapCollector) Describe(_ chan<- *prometheus.Desc) { +} + +func (w wrapCollector) Collect(ch chan<- prometheus.Metric) { + w.c.Update(context.Background(), ch) +} diff --git a/collector/data_stream.go b/collector/data_stream.go new file mode 100644 index 00000000..29f564e8 --- /dev/null +++ b/collector/data_stream.go @@ -0,0 +1,154 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "path" + + "github.com/prometheus/client_golang/prometheus" +) + +type dataStreamMetric struct { + Type prometheus.ValueType + Desc *prometheus.Desc + Value func(dataStreamStats DataStreamStatsDataStream) float64 + Labels func(dataStreamStats DataStreamStatsDataStream) []string +} + +var ( + defaultDataStreamLabels = []string{"data_stream"} + defaultDataStreamLabelValues = func(dataStreamStats DataStreamStatsDataStream) []string { + return []string{dataStreamStats.DataStream} + } +) + +// DataStream Information Struct +type DataStream struct { + logger *slog.Logger + client *http.Client + url *url.URL + + dataStreamMetrics []*dataStreamMetric +} + +// NewDataStream defines DataStream Prometheus metrics +func NewDataStream(logger *slog.Logger, client *http.Client, url *url.URL) *DataStream { + return &DataStream{ + logger: logger, + client: client, + url: url, + + dataStreamMetrics: []*dataStreamMetric{ + { + Type: prometheus.CounterValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "data_stream", "backing_indices_total"), + "Number of backing indices", + defaultDataStreamLabels, nil, + ), + Value: func(dataStreamStats DataStreamStatsDataStream) float64 { + return float64(dataStreamStats.BackingIndices) + }, + Labels: defaultDataStreamLabelValues, + }, + { + Type: prometheus.CounterValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "data_stream", "store_size_bytes"), + "Store size of data stream", + defaultDataStreamLabels, nil, + ), + Value: func(dataStreamStats DataStreamStatsDataStream) float64 { + return float64(dataStreamStats.StoreSizeBytes) + }, + Labels: defaultDataStreamLabelValues, + }, + }, + } +} + +// Describe adds DataStream metrics descriptions +func (ds *DataStream) Describe(ch chan<- *prometheus.Desc) { + for _, metric := range ds.dataStreamMetrics { + ch <- metric.Desc + } +} + +func (ds *DataStream) fetchAndDecodeDataStreamStats() (DataStreamStatsResponse, error) { + var dsr DataStreamStatsResponse + + u := *ds.url + u.Path = path.Join(u.Path, "/_data_stream/*/_stats") + res, err := ds.client.Get(u.String()) + if err != nil { + return dsr, fmt.Errorf("failed to get data stream stats health from %s://%s:%s%s: %s", + u.Scheme, u.Hostname(), u.Port(), u.Path, err) + } + + defer func() { + err = res.Body.Close() + if err != nil { + ds.logger.Warn( + "failed to close http.Client", + "err", err, + ) + } + }() + + if res.StatusCode != http.StatusOK { + return dsr, fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) + } + + bts, err := io.ReadAll(res.Body) + if err != nil { + return dsr, err + } + + if err := json.Unmarshal(bts, &dsr); err != nil { + return dsr, err + } + + return dsr, nil +} + +// Collect gets DataStream metric values +func (ds *DataStream) Collect(ch chan<- prometheus.Metric) { + + dataStreamStatsResp, err := ds.fetchAndDecodeDataStreamStats() + if err != nil { + ds.logger.Warn( + "failed to fetch and decode data stream stats", + "err", err, + ) + return + } + + for _, metric := range ds.dataStreamMetrics { + for _, dataStream := range dataStreamStatsResp.DataStreamStats { + fmt.Printf("Metric: %+v", dataStream) + ch <- prometheus.MustNewConstMetric( + metric.Desc, + metric.Type, + metric.Value(dataStream), + metric.Labels(dataStream)..., + ) + } + } +} diff --git a/collector/data_stream_response.go b/collector/data_stream_response.go new file mode 100644 index 00000000..41365a09 --- /dev/null +++ b/collector/data_stream_response.go @@ -0,0 +1,38 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +// DataStreamStatsResponse is a representation of the Data Stream stats +type DataStreamStatsResponse struct { + Shards DataStreamStatsShards `json:"_shards"` + DataStreamCount int64 `json:"data_stream_count"` + BackingIndices int64 `json:"backing_indices"` + TotalStoreSizeBytes int64 `json:"total_store_size_bytes"` + DataStreamStats []DataStreamStatsDataStream `json:"data_streams"` +} + +// DataStreamStatsShards defines data stream stats shards information structure +type DataStreamStatsShards struct { + Total int64 `json:"total"` + Successful int64 `json:"successful"` + Failed int64 `json:"failed"` +} + +// DataStreamStatsDataStream defines the structure of per data stream stats +type DataStreamStatsDataStream struct { + DataStream string `json:"data_stream"` + BackingIndices int64 `json:"backing_indices"` + StoreSizeBytes int64 `json:"store_size_bytes"` + MaximumTimestamp int64 `json:"maximum_timestamp"` +} diff --git a/collector/data_stream_test.go b/collector/data_stream_test.go new file mode 100644 index 00000000..7de95fb5 --- /dev/null +++ b/collector/data_stream_test.go @@ -0,0 +1,78 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "io" + "net/http" + "net/http/httptest" + "net/url" + "os" + "strings" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/promslog" +) + +func TestDataStream(t *testing.T) { + + tests := []struct { + name string + file string + want string + }{ + { + name: "7.15.0", + file: "../fixtures/datastream/7.15.0.json", + want: `# HELP elasticsearch_data_stream_backing_indices_total Number of backing indices + # TYPE elasticsearch_data_stream_backing_indices_total counter + elasticsearch_data_stream_backing_indices_total{data_stream="bar"} 2 + elasticsearch_data_stream_backing_indices_total{data_stream="foo"} 5 + # HELP elasticsearch_data_stream_store_size_bytes Store size of data stream + # TYPE elasticsearch_data_stream_store_size_bytes counter + elasticsearch_data_stream_store_size_bytes{data_stream="bar"} 6.7382272e+08 + elasticsearch_data_stream_store_size_bytes{data_stream="foo"} 4.29205396e+08 + `, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f, err := os.Open(tt.file) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.Copy(w, f) + })) + defer ts.Close() + + u, err := url.Parse(ts.URL) + if err != nil { + t.Fatal(err) + } + + c := NewDataStream(promslog.NewNopLogger(), http.DefaultClient, u) + if err != nil { + t.Fatal(err) + } + + if err := testutil.CollectAndCompare(c, strings.NewReader(tt.want)); err != nil { + t.Fatal(err) + } + }) + } +} diff --git a/collector/ilm_indices.go b/collector/ilm_indices.go new file mode 100644 index 00000000..9f30c726 --- /dev/null +++ b/collector/ilm_indices.go @@ -0,0 +1,153 @@ +// Copyright 2023 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "path" + + "github.com/prometheus/client_golang/prometheus" +) + +type ilmMetric struct { + Type prometheus.ValueType + Desc *prometheus.Desc + Value func(timeMillis float64) float64 + Labels []string +} + +// Index Lifecycle Management information object +type IlmIndiciesCollector struct { + logger *slog.Logger + client *http.Client + url *url.URL + + ilmMetric ilmMetric +} + +type IlmResponse struct { + Indices map[string]IlmIndexResponse `json:"indices"` +} + +type IlmIndexResponse struct { + Index string `json:"index"` + Managed bool `json:"managed"` + Phase string `json:"phase"` + Action string `json:"action"` + Step string `json:"step"` + StepTimeMillis float64 `json:"step_time_millis"` +} + +var ( + defaultIlmIndicesMappingsLabels = []string{"index", "phase", "action", "step"} +) + +// NewIlmIndicies defines Index Lifecycle Management Prometheus metrics +func NewIlmIndicies(logger *slog.Logger, client *http.Client, url *url.URL) *IlmIndiciesCollector { + subsystem := "ilm_index" + + return &IlmIndiciesCollector{ + logger: logger, + client: client, + url: url, + + ilmMetric: ilmMetric{ + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, subsystem, "status"), + "Status of ILM policy for index", + defaultIlmIndicesMappingsLabels, nil), + Value: func(timeMillis float64) float64 { + return timeMillis + }, + }, + } +} + +// Describe adds metrics description +func (i *IlmIndiciesCollector) Describe(ch chan<- *prometheus.Desc) { + ch <- i.ilmMetric.Desc +} + +func (i *IlmIndiciesCollector) fetchAndDecodeIlm() (IlmResponse, error) { + var ir IlmResponse + + u := *i.url + u.Path = path.Join(u.Path, "/_all/_ilm/explain") + + res, err := i.client.Get(u.String()) + if err != nil { + return ir, fmt.Errorf("failed to get index stats from %s://%s:%s%s: %s", + u.Scheme, u.Hostname(), u.Port(), u.Path, err) + } + + defer func() { + err = res.Body.Close() + if err != nil { + i.logger.Warn( + "failed to close http.Client", + "err", err, + ) + } + }() + + if res.StatusCode != http.StatusOK { + return ir, fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) + } + + bts, err := io.ReadAll(res.Body) + if err != nil { + return ir, err + } + + if err := json.Unmarshal(bts, &ir); err != nil { + return ir, err + } + + return ir, nil +} + +func bool2int(managed bool) float64 { + if managed { + return 1 + } + return 0 +} + +// Collect pulls metric values from Elasticsearch +func (i *IlmIndiciesCollector) Collect(ch chan<- prometheus.Metric) { + // indices + ilmResp, err := i.fetchAndDecodeIlm() + if err != nil { + i.logger.Warn( + "failed to fetch and decode ILM stats", + "err", err, + ) + return + } + + for indexName, indexIlm := range ilmResp.Indices { + ch <- prometheus.MustNewConstMetric( + i.ilmMetric.Desc, + i.ilmMetric.Type, + i.ilmMetric.Value(bool2int(indexIlm.Managed)), + indexName, indexIlm.Phase, indexIlm.Action, indexIlm.Step, + ) + } +} diff --git a/collector/ilm_indices_test.go b/collector/ilm_indices_test.go new file mode 100644 index 00000000..b091f6fb --- /dev/null +++ b/collector/ilm_indices_test.go @@ -0,0 +1,111 @@ +// Copyright 2023 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "io" + "net/http" + "net/http/httptest" + "net/url" + "os" + "strings" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/promslog" +) + +func TestILMMetrics(t *testing.T) { + // Testcases created using: + // docker run -d -p 9200:9200 elasticsearch:VERSION + // curl -XPUT http://localhost:9200/twitter + // curl -X PUT "localhost:9200/_ilm/policy/my_policy?pretty" -H 'Content-Type: application/json' -d' + // { + // "policy": { + // "phases": { + // "warm": { + // "min_age": "10d", + // "actions": { + // "forcemerge": { + // "max_num_segments": 1 + // } + // } + // }, + // "delete": { + // "min_age": "30d", + // "actions": { + // "delete": {} + // } + // } + // } + // } + // } + // ' + // curl -X PUT "localhost:9200/facebook?pretty" -H 'Content-Type: application/json' -d' + // { + // "settings": { + // "index": { + // "lifecycle": { + // "name": "my_policy" + // } + // } + // } + // } + // ' + // curl http://localhost:9200/_all/_ilm/explain + tests := []struct { + name string + file string + want string + }{ + { + name: "6.6.0", + file: "../fixtures/ilm_indices/6.6.0.json", + want: ` +# HELP elasticsearch_ilm_index_status Status of ILM policy for index +# TYPE elasticsearch_ilm_index_status gauge +elasticsearch_ilm_index_status{action="",index="twitter",phase="",step=""} 0 +elasticsearch_ilm_index_status{action="complete",index="facebook",phase="new",step="complete"} 1 + `, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f, err := os.Open(tt.file) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.Copy(w, f) + })) + defer ts.Close() + + u, err := url.Parse(ts.URL) + if err != nil { + t.Fatal(err) + } + + c := NewIlmIndicies(promslog.NewNopLogger(), http.DefaultClient, u) + if err != nil { + t.Fatal(err) + } + + if err := testutil.CollectAndCompare(c, strings.NewReader(tt.want)); err != nil { + t.Fatal(err) + } + }) + } +} diff --git a/collector/ilm_status.go b/collector/ilm_status.go new file mode 100644 index 00000000..067e375c --- /dev/null +++ b/collector/ilm_status.go @@ -0,0 +1,137 @@ +// Copyright 2023 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "path" + + "github.com/prometheus/client_golang/prometheus" +) + +var ( + ilmStatuses = []string{"STOPPED", "RUNNING", "STOPPING"} +) + +type ilmStatusMetric struct { + Type prometheus.ValueType + Desc *prometheus.Desc + Value func(ilm *IlmStatusResponse, status string) float64 + Labels func(status string) []string +} + +// IlmStatusCollector information struct +type IlmStatusCollector struct { + logger *slog.Logger + client *http.Client + url *url.URL + + metric ilmStatusMetric +} + +type IlmStatusResponse struct { + OperationMode string `json:"operation_mode"` +} + +// NewIlmStatus defines Indices IndexIlms Prometheus metrics +func NewIlmStatus(logger *slog.Logger, client *http.Client, url *url.URL) *IlmStatusCollector { + subsystem := "ilm" + + return &IlmStatusCollector{ + logger: logger, + client: client, + url: url, + + metric: ilmStatusMetric{ + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, subsystem, "status"), + "Current status of ilm. Status can be STOPPED, RUNNING, STOPPING.", + []string{"operation_mode"}, nil, + ), + Value: func(ilm *IlmStatusResponse, status string) float64 { + if ilm.OperationMode == status { + return 1 + } + return 0 + }, + }, + } +} + +// Describe add Snapshots metrics descriptions +func (im *IlmStatusCollector) Describe(ch chan<- *prometheus.Desc) { + ch <- im.metric.Desc +} + +func (im *IlmStatusCollector) fetchAndDecodeIlm() (*IlmStatusResponse, error) { + u := *im.url + u.Path = path.Join(im.url.Path, "/_ilm/status") + + res, err := im.client.Get(u.String()) + if err != nil { + return nil, fmt.Errorf("failed to get from %s://%s:%s%s: %s", + u.Scheme, u.Hostname(), u.Port(), u.Path, err) + } + + if res.StatusCode != http.StatusOK { + return nil, fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) + } + + body, err := io.ReadAll(res.Body) + if err != nil { + im.logger.Warn("failed to read response body", "err", err) + return nil, err + } + + err = res.Body.Close() + if err != nil { + im.logger.Warn("failed to close response body", "err", err) + return nil, err + } + + var imr IlmStatusResponse + if err := json.Unmarshal(body, &imr); err != nil { + return nil, err + } + + return &imr, nil +} + +// Collect gets all indices Ilms metric values +func (im *IlmStatusCollector) Collect(ch chan<- prometheus.Metric) { + indicesIlmsResponse, err := im.fetchAndDecodeIlm() + if err != nil { + im.logger.Warn( + "failed to fetch and decode cluster ilm status", + "err", err, + ) + return + } + + for _, status := range ilmStatuses { + ch <- prometheus.MustNewConstMetric( + im.metric.Desc, + im.metric.Type, + im.metric.Value(indicesIlmsResponse, status), + status, + ) + } + +} diff --git a/collector/ilm_status_test.go b/collector/ilm_status_test.go new file mode 100644 index 00000000..cc7e9ecb --- /dev/null +++ b/collector/ilm_status_test.go @@ -0,0 +1,79 @@ +// Copyright 2023 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "io" + "net/http" + "net/http/httptest" + "net/url" + "os" + "strings" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/promslog" +) + +func TestILMStatus(t *testing.T) { + // Testcases created using: + // docker run -d -p 9200:9200 elasticsearch:VERSION + // curl http://localhost:9200/_ilm/status + tests := []struct { + name string + file string + want string + }{ + { + name: "6.6.0", + file: "../fixtures/ilm_status/6.6.0.json", + want: ` +# HELP elasticsearch_ilm_status Current status of ilm. Status can be STOPPED, RUNNING, STOPPING. +# TYPE elasticsearch_ilm_status gauge +elasticsearch_ilm_status{operation_mode="RUNNING"} 1 +elasticsearch_ilm_status{operation_mode="STOPPED"} 0 +elasticsearch_ilm_status{operation_mode="STOPPING"} 0 + `, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f, err := os.Open(tt.file) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.Copy(w, f) + })) + defer ts.Close() + + u, err := url.Parse(ts.URL) + if err != nil { + t.Fatal(err) + } + + c := NewIlmStatus(promslog.NewNopLogger(), http.DefaultClient, u) + if err != nil { + t.Fatal(err) + } + + if err := testutil.CollectAndCompare(c, strings.NewReader(tt.want)); err != nil { + t.Fatal(err) + } + }) + } +} diff --git a/collector/indices.go b/collector/indices.go index d71b07b1..735d3afe 100644 --- a/collector/indices.go +++ b/collector/indices.go @@ -1,15 +1,30 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector import ( "encoding/json" "fmt" + "io" + "log/slog" "net/http" "net/url" "path" + "sort" + "strconv" - "github.com/go-kit/kit/log" - "github.com/go-kit/kit/log/level" - "github.com/justwatchcom/elasticsearch_exporter/pkg/clusterinfo" + "github.com/prometheus-community/elasticsearch_exporter/pkg/clusterinfo" "github.com/prometheus/client_golang/prometheus" ) @@ -32,25 +47,30 @@ type shardMetric struct { Labels labels } +type aliasMetric struct { + Type prometheus.ValueType + Desc *prometheus.Desc + Value func() float64 + Labels labels +} + // Indices information struct type Indices struct { - logger log.Logger + logger *slog.Logger client *http.Client url *url.URL shards bool + aliases bool clusterInfoCh chan *clusterinfo.Response lastClusterInfo *clusterinfo.Response - up prometheus.Gauge - totalScrapes prometheus.Counter - jsonParseFailures prometheus.Counter - indexMetrics []*indexMetric shardMetrics []*shardMetric + aliasMetrics []*aliasMetric } // NewIndices defines Indices Prometheus metrics -func NewIndices(logger log.Logger, client *http.Client, url *url.URL, shards bool) *Indices { +func NewIndices(logger *slog.Logger, client *http.Client, url *url.URL, shards bool, includeAliases bool) *Indices { indexLabels := labels{ keys: func(...string) []string { @@ -68,7 +88,21 @@ func NewIndices(logger log.Logger, client *http.Client, url *url.URL, shards boo shardLabels := labels{ keys: func(...string) []string { - return []string{"index", "shard", "node", "cluster"} + return []string{"index", "shard", "node", "primary", "cluster"} + }, + values: func(lastClusterinfo *clusterinfo.Response, s ...string) []string { + if lastClusterinfo != nil { + return append(s, lastClusterinfo.ClusterName) + } + // this shouldn't happen, as the clusterinfo Retriever has a blocking + // Run method. It blocks until the first clusterinfo call has succeeded + return append(s, "unknown_cluster") + }, + } + + aliasLabels := labels{ + keys: func(...string) []string { + return []string{"index", "alias", "cluster"} }, values: func(lastClusterinfo *clusterinfo.Response, s ...string) []string { if lastClusterinfo != nil { @@ -85,24 +119,12 @@ func NewIndices(logger log.Logger, client *http.Client, url *url.URL, shards boo client: client, url: url, shards: shards, + aliases: includeAliases, clusterInfoCh: make(chan *clusterinfo.Response), lastClusterInfo: &clusterinfo.Response{ ClusterName: "unknown_cluster", }, - up: prometheus.NewGauge(prometheus.GaugeOpts{ - Name: prometheus.BuildFQName(namespace, "index_stats", "up"), - Help: "Was the last scrape of the ElasticSearch index endpoint successful.", - }), - totalScrapes: prometheus.NewCounter(prometheus.CounterOpts{ - Name: prometheus.BuildFQName(namespace, "index_stats", "total_scrapes"), - Help: "Current total ElasticSearch index scrapes.", - }), - jsonParseFailures: prometheus.NewCounter(prometheus.CounterOpts{ - Name: prometheus.BuildFQName(namespace, "index_stats", "json_parse_failures"), - Help: "Number of errors while parsing JSON.", - }), - indexMetrics: []*indexMetric{ { Type: prometheus.GaugeValue, @@ -476,6 +498,18 @@ func NewIndices(logger log.Logger, client *http.Client, url *url.URL, shards boo }, Labels: indexLabels, }, + { + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "search", "active_queries"), + "The number of currently active queries", + indexLabels.keys(), nil, + ), + Value: func(indexStats IndexStatsIndexResponse) float64 { + return float64(indexStats.Total.Search.QueryCurrent) + }, + Labels: indexLabels, + }, { Type: prometheus.CounterValue, Desc: prometheus.NewDesc( @@ -584,6 +618,18 @@ func NewIndices(logger log.Logger, client *http.Client, url *url.URL, shards boo }, Labels: indexLabels, }, + { + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "index_stats", "index_current"), + "The number of documents currently being indexed to an index", + indexLabels.keys(), nil, + ), + Value: func(indexStats IndexStatsIndexResponse) float64 { + return float64(indexStats.Total.Indexing.IndexCurrent) + }, + Labels: indexLabels, + }, { Type: prometheus.CounterValue, Desc: prometheus.NewDesc( @@ -740,6 +786,30 @@ func NewIndices(logger log.Logger, client *http.Client, url *url.URL, shards boo }, Labels: indexLabels, }, + { + Type: prometheus.CounterValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "index_stats", "refresh_external_time_seconds_total"), + "Total external refresh time in seconds", + indexLabels.keys(), nil, + ), + Value: func(indexStats IndexStatsIndexResponse) float64 { + return float64(indexStats.Total.Refresh.ExternalTotalTimeInMillis) / 1000 + }, + Labels: indexLabels, + }, + { + Type: prometheus.CounterValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "index_stats", "refresh_external_total"), + "Total external refresh count", + indexLabels.keys(), nil, + ), + Value: func(indexStats IndexStatsIndexResponse) float64 { + return float64(indexStats.Total.Refresh.ExternalTotal) + }, + Labels: indexLabels, + }, { Type: prometheus.CounterValue, Desc: prometheus.NewDesc( @@ -949,7 +1019,7 @@ func NewIndices(logger log.Logger, client *http.Client, url *url.URL, shards boo { Type: prometheus.GaugeValue, Desc: prometheus.NewDesc( - prometheus.BuildFQName(namespace, "indices", "shared_docs"), + prometheus.BuildFQName(namespace, "indices", "shards_docs"), "Count of documents on this shard", shardLabels.keys(), nil, ), @@ -970,19 +1040,46 @@ func NewIndices(logger log.Logger, client *http.Client, url *url.URL, shards boo }, Labels: shardLabels, }, + { + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "indices", "shards_store_size_in_bytes"), + "Store size of this shard", + shardLabels.keys(), nil, + ), + Value: func(data IndexStatsIndexShardsDetailResponse) float64 { + return float64(data.Store.SizeInBytes) + }, + Labels: shardLabels, + }, + }, + + aliasMetrics: []*aliasMetric{ + { + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "indices", "aliases"), + "Record aliases associated with an index", + aliasLabels.keys(), nil, + ), + Value: func() float64 { + return float64(1) + }, + Labels: aliasLabels, + }, }, } // start go routine to fetch clusterinfo updates and save them to lastClusterinfo go func() { - _ = level.Debug(logger).Log("msg", "starting cluster info receive loop") + logger.Debug("starting cluster info receive loop") for ci := range indices.clusterInfoCh { - _ = level.Debug(logger).Log("msg", "received cluster info update", "cluster", ci.ClusterName) if ci != nil { + logger.Debug("received cluster info update", "cluster", ci.ClusterName) indices.lastClusterInfo = ci } } - _ = level.Debug(logger).Log("msg", "exiting cluster info receive loop") + logger.Debug("exiting cluster info receive loop") }() return indices } @@ -1003,9 +1100,10 @@ func (i *Indices) Describe(ch chan<- *prometheus.Desc) { for _, metric := range i.indexMetrics { ch <- metric.Desc } - ch <- i.up.Desc() - ch <- i.totalScrapes.Desc() - ch <- i.jsonParseFailures.Desc() + for _, metric := range i.aliasMetrics { + ch <- metric.Desc + } + } func (i *Indices) fetchAndDecodeIndexStats() (indexStatsResponse, error) { @@ -1014,58 +1112,120 @@ func (i *Indices) fetchAndDecodeIndexStats() (indexStatsResponse, error) { u := *i.url u.Path = path.Join(u.Path, "/_all/_stats") if i.shards { - u.RawQuery = "level=shards" + u.RawQuery = "ignore_unavailable=true&level=shards" + } else { + u.RawQuery = "ignore_unavailable=true" + } + + bts, err := i.queryURL(&u) + if err != nil { + return isr, err + } + + if err := json.Unmarshal(bts, &isr); err != nil { + return isr, err + } + + if i.aliases { + isr.Aliases = map[string][]string{} + asr, err := i.fetchAndDecodeAliases() + if err != nil { + i.logger.Error("error getting alias information", "err", err) + return isr, err + } + + for indexName, aliases := range asr { + var aliasList []string + for aliasName := range aliases.Aliases { + aliasList = append(aliasList, aliasName) + } + + if len(aliasList) > 0 { + sort.Strings(aliasList) + isr.Aliases[indexName] = aliasList + } + } + } + + return isr, nil +} + +func (i *Indices) fetchAndDecodeAliases() (aliasesResponse, error) { + var asr aliasesResponse + + u := *i.url + u.Path = path.Join(u.Path, "/_alias") + + bts, err := i.queryURL(&u) + if err != nil { + return asr, err + } + + if err := json.Unmarshal(bts, &asr); err != nil { + return asr, err } + return asr, nil +} + +func (i *Indices) queryURL(u *url.URL) ([]byte, error) { res, err := i.client.Get(u.String()) if err != nil { - return isr, fmt.Errorf("failed to get index stats from %s://%s:%s%s: %s", + return []byte{}, fmt.Errorf("failed to get resource from %s://%s:%s%s: %s", u.Scheme, u.Hostname(), u.Port(), u.Path, err) } defer func() { err = res.Body.Close() if err != nil { - _ = level.Warn(i.logger).Log( - "msg", "failed to close http.Client", + i.logger.Warn( + "failed to close http.Client", "err", err, ) } }() if res.StatusCode != http.StatusOK { - return isr, fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) + return []byte{}, fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) } - if err := json.NewDecoder(res.Body).Decode(&isr); err != nil { - i.jsonParseFailures.Inc() - return isr, err + bts, err := io.ReadAll(res.Body) + if err != nil { + return []byte{}, err } - return isr, nil + return bts, nil } // Collect gets Indices metric values func (i *Indices) Collect(ch chan<- prometheus.Metric) { - i.totalScrapes.Inc() - defer func() { - ch <- i.up - ch <- i.totalScrapes - ch <- i.jsonParseFailures - }() - // indices indexStatsResp, err := i.fetchAndDecodeIndexStats() if err != nil { - i.up.Set(0) - _ = level.Warn(i.logger).Log( - "msg", "failed to fetch and decode index stats", + i.logger.Warn( + "failed to fetch and decode index stats", "err", err, ) return } - i.totalScrapes.Inc() - i.up.Set(1) + + // Alias stats + if i.aliases { + for _, metric := range i.aliasMetrics { + for indexName, aliases := range indexStatsResp.Aliases { + for _, alias := range aliases { + labelValues := metric.Labels.values(i.lastClusterInfo, indexName, alias) + + ch <- prometheus.MustNewConstMetric( + metric.Desc, + metric.Type, + metric.Value(), + labelValues..., + ) + } + } + } + } // Index stats for indexName, indexStats := range indexStatsResp.Indices { @@ -1087,7 +1247,7 @@ func (i *Indices) Collect(ch chan<- prometheus.Metric) { metric.Desc, metric.Type, metric.Value(shard), - metric.Labels.values(i.lastClusterInfo, indexName, shardNumber, shard.Routing.Node)..., + metric.Labels.values(i.lastClusterInfo, indexName, shardNumber, shard.Routing.Node, strconv.FormatBool(shard.Routing.Primary))..., ) } } diff --git a/collector/indices_mappings.go b/collector/indices_mappings.go new file mode 100644 index 00000000..21f119a1 --- /dev/null +++ b/collector/indices_mappings.go @@ -0,0 +1,164 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "path" + + "github.com/prometheus/client_golang/prometheus" +) + +var ( + defaultIndicesMappingsLabels = []string{"index"} +) + +type indicesMappingsMetric struct { + Type prometheus.ValueType + Desc *prometheus.Desc + Value func(indexMapping IndexMapping) float64 +} + +// IndicesMappings information struct +type IndicesMappings struct { + logger *slog.Logger + client *http.Client + url *url.URL + + metrics []*indicesMappingsMetric +} + +// NewIndicesMappings defines Indices IndexMappings Prometheus metrics +func NewIndicesMappings(logger *slog.Logger, client *http.Client, url *url.URL) *IndicesMappings { + subsystem := "indices_mappings_stats" + + return &IndicesMappings{ + logger: logger, + client: client, + url: url, + + metrics: []*indicesMappingsMetric{ + { + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, subsystem, "fields"), + "Current number fields within cluster.", + defaultIndicesMappingsLabels, nil, + ), + Value: func(indexMapping IndexMapping) float64 { + return countFieldsRecursive(indexMapping.Mappings.Properties, 0) + }, + }, + }, + } +} + +func countFieldsRecursive(properties IndexMappingProperties, fieldCounter float64) float64 { + // iterate over all properties + for _, property := range properties { + + if property.Type != nil && *property.Type != "object" { + // property has a type set - counts as a field unless the value is object + // as the recursion below will handle counting that + fieldCounter++ + + // iterate over all fields of that property + for _, field := range property.Fields { + // field has a type set - counts as a field + if field.Type != nil { + fieldCounter++ + } + } + } + + // count recursively in case the property has more properties + if property.Properties != nil { + fieldCounter = 1 + countFieldsRecursive(property.Properties, fieldCounter) + } + } + + return fieldCounter +} + +// Describe add Snapshots metrics descriptions +func (im *IndicesMappings) Describe(ch chan<- *prometheus.Desc) { + for _, metric := range im.metrics { + ch <- metric.Desc + } +} + +func (im *IndicesMappings) getAndParseURL(u *url.URL) (*IndicesMappingsResponse, error) { + res, err := im.client.Get(u.String()) + if err != nil { + return nil, fmt.Errorf("failed to get from %s://%s:%s%s: %s", + u.Scheme, u.Hostname(), u.Port(), u.Path, err) + } + + if res.StatusCode != http.StatusOK { + return nil, fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) + } + + body, err := io.ReadAll(res.Body) + if err != nil { + im.logger.Warn("failed to read response body", "err", err) + return nil, err + } + + err = res.Body.Close() + if err != nil { + im.logger.Warn("failed to close response body", "err", err) + return nil, err + } + + var imr IndicesMappingsResponse + if err := json.Unmarshal(body, &imr); err != nil { + return nil, err + } + + return &imr, nil +} + +func (im *IndicesMappings) fetchAndDecodeIndicesMappings() (*IndicesMappingsResponse, error) { + u := *im.url + u.Path = path.Join(u.Path, "/_all/_mappings") + return im.getAndParseURL(&u) +} + +// Collect gets all indices mappings metric values +func (im *IndicesMappings) Collect(ch chan<- prometheus.Metric) { + indicesMappingsResponse, err := im.fetchAndDecodeIndicesMappings() + if err != nil { + im.logger.Warn( + "failed to fetch and decode cluster mappings stats", + "err", err, + ) + return + } + + for _, metric := range im.metrics { + for indexName, mappings := range *indicesMappingsResponse { + ch <- prometheus.MustNewConstMetric( + metric.Desc, + metric.Type, + metric.Value(mappings), + indexName, + ) + } + } +} diff --git a/collector/indices_mappings_response.go b/collector/indices_mappings_response.go new file mode 100644 index 00000000..3c54b3f7 --- /dev/null +++ b/collector/indices_mappings_response.go @@ -0,0 +1,47 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +// IndicesMappingsResponse is a representation of elasticsearch mappings for each index +type IndicesMappingsResponse map[string]IndexMapping + +// IndexMapping defines the struct of the tree for the mappings of each index +type IndexMapping struct { + Mappings IndexMappings `json:"mappings"` +} + +// IndexMappings defines all index mappings +type IndexMappings struct { + Properties IndexMappingProperties `json:"properties"` +} + +// IndexMappingProperties defines all the properties of the current mapping +type IndexMappingProperties map[string]*IndexMappingProperty + +// IndexMappingFields defines all the fields of the current mapping +type IndexMappingFields map[string]*IndexMappingField + +// IndexMappingProperty defines a single property of the current index properties +type IndexMappingProperty struct { + Type *string `json:"type"` + Properties IndexMappingProperties `json:"properties"` + Fields IndexMappingFields `json:"fields"` +} + +// IndexMappingField defines a single property of the current index field +type IndexMappingField struct { + Type *string `json:"type"` + Properties IndexMappingProperties `json:"properties"` + Fields IndexMappingFields `json:"fields"` +} diff --git a/collector/indices_mappings_test.go b/collector/indices_mappings_test.go new file mode 100644 index 00000000..73a2b423 --- /dev/null +++ b/collector/indices_mappings_test.go @@ -0,0 +1,126 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "io" + "net/http" + "net/http/httptest" + "net/url" + "os" + "strings" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/promslog" +) + +func TestMapping(t *testing.T) { + // Testcases created using: + // docker run -p 9200:9200 -e "discovery.type=single-node" elasticsearch:7.8.0 + // curl -XPUT http://localhost:9200/twitter + // curl -XPUT http://localhost:9200/facebook + /* curl -XPUT http://localhost:9200/twitter/_mapping -H 'Content-Type: application/json' -d'{ + "properties": { + "email": { + "type": "keyword" + }, + "phone": { + "type": "keyword" + } + } + }'*/ + /* curl -XPUT http://localhost:9200/facebook/_mapping -H 'Content-Type: application/json' -d'{ + "properties": { + "name": { + "type": "text", + "fields": { + "raw": { + "type": "keyword" + } + } + }, + "contact": { + "properties": { + "email": { + "type": "text", + "fields": { + "raw": { + "type": "keyword" + } + } + }, + "phone": { + "type": "text" + } + } + } + } + }'*/ + // curl http://localhost:9200/_all/_mapping + tests := []struct { + name string + file string + want string + }{ + { + name: "7.8.0", + file: "../fixtures/indices_mappings/7.8.0.json", + want: ` +# HELP elasticsearch_indices_mappings_stats_fields Current number fields within cluster. +# TYPE elasticsearch_indices_mappings_stats_fields gauge +elasticsearch_indices_mappings_stats_fields{index="facebook"} 6 +elasticsearch_indices_mappings_stats_fields{index="twitter"} 2 + `, + }, + { + name: "counts", + file: "../fixtures/indices_mappings/counts.json", + want: ` +# HELP elasticsearch_indices_mappings_stats_fields Current number fields within cluster. +# TYPE elasticsearch_indices_mappings_stats_fields gauge +elasticsearch_indices_mappings_stats_fields{index="test-data-2023.01.20"} 40 + `, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f, err := os.Open(tt.file) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.Copy(w, f) + })) + defer ts.Close() + + u, err := url.Parse(ts.URL) + if err != nil { + t.Fatal(err) + } + + c := NewIndicesMappings(promslog.NewNopLogger(), http.DefaultClient, u) + if err != nil { + t.Fatal(err) + } + + if err := testutil.CollectAndCompare(c, strings.NewReader(tt.want)); err != nil { + t.Fatal(err) + } + }) + } +} diff --git a/collector/indices_response.go b/collector/indices_response.go index 6b619872..b048960c 100644 --- a/collector/indices_response.go +++ b/collector/indices_response.go @@ -1,3 +1,16 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector // indexStatsResponse is a representation of a Elasticsearch Index Stats @@ -5,6 +18,15 @@ type indexStatsResponse struct { Shards IndexStatsShardsResponse `json:"_shards"` All IndexStatsIndexResponse `json:"_all"` Indices map[string]IndexStatsIndexResponse `json:"indices"` + Aliases map[string][]string +} + +// aliasesResponse is a representation of a Elasticsearch Alias Query +type aliasesResponse map[string]aliasMapping + +// aliasMapping is a mapping of index names to a map of associated alias names where the alias names are keys +type aliasMapping struct { + Aliases map[string]map[string]interface{} `json:"aliases"` } // IndexStatsShardsResponse defines index stats shards information structure @@ -123,9 +145,11 @@ type IndexStatsIndexMergesResponse struct { // IndexStatsIndexRefreshResponse defines index stats index refresh information structure type IndexStatsIndexRefreshResponse struct { - Total int64 `json:"total"` - TotalTimeInMillis int64 `json:"total_time_in_millis"` - Listeners int64 `json:"listeners"` + Total int64 `json:"total"` + TotalTimeInMillis int64 `json:"total_time_in_millis"` + ExternalTotal int64 `json:"external_total"` + ExternalTotalTimeInMillis int64 `json:"external_total_time_in_millis"` + Listeners int64 `json:"listeners"` } // IndexStatsIndexFlushResponse defines index stats index flush information structure diff --git a/collector/indices_settings.go b/collector/indices_settings.go index 7fce2a68..141c2e69 100644 --- a/collector/indices_settings.go +++ b/collector/indices_settings.go @@ -1,30 +1,58 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector import ( "encoding/json" "fmt" + "io" + "log/slog" "net/http" "net/url" "path" + "strconv" - "github.com/go-kit/kit/log" - "github.com/go-kit/kit/log/level" "github.com/prometheus/client_golang/prometheus" ) // IndicesSettings information struct type IndicesSettings struct { - logger log.Logger + logger *slog.Logger client *http.Client url *url.URL - up prometheus.Gauge - readOnlyIndices prometheus.Gauge + up prometheus.Gauge + readOnlyIndices prometheus.Gauge + totalScrapes, jsonParseFailures prometheus.Counter + metrics []*indicesSettingsMetric +} + +var ( + defaultIndicesTotalFieldsLabels = []string{"index"} + defaultTotalFieldsValue = 1000 //es default configuration for total fields + defaultDateCreation = 0 //es index default creation date +) + +type indicesSettingsMetric struct { + Type prometheus.ValueType + Desc *prometheus.Desc + Value func(indexSettings Settings) float64 } // NewIndicesSettings defines Indices Settings Prometheus metrics -func NewIndicesSettings(logger log.Logger, client *http.Client, url *url.URL) *IndicesSettings { +func NewIndicesSettings(logger *slog.Logger, client *http.Client, url *url.URL) *IndicesSettings { return &IndicesSettings{ logger: logger, client: client, @@ -32,11 +60,11 @@ func NewIndicesSettings(logger log.Logger, client *http.Client, url *url.URL) *I up: prometheus.NewGauge(prometheus.GaugeOpts{ Name: prometheus.BuildFQName(namespace, "indices_settings_stats", "up"), - Help: "Was the last scrape of the ElasticSearch Indices Settings endpoint successful.", + Help: "Was the last scrape of the Elasticsearch Indices Settings endpoint successful.", }), totalScrapes: prometheus.NewCounter(prometheus.CounterOpts{ Name: prometheus.BuildFQName(namespace, "indices_settings_stats", "total_scrapes"), - Help: "Current total ElasticSearch Indices Settings scrapes.", + Help: "Current total Elasticsearch Indices Settings scrapes.", }), readOnlyIndices: prometheus.NewGauge(prometheus.GaugeOpts{ Name: prometheus.BuildFQName(namespace, "indices_settings_stats", "read_only_indices"), @@ -46,6 +74,53 @@ func NewIndicesSettings(logger log.Logger, client *http.Client, url *url.URL) *I Name: prometheus.BuildFQName(namespace, "indices_settings_stats", "json_parse_failures"), Help: "Number of errors while parsing JSON.", }), + metrics: []*indicesSettingsMetric{ + { + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "indices_settings", "total_fields"), + "index mapping setting for total_fields", + defaultIndicesTotalFieldsLabels, nil, + ), + Value: func(indexSettings Settings) float64 { + val, err := strconv.ParseFloat(indexSettings.IndexInfo.Mapping.TotalFields.Limit, 64) + if err != nil { + return float64(defaultTotalFieldsValue) + } + return val + }, + }, + { + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "indices_settings", "replicas"), + "index setting number_of_replicas", + defaultIndicesTotalFieldsLabels, nil, + ), + Value: func(indexSettings Settings) float64 { + val, err := strconv.ParseFloat(indexSettings.IndexInfo.NumberOfReplicas, 64) + if err != nil { + return float64(defaultTotalFieldsValue) + } + return val + }, + }, + { + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "indices_settings", "creation_timestamp_seconds"), + "index setting creation_date", + defaultIndicesTotalFieldsLabels, nil, + ), + Value: func(indexSettings Settings) float64 { + val, err := strconv.ParseFloat(indexSettings.IndexInfo.CreationDate, 64) + if err != nil { + return float64(defaultDateCreation) + } + return val / 1000.0 + }, + }, + }, } } @@ -67,8 +142,8 @@ func (cs *IndicesSettings) getAndParseURL(u *url.URL, data interface{}) error { defer func() { err = res.Body.Close() if err != nil { - _ = level.Warn(cs.logger).Log( - "msg", "failed to close http.Client", + cs.logger.Warn( + "failed to close http.Client", "err", err, ) } @@ -78,7 +153,13 @@ func (cs *IndicesSettings) getAndParseURL(u *url.URL, data interface{}) error { return fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) } - if err := json.NewDecoder(res.Body).Decode(data); err != nil { + bts, err := io.ReadAll(res.Body) + if err != nil { + cs.jsonParseFailures.Inc() + return err + } + + if err := json.Unmarshal(bts, data); err != nil { cs.jsonParseFailures.Inc() return err } @@ -113,8 +194,8 @@ func (cs *IndicesSettings) Collect(ch chan<- prometheus.Metric) { if err != nil { cs.readOnlyIndices.Set(0) cs.up.Set(0) - _ = level.Warn(cs.logger).Log( - "msg", "failed to fetch and decode cluster settings stats", + cs.logger.Warn( + "failed to fetch and decode cluster settings stats", "err", err, ) return @@ -122,10 +203,18 @@ func (cs *IndicesSettings) Collect(ch chan<- prometheus.Metric) { cs.up.Set(1) var c int - for _, value := range asr { + for indexName, value := range asr { if value.Settings.IndexInfo.Blocks.ReadOnly == "true" { c++ } + for _, metric := range cs.metrics { + ch <- prometheus.MustNewConstMetric( + metric.Desc, + metric.Type, + metric.Value(value.Settings), + indexName, + ) + } } cs.readOnlyIndices.Set(float64(c)) } diff --git a/collector/indices_settings_response.go b/collector/indices_settings_response.go index 88b6b62d..cac3ee0b 100644 --- a/collector/indices_settings_response.go +++ b/collector/indices_settings_response.go @@ -1,3 +1,16 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector // IndicesSettingsResponse is a representation of Elasticsearch Settings for each Index @@ -15,10 +28,23 @@ type Settings struct { // IndexInfo defines the blocks of the current index type IndexInfo struct { - Blocks Blocks `json:"blocks"` + Blocks Blocks `json:"blocks"` + Mapping Mapping `json:"mapping"` + NumberOfReplicas string `json:"number_of_replicas"` + CreationDate string `json:"creation_date"` } // Blocks defines whether current index has read_only_allow_delete enabled type Blocks struct { ReadOnly string `json:"read_only_allow_delete"` } + +// Mapping defines mapping settings +type Mapping struct { + TotalFields TotalFields `json:"total_fields"` +} + +// TotalFields defines the limit on the number of mapped fields +type TotalFields struct { + Limit string `json:"limit"` +} diff --git a/collector/indices_settings_test.go b/collector/indices_settings_test.go index 1d6fcf8d..3b68b0c7 100644 --- a/collector/indices_settings_test.go +++ b/collector/indices_settings_test.go @@ -1,3 +1,16 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector import ( @@ -7,7 +20,7 @@ import ( "net/url" "testing" - "github.com/go-kit/kit/log" + "github.com/prometheus/common/promslog" ) func TestIndicesSettings(t *testing.T) { @@ -20,6 +33,11 @@ func TestIndicesSettings(t *testing.T) { // curl -XPUT http://localhost:9200/instagram/_settings --header "Content-Type: application/json" -d ' // { // "index": { + // "mapping": { + // "total_fields": { + // "limit": 10000 + // } + // }, // "blocks": { // "read_only_allow_delete": "true" // } @@ -37,7 +55,7 @@ func TestIndicesSettings(t *testing.T) { // curl http://localhost:9200/_all/_settings tcs := map[string]string{ - "6.5.4": `{"viber":{"settings":{"index":{"creation_date":"1548066996192","number_of_shards":"5","number_of_replicas":"1","uuid":"kt2cGV-yQRaloESpqj2zsg","version":{"created":"6050499"},"provided_name":"viber"}}},"facebook":{"settings":{"index":{"creation_date":"1548066984670","number_of_shards":"5","number_of_replicas":"1","uuid":"jrU8OWQZQD--9v5eg0tjbg","version":{"created":"6050499"},"provided_name":"facebook"}}},"twitter":{"settings":{"index":{"number_of_shards":"5","blocks":{"read_only_allow_delete":"true"},"provided_name":"twitter","creation_date":"1548066697559","number_of_replicas":"1","uuid":"-sqtc4fVRrS2jHJCZ2hQ9Q","version":{"created":"6050499"}}}},"instagram":{"settings":{"index":{"number_of_shards":"5","blocks":{"read_only_allow_delete":"true"},"provided_name":"instagram","creation_date":"1548066991932","number_of_replicas":"1","uuid":"WeGWaxa_S3KrgE5SZHolTw","version":{"created":"6050499"}}}}}`, + "6.5.4": `{"viber":{"settings":{"index":{"creation_date":"1618593207186","number_of_shards":"5","number_of_replicas":"1","uuid":"lWg86KTARzO3r7lELytT1Q","version":{"created":"6050499"},"provided_name":"viber"}}},"instagram":{"settings":{"index":{"mapping":{"total_fields":{"limit":"10000"}},"number_of_shards":"5","blocks":{"read_only_allow_delete":"true"},"provided_name":"instagram","creation_date":"1618593203353","number_of_replicas":"1","uuid":"msb6eG7aT8GmNe-a4oyVtQ","version":{"created":"6050499"}}}},"twitter":{"settings":{"index":{"number_of_shards":"5","blocks":{"read_only_allow_delete":"true"},"provided_name":"twitter","creation_date":"1618593193641","number_of_replicas":"1","uuid":"YRUT8t4aSkKsNmGl7K3y4Q","version":{"created":"6050499"}}}},"facebook":{"settings":{"index":{"creation_date":"1618593199101","number_of_shards":"5","number_of_replicas":"1","uuid":"trZhb_YOTV-RWKitTYw81A","version":{"created":"6050499"},"provided_name":"facebook"}}}}`, } for ver, out := range tcs { for hn, handler := range map[string]http.Handler{ @@ -52,7 +70,7 @@ func TestIndicesSettings(t *testing.T) { if err != nil { t.Fatalf("Failed to parse URL: %s", err) } - c := NewIndicesSettings(log.NewNopLogger(), http.DefaultClient, u) + c := NewIndicesSettings(promslog.NewNopLogger(), http.DefaultClient, u) nsr, err := c.fetchAndDecodeIndicesSettings() if err != nil { t.Fatalf("Failed to fetch or decode indices settings: %s", err) @@ -62,6 +80,7 @@ func TestIndicesSettings(t *testing.T) { // t.Errorf("Wrong setting for cluster routing allocation enabled") // } var counter int + var totalFields int for key, value := range nsr { if value.Settings.IndexInfo.Blocks.ReadOnly == "true" { counter++ @@ -69,10 +88,19 @@ func TestIndicesSettings(t *testing.T) { t.Errorf("Wrong read_only index") } } + if value.Settings.IndexInfo.Mapping.TotalFields.Limit == "10000" { + totalFields++ + if key != "instagram" { + t.Errorf("Expected 10000 total_fields only for instagram") + } + } } if counter != 2 { t.Errorf("Wrong number of read_only indexes") } + if totalFields != 1 { + t.Errorf(("Wrong number of total_fields found")) + } } } } diff --git a/collector/indices_test.go b/collector/indices_test.go index 5bdc11e8..6e3a832b 100644 --- a/collector/indices_test.go +++ b/collector/indices_test.go @@ -1,13 +1,30 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector import ( - "fmt" + "io" "net/http" "net/http/httptest" "net/url" + "os" + "path" + "strings" "testing" - "github.com/go-kit/kit/log" + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/promslog" ) func TestIndices(t *testing.T) { @@ -18,43 +35,1652 @@ func TestIndices(t *testing.T) { // curl -XPUT http://localhost:9200/foo_2/type1/1 -d '{"title":"abc001","content":"hello001"}' // curl -XPUT http://localhost:9200/foo_2/type1/2 -d '{"title":"def002","content":"world002"}' // curl -XPUT http://localhost:9200/foo_2/type1/3 -d '{"title":"def003","content":"world003"}' + // curl -XPOST -H "Content-Type: application/json" http://localhost:9200/_aliases -d '{"actions": [{"add": {"index": "foo_2","alias": "foo_alias_2_1"}}]}' + // curl -XPOST -H "Content-Type: application/json" http://localhost:9200/_aliases -d '{"actions": [{"add": {"index": "foo_3","alias": "foo_alias_3_2"}}]}' + // curl -XPOST -H "Content-Type: application/json" http://localhost:9200/_aliases -d '{"actions": [{"add": {"index": "foo_3","alias": "foo_alias_3_1", "is_write_index": true, "routing": "title"}}]}' // curl http://localhost:9200/_all/_stats - ti := map[string]string{ - "1.7.6": `{"_shards":{"total":20,"successful":10,"failed":0},"_all":{"primaries":{"docs":{"count":5,"deleted":0},"store":{"size_in_bytes":13798,"throttle_time_in_millis":0},"indexing":{"index_total":5,"index_time_in_millis":52,"index_current":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0},"refresh":{"total":5,"total_time_in_millis":163},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":30,"total_time_in_millis":42},"filter_cache":{"memory_size_in_bytes":0,"evictions":0},"id_cache":{"memory_size_in_bytes":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"percolate":{"total":0,"time_in_millis":0,"current":0,"memory_size_in_bytes":-1,"memory_size":"-1b","queries":0},"completion":{"size_in_bytes":0},"segments":{"count":5,"memory_in_bytes":18410,"index_writer_memory_in_bytes":0,"index_writer_max_memory_in_bytes":671088640,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0},"translog":{"operations":5,"size_in_bytes":102},"suggest":{"total":0,"time_in_millis":0,"current":0},"query_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":5,"deleted":0},"store":{"size_in_bytes":13798,"throttle_time_in_millis":0},"indexing":{"index_total":5,"index_time_in_millis":52,"index_current":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0},"refresh":{"total":5,"total_time_in_millis":163},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":30,"total_time_in_millis":42},"filter_cache":{"memory_size_in_bytes":0,"evictions":0},"id_cache":{"memory_size_in_bytes":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"percolate":{"total":0,"time_in_millis":0,"current":0,"memory_size_in_bytes":-1,"memory_size":"-1b","queries":0},"completion":{"size_in_bytes":0},"segments":{"count":5,"memory_in_bytes":18410,"index_writer_memory_in_bytes":0,"index_writer_max_memory_in_bytes":671088640,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0},"translog":{"operations":5,"size_in_bytes":102},"suggest":{"total":0,"time_in_millis":0,"current":0},"query_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},"indices":{"foo_2":{"primaries":{"docs":{"count":3,"deleted":0},"store":{"size_in_bytes":8207,"throttle_time_in_millis":0},"indexing":{"index_total":3,"index_time_in_millis":6,"index_current":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0},"refresh":{"total":3,"total_time_in_millis":38},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":16,"total_time_in_millis":0},"filter_cache":{"memory_size_in_bytes":0,"evictions":0},"id_cache":{"memory_size_in_bytes":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"percolate":{"total":0,"time_in_millis":0,"current":0,"memory_size_in_bytes":-1,"memory_size":"-1b","queries":0},"completion":{"size_in_bytes":0},"segments":{"count":3,"memory_in_bytes":11046,"index_writer_memory_in_bytes":0,"index_writer_max_memory_in_bytes":335544320,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0},"translog":{"operations":3,"size_in_bytes":102},"suggest":{"total":0,"time_in_millis":0,"current":0},"query_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":3,"deleted":0},"store":{"size_in_bytes":8207,"throttle_time_in_millis":0},"indexing":{"index_total":3,"index_time_in_millis":6,"index_current":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0},"refresh":{"total":3,"total_time_in_millis":38},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":16,"total_time_in_millis":0},"filter_cache":{"memory_size_in_bytes":0,"evictions":0},"id_cache":{"memory_size_in_bytes":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"percolate":{"total":0,"time_in_millis":0,"current":0,"memory_size_in_bytes":-1,"memory_size":"-1b","queries":0},"completion":{"size_in_bytes":0},"segments":{"count":3,"memory_in_bytes":11046,"index_writer_memory_in_bytes":0,"index_writer_max_memory_in_bytes":335544320,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0},"translog":{"operations":3,"size_in_bytes":102},"suggest":{"total":0,"time_in_millis":0,"current":0},"query_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},"foo_1":{"primaries":{"docs":{"count":2,"deleted":0},"store":{"size_in_bytes":5591,"throttle_time_in_millis":0},"indexing":{"index_total":2,"index_time_in_millis":46,"index_current":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0},"refresh":{"total":2,"total_time_in_millis":125},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":14,"total_time_in_millis":42},"filter_cache":{"memory_size_in_bytes":0,"evictions":0},"id_cache":{"memory_size_in_bytes":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"percolate":{"total":0,"time_in_millis":0,"current":0,"memory_size_in_bytes":-1,"memory_size":"-1b","queries":0},"completion":{"size_in_bytes":0},"segments":{"count":2,"memory_in_bytes":7364,"index_writer_memory_in_bytes":0,"index_writer_max_memory_in_bytes":335544320,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0},"translog":{"operations":2,"size_in_bytes":17},"suggest":{"total":0,"time_in_millis":0,"current":0},"query_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":2,"deleted":0},"store":{"size_in_bytes":5591,"throttle_time_in_millis":0},"indexing":{"index_total":2,"index_time_in_millis":46,"index_current":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0},"refresh":{"total":2,"total_time_in_millis":125},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":14,"total_time_in_millis":42},"filter_cache":{"memory_size_in_bytes":0,"evictions":0},"id_cache":{"memory_size_in_bytes":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"percolate":{"total":0,"time_in_millis":0,"current":0,"memory_size_in_bytes":-1,"memory_size":"-1b","queries":0},"completion":{"size_in_bytes":0},"segments":{"count":2,"memory_in_bytes":7364,"index_writer_memory_in_bytes":0,"index_writer_max_memory_in_bytes":335544320,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0},"translog":{"operations":2,"size_in_bytes":17},"suggest":{"total":0,"time_in_millis":0,"current":0},"query_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}}}}`, - "2.4.5": `{"_shards":{"total":20,"successful":10,"failed":0},"_all":{"primaries":{"docs":{"count":5,"deleted":0},"store":{"size_in_bytes":3610,"throttle_time_in_millis":0},"indexing":{"index_total":5,"index_time_in_millis":40,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":209715200},"refresh":{"total":5,"total_time_in_millis":171},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":30,"total_time_in_millis":12},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"percolate":{"total":0,"time_in_millis":0,"current":0,"memory_size_in_bytes":-1,"memory_size":"-1b","queries":0},"completion":{"size_in_bytes":0},"segments":{"count":5,"memory_in_bytes":10530,"terms_memory_in_bytes":7550,"stored_fields_memory_in_bytes":1560,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":960,"doc_values_memory_in_bytes":460,"index_writer_memory_in_bytes":0,"index_writer_max_memory_in_bytes":103887660,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0},"translog":{"operations":5,"size_in_bytes":843},"suggest":{"total":0,"time_in_millis":0,"current":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":5,"deleted":0},"store":{"size_in_bytes":3610,"throttle_time_in_millis":0},"indexing":{"index_total":5,"index_time_in_millis":40,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":209715200},"refresh":{"total":5,"total_time_in_millis":171},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":30,"total_time_in_millis":12},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"percolate":{"total":0,"time_in_millis":0,"current":0,"memory_size_in_bytes":-1,"memory_size":"-1b","queries":0},"completion":{"size_in_bytes":0},"segments":{"count":5,"memory_in_bytes":10530,"terms_memory_in_bytes":7550,"stored_fields_memory_in_bytes":1560,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":960,"doc_values_memory_in_bytes":460,"index_writer_memory_in_bytes":0,"index_writer_max_memory_in_bytes":103887660,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0},"translog":{"operations":5,"size_in_bytes":843},"suggest":{"total":0,"time_in_millis":0,"current":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},"indices":{"foo_2":{"primaries":{"docs":{"count":3,"deleted":0},"store":{"size_in_bytes":3350,"throttle_time_in_millis":0},"indexing":{"index_total":3,"index_time_in_millis":6,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":104857600},"refresh":{"total":3,"total_time_in_millis":34},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":16,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"percolate":{"total":0,"time_in_millis":0,"current":0,"memory_size_in_bytes":-1,"memory_size":"-1b","queries":0},"completion":{"size_in_bytes":0},"segments":{"count":3,"memory_in_bytes":6318,"terms_memory_in_bytes":4530,"stored_fields_memory_in_bytes":936,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":576,"doc_values_memory_in_bytes":276,"index_writer_memory_in_bytes":0,"index_writer_max_memory_in_bytes":51943830,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0},"translog":{"operations":3,"size_in_bytes":470},"suggest":{"total":0,"time_in_millis":0,"current":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":3,"deleted":0},"store":{"size_in_bytes":3350,"throttle_time_in_millis":0},"indexing":{"index_total":3,"index_time_in_millis":6,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":104857600},"refresh":{"total":3,"total_time_in_millis":34},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":16,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"percolate":{"total":0,"time_in_millis":0,"current":0,"memory_size_in_bytes":-1,"memory_size":"-1b","queries":0},"completion":{"size_in_bytes":0},"segments":{"count":3,"memory_in_bytes":6318,"terms_memory_in_bytes":4530,"stored_fields_memory_in_bytes":936,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":576,"doc_values_memory_in_bytes":276,"index_writer_memory_in_bytes":0,"index_writer_max_memory_in_bytes":51943830,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0},"translog":{"operations":3,"size_in_bytes":470},"suggest":{"total":0,"time_in_millis":0,"current":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},"foo_1":{"primaries":{"docs":{"count":2,"deleted":0},"store":{"size_in_bytes":260,"throttle_time_in_millis":0},"indexing":{"index_total":2,"index_time_in_millis":34,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":104857600},"refresh":{"total":2,"total_time_in_millis":137},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":14,"total_time_in_millis":12},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"percolate":{"total":0,"time_in_millis":0,"current":0,"memory_size_in_bytes":-1,"memory_size":"-1b","queries":0},"completion":{"size_in_bytes":0},"segments":{"count":2,"memory_in_bytes":4212,"terms_memory_in_bytes":3020,"stored_fields_memory_in_bytes":624,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":384,"doc_values_memory_in_bytes":184,"index_writer_memory_in_bytes":0,"index_writer_max_memory_in_bytes":51943830,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0},"translog":{"operations":2,"size_in_bytes":373},"suggest":{"total":0,"time_in_millis":0,"current":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":2,"deleted":0},"store":{"size_in_bytes":260,"throttle_time_in_millis":0},"indexing":{"index_total":2,"index_time_in_millis":34,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":104857600},"refresh":{"total":2,"total_time_in_millis":137},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":14,"total_time_in_millis":12},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"percolate":{"total":0,"time_in_millis":0,"current":0,"memory_size_in_bytes":-1,"memory_size":"-1b","queries":0},"completion":{"size_in_bytes":0},"segments":{"count":2,"memory_in_bytes":4212,"terms_memory_in_bytes":3020,"stored_fields_memory_in_bytes":624,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":384,"doc_values_memory_in_bytes":184,"index_writer_memory_in_bytes":0,"index_writer_max_memory_in_bytes":51943830,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0},"translog":{"operations":2,"size_in_bytes":373},"suggest":{"total":0,"time_in_millis":0,"current":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}}}}`, - "5.4.2": `{"_shards":{"total":26,"successful":13,"failed":0},"_all":{"primaries":{"docs":{"count":76,"deleted":0},"store":{"size_in_bytes":128534,"throttle_time_in_millis":0},"indexing":{"index_total":78,"index_time_in_millis":1598,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":272629760},"refresh":{"total":15,"total_time_in_millis":1361,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":26,"total_time_in_millis":124},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":13,"memory_in_bytes":56523,"terms_memory_in_bytes":44419,"stored_fields_memory_in_bytes":4056,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":2880,"points_memory_in_bytes":652,"doc_values_memory_in_bytes":4516,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":78,"size_in_bytes":56679},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":76,"deleted":0},"store":{"size_in_bytes":128534,"throttle_time_in_millis":0},"indexing":{"index_total":78,"index_time_in_millis":1598,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":272629760},"refresh":{"total":15,"total_time_in_millis":1361,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":26,"total_time_in_millis":124},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":13,"memory_in_bytes":56523,"terms_memory_in_bytes":44419,"stored_fields_memory_in_bytes":4056,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":2880,"points_memory_in_bytes":652,"doc_values_memory_in_bytes":4516,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":78,"size_in_bytes":56679},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},"indices":{".monitoring-es-2-2017.08.23":{"primaries":{"docs":{"count":65,"deleted":0},"store":{"size_in_bytes":68917,"throttle_time_in_millis":0},"indexing":{"index_total":65,"index_time_in_millis":106,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":20971520},"refresh":{"total":3,"total_time_in_millis":390,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":4,"total_time_in_millis":15},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":3,"memory_in_bytes":23830,"terms_memory_in_bytes":18474,"stored_fields_memory_in_bytes":936,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":320,"points_memory_in_bytes":648,"doc_values_memory_in_bytes":3452,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":65,"size_in_bytes":37990},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":65,"deleted":0},"store":{"size_in_bytes":68917,"throttle_time_in_millis":0},"indexing":{"index_total":65,"index_time_in_millis":106,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":20971520},"refresh":{"total":3,"total_time_in_millis":390,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":4,"total_time_in_millis":15},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":3,"memory_in_bytes":23830,"terms_memory_in_bytes":18474,"stored_fields_memory_in_bytes":936,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":320,"points_memory_in_bytes":648,"doc_values_memory_in_bytes":3452,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":65,"size_in_bytes":37990},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},".monitoring-data-2":{"primaries":{"docs":{"count":2,"deleted":0},"store":{"size_in_bytes":4226,"throttle_time_in_millis":0},"indexing":{"index_total":4,"index_time_in_millis":13,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":20971520},"refresh":{"total":2,"total_time_in_millis":74,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":3,"total_time_in_millis":2},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":1,"memory_in_bytes":1335,"terms_memory_in_bytes":787,"stored_fields_memory_in_bytes":312,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":0,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":236,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":4,"size_in_bytes":6738},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":2,"deleted":0},"store":{"size_in_bytes":4226,"throttle_time_in_millis":0},"indexing":{"index_total":4,"index_time_in_millis":13,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":20971520},"refresh":{"total":2,"total_time_in_millis":74,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":3,"total_time_in_millis":2},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":1,"memory_in_bytes":1335,"terms_memory_in_bytes":787,"stored_fields_memory_in_bytes":312,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":0,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":236,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":4,"size_in_bytes":6738},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},"foo_2":{"primaries":{"docs":{"count":3,"deleted":0},"store":{"size_in_bytes":11909,"throttle_time_in_millis":0},"indexing":{"index_total":3,"index_time_in_millis":12,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":104857600},"refresh":{"total":3,"total_time_in_millis":42,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":8,"total_time_in_millis":4},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":3,"memory_in_bytes":7764,"terms_memory_in_bytes":5976,"stored_fields_memory_in_bytes":936,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":576,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":276,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":3,"size_in_bytes":494},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":3,"deleted":0},"store":{"size_in_bytes":11909,"throttle_time_in_millis":0},"indexing":{"index_total":3,"index_time_in_millis":12,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":104857600},"refresh":{"total":3,"total_time_in_millis":42,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":8,"total_time_in_millis":4},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":3,"memory_in_bytes":7764,"terms_memory_in_bytes":5976,"stored_fields_memory_in_bytes":936,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":576,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":276,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":3,"size_in_bytes":494},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},"foo_1":{"primaries":{"docs":{"count":2,"deleted":0},"store":{"size_in_bytes":8038,"throttle_time_in_millis":0},"indexing":{"index_total":2,"index_time_in_millis":46,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":104857600},"refresh":{"total":2,"total_time_in_millis":84,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":7,"total_time_in_millis":94},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":2,"memory_in_bytes":5176,"terms_memory_in_bytes":3984,"stored_fields_memory_in_bytes":624,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":384,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":184,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":2,"size_in_bytes":389},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":2,"deleted":0},"store":{"size_in_bytes":8038,"throttle_time_in_millis":0},"indexing":{"index_total":2,"index_time_in_millis":46,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":104857600},"refresh":{"total":2,"total_time_in_millis":84,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":7,"total_time_in_millis":94},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":2,"memory_in_bytes":5176,"terms_memory_in_bytes":3984,"stored_fields_memory_in_bytes":624,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":384,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":184,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":2,"size_in_bytes":389},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},".watches":{"primaries":{"docs":{"count":4,"deleted":0},"store":{"size_in_bytes":35444,"throttle_time_in_millis":0},"indexing":{"index_total":4,"index_time_in_millis":1421,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":20971520},"refresh":{"total":5,"total_time_in_millis":771,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":4,"total_time_in_millis":9},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":4,"memory_in_bytes":18418,"terms_memory_in_bytes":15198,"stored_fields_memory_in_bytes":1248,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":1600,"points_memory_in_bytes":4,"doc_values_memory_in_bytes":368,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":4,"size_in_bytes":11068},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":4,"deleted":0},"store":{"size_in_bytes":35444,"throttle_time_in_millis":0},"indexing":{"index_total":4,"index_time_in_millis":1421,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":20971520},"refresh":{"total":5,"total_time_in_millis":771,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":4,"total_time_in_millis":9},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":4,"memory_in_bytes":18418,"terms_memory_in_bytes":15198,"stored_fields_memory_in_bytes":1248,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":1600,"points_memory_in_bytes":4,"doc_values_memory_in_bytes":368,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":4,"size_in_bytes":11068},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}}}}`, - "5.5.2": `{"_shards":{"total":34,"successful":34,"failed":0},"_all":{"primaries":{"docs":{"count":256658,"deleted":148},"store":{"size_in_bytes":175959144,"throttle_time_in_millis":0},"indexing":{"index_total":413652,"index_time_in_millis":316231,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":88438,"time_in_millis":2799,"exists_total":88438,"exists_time_in_millis":2799,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":88458,"query_time_in_millis":2513,"query_current":0,"fetch_total":88446,"fetch_time_in_millis":2685,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":10275,"total_time_in_millis":5895937,"total_docs":80376844,"total_size_in_bytes":49005089428,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":274,"total_auto_throttle_in_bytes":354609338},"refresh":{"total":100264,"total_time_in_millis":818781,"listeners":0},"flush":{"total":5,"total_time_in_millis":124},"warmer":{"current":0,"total":100286,"total_time_in_millis":23851},"query_cache":{"memory_size_in_bytes":0,"total_count":22,"hit_count":0,"miss_count":22,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":38,"memory_in_bytes":720166,"terms_memory_in_bytes":481188,"stored_fields_memory_in_bytes":31920,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":3072,"points_memory_in_bytes":61858,"doc_values_memory_in_bytes":142128,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":137331,"size_in_bytes":167642357},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":1},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":513316,"deleted":324},"store":{"size_in_bytes":352143858,"throttle_time_in_millis":0},"indexing":{"index_total":827302,"index_time_in_millis":625030,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":176883,"time_in_millis":6265,"exists_total":176883,"exists_time_in_millis":6265,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":176913,"query_time_in_millis":5115,"query_current":0,"fetch_total":176891,"fetch_time_in_millis":5862,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":20547,"total_time_in_millis":11765629,"total_docs":160766745,"total_size_in_bytes":98024993696,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":522,"total_auto_throttle_in_bytes":709218676},"refresh":{"total":200378,"total_time_in_millis":1620051,"listeners":0},"flush":{"total":10,"total_time_in_millis":264},"warmer":{"current":0,"total":200427,"total_time_in_millis":46689},"query_cache":{"memory_size_in_bytes":0,"total_count":54,"hit_count":0,"miss_count":54,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":776,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":86,"memory_in_bytes":1496932,"terms_memory_in_bytes":1008932,"stored_fields_memory_in_bytes":66896,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":6784,"points_memory_in_bytes":124368,"doc_values_memory_in_bytes":289952,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":1502755202429,"file_sizes":{}},"translog":{"operations":274662,"size_in_bytes":335284714},"request_cache":{"memory_size_in_bytes":1794,"evictions":0,"hit_count":0,"miss_count":3},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},"indices":{".monitoring-kibana-6-2017.08.16":{"primaries":{"docs":{"count":12459,"deleted":0},"store":{"size_in_bytes":4880578,"throttle_time_in_millis":0},"indexing":{"index_total":12459,"index_time_in_millis":20073,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":1372,"total_time_in_millis":275560,"total_docs":8619963,"total_size_in_bytes":3518738895,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":20971520},"refresh":{"total":12724,"total_time_in_millis":79600,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":12725,"total_time_in_millis":2653},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":2,"memory_in_bytes":34337,"terms_memory_in_bytes":30104,"stored_fields_memory_in_bytes":968,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":128,"points_memory_in_bytes":1393,"doc_values_memory_in_bytes":1744,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":12459,"size_in_bytes":12175093},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":24918,"deleted":0},"store":{"size_in_bytes":9682148,"throttle_time_in_millis":0},"indexing":{"index_total":24918,"index_time_in_millis":37852,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":1,"query_time_in_millis":10,"query_current":0,"fetch_total":1,"fetch_time_in_millis":1,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":2743,"total_time_in_millis":549689,"total_docs":17234974,"total_size_in_bytes":7034624631,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":41943040},"refresh":{"total":25390,"total_time_in_millis":155546,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":25392,"total_time_in_millis":5196},"query_cache":{"memory_size_in_bytes":0,"total_count":3,"hit_count":0,"miss_count":3,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":7,"memory_in_bytes":83565,"terms_memory_in_bytes":73488,"stored_fields_memory_in_bytes":2968,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":448,"points_memory_in_bytes":2897,"doc_values_memory_in_bytes":3764,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":24918,"size_in_bytes":24350186},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},".monitoring-kibana-6-2017.08.15":{"primaries":{"docs":{"count":25917,"deleted":0},"store":{"size_in_bytes":9617967,"throttle_time_in_millis":0},"indexing":{"index_total":25917,"index_time_in_millis":36304,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":1,"query_time_in_millis":10,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":2055,"total_time_in_millis":746516,"total_docs":27797269,"total_size_in_bytes":10672726928,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":20971520},"refresh":{"total":19569,"total_time_in_millis":123083,"listeners":0},"flush":{"total":1,"total_time_in_millis":18},"warmer":{"current":0,"total":19571,"total_time_in_millis":3995},"query_cache":{"memory_size_in_bytes":0,"total_count":3,"hit_count":0,"miss_count":3,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":3,"memory_in_bytes":58226,"terms_memory_in_bytes":52997,"stored_fields_memory_in_bytes":1912,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":192,"points_memory_in_bytes":2721,"doc_values_memory_in_bytes":404,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":43},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":51834,"deleted":0},"store":{"size_in_bytes":19309686,"throttle_time_in_millis":0},"indexing":{"index_total":51834,"index_time_in_millis":68258,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":1,"query_time_in_millis":10,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":4109,"total_time_in_millis":1477106,"total_docs":55598675,"total_size_in_bytes":21347372840,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":41943040},"refresh":{"total":39103,"total_time_in_millis":238886,"listeners":0},"flush":{"total":2,"total_time_in_millis":44},"warmer":{"current":0,"total":39108,"total_time_in_millis":7775},"query_cache":{"memory_size_in_bytes":0,"total_count":3,"hit_count":0,"miss_count":3,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":11,"memory_in_bytes":141204,"terms_memory_in_bytes":128132,"stored_fields_memory_in_bytes":5472,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":704,"points_memory_in_bytes":5628,"doc_values_memory_in_bytes":1268,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":1502755202429,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":86},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},".monitoring-kibana-6-2017.08.14":{"primaries":{"docs":{"count":6147,"deleted":0},"store":{"size_in_bytes":2467088,"throttle_time_in_millis":0},"indexing":{"index_total":6147,"index_time_in_millis":9228,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":1,"query_time_in_millis":32,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":397,"total_time_in_millis":48142,"total_docs":1231276,"total_size_in_bytes":559560922,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":20971520},"refresh":{"total":3733,"total_time_in_millis":28841,"listeners":0},"flush":{"total":1,"total_time_in_millis":7},"warmer":{"current":0,"total":3735,"total_time_in_millis":1168},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":3,"memory_in_bytes":29099,"terms_memory_in_bytes":25724,"stored_fields_memory_in_bytes":1104,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":192,"points_memory_in_bytes":715,"doc_values_memory_in_bytes":1364,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":43},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":12294,"deleted":0},"store":{"size_in_bytes":5029190,"throttle_time_in_millis":0},"indexing":{"index_total":12294,"index_time_in_millis":16557,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":1,"query_time_in_millis":32,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":792,"total_time_in_millis":96523,"total_docs":2467549,"total_size_in_bytes":1121117660,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":41943040},"refresh":{"total":7449,"total_time_in_millis":51544,"listeners":0},"flush":{"total":2,"total_time_in_millis":16},"warmer":{"current":0,"total":7453,"total_time_in_millis":1872},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":11,"memory_in_bytes":83924,"terms_memory_in_bytes":73590,"stored_fields_memory_in_bytes":3768,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":704,"points_memory_in_bytes":1618,"doc_values_memory_in_bytes":4244,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":86},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},".kibana":{"primaries":{"docs":{"count":1,"deleted":0},"store":{"size_in_bytes":3967,"throttle_time_in_millis":0},"indexing":{"index_total":1,"index_time_in_millis":2,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":88438,"time_in_millis":2799,"exists_total":88438,"exists_time_in_millis":2799,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":88441,"query_time_in_millis":2287,"query_current":0,"fetch_total":88441,"fetch_time_in_millis":2685,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":20971520},"refresh":{"total":2,"total_time_in_millis":19,"listeners":0},"flush":{"total":1,"total_time_in_millis":7},"warmer":{"current":0,"total":5,"total_time_in_millis":12},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":1,"memory_in_bytes":2219,"terms_memory_in_bytes":1751,"stored_fields_memory_in_bytes":312,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":64,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":92,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":43},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":2,"deleted":0},"store":{"size_in_bytes":7934,"throttle_time_in_millis":0},"indexing":{"index_total":2,"index_time_in_millis":4,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":176883,"time_in_millis":6265,"exists_total":176883,"exists_time_in_millis":6265,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":176879,"query_time_in_millis":4703,"query_current":0,"fetch_total":176879,"fetch_time_in_millis":5860,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":41943040},"refresh":{"total":4,"total_time_in_millis":33,"listeners":0},"flush":{"total":2,"total_time_in_millis":14},"warmer":{"current":0,"total":10,"total_time_in_millis":26},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":2,"memory_in_bytes":4438,"terms_memory_in_bytes":3502,"stored_fields_memory_in_bytes":624,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":128,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":184,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":86},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},".monitoring-es-6-2017.08.15":{"primaries":{"docs":{"count":120970,"deleted":60},"store":{"size_in_bytes":90471073,"throttle_time_in_millis":0},"indexing":{"index_total":207360,"index_time_in_millis":142584,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":1,"query_time_in_millis":85,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":3781,"total_time_in_millis":2188959,"total_docs":19326607,"total_size_in_bytes":15981823826,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":274,"total_auto_throttle_in_bytes":19065018},"refresh":{"total":37364,"total_time_in_millis":337011,"listeners":0},"flush":{"total":1,"total_time_in_millis":67},"warmer":{"current":0,"total":37365,"total_time_in_millis":8943},"query_cache":{"memory_size_in_bytes":0,"total_count":9,"hit_count":0,"miss_count":9,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":9,"memory_in_bytes":297633,"terms_memory_in_bytes":184606,"stored_fields_memory_in_bytes":13736,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":576,"points_memory_in_bytes":31279,"doc_values_memory_in_bytes":67436,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":43},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":241940,"deleted":120},"store":{"size_in_bytes":180988889,"throttle_time_in_millis":0},"indexing":{"index_total":414720,"index_time_in_millis":286230,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":2,"query_time_in_millis":135,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":7561,"total_time_in_millis":4425176,"total_docs":38722769,"total_size_in_bytes":32018268991,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":522,"total_auto_throttle_in_bytes":38130036},"refresh":{"total":74706,"total_time_in_millis":675900,"listeners":0},"flush":{"total":2,"total_time_in_millis":148},"warmer":{"current":0,"total":74710,"total_time_in_millis":18069},"query_cache":{"memory_size_in_bytes":0,"total_count":24,"hit_count":0,"miss_count":24,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":424,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":16,"memory_in_bytes":590531,"terms_memory_in_bytes":362031,"stored_fields_memory_in_bytes":26728,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":1024,"points_memory_in_bytes":62748,"doc_values_memory_in_bytes":138000,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":1502755201903,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":86},"request_cache":{"memory_size_in_bytes":897,"evictions":0,"hit_count":0,"miss_count":1},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},".monitoring-es-6-2017.08.14":{"primaries":{"docs":{"count":24614,"deleted":12},"store":{"size_in_bytes":17680221,"throttle_time_in_millis":0},"indexing":{"index_total":36896,"index_time_in_millis":35441,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":1,"query_time_in_millis":24,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":927,"total_time_in_millis":1245791,"total_docs":11392506,"total_size_in_bytes":8435013687,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":20971520},"refresh":{"total":9432,"total_time_in_millis":90529,"listeners":0},"flush":{"total":1,"total_time_in_millis":25},"warmer":{"current":0,"total":9434,"total_time_in_millis":3098},"query_cache":{"memory_size_in_bytes":0,"total_count":2,"hit_count":0,"miss_count":2,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":7,"memory_in_bytes":83467,"terms_memory_in_bytes":59601,"stored_fields_memory_in_bytes":4040,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":448,"points_memory_in_bytes":7054,"doc_values_memory_in_bytes":12324,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":43},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":49228,"deleted":18},"store":{"size_in_bytes":35172184,"throttle_time_in_millis":0},"indexing":{"index_total":73792,"index_time_in_millis":69939,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":2,"query_time_in_millis":61,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":1853,"total_time_in_millis":2468444,"total_docs":22769560,"total_size_in_bytes":16842830754,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":41943040},"refresh":{"total":18843,"total_time_in_millis":176757,"listeners":0},"flush":{"total":2,"total_time_in_millis":42},"warmer":{"current":0,"total":18847,"total_time_in_millis":5819},"query_cache":{"memory_size_in_bytes":0,"total_count":7,"hit_count":0,"miss_count":7,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":352,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":9,"memory_in_bytes":137869,"terms_memory_in_bytes":97131,"stored_fields_memory_in_bytes":6680,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":576,"points_memory_in_bytes":13662,"doc_values_memory_in_bytes":19820,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":86},"request_cache":{"memory_size_in_bytes":897,"evictions":0,"hit_count":0,"miss_count":1},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},"foo_2":{"primaries":{"docs":{"count":3,"deleted":0},"store":{"size_in_bytes":12138,"throttle_time_in_millis":0},"indexing":{"index_total":3,"index_time_in_millis":4,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":5,"query_time_in_millis":0,"query_current":0,"fetch_total":2,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":104857600},"refresh":{"total":3,"total_time_in_millis":12,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":8,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":3,"memory_in_bytes":7764,"terms_memory_in_bytes":5976,"stored_fields_memory_in_bytes":936,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":576,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":276,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":3,"size_in_bytes":524},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":6,"deleted":0},"store":{"size_in_bytes":24276,"throttle_time_in_millis":0},"indexing":{"index_total":5,"index_time_in_millis":6,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":10,"query_time_in_millis":0,"query_current":0,"fetch_total":5,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":209715200},"refresh":{"total":5,"total_time_in_millis":20,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":16,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":6,"memory_in_bytes":15528,"terms_memory_in_bytes":11952,"stored_fields_memory_in_bytes":1872,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":1152,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":552,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":6,"size_in_bytes":1048},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},"foo_1":{"primaries":{"docs":{"count":2,"deleted":0},"store":{"size_in_bytes":8246,"throttle_time_in_millis":0},"indexing":{"index_total":4,"index_time_in_millis":7,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":7,"query_time_in_millis":8,"query_current":0,"fetch_total":3,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":104857600},"refresh":{"total":4,"total_time_in_millis":18,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":9,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":2,"memory_in_bytes":5176,"terms_memory_in_bytes":3984,"stored_fields_memory_in_bytes":624,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":384,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":184,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":4,"size_in_bytes":609},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":4,"deleted":0},"store":{"size_in_bytes":16492,"throttle_time_in_millis":0},"indexing":{"index_total":7,"index_time_in_millis":13,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":15,"query_time_in_millis":21,"query_current":0,"fetch_total":5,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":209715200},"refresh":{"total":7,"total_time_in_millis":32,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":18,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":4,"memory_in_bytes":10352,"terms_memory_in_bytes":7968,"stored_fields_memory_in_bytes":1248,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":768,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":368,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":8,"size_in_bytes":1218},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}},".monitoring-es-6-2017.08.16":{"primaries":{"docs":{"count":66545,"deleted":76},"store":{"size_in_bytes":50817866,"throttle_time_in_millis":0},"indexing":{"index_total":124865,"index_time_in_millis":72588,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":1,"query_time_in_millis":67,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":1743,"total_time_in_millis":1390969,"total_docs":12009223,"total_size_in_bytes":9837225170,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":20971520},"refresh":{"total":17433,"total_time_in_millis":159668,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":17434,"total_time_in_millis":3982},"query_cache":{"memory_size_in_bytes":0,"total_count":8,"hit_count":0,"miss_count":8,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":8,"memory_in_bytes":202245,"terms_memory_in_bytes":116445,"stored_fields_memory_in_bytes":8288,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":512,"points_memory_in_bytes":18696,"doc_values_memory_in_bytes":58304,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":124865,"size_in_bytes":155465916},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":1},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"total":{"docs":{"count":133090,"deleted":186},"store":{"size_in_bytes":101913059,"throttle_time_in_millis":0},"indexing":{"index_total":249730,"index_time_in_millis":146171,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":2,"query_time_in_millis":143,"query_current":0,"fetch_total":1,"fetch_time_in_millis":1,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":3489,"total_time_in_millis":2748691,"total_docs":23973218,"total_size_in_bytes":19660778820,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":41943040},"refresh":{"total":34871,"total_time_in_millis":321333,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":34873,"total_time_in_millis":7932},"query_cache":{"memory_size_in_bytes":0,"total_count":17,"hit_count":0,"miss_count":17,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":20,"memory_in_bytes":429521,"terms_memory_in_bytes":251138,"stored_fields_memory_in_bytes":17536,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":1280,"points_memory_in_bytes":37815,"doc_values_memory_in_bytes":121752,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":249730,"size_in_bytes":310931832},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":1},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}}}}}`, + tests := []struct { + name string + file string + want string + }{ + { + name: "1.7.6", + file: "1.7.6.json", + want: `# HELP elasticsearch_index_stats_fielddata_evictions_total Total fielddata evictions count + # TYPE elasticsearch_index_stats_fielddata_evictions_total counter + elasticsearch_index_stats_fielddata_evictions_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_fielddata_evictions_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_fielddata_memory_bytes_total Total fielddata memory bytes + # TYPE elasticsearch_index_stats_fielddata_memory_bytes_total counter + elasticsearch_index_stats_fielddata_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_fielddata_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_flush_time_seconds_total Total flush time in seconds + # TYPE elasticsearch_index_stats_flush_time_seconds_total counter + elasticsearch_index_stats_flush_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_flush_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_flush_total Total flush count + # TYPE elasticsearch_index_stats_flush_total counter + elasticsearch_index_stats_flush_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_flush_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_get_time_seconds_total Total get time in seconds + # TYPE elasticsearch_index_stats_get_time_seconds_total counter + elasticsearch_index_stats_get_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_get_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_get_total Total get count + # TYPE elasticsearch_index_stats_get_total counter + elasticsearch_index_stats_get_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_get_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_index_current The number of documents currently being indexed to an index + # TYPE elasticsearch_index_stats_index_current gauge + elasticsearch_index_stats_index_current{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_index_current{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_indexing_delete_time_seconds_total Total indexing delete time in seconds + # TYPE elasticsearch_index_stats_indexing_delete_time_seconds_total counter + elasticsearch_index_stats_indexing_delete_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_delete_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_indexing_delete_total Total indexing delete count + # TYPE elasticsearch_index_stats_indexing_delete_total counter + elasticsearch_index_stats_indexing_delete_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_delete_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_indexing_index_time_seconds_total Total indexing index time in seconds + # TYPE elasticsearch_index_stats_indexing_index_time_seconds_total counter + elasticsearch_index_stats_indexing_index_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0.046 + elasticsearch_index_stats_indexing_index_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0.006 + # HELP elasticsearch_index_stats_indexing_index_total Total indexing index count + # TYPE elasticsearch_index_stats_indexing_index_total counter + elasticsearch_index_stats_indexing_index_total{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_index_stats_indexing_index_total{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_index_stats_indexing_noop_update_total Total indexing no-op update count + # TYPE elasticsearch_index_stats_indexing_noop_update_total counter + elasticsearch_index_stats_indexing_noop_update_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_noop_update_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_indexing_throttle_time_seconds_total Total indexing throttle time in seconds + # TYPE elasticsearch_index_stats_indexing_throttle_time_seconds_total counter + elasticsearch_index_stats_indexing_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_merge_auto_throttle_bytes_total Total bytes that were auto-throttled during merging + # TYPE elasticsearch_index_stats_merge_auto_throttle_bytes_total counter + elasticsearch_index_stats_merge_auto_throttle_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_auto_throttle_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_merge_stopped_time_seconds_total Total large merge stopped time in seconds, allowing smaller merges to complete + # TYPE elasticsearch_index_stats_merge_stopped_time_seconds_total counter + elasticsearch_index_stats_merge_stopped_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_stopped_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_merge_throttle_time_seconds_total Total merge I/O throttle time in seconds + # TYPE elasticsearch_index_stats_merge_throttle_time_seconds_total counter + elasticsearch_index_stats_merge_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_merge_time_seconds_total Total merge time in seconds + # TYPE elasticsearch_index_stats_merge_time_seconds_total counter + elasticsearch_index_stats_merge_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_merge_total Total merge count + # TYPE elasticsearch_index_stats_merge_total counter + elasticsearch_index_stats_merge_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_caches_total Total query cache caches count + # TYPE elasticsearch_index_stats_query_cache_caches_total counter + elasticsearch_index_stats_query_cache_caches_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_caches_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_evictions_total Total query cache evictions count + # TYPE elasticsearch_index_stats_query_cache_evictions_total counter + elasticsearch_index_stats_query_cache_evictions_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_evictions_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_hits_total Total query cache hits count + # TYPE elasticsearch_index_stats_query_cache_hits_total counter + elasticsearch_index_stats_query_cache_hits_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_hits_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_memory_bytes_total Total query cache memory bytes + # TYPE elasticsearch_index_stats_query_cache_memory_bytes_total counter + elasticsearch_index_stats_query_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_misses_total Total query cache misses count + # TYPE elasticsearch_index_stats_query_cache_misses_total counter + elasticsearch_index_stats_query_cache_misses_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_misses_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_size Total query cache size + # TYPE elasticsearch_index_stats_query_cache_size gauge + elasticsearch_index_stats_query_cache_size{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_size{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_refresh_external_time_seconds_total Total external refresh time in seconds + # TYPE elasticsearch_index_stats_refresh_external_time_seconds_total counter + elasticsearch_index_stats_refresh_external_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_refresh_external_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_refresh_external_total Total external refresh count + # TYPE elasticsearch_index_stats_refresh_external_total counter + elasticsearch_index_stats_refresh_external_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_refresh_external_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_refresh_time_seconds_total Total refresh time in seconds + # TYPE elasticsearch_index_stats_refresh_time_seconds_total counter + elasticsearch_index_stats_refresh_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0.125 + elasticsearch_index_stats_refresh_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0.038 + # HELP elasticsearch_index_stats_refresh_total Total refresh count + # TYPE elasticsearch_index_stats_refresh_total counter + elasticsearch_index_stats_refresh_total{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_index_stats_refresh_total{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_index_stats_request_cache_evictions_total Total request cache evictions count + # TYPE elasticsearch_index_stats_request_cache_evictions_total counter + elasticsearch_index_stats_request_cache_evictions_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_evictions_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_request_cache_hits_total Total request cache hits count + # TYPE elasticsearch_index_stats_request_cache_hits_total counter + elasticsearch_index_stats_request_cache_hits_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_hits_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_request_cache_memory_bytes_total Total request cache memory bytes + # TYPE elasticsearch_index_stats_request_cache_memory_bytes_total counter + elasticsearch_index_stats_request_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_request_cache_misses_total Total request cache misses count + # TYPE elasticsearch_index_stats_request_cache_misses_total counter + elasticsearch_index_stats_request_cache_misses_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_misses_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_fetch_time_seconds_total Total search fetch time in seconds + # TYPE elasticsearch_index_stats_search_fetch_time_seconds_total counter + elasticsearch_index_stats_search_fetch_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_fetch_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_fetch_total Total search fetch count + # TYPE elasticsearch_index_stats_search_fetch_total counter + elasticsearch_index_stats_search_fetch_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_fetch_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_query_time_seconds_total Total search query time in seconds + # TYPE elasticsearch_index_stats_search_query_time_seconds_total counter + elasticsearch_index_stats_search_query_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_query_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_query_total Total number of queries + # TYPE elasticsearch_index_stats_search_query_total counter + elasticsearch_index_stats_search_query_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_query_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_scroll_current Current search scroll count + # TYPE elasticsearch_index_stats_search_scroll_current gauge + elasticsearch_index_stats_search_scroll_current{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_scroll_current{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_scroll_time_seconds_total Total search scroll time in seconds + # TYPE elasticsearch_index_stats_search_scroll_time_seconds_total counter + elasticsearch_index_stats_search_scroll_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_scroll_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_scroll_total Total search scroll count + # TYPE elasticsearch_index_stats_search_scroll_total counter + elasticsearch_index_stats_search_scroll_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_scroll_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_suggest_time_seconds_total Total search suggest time in seconds + # TYPE elasticsearch_index_stats_search_suggest_time_seconds_total counter + elasticsearch_index_stats_search_suggest_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_suggest_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_suggest_total Total search suggest count + # TYPE elasticsearch_index_stats_search_suggest_total counter + elasticsearch_index_stats_search_suggest_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_suggest_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_warmer_time_seconds_total Total warmer time in seconds + # TYPE elasticsearch_index_stats_warmer_time_seconds_total counter + elasticsearch_index_stats_warmer_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0.042 + elasticsearch_index_stats_warmer_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_warmer_total Total warmer count + # TYPE elasticsearch_index_stats_warmer_total counter + elasticsearch_index_stats_warmer_total{cluster="unknown_cluster",index="foo_1"} 14 + elasticsearch_index_stats_warmer_total{cluster="unknown_cluster",index="foo_2"} 16 + # HELP elasticsearch_indices_aliases Record aliases associated with an index + # TYPE elasticsearch_indices_aliases gauge + elasticsearch_indices_aliases{alias="foo_alias_2_1",cluster="unknown_cluster",index="foo_2"} 1 + elasticsearch_indices_aliases{alias="foo_alias_3_1",cluster="unknown_cluster",index="foo_3"} 1 + elasticsearch_indices_aliases{alias="foo_alias_3_2",cluster="unknown_cluster",index="foo_3"} 1 + # HELP elasticsearch_indices_completion_bytes_primary Current size of completion with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_completion_bytes_primary gauge + elasticsearch_indices_completion_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_completion_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_completion_bytes_total Current size of completion with all shards on all nodes in bytes + # TYPE elasticsearch_indices_completion_bytes_total gauge + elasticsearch_indices_completion_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_completion_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_deleted_docs_primary Count of deleted documents with only primary shards + # TYPE elasticsearch_indices_deleted_docs_primary gauge + elasticsearch_indices_deleted_docs_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_deleted_docs_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_deleted_docs_total Total count of deleted documents + # TYPE elasticsearch_indices_deleted_docs_total gauge + elasticsearch_indices_deleted_docs_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_deleted_docs_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_docs_primary Count of documents with only primary shards + # TYPE elasticsearch_indices_docs_primary gauge + elasticsearch_indices_docs_primary{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_indices_docs_primary{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_indices_docs_total Total count of documents + # TYPE elasticsearch_indices_docs_total gauge + elasticsearch_indices_docs_total{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_indices_docs_total{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_indices_segment_count_primary Current number of segments with only primary shards on all nodes + # TYPE elasticsearch_indices_segment_count_primary gauge + elasticsearch_indices_segment_count_primary{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_indices_segment_count_primary{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_indices_segment_count_total Current number of segments with all shards on all nodes + # TYPE elasticsearch_indices_segment_count_total gauge + elasticsearch_indices_segment_count_total{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_indices_segment_count_total{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_indices_segment_doc_values_memory_bytes_primary Current size of doc values with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_doc_values_memory_bytes_primary gauge + elasticsearch_indices_segment_doc_values_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_doc_values_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_doc_values_memory_bytes_total Current size of doc values with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_doc_values_memory_bytes_total gauge + elasticsearch_indices_segment_doc_values_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_doc_values_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_fields_memory_bytes_primary Current size of fields with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fields_memory_bytes_primary gauge + elasticsearch_indices_segment_fields_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_fields_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_fields_memory_bytes_total Current size of fields with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fields_memory_bytes_total gauge + elasticsearch_indices_segment_fields_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_fields_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary Current size of fixed bit with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary gauge + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total Current size of fixed bit with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total gauge + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_index_writer_memory_bytes_primary Current size of index writer with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_index_writer_memory_bytes_primary gauge + elasticsearch_indices_segment_index_writer_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_index_writer_memory_bytes_total Current size of index writer with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_index_writer_memory_bytes_total gauge + elasticsearch_indices_segment_index_writer_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_memory_bytes_primary Current size of segments with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_memory_bytes_primary gauge + elasticsearch_indices_segment_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 7364 + elasticsearch_indices_segment_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 11046 + # HELP elasticsearch_indices_segment_memory_bytes_total Current size of segments with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_memory_bytes_total gauge + elasticsearch_indices_segment_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 7364 + elasticsearch_indices_segment_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 11046 + # HELP elasticsearch_indices_segment_norms_memory_bytes_primary Current size of norms with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_norms_memory_bytes_primary gauge + elasticsearch_indices_segment_norms_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_norms_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_norms_memory_bytes_total Current size of norms with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_norms_memory_bytes_total gauge + elasticsearch_indices_segment_norms_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_norms_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_points_memory_bytes_primary Current size of points with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_points_memory_bytes_primary gauge + elasticsearch_indices_segment_points_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_points_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_points_memory_bytes_total Current size of points with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_points_memory_bytes_total gauge + elasticsearch_indices_segment_points_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_points_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_term_vectors_memory_primary_bytes Current size of term vectors with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_term_vectors_memory_primary_bytes gauge + elasticsearch_indices_segment_term_vectors_memory_primary_bytes{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_term_vectors_memory_primary_bytes{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_term_vectors_memory_total_bytes Current size of term vectors with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_term_vectors_memory_total_bytes gauge + elasticsearch_indices_segment_term_vectors_memory_total_bytes{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_term_vectors_memory_total_bytes{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_terms_memory_primary Current size of terms with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_terms_memory_primary gauge + elasticsearch_indices_segment_terms_memory_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_terms_memory_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_terms_memory_total Current number of terms with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_terms_memory_total gauge + elasticsearch_indices_segment_terms_memory_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_terms_memory_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_version_map_memory_bytes_primary Current size of version map with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_version_map_memory_bytes_primary gauge + elasticsearch_indices_segment_version_map_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_version_map_memory_bytes_total Current size of version map with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_version_map_memory_bytes_total gauge + elasticsearch_indices_segment_version_map_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_store_size_bytes_primary Current total size of stored index data in bytes with only primary shards on all nodes + # TYPE elasticsearch_indices_store_size_bytes_primary gauge + elasticsearch_indices_store_size_bytes_primary{cluster="unknown_cluster",index="foo_1"} 5591 + elasticsearch_indices_store_size_bytes_primary{cluster="unknown_cluster",index="foo_2"} 8207 + # HELP elasticsearch_indices_store_size_bytes_total Current total size of stored index data in bytes with all shards on all nodes + # TYPE elasticsearch_indices_store_size_bytes_total gauge + elasticsearch_indices_store_size_bytes_total{cluster="unknown_cluster",index="foo_1"} 5591 + elasticsearch_indices_store_size_bytes_total{cluster="unknown_cluster",index="foo_2"} 8207 + # HELP elasticsearch_search_active_queries The number of currently active queries + # TYPE elasticsearch_search_active_queries gauge + elasticsearch_search_active_queries{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_search_active_queries{cluster="unknown_cluster",index="foo_2"} 0 +`, + }, + { + name: "2.4.5", + file: "2.4.5.json", + want: `# HELP elasticsearch_index_stats_fielddata_evictions_total Total fielddata evictions count + # TYPE elasticsearch_index_stats_fielddata_evictions_total counter + elasticsearch_index_stats_fielddata_evictions_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_fielddata_evictions_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_fielddata_memory_bytes_total Total fielddata memory bytes + # TYPE elasticsearch_index_stats_fielddata_memory_bytes_total counter + elasticsearch_index_stats_fielddata_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_fielddata_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_flush_time_seconds_total Total flush time in seconds + # TYPE elasticsearch_index_stats_flush_time_seconds_total counter + elasticsearch_index_stats_flush_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_flush_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_flush_total Total flush count + # TYPE elasticsearch_index_stats_flush_total counter + elasticsearch_index_stats_flush_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_flush_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_get_time_seconds_total Total get time in seconds + # TYPE elasticsearch_index_stats_get_time_seconds_total counter + elasticsearch_index_stats_get_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_get_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_get_total Total get count + # TYPE elasticsearch_index_stats_get_total counter + elasticsearch_index_stats_get_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_get_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_index_current The number of documents currently being indexed to an index + # TYPE elasticsearch_index_stats_index_current gauge + elasticsearch_index_stats_index_current{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_index_current{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_indexing_delete_time_seconds_total Total indexing delete time in seconds + # TYPE elasticsearch_index_stats_indexing_delete_time_seconds_total counter + elasticsearch_index_stats_indexing_delete_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_delete_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_indexing_delete_total Total indexing delete count + # TYPE elasticsearch_index_stats_indexing_delete_total counter + elasticsearch_index_stats_indexing_delete_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_delete_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_indexing_index_time_seconds_total Total indexing index time in seconds + # TYPE elasticsearch_index_stats_indexing_index_time_seconds_total counter + elasticsearch_index_stats_indexing_index_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0.034 + elasticsearch_index_stats_indexing_index_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0.006 + # HELP elasticsearch_index_stats_indexing_index_total Total indexing index count + # TYPE elasticsearch_index_stats_indexing_index_total counter + elasticsearch_index_stats_indexing_index_total{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_index_stats_indexing_index_total{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_index_stats_indexing_noop_update_total Total indexing no-op update count + # TYPE elasticsearch_index_stats_indexing_noop_update_total counter + elasticsearch_index_stats_indexing_noop_update_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_noop_update_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_indexing_throttle_time_seconds_total Total indexing throttle time in seconds + # TYPE elasticsearch_index_stats_indexing_throttle_time_seconds_total counter + elasticsearch_index_stats_indexing_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_merge_auto_throttle_bytes_total Total bytes that were auto-throttled during merging + # TYPE elasticsearch_index_stats_merge_auto_throttle_bytes_total counter + elasticsearch_index_stats_merge_auto_throttle_bytes_total{cluster="unknown_cluster",index="foo_1"} 1.048576e+08 + elasticsearch_index_stats_merge_auto_throttle_bytes_total{cluster="unknown_cluster",index="foo_2"} 1.048576e+08 + # HELP elasticsearch_index_stats_merge_stopped_time_seconds_total Total large merge stopped time in seconds, allowing smaller merges to complete + # TYPE elasticsearch_index_stats_merge_stopped_time_seconds_total counter + elasticsearch_index_stats_merge_stopped_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_stopped_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_merge_throttle_time_seconds_total Total merge I/O throttle time in seconds + # TYPE elasticsearch_index_stats_merge_throttle_time_seconds_total counter + elasticsearch_index_stats_merge_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_merge_time_seconds_total Total merge time in seconds + # TYPE elasticsearch_index_stats_merge_time_seconds_total counter + elasticsearch_index_stats_merge_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_merge_total Total merge count + # TYPE elasticsearch_index_stats_merge_total counter + elasticsearch_index_stats_merge_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_caches_total Total query cache caches count + # TYPE elasticsearch_index_stats_query_cache_caches_total counter + elasticsearch_index_stats_query_cache_caches_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_caches_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_evictions_total Total query cache evictions count + # TYPE elasticsearch_index_stats_query_cache_evictions_total counter + elasticsearch_index_stats_query_cache_evictions_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_evictions_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_hits_total Total query cache hits count + # TYPE elasticsearch_index_stats_query_cache_hits_total counter + elasticsearch_index_stats_query_cache_hits_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_hits_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_memory_bytes_total Total query cache memory bytes + # TYPE elasticsearch_index_stats_query_cache_memory_bytes_total counter + elasticsearch_index_stats_query_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_misses_total Total query cache misses count + # TYPE elasticsearch_index_stats_query_cache_misses_total counter + elasticsearch_index_stats_query_cache_misses_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_misses_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_size Total query cache size + # TYPE elasticsearch_index_stats_query_cache_size gauge + elasticsearch_index_stats_query_cache_size{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_size{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_refresh_external_time_seconds_total Total external refresh time in seconds + # TYPE elasticsearch_index_stats_refresh_external_time_seconds_total counter + elasticsearch_index_stats_refresh_external_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_refresh_external_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_refresh_external_total Total external refresh count + # TYPE elasticsearch_index_stats_refresh_external_total counter + elasticsearch_index_stats_refresh_external_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_refresh_external_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_refresh_time_seconds_total Total refresh time in seconds + # TYPE elasticsearch_index_stats_refresh_time_seconds_total counter + elasticsearch_index_stats_refresh_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0.137 + elasticsearch_index_stats_refresh_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0.034 + # HELP elasticsearch_index_stats_refresh_total Total refresh count + # TYPE elasticsearch_index_stats_refresh_total counter + elasticsearch_index_stats_refresh_total{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_index_stats_refresh_total{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_index_stats_request_cache_evictions_total Total request cache evictions count + # TYPE elasticsearch_index_stats_request_cache_evictions_total counter + elasticsearch_index_stats_request_cache_evictions_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_evictions_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_request_cache_hits_total Total request cache hits count + # TYPE elasticsearch_index_stats_request_cache_hits_total counter + elasticsearch_index_stats_request_cache_hits_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_hits_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_request_cache_memory_bytes_total Total request cache memory bytes + # TYPE elasticsearch_index_stats_request_cache_memory_bytes_total counter + elasticsearch_index_stats_request_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_request_cache_misses_total Total request cache misses count + # TYPE elasticsearch_index_stats_request_cache_misses_total counter + elasticsearch_index_stats_request_cache_misses_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_misses_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_fetch_time_seconds_total Total search fetch time in seconds + # TYPE elasticsearch_index_stats_search_fetch_time_seconds_total counter + elasticsearch_index_stats_search_fetch_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_fetch_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_fetch_total Total search fetch count + # TYPE elasticsearch_index_stats_search_fetch_total counter + elasticsearch_index_stats_search_fetch_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_fetch_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_query_time_seconds_total Total search query time in seconds + # TYPE elasticsearch_index_stats_search_query_time_seconds_total counter + elasticsearch_index_stats_search_query_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_query_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_query_total Total number of queries + # TYPE elasticsearch_index_stats_search_query_total counter + elasticsearch_index_stats_search_query_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_query_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_scroll_current Current search scroll count + # TYPE elasticsearch_index_stats_search_scroll_current gauge + elasticsearch_index_stats_search_scroll_current{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_scroll_current{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_scroll_time_seconds_total Total search scroll time in seconds + # TYPE elasticsearch_index_stats_search_scroll_time_seconds_total counter + elasticsearch_index_stats_search_scroll_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_scroll_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_scroll_total Total search scroll count + # TYPE elasticsearch_index_stats_search_scroll_total counter + elasticsearch_index_stats_search_scroll_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_scroll_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_suggest_time_seconds_total Total search suggest time in seconds + # TYPE elasticsearch_index_stats_search_suggest_time_seconds_total counter + elasticsearch_index_stats_search_suggest_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_suggest_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_suggest_total Total search suggest count + # TYPE elasticsearch_index_stats_search_suggest_total counter + elasticsearch_index_stats_search_suggest_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_suggest_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_warmer_time_seconds_total Total warmer time in seconds + # TYPE elasticsearch_index_stats_warmer_time_seconds_total counter + elasticsearch_index_stats_warmer_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0.012 + elasticsearch_index_stats_warmer_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_warmer_total Total warmer count + # TYPE elasticsearch_index_stats_warmer_total counter + elasticsearch_index_stats_warmer_total{cluster="unknown_cluster",index="foo_1"} 14 + elasticsearch_index_stats_warmer_total{cluster="unknown_cluster",index="foo_2"} 16 + # HELP elasticsearch_indices_aliases Record aliases associated with an index + # TYPE elasticsearch_indices_aliases gauge + elasticsearch_indices_aliases{alias="foo_alias_2_1",cluster="unknown_cluster",index="foo_2"} 1 + elasticsearch_indices_aliases{alias="foo_alias_3_1",cluster="unknown_cluster",index="foo_3"} 1 + elasticsearch_indices_aliases{alias="foo_alias_3_2",cluster="unknown_cluster",index="foo_3"} 1 + # HELP elasticsearch_indices_completion_bytes_primary Current size of completion with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_completion_bytes_primary gauge + elasticsearch_indices_completion_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_completion_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_completion_bytes_total Current size of completion with all shards on all nodes in bytes + # TYPE elasticsearch_indices_completion_bytes_total gauge + elasticsearch_indices_completion_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_completion_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_deleted_docs_primary Count of deleted documents with only primary shards + # TYPE elasticsearch_indices_deleted_docs_primary gauge + elasticsearch_indices_deleted_docs_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_deleted_docs_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_deleted_docs_total Total count of deleted documents + # TYPE elasticsearch_indices_deleted_docs_total gauge + elasticsearch_indices_deleted_docs_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_deleted_docs_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_docs_primary Count of documents with only primary shards + # TYPE elasticsearch_indices_docs_primary gauge + elasticsearch_indices_docs_primary{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_indices_docs_primary{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_indices_docs_total Total count of documents + # TYPE elasticsearch_indices_docs_total gauge + elasticsearch_indices_docs_total{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_indices_docs_total{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_indices_segment_count_primary Current number of segments with only primary shards on all nodes + # TYPE elasticsearch_indices_segment_count_primary gauge + elasticsearch_indices_segment_count_primary{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_indices_segment_count_primary{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_indices_segment_count_total Current number of segments with all shards on all nodes + # TYPE elasticsearch_indices_segment_count_total gauge + elasticsearch_indices_segment_count_total{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_indices_segment_count_total{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_indices_segment_doc_values_memory_bytes_primary Current size of doc values with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_doc_values_memory_bytes_primary gauge + elasticsearch_indices_segment_doc_values_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 184 + elasticsearch_indices_segment_doc_values_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 276 + # HELP elasticsearch_indices_segment_doc_values_memory_bytes_total Current size of doc values with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_doc_values_memory_bytes_total gauge + elasticsearch_indices_segment_doc_values_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 184 + elasticsearch_indices_segment_doc_values_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 276 + # HELP elasticsearch_indices_segment_fields_memory_bytes_primary Current size of fields with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fields_memory_bytes_primary gauge + elasticsearch_indices_segment_fields_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 624 + elasticsearch_indices_segment_fields_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 936 + # HELP elasticsearch_indices_segment_fields_memory_bytes_total Current size of fields with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fields_memory_bytes_total gauge + elasticsearch_indices_segment_fields_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 624 + elasticsearch_indices_segment_fields_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 936 + # HELP elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary Current size of fixed bit with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary gauge + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total Current size of fixed bit with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total gauge + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_index_writer_memory_bytes_primary Current size of index writer with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_index_writer_memory_bytes_primary gauge + elasticsearch_indices_segment_index_writer_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_index_writer_memory_bytes_total Current size of index writer with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_index_writer_memory_bytes_total gauge + elasticsearch_indices_segment_index_writer_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_memory_bytes_primary Current size of segments with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_memory_bytes_primary gauge + elasticsearch_indices_segment_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 4212 + elasticsearch_indices_segment_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 6318 + # HELP elasticsearch_indices_segment_memory_bytes_total Current size of segments with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_memory_bytes_total gauge + elasticsearch_indices_segment_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 4212 + elasticsearch_indices_segment_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 6318 + # HELP elasticsearch_indices_segment_norms_memory_bytes_primary Current size of norms with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_norms_memory_bytes_primary gauge + elasticsearch_indices_segment_norms_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 384 + elasticsearch_indices_segment_norms_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 576 + # HELP elasticsearch_indices_segment_norms_memory_bytes_total Current size of norms with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_norms_memory_bytes_total gauge + elasticsearch_indices_segment_norms_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 384 + elasticsearch_indices_segment_norms_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 576 + # HELP elasticsearch_indices_segment_points_memory_bytes_primary Current size of points with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_points_memory_bytes_primary gauge + elasticsearch_indices_segment_points_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_points_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_points_memory_bytes_total Current size of points with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_points_memory_bytes_total gauge + elasticsearch_indices_segment_points_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_points_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_term_vectors_memory_primary_bytes Current size of term vectors with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_term_vectors_memory_primary_bytes gauge + elasticsearch_indices_segment_term_vectors_memory_primary_bytes{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_term_vectors_memory_primary_bytes{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_term_vectors_memory_total_bytes Current size of term vectors with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_term_vectors_memory_total_bytes gauge + elasticsearch_indices_segment_term_vectors_memory_total_bytes{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_term_vectors_memory_total_bytes{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_terms_memory_primary Current size of terms with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_terms_memory_primary gauge + elasticsearch_indices_segment_terms_memory_primary{cluster="unknown_cluster",index="foo_1"} 3020 + elasticsearch_indices_segment_terms_memory_primary{cluster="unknown_cluster",index="foo_2"} 4530 + # HELP elasticsearch_indices_segment_terms_memory_total Current number of terms with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_terms_memory_total gauge + elasticsearch_indices_segment_terms_memory_total{cluster="unknown_cluster",index="foo_1"} 3020 + elasticsearch_indices_segment_terms_memory_total{cluster="unknown_cluster",index="foo_2"} 4530 + # HELP elasticsearch_indices_segment_version_map_memory_bytes_primary Current size of version map with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_version_map_memory_bytes_primary gauge + elasticsearch_indices_segment_version_map_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_version_map_memory_bytes_total Current size of version map with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_version_map_memory_bytes_total gauge + elasticsearch_indices_segment_version_map_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_store_size_bytes_primary Current total size of stored index data in bytes with only primary shards on all nodes + # TYPE elasticsearch_indices_store_size_bytes_primary gauge + elasticsearch_indices_store_size_bytes_primary{cluster="unknown_cluster",index="foo_1"} 260 + elasticsearch_indices_store_size_bytes_primary{cluster="unknown_cluster",index="foo_2"} 3350 + # HELP elasticsearch_indices_store_size_bytes_total Current total size of stored index data in bytes with all shards on all nodes + # TYPE elasticsearch_indices_store_size_bytes_total gauge + elasticsearch_indices_store_size_bytes_total{cluster="unknown_cluster",index="foo_1"} 260 + elasticsearch_indices_store_size_bytes_total{cluster="unknown_cluster",index="foo_2"} 3350 + # HELP elasticsearch_search_active_queries The number of currently active queries + # TYPE elasticsearch_search_active_queries gauge + elasticsearch_search_active_queries{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_search_active_queries{cluster="unknown_cluster",index="foo_2"} 0 + +`, + }, + { + name: "5.4.2", + file: "5.4.2.json", + want: `# HELP elasticsearch_index_stats_fielddata_evictions_total Total fielddata evictions count + # TYPE elasticsearch_index_stats_fielddata_evictions_total counter + elasticsearch_index_stats_fielddata_evictions_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_fielddata_evictions_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_fielddata_evictions_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_fielddata_evictions_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_fielddata_evictions_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_fielddata_memory_bytes_total Total fielddata memory bytes + # TYPE elasticsearch_index_stats_fielddata_memory_bytes_total counter + elasticsearch_index_stats_fielddata_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_fielddata_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_fielddata_memory_bytes_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_fielddata_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_fielddata_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_flush_time_seconds_total Total flush time in seconds + # TYPE elasticsearch_index_stats_flush_time_seconds_total counter + elasticsearch_index_stats_flush_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_flush_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_flush_time_seconds_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_flush_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_flush_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_flush_total Total flush count + # TYPE elasticsearch_index_stats_flush_total counter + elasticsearch_index_stats_flush_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_flush_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_flush_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_flush_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_flush_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_get_time_seconds_total Total get time in seconds + # TYPE elasticsearch_index_stats_get_time_seconds_total counter + elasticsearch_index_stats_get_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_get_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_get_time_seconds_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_get_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_get_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_get_total Total get count + # TYPE elasticsearch_index_stats_get_total counter + elasticsearch_index_stats_get_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_get_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_get_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_get_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_get_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_index_current The number of documents currently being indexed to an index + # TYPE elasticsearch_index_stats_index_current gauge + elasticsearch_index_stats_index_current{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_index_current{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_index_current{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_index_current{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_index_current{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_indexing_delete_time_seconds_total Total indexing delete time in seconds + # TYPE elasticsearch_index_stats_indexing_delete_time_seconds_total counter + elasticsearch_index_stats_indexing_delete_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_indexing_delete_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_indexing_delete_time_seconds_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_indexing_delete_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_delete_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_indexing_delete_total Total indexing delete count + # TYPE elasticsearch_index_stats_indexing_delete_total counter + elasticsearch_index_stats_indexing_delete_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_indexing_delete_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_indexing_delete_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_indexing_delete_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_delete_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_indexing_index_time_seconds_total Total indexing index time in seconds + # TYPE elasticsearch_index_stats_indexing_index_time_seconds_total counter + elasticsearch_index_stats_indexing_index_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0.013 + elasticsearch_index_stats_indexing_index_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0.106 + elasticsearch_index_stats_indexing_index_time_seconds_total{cluster="unknown_cluster",index=".watches"} 1.421 + elasticsearch_index_stats_indexing_index_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0.046 + elasticsearch_index_stats_indexing_index_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0.012 + # HELP elasticsearch_index_stats_indexing_index_total Total indexing index count + # TYPE elasticsearch_index_stats_indexing_index_total counter + elasticsearch_index_stats_indexing_index_total{cluster="unknown_cluster",index=".monitoring-data-2"} 4 + elasticsearch_index_stats_indexing_index_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 65 + elasticsearch_index_stats_indexing_index_total{cluster="unknown_cluster",index=".watches"} 4 + elasticsearch_index_stats_indexing_index_total{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_index_stats_indexing_index_total{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_index_stats_indexing_noop_update_total Total indexing no-op update count + # TYPE elasticsearch_index_stats_indexing_noop_update_total counter + elasticsearch_index_stats_indexing_noop_update_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_indexing_noop_update_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_indexing_noop_update_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_indexing_noop_update_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_noop_update_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_indexing_throttle_time_seconds_total Total indexing throttle time in seconds + # TYPE elasticsearch_index_stats_indexing_throttle_time_seconds_total counter + elasticsearch_index_stats_indexing_throttle_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_indexing_throttle_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_indexing_throttle_time_seconds_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_indexing_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_merge_auto_throttle_bytes_total Total bytes that were auto-throttled during merging + # TYPE elasticsearch_index_stats_merge_auto_throttle_bytes_total counter + elasticsearch_index_stats_merge_auto_throttle_bytes_total{cluster="unknown_cluster",index=".monitoring-data-2"} 2.097152e+07 + elasticsearch_index_stats_merge_auto_throttle_bytes_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 2.097152e+07 + elasticsearch_index_stats_merge_auto_throttle_bytes_total{cluster="unknown_cluster",index=".watches"} 2.097152e+07 + elasticsearch_index_stats_merge_auto_throttle_bytes_total{cluster="unknown_cluster",index="foo_1"} 1.048576e+08 + elasticsearch_index_stats_merge_auto_throttle_bytes_total{cluster="unknown_cluster",index="foo_2"} 1.048576e+08 + # HELP elasticsearch_index_stats_merge_stopped_time_seconds_total Total large merge stopped time in seconds, allowing smaller merges to complete + # TYPE elasticsearch_index_stats_merge_stopped_time_seconds_total counter + elasticsearch_index_stats_merge_stopped_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_merge_stopped_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_merge_stopped_time_seconds_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_merge_stopped_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_stopped_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_merge_throttle_time_seconds_total Total merge I/O throttle time in seconds + # TYPE elasticsearch_index_stats_merge_throttle_time_seconds_total counter + elasticsearch_index_stats_merge_throttle_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_merge_throttle_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_merge_throttle_time_seconds_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_merge_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_merge_time_seconds_total Total merge time in seconds + # TYPE elasticsearch_index_stats_merge_time_seconds_total counter + elasticsearch_index_stats_merge_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_merge_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_merge_time_seconds_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_merge_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_merge_total Total merge count + # TYPE elasticsearch_index_stats_merge_total counter + elasticsearch_index_stats_merge_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_merge_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_merge_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_merge_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_caches_total Total query cache caches count + # TYPE elasticsearch_index_stats_query_cache_caches_total counter + elasticsearch_index_stats_query_cache_caches_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_query_cache_caches_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_query_cache_caches_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_query_cache_caches_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_caches_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_evictions_total Total query cache evictions count + # TYPE elasticsearch_index_stats_query_cache_evictions_total counter + elasticsearch_index_stats_query_cache_evictions_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_query_cache_evictions_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_query_cache_evictions_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_query_cache_evictions_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_evictions_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_hits_total Total query cache hits count + # TYPE elasticsearch_index_stats_query_cache_hits_total counter + elasticsearch_index_stats_query_cache_hits_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_query_cache_hits_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_query_cache_hits_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_query_cache_hits_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_hits_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_memory_bytes_total Total query cache memory bytes + # TYPE elasticsearch_index_stats_query_cache_memory_bytes_total counter + elasticsearch_index_stats_query_cache_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_query_cache_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_query_cache_memory_bytes_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_query_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_misses_total Total query cache misses count + # TYPE elasticsearch_index_stats_query_cache_misses_total counter + elasticsearch_index_stats_query_cache_misses_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_query_cache_misses_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_query_cache_misses_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_query_cache_misses_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_misses_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_query_cache_size Total query cache size + # TYPE elasticsearch_index_stats_query_cache_size gauge + elasticsearch_index_stats_query_cache_size{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_query_cache_size{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_query_cache_size{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_query_cache_size{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_size{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_refresh_external_time_seconds_total Total external refresh time in seconds + # TYPE elasticsearch_index_stats_refresh_external_time_seconds_total counter + elasticsearch_index_stats_refresh_external_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_refresh_external_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_refresh_external_time_seconds_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_refresh_external_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_refresh_external_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_refresh_external_total Total external refresh count + # TYPE elasticsearch_index_stats_refresh_external_total counter + elasticsearch_index_stats_refresh_external_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_refresh_external_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_refresh_external_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_refresh_external_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_refresh_external_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_refresh_time_seconds_total Total refresh time in seconds + # TYPE elasticsearch_index_stats_refresh_time_seconds_total counter + elasticsearch_index_stats_refresh_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0.074 + elasticsearch_index_stats_refresh_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0.39 + elasticsearch_index_stats_refresh_time_seconds_total{cluster="unknown_cluster",index=".watches"} 0.771 + elasticsearch_index_stats_refresh_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0.084 + elasticsearch_index_stats_refresh_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0.042 + # HELP elasticsearch_index_stats_refresh_total Total refresh count + # TYPE elasticsearch_index_stats_refresh_total counter + elasticsearch_index_stats_refresh_total{cluster="unknown_cluster",index=".monitoring-data-2"} 2 + elasticsearch_index_stats_refresh_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 3 + elasticsearch_index_stats_refresh_total{cluster="unknown_cluster",index=".watches"} 5 + elasticsearch_index_stats_refresh_total{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_index_stats_refresh_total{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_index_stats_request_cache_evictions_total Total request cache evictions count + # TYPE elasticsearch_index_stats_request_cache_evictions_total counter + elasticsearch_index_stats_request_cache_evictions_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_request_cache_evictions_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_request_cache_evictions_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_request_cache_evictions_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_evictions_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_request_cache_hits_total Total request cache hits count + # TYPE elasticsearch_index_stats_request_cache_hits_total counter + elasticsearch_index_stats_request_cache_hits_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_request_cache_hits_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_request_cache_hits_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_request_cache_hits_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_hits_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_request_cache_memory_bytes_total Total request cache memory bytes + # TYPE elasticsearch_index_stats_request_cache_memory_bytes_total counter + elasticsearch_index_stats_request_cache_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_request_cache_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_request_cache_memory_bytes_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_request_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_request_cache_misses_total Total request cache misses count + # TYPE elasticsearch_index_stats_request_cache_misses_total counter + elasticsearch_index_stats_request_cache_misses_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_request_cache_misses_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_request_cache_misses_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_request_cache_misses_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_misses_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_fetch_time_seconds_total Total search fetch time in seconds + # TYPE elasticsearch_index_stats_search_fetch_time_seconds_total counter + elasticsearch_index_stats_search_fetch_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_search_fetch_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_search_fetch_time_seconds_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_search_fetch_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_fetch_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_fetch_total Total search fetch count + # TYPE elasticsearch_index_stats_search_fetch_total counter + elasticsearch_index_stats_search_fetch_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_search_fetch_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_search_fetch_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_search_fetch_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_fetch_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_query_time_seconds_total Total search query time in seconds + # TYPE elasticsearch_index_stats_search_query_time_seconds_total counter + elasticsearch_index_stats_search_query_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_search_query_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_search_query_time_seconds_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_search_query_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_query_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_query_total Total number of queries + # TYPE elasticsearch_index_stats_search_query_total counter + elasticsearch_index_stats_search_query_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_search_query_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_search_query_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_search_query_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_query_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_scroll_current Current search scroll count + # TYPE elasticsearch_index_stats_search_scroll_current gauge + elasticsearch_index_stats_search_scroll_current{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_search_scroll_current{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_search_scroll_current{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_search_scroll_current{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_scroll_current{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_scroll_time_seconds_total Total search scroll time in seconds + # TYPE elasticsearch_index_stats_search_scroll_time_seconds_total counter + elasticsearch_index_stats_search_scroll_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_search_scroll_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_search_scroll_time_seconds_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_search_scroll_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_scroll_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_scroll_total Total search scroll count + # TYPE elasticsearch_index_stats_search_scroll_total counter + elasticsearch_index_stats_search_scroll_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_search_scroll_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_search_scroll_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_search_scroll_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_scroll_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_suggest_time_seconds_total Total search suggest time in seconds + # TYPE elasticsearch_index_stats_search_suggest_time_seconds_total counter + elasticsearch_index_stats_search_suggest_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_search_suggest_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_search_suggest_time_seconds_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_search_suggest_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_suggest_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_search_suggest_total Total search suggest count + # TYPE elasticsearch_index_stats_search_suggest_total counter + elasticsearch_index_stats_search_suggest_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_index_stats_search_suggest_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_index_stats_search_suggest_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_index_stats_search_suggest_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_suggest_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_index_stats_warmer_time_seconds_total Total warmer time in seconds + # TYPE elasticsearch_index_stats_warmer_time_seconds_total counter + elasticsearch_index_stats_warmer_time_seconds_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0.002 + elasticsearch_index_stats_warmer_time_seconds_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0.015 + elasticsearch_index_stats_warmer_time_seconds_total{cluster="unknown_cluster",index=".watches"} 0.009 + elasticsearch_index_stats_warmer_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0.094 + elasticsearch_index_stats_warmer_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0.004 + # HELP elasticsearch_index_stats_warmer_total Total warmer count + # TYPE elasticsearch_index_stats_warmer_total counter + elasticsearch_index_stats_warmer_total{cluster="unknown_cluster",index=".monitoring-data-2"} 3 + elasticsearch_index_stats_warmer_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 4 + elasticsearch_index_stats_warmer_total{cluster="unknown_cluster",index=".watches"} 4 + elasticsearch_index_stats_warmer_total{cluster="unknown_cluster",index="foo_1"} 7 + elasticsearch_index_stats_warmer_total{cluster="unknown_cluster",index="foo_2"} 8 + # HELP elasticsearch_indices_aliases Record aliases associated with an index + # TYPE elasticsearch_indices_aliases gauge + elasticsearch_indices_aliases{alias="foo_alias_2_1",cluster="unknown_cluster",index="foo_2"} 1 + elasticsearch_indices_aliases{alias="foo_alias_3_1",cluster="unknown_cluster",index="foo_3"} 1 + elasticsearch_indices_aliases{alias="foo_alias_3_2",cluster="unknown_cluster",index="foo_3"} 1 + # HELP elasticsearch_indices_completion_bytes_primary Current size of completion with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_completion_bytes_primary gauge + elasticsearch_indices_completion_bytes_primary{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_completion_bytes_primary{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_indices_completion_bytes_primary{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_indices_completion_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_completion_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_completion_bytes_total Current size of completion with all shards on all nodes in bytes + # TYPE elasticsearch_indices_completion_bytes_total gauge + elasticsearch_indices_completion_bytes_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_completion_bytes_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_indices_completion_bytes_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_indices_completion_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_completion_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_deleted_docs_primary Count of deleted documents with only primary shards + # TYPE elasticsearch_indices_deleted_docs_primary gauge + elasticsearch_indices_deleted_docs_primary{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_deleted_docs_primary{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_indices_deleted_docs_primary{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_indices_deleted_docs_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_deleted_docs_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_deleted_docs_total Total count of deleted documents + # TYPE elasticsearch_indices_deleted_docs_total gauge + elasticsearch_indices_deleted_docs_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_deleted_docs_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_indices_deleted_docs_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_indices_deleted_docs_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_deleted_docs_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_docs_primary Count of documents with only primary shards + # TYPE elasticsearch_indices_docs_primary gauge + elasticsearch_indices_docs_primary{cluster="unknown_cluster",index=".monitoring-data-2"} 2 + elasticsearch_indices_docs_primary{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 65 + elasticsearch_indices_docs_primary{cluster="unknown_cluster",index=".watches"} 4 + elasticsearch_indices_docs_primary{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_indices_docs_primary{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_indices_docs_total Total count of documents + # TYPE elasticsearch_indices_docs_total gauge + elasticsearch_indices_docs_total{cluster="unknown_cluster",index=".monitoring-data-2"} 2 + elasticsearch_indices_docs_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 65 + elasticsearch_indices_docs_total{cluster="unknown_cluster",index=".watches"} 4 + elasticsearch_indices_docs_total{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_indices_docs_total{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_indices_segment_count_primary Current number of segments with only primary shards on all nodes + # TYPE elasticsearch_indices_segment_count_primary gauge + elasticsearch_indices_segment_count_primary{cluster="unknown_cluster",index=".monitoring-data-2"} 1 + elasticsearch_indices_segment_count_primary{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 3 + elasticsearch_indices_segment_count_primary{cluster="unknown_cluster",index=".watches"} 4 + elasticsearch_indices_segment_count_primary{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_indices_segment_count_primary{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_indices_segment_count_total Current number of segments with all shards on all nodes + # TYPE elasticsearch_indices_segment_count_total gauge + elasticsearch_indices_segment_count_total{cluster="unknown_cluster",index=".monitoring-data-2"} 1 + elasticsearch_indices_segment_count_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 3 + elasticsearch_indices_segment_count_total{cluster="unknown_cluster",index=".watches"} 4 + elasticsearch_indices_segment_count_total{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_indices_segment_count_total{cluster="unknown_cluster",index="foo_2"} 3 + # HELP elasticsearch_indices_segment_doc_values_memory_bytes_primary Current size of doc values with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_doc_values_memory_bytes_primary gauge + elasticsearch_indices_segment_doc_values_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-data-2"} 236 + elasticsearch_indices_segment_doc_values_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 3452 + elasticsearch_indices_segment_doc_values_memory_bytes_primary{cluster="unknown_cluster",index=".watches"} 368 + elasticsearch_indices_segment_doc_values_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 184 + elasticsearch_indices_segment_doc_values_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 276 + # HELP elasticsearch_indices_segment_doc_values_memory_bytes_total Current size of doc values with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_doc_values_memory_bytes_total gauge + elasticsearch_indices_segment_doc_values_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-data-2"} 236 + elasticsearch_indices_segment_doc_values_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 3452 + elasticsearch_indices_segment_doc_values_memory_bytes_total{cluster="unknown_cluster",index=".watches"} 368 + elasticsearch_indices_segment_doc_values_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 184 + elasticsearch_indices_segment_doc_values_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 276 + # HELP elasticsearch_indices_segment_fields_memory_bytes_primary Current size of fields with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fields_memory_bytes_primary gauge + elasticsearch_indices_segment_fields_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-data-2"} 312 + elasticsearch_indices_segment_fields_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 936 + elasticsearch_indices_segment_fields_memory_bytes_primary{cluster="unknown_cluster",index=".watches"} 1248 + elasticsearch_indices_segment_fields_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 624 + elasticsearch_indices_segment_fields_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 936 + # HELP elasticsearch_indices_segment_fields_memory_bytes_total Current size of fields with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fields_memory_bytes_total gauge + elasticsearch_indices_segment_fields_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-data-2"} 312 + elasticsearch_indices_segment_fields_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 936 + elasticsearch_indices_segment_fields_memory_bytes_total{cluster="unknown_cluster",index=".watches"} 1248 + elasticsearch_indices_segment_fields_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 624 + elasticsearch_indices_segment_fields_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 936 + # HELP elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary Current size of fixed bit with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary gauge + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total Current size of fixed bit with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total gauge + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_index_writer_memory_bytes_primary Current size of index writer with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_index_writer_memory_bytes_primary gauge + elasticsearch_indices_segment_index_writer_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_primary{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_index_writer_memory_bytes_total Current size of index writer with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_index_writer_memory_bytes_total gauge + elasticsearch_indices_segment_index_writer_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_memory_bytes_primary Current size of segments with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_memory_bytes_primary gauge + elasticsearch_indices_segment_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-data-2"} 1335 + elasticsearch_indices_segment_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 23830 + elasticsearch_indices_segment_memory_bytes_primary{cluster="unknown_cluster",index=".watches"} 18418 + elasticsearch_indices_segment_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 5176 + elasticsearch_indices_segment_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 7764 + # HELP elasticsearch_indices_segment_memory_bytes_total Current size of segments with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_memory_bytes_total gauge + elasticsearch_indices_segment_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-data-2"} 1335 + elasticsearch_indices_segment_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 23830 + elasticsearch_indices_segment_memory_bytes_total{cluster="unknown_cluster",index=".watches"} 18418 + elasticsearch_indices_segment_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 5176 + elasticsearch_indices_segment_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 7764 + # HELP elasticsearch_indices_segment_norms_memory_bytes_primary Current size of norms with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_norms_memory_bytes_primary gauge + elasticsearch_indices_segment_norms_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_segment_norms_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 320 + elasticsearch_indices_segment_norms_memory_bytes_primary{cluster="unknown_cluster",index=".watches"} 1600 + elasticsearch_indices_segment_norms_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 384 + elasticsearch_indices_segment_norms_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 576 + # HELP elasticsearch_indices_segment_norms_memory_bytes_total Current size of norms with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_norms_memory_bytes_total gauge + elasticsearch_indices_segment_norms_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_segment_norms_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 320 + elasticsearch_indices_segment_norms_memory_bytes_total{cluster="unknown_cluster",index=".watches"} 1600 + elasticsearch_indices_segment_norms_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 384 + elasticsearch_indices_segment_norms_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 576 + # HELP elasticsearch_indices_segment_points_memory_bytes_primary Current size of points with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_points_memory_bytes_primary gauge + elasticsearch_indices_segment_points_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_segment_points_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 648 + elasticsearch_indices_segment_points_memory_bytes_primary{cluster="unknown_cluster",index=".watches"} 4 + elasticsearch_indices_segment_points_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_points_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_points_memory_bytes_total Current size of points with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_points_memory_bytes_total gauge + elasticsearch_indices_segment_points_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_segment_points_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 648 + elasticsearch_indices_segment_points_memory_bytes_total{cluster="unknown_cluster",index=".watches"} 4 + elasticsearch_indices_segment_points_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_points_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_term_vectors_memory_primary_bytes Current size of term vectors with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_term_vectors_memory_primary_bytes gauge + elasticsearch_indices_segment_term_vectors_memory_primary_bytes{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_segment_term_vectors_memory_primary_bytes{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_indices_segment_term_vectors_memory_primary_bytes{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_indices_segment_term_vectors_memory_primary_bytes{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_term_vectors_memory_primary_bytes{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_term_vectors_memory_total_bytes Current size of term vectors with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_term_vectors_memory_total_bytes gauge + elasticsearch_indices_segment_term_vectors_memory_total_bytes{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_segment_term_vectors_memory_total_bytes{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_indices_segment_term_vectors_memory_total_bytes{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_indices_segment_term_vectors_memory_total_bytes{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_term_vectors_memory_total_bytes{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_terms_memory_primary Current size of terms with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_terms_memory_primary gauge + elasticsearch_indices_segment_terms_memory_primary{cluster="unknown_cluster",index=".monitoring-data-2"} 787 + elasticsearch_indices_segment_terms_memory_primary{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 18474 + elasticsearch_indices_segment_terms_memory_primary{cluster="unknown_cluster",index=".watches"} 15198 + elasticsearch_indices_segment_terms_memory_primary{cluster="unknown_cluster",index="foo_1"} 3984 + elasticsearch_indices_segment_terms_memory_primary{cluster="unknown_cluster",index="foo_2"} 5976 + # HELP elasticsearch_indices_segment_terms_memory_total Current number of terms with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_terms_memory_total gauge + elasticsearch_indices_segment_terms_memory_total{cluster="unknown_cluster",index=".monitoring-data-2"} 787 + elasticsearch_indices_segment_terms_memory_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 18474 + elasticsearch_indices_segment_terms_memory_total{cluster="unknown_cluster",index=".watches"} 15198 + elasticsearch_indices_segment_terms_memory_total{cluster="unknown_cluster",index="foo_1"} 3984 + elasticsearch_indices_segment_terms_memory_total{cluster="unknown_cluster",index="foo_2"} 5976 + # HELP elasticsearch_indices_segment_version_map_memory_bytes_primary Current size of version map with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_version_map_memory_bytes_primary gauge + elasticsearch_indices_segment_version_map_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_primary{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_primary{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_segment_version_map_memory_bytes_total Current size of version map with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_version_map_memory_bytes_total gauge + elasticsearch_indices_segment_version_map_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_total{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + # HELP elasticsearch_indices_store_size_bytes_primary Current total size of stored index data in bytes with only primary shards on all nodes + # TYPE elasticsearch_indices_store_size_bytes_primary gauge + elasticsearch_indices_store_size_bytes_primary{cluster="unknown_cluster",index=".monitoring-data-2"} 4226 + elasticsearch_indices_store_size_bytes_primary{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 68917 + elasticsearch_indices_store_size_bytes_primary{cluster="unknown_cluster",index=".watches"} 35444 + elasticsearch_indices_store_size_bytes_primary{cluster="unknown_cluster",index="foo_1"} 8038 + elasticsearch_indices_store_size_bytes_primary{cluster="unknown_cluster",index="foo_2"} 11909 + # HELP elasticsearch_indices_store_size_bytes_total Current total size of stored index data in bytes with all shards on all nodes + # TYPE elasticsearch_indices_store_size_bytes_total gauge + elasticsearch_indices_store_size_bytes_total{cluster="unknown_cluster",index=".monitoring-data-2"} 4226 + elasticsearch_indices_store_size_bytes_total{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 68917 + elasticsearch_indices_store_size_bytes_total{cluster="unknown_cluster",index=".watches"} 35444 + elasticsearch_indices_store_size_bytes_total{cluster="unknown_cluster",index="foo_1"} 8038 + elasticsearch_indices_store_size_bytes_total{cluster="unknown_cluster",index="foo_2"} 11909 + # HELP elasticsearch_search_active_queries The number of currently active queries + # TYPE elasticsearch_search_active_queries gauge + elasticsearch_search_active_queries{cluster="unknown_cluster",index=".monitoring-data-2"} 0 + elasticsearch_search_active_queries{cluster="unknown_cluster",index=".monitoring-es-2-2017.08.23"} 0 + elasticsearch_search_active_queries{cluster="unknown_cluster",index=".watches"} 0 + elasticsearch_search_active_queries{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_search_active_queries{cluster="unknown_cluster",index="foo_2"} 0 + +`, + }, + { + name: "7.17.3", + file: "7.17.3.json", + want: `# HELP elasticsearch_index_stats_fielddata_evictions_total Total fielddata evictions count + # TYPE elasticsearch_index_stats_fielddata_evictions_total counter + elasticsearch_index_stats_fielddata_evictions_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_fielddata_evictions_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_fielddata_evictions_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_fielddata_evictions_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_fielddata_memory_bytes_total Total fielddata memory bytes + # TYPE elasticsearch_index_stats_fielddata_memory_bytes_total counter + elasticsearch_index_stats_fielddata_memory_bytes_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_fielddata_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_fielddata_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_fielddata_memory_bytes_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_flush_time_seconds_total Total flush time in seconds + # TYPE elasticsearch_index_stats_flush_time_seconds_total counter + elasticsearch_index_stats_flush_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0.15 + elasticsearch_index_stats_flush_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_flush_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_flush_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_flush_total Total flush count + # TYPE elasticsearch_index_stats_flush_total counter + elasticsearch_index_stats_flush_total{cluster="unknown_cluster",index=".geoip_databases"} 4 + elasticsearch_index_stats_flush_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_flush_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_flush_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_get_time_seconds_total Total get time in seconds + # TYPE elasticsearch_index_stats_get_time_seconds_total counter + elasticsearch_index_stats_get_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_get_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_get_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_get_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_get_total Total get count + # TYPE elasticsearch_index_stats_get_total counter + elasticsearch_index_stats_get_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_get_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_get_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_get_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_index_current The number of documents currently being indexed to an index + # TYPE elasticsearch_index_stats_index_current gauge + elasticsearch_index_stats_index_current{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_index_current{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_index_current{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_index_current{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_indexing_delete_time_seconds_total Total indexing delete time in seconds + # TYPE elasticsearch_index_stats_indexing_delete_time_seconds_total counter + elasticsearch_index_stats_indexing_delete_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_indexing_delete_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_delete_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_indexing_delete_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_indexing_delete_total Total indexing delete count + # TYPE elasticsearch_index_stats_indexing_delete_total counter + elasticsearch_index_stats_indexing_delete_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_indexing_delete_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_delete_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_indexing_delete_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_indexing_index_time_seconds_total Total indexing index time in seconds + # TYPE elasticsearch_index_stats_indexing_index_time_seconds_total counter + elasticsearch_index_stats_indexing_index_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0.738 + elasticsearch_index_stats_indexing_index_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0.001 + elasticsearch_index_stats_indexing_index_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0.001 + elasticsearch_index_stats_indexing_index_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0.001 + # HELP elasticsearch_index_stats_indexing_index_total Total indexing index count + # TYPE elasticsearch_index_stats_indexing_index_total counter + elasticsearch_index_stats_indexing_index_total{cluster="unknown_cluster",index=".geoip_databases"} 40 + elasticsearch_index_stats_indexing_index_total{cluster="unknown_cluster",index="foo_1"} 1 + elasticsearch_index_stats_indexing_index_total{cluster="unknown_cluster",index="foo_2"} 1 + elasticsearch_index_stats_indexing_index_total{cluster="unknown_cluster",index="foo_3"} 1 + # HELP elasticsearch_index_stats_indexing_noop_update_total Total indexing no-op update count + # TYPE elasticsearch_index_stats_indexing_noop_update_total counter + elasticsearch_index_stats_indexing_noop_update_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_indexing_noop_update_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_noop_update_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_indexing_noop_update_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_indexing_throttle_time_seconds_total Total indexing throttle time in seconds + # TYPE elasticsearch_index_stats_indexing_throttle_time_seconds_total counter + elasticsearch_index_stats_indexing_throttle_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_indexing_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_indexing_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_indexing_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_merge_auto_throttle_bytes_total Total bytes that were auto-throttled during merging + # TYPE elasticsearch_index_stats_merge_auto_throttle_bytes_total counter + elasticsearch_index_stats_merge_auto_throttle_bytes_total{cluster="unknown_cluster",index=".geoip_databases"} 2.097152e+07 + elasticsearch_index_stats_merge_auto_throttle_bytes_total{cluster="unknown_cluster",index="foo_1"} 2.097152e+07 + elasticsearch_index_stats_merge_auto_throttle_bytes_total{cluster="unknown_cluster",index="foo_2"} 2.097152e+07 + elasticsearch_index_stats_merge_auto_throttle_bytes_total{cluster="unknown_cluster",index="foo_3"} 2.097152e+07 + # HELP elasticsearch_index_stats_merge_stopped_time_seconds_total Total large merge stopped time in seconds, allowing smaller merges to complete + # TYPE elasticsearch_index_stats_merge_stopped_time_seconds_total counter + elasticsearch_index_stats_merge_stopped_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_merge_stopped_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_stopped_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_merge_stopped_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_merge_throttle_time_seconds_total Total merge I/O throttle time in seconds + # TYPE elasticsearch_index_stats_merge_throttle_time_seconds_total counter + elasticsearch_index_stats_merge_throttle_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_merge_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_merge_throttle_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_merge_time_seconds_total Total merge time in seconds + # TYPE elasticsearch_index_stats_merge_time_seconds_total counter + elasticsearch_index_stats_merge_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_merge_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_merge_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_merge_total Total merge count + # TYPE elasticsearch_index_stats_merge_total counter + elasticsearch_index_stats_merge_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_merge_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_merge_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_merge_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_query_cache_caches_total Total query cache caches count + # TYPE elasticsearch_index_stats_query_cache_caches_total counter + elasticsearch_index_stats_query_cache_caches_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_query_cache_caches_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_caches_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_query_cache_caches_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_query_cache_evictions_total Total query cache evictions count + # TYPE elasticsearch_index_stats_query_cache_evictions_total counter + elasticsearch_index_stats_query_cache_evictions_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_query_cache_evictions_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_evictions_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_query_cache_evictions_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_query_cache_hits_total Total query cache hits count + # TYPE elasticsearch_index_stats_query_cache_hits_total counter + elasticsearch_index_stats_query_cache_hits_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_query_cache_hits_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_hits_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_query_cache_hits_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_query_cache_memory_bytes_total Total query cache memory bytes + # TYPE elasticsearch_index_stats_query_cache_memory_bytes_total counter + elasticsearch_index_stats_query_cache_memory_bytes_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_query_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_query_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_query_cache_misses_total Total query cache misses count + # TYPE elasticsearch_index_stats_query_cache_misses_total counter + elasticsearch_index_stats_query_cache_misses_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_query_cache_misses_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_misses_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_query_cache_misses_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_query_cache_size Total query cache size + # TYPE elasticsearch_index_stats_query_cache_size gauge + elasticsearch_index_stats_query_cache_size{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_query_cache_size{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_query_cache_size{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_query_cache_size{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_refresh_external_time_seconds_total Total external refresh time in seconds + # TYPE elasticsearch_index_stats_refresh_external_time_seconds_total counter + elasticsearch_index_stats_refresh_external_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0.045 + elasticsearch_index_stats_refresh_external_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0.008 + elasticsearch_index_stats_refresh_external_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0.01 + elasticsearch_index_stats_refresh_external_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0.01 + # HELP elasticsearch_index_stats_refresh_external_total Total external refresh count + # TYPE elasticsearch_index_stats_refresh_external_total counter + elasticsearch_index_stats_refresh_external_total{cluster="unknown_cluster",index=".geoip_databases"} 6 + elasticsearch_index_stats_refresh_external_total{cluster="unknown_cluster",index="foo_1"} 3 + elasticsearch_index_stats_refresh_external_total{cluster="unknown_cluster",index="foo_2"} 3 + elasticsearch_index_stats_refresh_external_total{cluster="unknown_cluster",index="foo_3"} 3 + # HELP elasticsearch_index_stats_refresh_time_seconds_total Total refresh time in seconds + # TYPE elasticsearch_index_stats_refresh_time_seconds_total counter + elasticsearch_index_stats_refresh_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0.05 + elasticsearch_index_stats_refresh_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0.008 + elasticsearch_index_stats_refresh_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0.009 + elasticsearch_index_stats_refresh_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0.009 + # HELP elasticsearch_index_stats_refresh_total Total refresh count + # TYPE elasticsearch_index_stats_refresh_total counter + elasticsearch_index_stats_refresh_total{cluster="unknown_cluster",index=".geoip_databases"} 9 + elasticsearch_index_stats_refresh_total{cluster="unknown_cluster",index="foo_1"} 3 + elasticsearch_index_stats_refresh_total{cluster="unknown_cluster",index="foo_2"} 3 + elasticsearch_index_stats_refresh_total{cluster="unknown_cluster",index="foo_3"} 3 + # HELP elasticsearch_index_stats_request_cache_evictions_total Total request cache evictions count + # TYPE elasticsearch_index_stats_request_cache_evictions_total counter + elasticsearch_index_stats_request_cache_evictions_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_request_cache_evictions_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_evictions_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_request_cache_evictions_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_request_cache_hits_total Total request cache hits count + # TYPE elasticsearch_index_stats_request_cache_hits_total counter + elasticsearch_index_stats_request_cache_hits_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_request_cache_hits_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_hits_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_request_cache_hits_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_request_cache_memory_bytes_total Total request cache memory bytes + # TYPE elasticsearch_index_stats_request_cache_memory_bytes_total counter + elasticsearch_index_stats_request_cache_memory_bytes_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_request_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_request_cache_memory_bytes_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_request_cache_misses_total Total request cache misses count + # TYPE elasticsearch_index_stats_request_cache_misses_total counter + elasticsearch_index_stats_request_cache_misses_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_request_cache_misses_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_request_cache_misses_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_request_cache_misses_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_search_fetch_time_seconds_total Total search fetch time in seconds + # TYPE elasticsearch_index_stats_search_fetch_time_seconds_total counter + elasticsearch_index_stats_search_fetch_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0.096 + elasticsearch_index_stats_search_fetch_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_fetch_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_search_fetch_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_search_fetch_total Total search fetch count + # TYPE elasticsearch_index_stats_search_fetch_total counter + elasticsearch_index_stats_search_fetch_total{cluster="unknown_cluster",index=".geoip_databases"} 43 + elasticsearch_index_stats_search_fetch_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_fetch_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_search_fetch_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_search_query_time_seconds_total Total search query time in seconds + # TYPE elasticsearch_index_stats_search_query_time_seconds_total counter + elasticsearch_index_stats_search_query_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0.071 + elasticsearch_index_stats_search_query_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_query_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_search_query_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_search_query_total Total number of queries + # TYPE elasticsearch_index_stats_search_query_total counter + elasticsearch_index_stats_search_query_total{cluster="unknown_cluster",index=".geoip_databases"} 43 + elasticsearch_index_stats_search_query_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_query_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_search_query_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_search_scroll_current Current search scroll count + # TYPE elasticsearch_index_stats_search_scroll_current gauge + elasticsearch_index_stats_search_scroll_current{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_search_scroll_current{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_scroll_current{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_search_scroll_current{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_search_scroll_time_seconds_total Total search scroll time in seconds + # TYPE elasticsearch_index_stats_search_scroll_time_seconds_total counter + elasticsearch_index_stats_search_scroll_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0.06 + elasticsearch_index_stats_search_scroll_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_scroll_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_search_scroll_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_search_scroll_total Total search scroll count + # TYPE elasticsearch_index_stats_search_scroll_total counter + elasticsearch_index_stats_search_scroll_total{cluster="unknown_cluster",index=".geoip_databases"} 3 + elasticsearch_index_stats_search_scroll_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_scroll_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_search_scroll_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_search_suggest_time_seconds_total Total search suggest time in seconds + # TYPE elasticsearch_index_stats_search_suggest_time_seconds_total counter + elasticsearch_index_stats_search_suggest_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_search_suggest_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_suggest_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_search_suggest_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_search_suggest_total Total search suggest count + # TYPE elasticsearch_index_stats_search_suggest_total counter + elasticsearch_index_stats_search_suggest_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_search_suggest_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_search_suggest_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_search_suggest_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_warmer_time_seconds_total Total warmer time in seconds + # TYPE elasticsearch_index_stats_warmer_time_seconds_total counter + elasticsearch_index_stats_warmer_time_seconds_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_index_stats_warmer_time_seconds_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_index_stats_warmer_time_seconds_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_index_stats_warmer_time_seconds_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_index_stats_warmer_total Total warmer count + # TYPE elasticsearch_index_stats_warmer_total counter + elasticsearch_index_stats_warmer_total{cluster="unknown_cluster",index=".geoip_databases"} 5 + elasticsearch_index_stats_warmer_total{cluster="unknown_cluster",index="foo_1"} 2 + elasticsearch_index_stats_warmer_total{cluster="unknown_cluster",index="foo_2"} 2 + elasticsearch_index_stats_warmer_total{cluster="unknown_cluster",index="foo_3"} 2 + # HELP elasticsearch_indices_aliases Record aliases associated with an index + # TYPE elasticsearch_indices_aliases gauge + elasticsearch_indices_aliases{alias="foo_alias_2_1",cluster="unknown_cluster",index="foo_2"} 1 + elasticsearch_indices_aliases{alias="foo_alias_3_1",cluster="unknown_cluster",index="foo_3"} 1 + elasticsearch_indices_aliases{alias="foo_alias_3_2",cluster="unknown_cluster",index="foo_3"} 1 + # HELP elasticsearch_indices_completion_bytes_primary Current size of completion with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_completion_bytes_primary gauge + elasticsearch_indices_completion_bytes_primary{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_completion_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_completion_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_indices_completion_bytes_primary{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_indices_completion_bytes_total Current size of completion with all shards on all nodes in bytes + # TYPE elasticsearch_indices_completion_bytes_total gauge + elasticsearch_indices_completion_bytes_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_completion_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_completion_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_indices_completion_bytes_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_indices_deleted_docs_primary Count of deleted documents with only primary shards + # TYPE elasticsearch_indices_deleted_docs_primary gauge + elasticsearch_indices_deleted_docs_primary{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_deleted_docs_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_deleted_docs_primary{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_indices_deleted_docs_primary{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_indices_deleted_docs_total Total count of deleted documents + # TYPE elasticsearch_indices_deleted_docs_total gauge + elasticsearch_indices_deleted_docs_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_deleted_docs_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_deleted_docs_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_indices_deleted_docs_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_indices_docs_primary Count of documents with only primary shards + # TYPE elasticsearch_indices_docs_primary gauge + elasticsearch_indices_docs_primary{cluster="unknown_cluster",index=".geoip_databases"} 40 + elasticsearch_indices_docs_primary{cluster="unknown_cluster",index="foo_1"} 1 + elasticsearch_indices_docs_primary{cluster="unknown_cluster",index="foo_2"} 1 + elasticsearch_indices_docs_primary{cluster="unknown_cluster",index="foo_3"} 1 + # HELP elasticsearch_indices_docs_total Total count of documents + # TYPE elasticsearch_indices_docs_total gauge + elasticsearch_indices_docs_total{cluster="unknown_cluster",index=".geoip_databases"} 40 + elasticsearch_indices_docs_total{cluster="unknown_cluster",index="foo_1"} 1 + elasticsearch_indices_docs_total{cluster="unknown_cluster",index="foo_2"} 1 + elasticsearch_indices_docs_total{cluster="unknown_cluster",index="foo_3"} 1 + # HELP elasticsearch_indices_segment_count_primary Current number of segments with only primary shards on all nodes + # TYPE elasticsearch_indices_segment_count_primary gauge + elasticsearch_indices_segment_count_primary{cluster="unknown_cluster",index=".geoip_databases"} 4 + elasticsearch_indices_segment_count_primary{cluster="unknown_cluster",index="foo_1"} 1 + elasticsearch_indices_segment_count_primary{cluster="unknown_cluster",index="foo_2"} 1 + elasticsearch_indices_segment_count_primary{cluster="unknown_cluster",index="foo_3"} 1 + # HELP elasticsearch_indices_segment_count_total Current number of segments with all shards on all nodes + # TYPE elasticsearch_indices_segment_count_total gauge + elasticsearch_indices_segment_count_total{cluster="unknown_cluster",index=".geoip_databases"} 4 + elasticsearch_indices_segment_count_total{cluster="unknown_cluster",index="foo_1"} 1 + elasticsearch_indices_segment_count_total{cluster="unknown_cluster",index="foo_2"} 1 + elasticsearch_indices_segment_count_total{cluster="unknown_cluster",index="foo_3"} 1 + # HELP elasticsearch_indices_segment_doc_values_memory_bytes_primary Current size of doc values with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_doc_values_memory_bytes_primary gauge + elasticsearch_indices_segment_doc_values_memory_bytes_primary{cluster="unknown_cluster",index=".geoip_databases"} 304 + elasticsearch_indices_segment_doc_values_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 76 + elasticsearch_indices_segment_doc_values_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 76 + elasticsearch_indices_segment_doc_values_memory_bytes_primary{cluster="unknown_cluster",index="foo_3"} 76 + # HELP elasticsearch_indices_segment_doc_values_memory_bytes_total Current size of doc values with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_doc_values_memory_bytes_total gauge + elasticsearch_indices_segment_doc_values_memory_bytes_total{cluster="unknown_cluster",index=".geoip_databases"} 304 + elasticsearch_indices_segment_doc_values_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 76 + elasticsearch_indices_segment_doc_values_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 76 + elasticsearch_indices_segment_doc_values_memory_bytes_total{cluster="unknown_cluster",index="foo_3"} 76 + # HELP elasticsearch_indices_segment_fields_memory_bytes_primary Current size of fields with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fields_memory_bytes_primary gauge + elasticsearch_indices_segment_fields_memory_bytes_primary{cluster="unknown_cluster",index=".geoip_databases"} 2016 + elasticsearch_indices_segment_fields_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 488 + elasticsearch_indices_segment_fields_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 488 + elasticsearch_indices_segment_fields_memory_bytes_primary{cluster="unknown_cluster",index="foo_3"} 488 + # HELP elasticsearch_indices_segment_fields_memory_bytes_total Current size of fields with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fields_memory_bytes_total gauge + elasticsearch_indices_segment_fields_memory_bytes_total{cluster="unknown_cluster",index=".geoip_databases"} 2016 + elasticsearch_indices_segment_fields_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 488 + elasticsearch_indices_segment_fields_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 488 + elasticsearch_indices_segment_fields_memory_bytes_total{cluster="unknown_cluster",index="foo_3"} 488 + # HELP elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary Current size of fixed bit with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary gauge + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_primary{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total Current size of fixed bit with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total gauge + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_indices_segment_fixed_bit_set_memory_bytes_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_indices_segment_index_writer_memory_bytes_primary Current size of index writer with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_index_writer_memory_bytes_primary gauge + elasticsearch_indices_segment_index_writer_memory_bytes_primary{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_primary{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_indices_segment_index_writer_memory_bytes_total Current size of index writer with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_index_writer_memory_bytes_total gauge + elasticsearch_indices_segment_index_writer_memory_bytes_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_indices_segment_index_writer_memory_bytes_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_indices_segment_memory_bytes_primary Current size of segments with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_memory_bytes_primary gauge + elasticsearch_indices_segment_memory_bytes_primary{cluster="unknown_cluster",index=".geoip_databases"} 4368 + elasticsearch_indices_segment_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 1876 + elasticsearch_indices_segment_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 1876 + elasticsearch_indices_segment_memory_bytes_primary{cluster="unknown_cluster",index="foo_3"} 1876 + # HELP elasticsearch_indices_segment_memory_bytes_total Current size of segments with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_memory_bytes_total gauge + elasticsearch_indices_segment_memory_bytes_total{cluster="unknown_cluster",index=".geoip_databases"} 4368 + elasticsearch_indices_segment_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 1876 + elasticsearch_indices_segment_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 1876 + elasticsearch_indices_segment_memory_bytes_total{cluster="unknown_cluster",index="foo_3"} 1876 + # HELP elasticsearch_indices_segment_norms_memory_bytes_primary Current size of norms with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_norms_memory_bytes_primary gauge + elasticsearch_indices_segment_norms_memory_bytes_primary{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_segment_norms_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 128 + elasticsearch_indices_segment_norms_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 128 + elasticsearch_indices_segment_norms_memory_bytes_primary{cluster="unknown_cluster",index="foo_3"} 128 + # HELP elasticsearch_indices_segment_norms_memory_bytes_total Current size of norms with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_norms_memory_bytes_total gauge + elasticsearch_indices_segment_norms_memory_bytes_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_segment_norms_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 128 + elasticsearch_indices_segment_norms_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 128 + elasticsearch_indices_segment_norms_memory_bytes_total{cluster="unknown_cluster",index="foo_3"} 128 + # HELP elasticsearch_indices_segment_points_memory_bytes_primary Current size of points with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_points_memory_bytes_primary gauge + elasticsearch_indices_segment_points_memory_bytes_primary{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_segment_points_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_points_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_indices_segment_points_memory_bytes_primary{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_indices_segment_points_memory_bytes_total Current size of points with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_points_memory_bytes_total gauge + elasticsearch_indices_segment_points_memory_bytes_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_segment_points_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_points_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_indices_segment_points_memory_bytes_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_indices_segment_term_vectors_memory_primary_bytes Current size of term vectors with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_term_vectors_memory_primary_bytes gauge + elasticsearch_indices_segment_term_vectors_memory_primary_bytes{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_segment_term_vectors_memory_primary_bytes{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_term_vectors_memory_primary_bytes{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_indices_segment_term_vectors_memory_primary_bytes{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_indices_segment_term_vectors_memory_total_bytes Current size of term vectors with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_term_vectors_memory_total_bytes gauge + elasticsearch_indices_segment_term_vectors_memory_total_bytes{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_segment_term_vectors_memory_total_bytes{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_term_vectors_memory_total_bytes{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_indices_segment_term_vectors_memory_total_bytes{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_indices_segment_terms_memory_primary Current size of terms with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_terms_memory_primary gauge + elasticsearch_indices_segment_terms_memory_primary{cluster="unknown_cluster",index=".geoip_databases"} 2048 + elasticsearch_indices_segment_terms_memory_primary{cluster="unknown_cluster",index="foo_1"} 1184 + elasticsearch_indices_segment_terms_memory_primary{cluster="unknown_cluster",index="foo_2"} 1184 + elasticsearch_indices_segment_terms_memory_primary{cluster="unknown_cluster",index="foo_3"} 1184 + # HELP elasticsearch_indices_segment_terms_memory_total Current number of terms with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_terms_memory_total gauge + elasticsearch_indices_segment_terms_memory_total{cluster="unknown_cluster",index=".geoip_databases"} 2048 + elasticsearch_indices_segment_terms_memory_total{cluster="unknown_cluster",index="foo_1"} 1184 + elasticsearch_indices_segment_terms_memory_total{cluster="unknown_cluster",index="foo_2"} 1184 + elasticsearch_indices_segment_terms_memory_total{cluster="unknown_cluster",index="foo_3"} 1184 + # HELP elasticsearch_indices_segment_version_map_memory_bytes_primary Current size of version map with only primary shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_version_map_memory_bytes_primary gauge + elasticsearch_indices_segment_version_map_memory_bytes_primary{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_primary{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_primary{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_primary{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_indices_segment_version_map_memory_bytes_total Current size of version map with all shards on all nodes in bytes + # TYPE elasticsearch_indices_segment_version_map_memory_bytes_total gauge + elasticsearch_indices_segment_version_map_memory_bytes_total{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_total{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_total{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_indices_segment_version_map_memory_bytes_total{cluster="unknown_cluster",index="foo_3"} 0 + # HELP elasticsearch_indices_store_size_bytes_primary Current total size of stored index data in bytes with only primary shards on all nodes + # TYPE elasticsearch_indices_store_size_bytes_primary gauge + elasticsearch_indices_store_size_bytes_primary{cluster="unknown_cluster",index=".geoip_databases"} 3.9904033e+07 + elasticsearch_indices_store_size_bytes_primary{cluster="unknown_cluster",index="foo_1"} 4413 + elasticsearch_indices_store_size_bytes_primary{cluster="unknown_cluster",index="foo_2"} 4459 + elasticsearch_indices_store_size_bytes_primary{cluster="unknown_cluster",index="foo_3"} 4459 + # HELP elasticsearch_indices_store_size_bytes_total Current total size of stored index data in bytes with all shards on all nodes + # TYPE elasticsearch_indices_store_size_bytes_total gauge + elasticsearch_indices_store_size_bytes_total{cluster="unknown_cluster",index=".geoip_databases"} 3.9904033e+07 + elasticsearch_indices_store_size_bytes_total{cluster="unknown_cluster",index="foo_1"} 4413 + elasticsearch_indices_store_size_bytes_total{cluster="unknown_cluster",index="foo_2"} 4459 + elasticsearch_indices_store_size_bytes_total{cluster="unknown_cluster",index="foo_3"} 4459 + # HELP elasticsearch_search_active_queries The number of currently active queries + # TYPE elasticsearch_search_active_queries gauge + elasticsearch_search_active_queries{cluster="unknown_cluster",index=".geoip_databases"} 0 + elasticsearch_search_active_queries{cluster="unknown_cluster",index="foo_1"} 0 + elasticsearch_search_active_queries{cluster="unknown_cluster",index="foo_2"} 0 + elasticsearch_search_active_queries{cluster="unknown_cluster",index="foo_3"} 0 +`, + }, } - for ver, out := range ti { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, out) - })) - defer ts.Close() - - u, err := url.Parse(ts.URL) - if err != nil { - t.Fatalf("Failed to parse URL: %s", err) - } - i := NewIndices(log.NewNopLogger(), http.DefaultClient, u, false) - stats, err := i.fetchAndDecodeIndexStats() - if err != nil { - t.Fatalf("Failed to fetch or decode indices stats: %s", err) - } - t.Logf("[%s] Index Response: %+v", ver, stats) - if stats.Indices["foo_1"].Primaries.Docs.Count != 2 { - t.Errorf("Wrong number of primary docs") - } - if stats.Indices["foo_1"].Primaries.Store.SizeInBytes == 0 { - t.Errorf("Wrong number of primary store size in bytes") - } - if stats.Indices["foo_1"].Total.Store.SizeInBytes == 0 { - t.Errorf("Wrong number of total store size in bytes") - } - if stats.Indices["foo_1"].Total.Indexing.IndexTimeInMillis == 0 { - t.Errorf("Wrong indexing time recorded") - } - if stats.Indices["foo_1"].Total.Indexing.IndexTotal == 0 { - t.Errorf("Wrong indexing total recorded") - } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fStats, err := os.Open(path.Join("../fixtures/indices/", tt.file)) + if err != nil { + t.Fatal(err) + } + defer fStats.Close() + fAlias, err := os.Open(path.Join("../fixtures/indices/alias/", tt.file)) + if err != nil { + t.Fatal(err) + } + defer fAlias.Close() + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/_all/_stats": + io.Copy(w, fStats) + case "/_alias": + io.Copy(w, fAlias) + default: + http.Error(w, "Not Found", http.StatusNotFound) + } + + })) + defer ts.Close() + + u, err := url.Parse(ts.URL) + if err != nil { + t.Fatal(err) + } + + c := NewIndices(promslog.NewNopLogger(), http.DefaultClient, u, false, true) + if err != nil { + t.Fatal(err) + } + + if err := testutil.CollectAndCompare(c, strings.NewReader(tt.want)); err != nil { + t.Fatal(err) + } + }) } } diff --git a/collector/nodes.go b/collector/nodes.go index 43ffa0e8..2fb07693 100644 --- a/collector/nodes.go +++ b/collector/nodes.go @@ -1,24 +1,45 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector import ( "encoding/json" "fmt" + "io" + "log/slog" "net/http" "net/url" "path" - "github.com/go-kit/kit/log" - "github.com/go-kit/kit/log/level" "github.com/prometheus/client_golang/prometheus" ) func getRoles(node NodeStatsNodeResponse) map[string]bool { // default settings (2.x) and map, which roles to consider roles := map[string]bool{ - "master": false, - "data": false, - "ingest": false, - "client": true, + "master": false, + "data": false, + "data_hot": false, + "data_warm": false, + "data_cold": false, + "data_frozen": false, + "data_content": false, + "ml": false, + "remote_cluster_client": false, + "transform": false, + "ingest": false, + "client": true, } // assumption: a 5.x node has at least one role, otherwise it's a 1.7 or 2.x node if len(node.Roles) > 0 { @@ -48,32 +69,20 @@ func getRoles(node NodeStatsNodeResponse) map[string]bool { return roles } -func createRoleMetric(role string) *nodeMetric { - return &nodeMetric{ - Type: prometheus.GaugeValue, - Desc: prometheus.NewDesc( - prometheus.BuildFQName(namespace, "nodes", "roles"), - "Node roles", - defaultRoleLabels, prometheus.Labels{"role": role}, - ), - Value: func(node NodeStatsNodeResponse) float64 { - return 1.0 - }, - Labels: func(cluster string, node NodeStatsNodeResponse) []string { - return []string{ - cluster, - node.Host, - node.Name, - } - }, - } -} +var ( + nodesRolesMetric = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "nodes", "roles"), + "Node roles", + append(defaultRoleLabels, "role"), nil, + ) +) var ( defaultNodeLabels = []string{"cluster", "host", "name", "es_master_node", "es_data_node", "es_ingest_node", "es_client_node"} defaultRoleLabels = []string{"cluster", "host", "name"} defaultThreadPoolLabels = append(defaultNodeLabels, "type") defaultBreakerLabels = append(defaultNodeLabels, "breaker") + defaultIndexingPressureLabels = []string{"cluster", "host", "name", "indexing_pressure"} defaultFilesystemDataLabels = append(defaultNodeLabels, "mount", "path") defaultFilesystemIODeviceLabels = append(defaultNodeLabels, "device") defaultCacheLabels = append(defaultNodeLabels, "cache") @@ -128,6 +137,13 @@ type breakerMetric struct { Labels func(cluster string, node NodeStatsNodeResponse, breaker string) []string } +type indexingPressureMetric struct { + Type prometheus.ValueType + Desc *prometheus.Desc + Value func(indexingPressureStats NodeStatsIndexingPressureResponse) float64 + Labels func(cluster string, node NodeStatsNodeResponse, indexingPressure string) []string +} + type threadPoolMetric struct { Type prometheus.ValueType Desc *prometheus.Desc @@ -151,25 +167,23 @@ type filesystemIODeviceMetric struct { // Nodes information struct type Nodes struct { - logger log.Logger + logger *slog.Logger client *http.Client url *url.URL all bool node string - up prometheus.Gauge - totalScrapes, jsonParseFailures prometheus.Counter - nodeMetrics []*nodeMetric gcCollectionMetrics []*gcCollectionMetric breakerMetrics []*breakerMetric + indexingPressureMetrics []*indexingPressureMetric threadPoolMetrics []*threadPoolMetric filesystemDataMetrics []*filesystemDataMetric filesystemIODeviceMetrics []*filesystemIODeviceMetric } // NewNodes defines Nodes Prometheus metrics -func NewNodes(logger log.Logger, client *http.Client, url *url.URL, all bool, node string) *Nodes { +func NewNodes(logger *slog.Logger, client *http.Client, url *url.URL, all bool, node string) *Nodes { return &Nodes{ logger: logger, client: client, @@ -177,19 +191,6 @@ func NewNodes(logger log.Logger, client *http.Client, url *url.URL, all bool, no all: all, node: node, - up: prometheus.NewGauge(prometheus.GaugeOpts{ - Name: prometheus.BuildFQName(namespace, "node_stats", "up"), - Help: "Was the last scrape of the ElasticSearch nodes endpoint successful.", - }), - totalScrapes: prometheus.NewCounter(prometheus.CounterOpts{ - Name: prometheus.BuildFQName(namespace, "node_stats", "total_scrapes"), - Help: "Current total ElasticSearch node scrapes.", - }), - jsonParseFailures: prometheus.NewCounter(prometheus.CounterOpts{ - Name: prometheus.BuildFQName(namespace, "node_stats", "json_parse_failures"), - Help: "Number of errors while parsing JSON.", - }), - nodeMetrics: []*nodeMetric{ { Type: prometheus.GaugeValue, @@ -492,7 +493,7 @@ func NewNodes(logger log.Logger, client *http.Client, url *url.URL, all bool, no Labels: defaultNodeLabelValues, }, { - Type: prometheus.CounterValue, + Type: prometheus.GaugeValue, Desc: prometheus.NewDesc( prometheus.BuildFQName(namespace, "indices", "translog_size_in_bytes"), "Total translog size in bytes", @@ -599,6 +600,30 @@ func NewNodes(logger log.Logger, client *http.Client, url *url.URL, all bool, no }, Labels: defaultNodeLabelValues, }, + { + Type: prometheus.CounterValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "indices_refresh", "external_total"), + "Total external refreshes", + defaultNodeLabels, nil, + ), + Value: func(node NodeStatsNodeResponse) float64 { + return float64(node.Indices.Refresh.ExternalTotal) + }, + Labels: defaultNodeLabelValues, + }, + { + Type: prometheus.CounterValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "indices_refresh", "external_time_seconds_total"), + "Total time spent external refreshing in seconds", + defaultNodeLabels, nil, + ), + Value: func(node NodeStatsNodeResponse) float64 { + return float64(node.Indices.Refresh.ExternalTotalTimeInMillis) / 1000 + }, + Labels: defaultNodeLabelValues, + }, { Type: prometheus.CounterValue, Desc: prometheus.NewDesc( @@ -1348,6 +1373,20 @@ func NewNodes(logger log.Logger, client *http.Client, url *url.URL, all bool, no return append(defaultNodeLabelValues(cluster, node), "mapped") }, }, + { + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "jvm", "uptime_seconds"), + "JVM process uptime in seconds", + append(defaultNodeLabels, "type"), nil, + ), + Value: func(node NodeStatsNodeResponse) float64 { + return float64(node.JVM.Uptime) / 1000 + }, + Labels: func(cluster string, node NodeStatsNodeResponse) []string { + return append(defaultNodeLabelValues(cluster, node), "mapped") + }, + }, { Type: prometheus.GaugeValue, Desc: prometheus.NewDesc( @@ -1423,43 +1462,15 @@ func NewNodes(logger log.Logger, client *http.Client, url *url.URL, all bool, no { Type: prometheus.CounterValue, Desc: prometheus.NewDesc( - prometheus.BuildFQName(namespace, "process", "cpu_time_seconds_sum"), + prometheus.BuildFQName(namespace, "process", "cpu_seconds_total"), "Process CPU time in seconds", - append(defaultNodeLabels, "type"), nil, + defaultNodeLabels, nil, ), Value: func(node NodeStatsNodeResponse) float64 { return float64(node.Process.CPU.Total) / 1000 }, Labels: func(cluster string, node NodeStatsNodeResponse) []string { - return append(defaultNodeLabelValues(cluster, node), "total") - }, - }, - { - Type: prometheus.CounterValue, - Desc: prometheus.NewDesc( - prometheus.BuildFQName(namespace, "process", "cpu_time_seconds_sum"), - "Process CPU time in seconds", - append(defaultNodeLabels, "type"), nil, - ), - Value: func(node NodeStatsNodeResponse) float64 { - return float64(node.Process.CPU.Sys) / 1000 - }, - Labels: func(cluster string, node NodeStatsNodeResponse) []string { - return append(defaultNodeLabelValues(cluster, node), "sys") - }, - }, - { - Type: prometheus.CounterValue, - Desc: prometheus.NewDesc( - prometheus.BuildFQName(namespace, "process", "cpu_time_seconds_sum"), - "Process CPU time in seconds", - append(defaultNodeLabels, "type"), nil, - ), - Value: func(node NodeStatsNodeResponse) float64 { - return float64(node.Process.CPU.User) / 1000 - }, - Labels: func(cluster string, node NodeStatsNodeResponse) []string { - return append(defaultNodeLabelValues(cluster, node), "user") + return defaultNodeLabelValues(cluster, node) }, }, { @@ -1599,6 +1610,46 @@ func NewNodes(logger log.Logger, client *http.Client, url *url.URL, all bool, no }, }, }, + indexingPressureMetrics: []*indexingPressureMetric{ + { + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "indexing_pressure", "current_all_in_bytes"), + "Memory consumed, in bytes, by indexing requests in the coordinating, primary, or replica stage.", + defaultIndexingPressureLabels, nil, + ), + Value: func(indexingPressureMem NodeStatsIndexingPressureResponse) float64 { + return float64(indexingPressureMem.Current.AllInBytes) + }, + Labels: func(cluster string, node NodeStatsNodeResponse, indexingPressure string) []string { + return []string{ + cluster, + node.Host, + node.Name, + indexingPressure, + } + }, + }, + { + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "indexing_pressure", "limit_in_bytes"), + "Configured memory limit, in bytes, for the indexing requests", + defaultIndexingPressureLabels, nil, + ), + Value: func(indexingPressureStats NodeStatsIndexingPressureResponse) float64 { + return float64(indexingPressureStats.LimitInBytes) + }, + Labels: func(cluster string, node NodeStatsNodeResponse, indexingPressure string) []string { + return []string{ + cluster, + node.Host, + node.Name, + indexingPressure, + } + }, + }, + }, threadPoolMetrics: []*threadPoolMetric{ { Type: prometheus.CounterValue, @@ -1778,12 +1829,20 @@ func NewNodes(logger log.Logger, client *http.Client, url *url.URL, all bool, no // Describe add metrics descriptions func (c *Nodes) Describe(ch chan<- *prometheus.Desc) { + ch <- nodesRolesMetric + for _, metric := range c.nodeMetrics { ch <- metric.Desc } for _, metric := range c.gcCollectionMetrics { ch <- metric.Desc } + for _, metric := range c.breakerMetrics { + ch <- metric.Desc + } + for _, metric := range c.indexingPressureMetrics { + ch <- metric.Desc + } for _, metric := range c.threadPoolMetrics { ch <- metric.Desc } @@ -1793,9 +1852,6 @@ func (c *Nodes) Describe(ch chan<- *prometheus.Desc) { for _, metric := range c.filesystemIODeviceMetrics { ch <- metric.Desc } - ch <- c.up.Desc() - ch <- c.totalScrapes.Desc() - ch <- c.jsonParseFailures.Desc() } func (c *Nodes) fetchAndDecodeNodeStats() (nodeStatsResponse, error) { @@ -1818,8 +1874,8 @@ func (c *Nodes) fetchAndDecodeNodeStats() (nodeStatsResponse, error) { defer func() { err = res.Body.Close() if err != nil { - _ = level.Warn(c.logger).Log( - "msg", "failed to close http.Client", + c.logger.Warn( + "failed to close http.Client", "err", err, ) } @@ -1829,8 +1885,12 @@ func (c *Nodes) fetchAndDecodeNodeStats() (nodeStatsResponse, error) { return nsr, fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) } - if err := json.NewDecoder(res.Body).Decode(&nsr); err != nil { - c.jsonParseFailures.Inc() + bts, err := io.ReadAll(res.Body) + if err != nil { + return nsr, err + } + + if err := json.Unmarshal(bts, &nsr); err != nil { return nsr, err } return nsr, nil @@ -1838,38 +1898,38 @@ func (c *Nodes) fetchAndDecodeNodeStats() (nodeStatsResponse, error) { // Collect gets nodes metric values func (c *Nodes) Collect(ch chan<- prometheus.Metric) { - c.totalScrapes.Inc() - defer func() { - ch <- c.up - ch <- c.totalScrapes - ch <- c.jsonParseFailures - }() - nodeStatsResp, err := c.fetchAndDecodeNodeStats() if err != nil { - c.up.Set(0) - _ = level.Warn(c.logger).Log( - "msg", "failed to fetch and decode node stats", + c.logger.Warn( + "failed to fetch and decode node stats", "err", err, ) return } - c.up.Set(1) for _, node := range nodeStatsResp.Nodes { // Handle the node labels metric roles := getRoles(node) - for _, role := range []string{"master", "data", "client", "ingest"} { - if roles[role] { - metric := createRoleMetric(role) - ch <- prometheus.MustNewConstMetric( - metric.Desc, - metric.Type, - metric.Value(node), - metric.Labels(nodeStatsResp.ClusterName, node)..., - ) + for role, roleEnabled := range roles { + val := 0.0 + if roleEnabled { + val = 1.0 } + + labels := []string{ + nodeStatsResp.ClusterName, + node.Host, + node.Name, + role, + } + + ch <- prometheus.MustNewConstMetric( + nodesRolesMetric, + prometheus.GaugeValue, + val, + labels..., + ) } for _, metric := range c.nodeMetrics { @@ -1905,6 +1965,18 @@ func (c *Nodes) Collect(ch chan<- prometheus.Metric) { } } + // Indexing Pressure stats + for indexingPressure, ipstats := range node.IndexingPressure { + for _, metric := range c.indexingPressureMetrics { + ch <- prometheus.MustNewConstMetric( + metric.Desc, + metric.Type, + metric.Value(ipstats), + metric.Labels(nodeStatsResp.ClusterName, node, indexingPressure)..., + ) + } + } + // Thread Pool stats for pool, pstats := range node.ThreadPool { for _, metric := range c.threadPoolMetrics { diff --git a/collector/nodes_response.go b/collector/nodes_response.go index 636dc1d3..6ba2ad7b 100644 --- a/collector/nodes_response.go +++ b/collector/nodes_response.go @@ -1,8 +1,21 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector import "encoding/json" -// nodeStatsResponse is a representation of a Elasticsearch Node Stats +// nodeStatsResponse is a representation of an Elasticsearch Node Stats type nodeStatsResponse struct { ClusterName string `json:"cluster_name"` Nodes map[string]NodeStatsNodeResponse @@ -10,23 +23,24 @@ type nodeStatsResponse struct { // NodeStatsNodeResponse defines node stats information structure for nodes type NodeStatsNodeResponse struct { - Name string `json:"name"` - Host string `json:"host"` - Timestamp int64 `json:"timestamp"` - TransportAddress string `json:"transport_address"` - Hostname string `json:"hostname"` - Roles []string `json:"roles"` - Attributes map[string]string `json:"attributes"` - Indices NodeStatsIndicesResponse `json:"indices"` - OS NodeStatsOSResponse `json:"os"` - Network NodeStatsNetworkResponse `json:"network"` - FS NodeStatsFSResponse `json:"fs"` - ThreadPool map[string]NodeStatsThreadPoolPoolResponse `json:"thread_pool"` - JVM NodeStatsJVMResponse `json:"jvm"` - Breakers map[string]NodeStatsBreakersResponse `json:"breakers"` - HTTP map[string]int `json:"http"` - Transport NodeStatsTransportResponse `json:"transport"` - Process NodeStatsProcessResponse `json:"process"` + Name string `json:"name"` + Host string `json:"host"` + Timestamp int64 `json:"timestamp"` + TransportAddress string `json:"transport_address"` + Hostname string `json:"hostname"` + Roles []string `json:"roles"` + Attributes map[string]string `json:"attributes"` + Indices NodeStatsIndicesResponse `json:"indices"` + OS NodeStatsOSResponse `json:"os"` + Network NodeStatsNetworkResponse `json:"network"` + FS NodeStatsFSResponse `json:"fs"` + ThreadPool map[string]NodeStatsThreadPoolPoolResponse `json:"thread_pool"` + JVM NodeStatsJVMResponse `json:"jvm"` + Breakers map[string]NodeStatsBreakersResponse `json:"breakers"` + HTTP map[string]interface{} `json:"http"` + Transport NodeStatsTransportResponse `json:"transport"` + Process NodeStatsProcessResponse `json:"process"` + IndexingPressure map[string]NodeStatsIndexingPressureResponse `json:"indexing_pressure"` } // NodeStatsBreakersResponse is a representation of a statistics about the field data circuit breaker @@ -37,11 +51,23 @@ type NodeStatsBreakersResponse struct { Tripped int64 `json:"tripped"` } +// NodeStatsIndexingPressureResponse is a representation of a elasticsearch indexing pressure +type NodeStatsIndexingPressureResponse struct { + Current NodeStatsIndexingPressureCurrentResponse `json:"current"` + LimitInBytes int64 `json:"limit_in_bytes"` +} + +// NodeStatsIndexingPressureMemoryCurrentResponse is a representation of a elasticsearch indexing pressure current memory usage +type NodeStatsIndexingPressureCurrentResponse struct { + AllInBytes int64 `json:"all_in_bytes"` +} + // NodeStatsJVMResponse is a representation of a JVM stats, memory pool information, garbage collection, buffer pools, number of loaded/unloaded classes type NodeStatsJVMResponse struct { BufferPools map[string]NodeStatsJVMBufferPoolResponse `json:"buffer_pools"` GC NodeStatsJVMGCResponse `json:"gc"` Mem NodeStatsJVMMemResponse `json:"mem"` + Uptime int64 `json:"uptime_in_millis"` } // NodeStatsJVMGCResponse defines node stats JVM garbage collector information structure @@ -146,8 +172,10 @@ type NodeStatsIndicesDocsResponse struct { // NodeStatsIndicesRefreshResponse defines node stats refresh information structure for indices type NodeStatsIndicesRefreshResponse struct { - Total int64 `json:"total"` - TotalTime int64 `json:"total_time_in_millis"` + Total int64 `json:"total"` + TotalTime int64 `json:"total_time_in_millis"` + ExternalTotal int64 `json:"external_total"` + ExternalTotalTimeInMillis int64 `json:"external_total_time_in_millis"` } // NodeStatsIndicesTranslogResponse defines node stats translog information structure for indices @@ -283,10 +311,6 @@ type NodeStatsOSSwapResponse struct { // NodeStatsOSCPUResponse defines node stats operating system CPU usage structure type NodeStatsOSCPUResponse struct { - Sys int64 `json:"sys"` - User int64 `json:"user"` - Idle int64 `json:"idle"` - Steal int64 `json:"stolen"` LoadAvg NodeStatsOSCPULoadResponse `json:"load_average"` Percent int64 `json:"percent"` } @@ -317,8 +341,6 @@ type NodeStatsProcessMemResponse struct { // NodeStatsProcessCPUResponse defines node stats process CPU usage structure type NodeStatsProcessCPUResponse struct { Percent int64 `json:"percent"` - Sys int64 `json:"sys_in_millis"` - User int64 `json:"user_in_millis"` Total int64 `json:"total_in_millis"` } diff --git a/collector/nodes_test.go b/collector/nodes_test.go index 71495859..9e731837 100644 --- a/collector/nodes_test.go +++ b/collector/nodes_test.go @@ -1,162 +1,1606 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector import ( - "encoding/base64" - "fmt" + "io" "net/http" "net/http/httptest" "net/url" + "os" "strings" "testing" - "github.com/go-kit/kit/log" + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/promslog" ) func TestNodesStats(t *testing.T) { - // Testcases created using: - // docker run -d -p 9200:9200 elasticsearch:VERSION-alpine - // curl -XPUT http://localhost:9200/twitter - // curl http://localhost:9200/_nodes/stats - tcs := map[string]string{ - "1.7.6": `{"cluster_name":"elasticsearch","nodes":{"vKnRv2bPThCJIDTj92NvQg":{"timestamp":1498820641883,"name":"Overmind","transport_address":"inet[/172.17.0.4:9300]","host":"2603876b583f","ip":["inet[/172.17.0.4:9300]","NONE"],"indices":{"docs":{"count":0,"deleted":0},"store":{"size_in_bytes":575,"throttle_time_in_millis":0},"indexing":{"index_total":0,"index_time_in_millis":0,"index_current":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0},"refresh":{"total":0,"total_time_in_millis":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":10,"total_time_in_millis":52},"filter_cache":{"memory_size_in_bytes":0,"evictions":0},"id_cache":{"memory_size_in_bytes":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"percolate":{"total":0,"time_in_millis":0,"current":0,"memory_size_in_bytes":-1,"memory_size":"-1b","queries":0},"completion":{"size_in_bytes":0},"segments":{"count":0,"memory_in_bytes":0,"index_writer_memory_in_bytes":0,"index_writer_max_memory_in_bytes":335544320,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0},"translog":{"operations":0,"size_in_bytes":17},"suggest":{"total":0,"time_in_millis":0,"current":0},"query_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"os":{"timestamp":1498820641896},"process":{"timestamp":1498820641896,"open_file_descriptors":123},"jvm":{"timestamp":1498820641896,"uptime_in_millis":17871,"mem":{"heap_used_in_bytes":82958528,"heap_used_percent":7,"heap_committed_in_bytes":251002880,"heap_max_in_bytes":1056309248,"non_heap_used_in_bytes":44442536,"non_heap_committed_in_bytes":45400064,"pools":{"young":{"used_in_bytes":62150064,"max_in_bytes":139591680,"peak_used_in_bytes":139591680,"peak_max_in_bytes":139591680},"survivor":{"used_in_bytes":17432576,"max_in_bytes":17432576,"peak_used_in_bytes":17432576,"peak_max_in_bytes":17432576},"old":{"used_in_bytes":3375888,"max_in_bytes":899284992,"peak_used_in_bytes":10899920,"peak_max_in_bytes":899284992}}},"threads":{"count":36,"peak_count":36},"gc":{"collectors":{"young":{"collection_count":1,"collection_time_in_millis":40},"old":{"collection_count":1,"collection_time_in_millis":42}}},"buffer_pools":{"direct":{"count":27,"used_in_bytes":4981411,"total_capacity_in_bytes":4981411},"mapped":{"count":0,"used_in_bytes":0,"total_capacity_in_bytes":0}}},"thread_pool":{"percolate":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":1,"completed":1},"index":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"refresh":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"suggest":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":14},"warmer":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":1,"completed":5},"search":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"optimize":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":1,"queue":0,"active":1,"rejected":0,"largest":1,"completed":1},"get":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"bulk":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"network":{},"fs":{"timestamp":1498820641898,"total":{"total_in_bytes":63375708160,"free_in_bytes":59667320832,"available_in_bytes":56424390656},"data":[{"path":"/usr/share/elasticsearch/data/elasticsearch/nodes/0","mount":"/usr/share/elasticsearch/data (/dev/sda2)","type":"ext4","total_in_bytes":63375708160,"free_in_bytes":59667320832,"available_in_bytes":56424390656}]},"transport":{"server_open":13,"rx_count":6,"rx_size_in_bytes":1428,"tx_count":6,"tx_size_in_bytes":1428},"http":{"current_open":1,"total_opened":2},"breakers":{"request":{"limit_size_in_bytes":422523699,"limit_size":"402.9mb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":633785548,"limit_size":"604.4mb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"parent":{"limit_size_in_bytes":739416473,"limit_size":"705.1mb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0}}}}}`, - "2.4.5": `{"cluster_name":"elasticsearch","nodes":{"VnnrklnAQ7KRXhW2WkgPxA":{"timestamp":1498820602662,"name":"Battering Ram","transport_address":"172.17.0.4:9300","host":"172.17.0.4","ip":["172.17.0.4:9300","NONE"],"indices":{"docs":{"count":0,"deleted":0},"store":{"size_in_bytes":650,"throttle_time_in_millis":0},"indexing":{"index_total":0,"index_time_in_millis":0,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":104857600},"refresh":{"total":0,"total_time_in_millis":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":10,"total_time_in_millis":60},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"percolate":{"total":0,"time_in_millis":0,"current":0,"memory_size_in_bytes":-1,"memory_size":"-1b","queries":0},"completion":{"size_in_bytes":0},"segments":{"count":0,"memory_in_bytes":0,"terms_memory_in_bytes":0,"stored_fields_memory_in_bytes":0,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":0,"doc_values_memory_in_bytes":0,"index_writer_memory_in_bytes":0,"index_writer_max_memory_in_bytes":105630920,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0},"translog":{"operations":0,"size_in_bytes":215},"suggest":{"total":0,"time_in_millis":0,"current":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"os":{"timestamp":1498820602670,"cpu_percent":7,"load_average":0.32861328125,"mem":{"total_in_bytes":2096177152,"free_in_bytes":1624637440,"used_in_bytes":471539712,"free_percent":78,"used_percent":22},"swap":{"total_in_bytes":4195348480,"free_in_bytes":4005060608,"used_in_bytes":190287872}},"process":{"timestamp":1498820602670,"open_file_descriptors":116,"max_file_descriptors":1048576,"cpu":{"percent":7,"total_in_millis":10270},"mem":{"total_virtual_in_bytes":2681352192}},"jvm":{"timestamp":1498820602671,"uptime_in_millis":38833,"mem":{"heap_used_in_bytes":88986784,"heap_used_percent":8,"heap_committed_in_bytes":251002880,"heap_max_in_bytes":1056309248,"non_heap_used_in_bytes":49185912,"non_heap_committed_in_bytes":49987584,"pools":{"young":{"used_in_bytes":58281984,"max_in_bytes":139591680,"peak_used_in_bytes":139591680,"peak_max_in_bytes":139591680},"survivor":{"used_in_bytes":17432576,"max_in_bytes":17432576,"peak_used_in_bytes":17432576,"peak_max_in_bytes":17432576},"old":{"used_in_bytes":13272224,"max_in_bytes":899284992,"peak_used_in_bytes":13272224,"peak_max_in_bytes":899284992}}},"threads":{"count":35,"peak_count":38},"gc":{"collectors":{"young":{"collection_count":2,"collection_time_in_millis":87},"old":{"collection_count":1,"collection_time_in_millis":74}}},"buffer_pools":{"direct":{"count":23,"used_in_bytes":3416836,"total_capacity_in_bytes":3416836},"mapped":{"count":0,"used_in_bytes":0,"total_capacity_in_bytes":0}},"classes":{"current_loaded_count":7221,"total_loaded_count":7221,"total_unloaded_count":0}},"thread_pool":{"bulk":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":5,"completed":28},"get":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"index":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":1,"completed":2},"management":{"threads":2,"queue":0,"active":1,"rejected":0,"largest":2,"completed":5},"percolate":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"refresh":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"search":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"suggest":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":1,"completed":5}},"fs":{"timestamp":1498820602672,"total":{"total_in_bytes":63375708160,"free_in_bytes":59667599360,"available_in_bytes":56424669184,"spins":"true"},"data":[{"path":"/usr/share/elasticsearch/data/elasticsearch/nodes/0","mount":"/usr/share/elasticsearch/data (/dev/sda2)","type":"ext4","total_in_bytes":63375708160,"free_in_bytes":59667599360,"available_in_bytes":56424669184,"spins":"true"}]},"transport":{"server_open":0,"rx_count":6,"rx_size_in_bytes":2028,"tx_count":6,"tx_size_in_bytes":2028},"http":{"current_open":1,"total_opened":3},"breakers":{"request":{"limit_size_in_bytes":422523699,"limit_size":"402.9mb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":633785548,"limit_size":"604.4mb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":1056309248,"limit_size":"1007.3mb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":739416473,"limit_size":"705.1mb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0}},"script":{"compilations":0,"cache_evictions":0}}}}`, - "5.4.2": `{"_nodes":{"total":1,"successful":1,"failed":0},"cluster_name":"elasticsearch","nodes":{"0hHcEFK1S7qMlk8hQCm7wQ":{"timestamp":1498820489394,"name":"0hHcEFK","transport_address":"127.0.0.1:9300","host":"127.0.0.1","ip":"127.0.0.1:9300","roles":["master","data","ingest"],"indices":{"docs":{"count":0,"deleted":0},"store":{"size_in_bytes":650,"throttle_time_in_millis":0},"indexing":{"index_total":0,"index_time_in_millis":0,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":104857600},"refresh":{"total":0,"total_time_in_millis":0,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":5,"total_time_in_millis":27},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":0,"memory_in_bytes":0,"terms_memory_in_bytes":0,"stored_fields_memory_in_bytes":0,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":0,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":0,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":215},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"os":{"timestamp":1498820489400,"cpu":{"percent":0,"load_average":{"1m":0.35,"5m":0.28,"15m":0.12}},"mem":{"total_in_bytes":2096177152,"free_in_bytes":83501056,"used_in_bytes":2012676096,"free_percent":4,"used_percent":96},"swap":{"total_in_bytes":4195348480,"free_in_bytes":3487707136,"used_in_bytes":707641344}},"process":{"timestamp":1498820489400,"open_file_descriptors":139,"max_file_descriptors":1048576,"cpu":{"percent":0,"total_in_millis":26600},"mem":{"total_virtual_in_bytes":3823181824}},"jvm":{"timestamp":1498820489400,"uptime_in_millis":185693,"mem":{"heap_used_in_bytes":114959064,"heap_used_percent":5,"heap_committed_in_bytes":2130051072,"heap_max_in_bytes":2130051072,"non_heap_used_in_bytes":65471864,"non_heap_committed_in_bytes":69906432,"pools":{"young":{"used_in_bytes":82057312,"max_in_bytes":139591680,"peak_used_in_bytes":139591680,"peak_max_in_bytes":139591680},"survivor":{"used_in_bytes":17432576,"max_in_bytes":17432576,"peak_used_in_bytes":17432576,"peak_max_in_bytes":17432576},"old":{"used_in_bytes":15469176,"max_in_bytes":1973026816,"peak_used_in_bytes":15469176,"peak_max_in_bytes":1973026816}}},"threads":{"count":26,"peak_count":29},"gc":{"collectors":{"young":{"collection_count":4,"collection_time_in_millis":1618},"old":{"collection_count":1,"collection_time_in_millis":76}}},"buffer_pools":{"direct":{"count":16,"used_in_bytes":33776600,"total_capacity_in_bytes":33776599},"mapped":{"count":0,"used_in_bytes":0,"total_capacity_in_bytes":0}},"classes":{"current_loaded_count":9995,"total_loaded_count":9995,"total_unloaded_count":0}},"thread_pool":{"bulk":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":28},"get":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"index":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":2,"queue":0,"active":1,"rejected":0,"largest":2,"completed":20},"refresh":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":1,"completed":31},"search":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1498820489401,"total":{"total_in_bytes":63375708160,"free_in_bytes":59668226048,"available_in_bytes":56425295872,"spins":"true"},"data":[{"path":"/usr/share/elasticsearch/data/nodes/0","mount":"/usr/share/elasticsearch/data (/dev/sda2)","type":"ext4","total_in_bytes":63375708160,"free_in_bytes":59668226048,"available_in_bytes":56425295872,"spins":"true"}],"io_stats":{"devices":[{"device_name":"sda2","operations":3017,"read_operations":1800,"write_operations":1217,"read_kilobytes":24816,"write_kilobytes":6580}],"total":{"operations":3017,"read_operations":1800,"write_operations":1217,"read_kilobytes":24816,"write_kilobytes":6580}}},"transport":{"server_open":0,"rx_count":0,"rx_size_in_bytes":0,"tx_count":0,"tx_size_in_bytes":0},"http":{"current_open":2,"total_opened":3},"breakers":{"request":{"limit_size_in_bytes":1278030643,"limit_size":"1.1gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":1278030643,"limit_size":"1.1gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":2130051072,"limit_size":"1.9gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":1491035750,"limit_size":"1.3gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0}},"script":{"compilations":0,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{}}}}}`, - "5.5.0": `{"_nodes":{"total":13,"successful":13,"failed":0},"cluster_name":"multinode","nodes":{"IAMD9JnLR4qOa-dl3cDaig":{"timestamp":1511714498349,"name":"elasticin-02","transport_address":"10.0.0.108:9300","host":"elasticin-02","ip":"10.0.0.108:9300","roles":["ingest"],"attributes":{"ml.enabled":"true"},"indices":{"docs":{"count":0,"deleted":0},"store":{"size_in_bytes":0,"throttle_time_in_millis":0},"indexing":{"index_total":0,"index_time_in_millis":0,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":0},"refresh":{"total":0,"total_time_in_millis":0,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":0,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":0,"memory_in_bytes":0,"terms_memory_in_bytes":0,"stored_fields_memory_in_bytes":0,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":0,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":0,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-9223372036854775808,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"os":{"timestamp":1511714497950,"cpu":{"percent":1,"load_average":{"1m":0.06,"5m":0.21,"15m":0.29}},"mem":{"total_in_bytes":8375726080,"free_in_bytes":545091584,"used_in_bytes":7830634496,"free_percent":7,"used_percent":93},"swap":{"total_in_bytes":1073737728,"free_in_bytes":1073737728,"used_in_bytes":0},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":37998635799304},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}}}},"process":{"timestamp":1511714497950,"open_file_descriptors":507,"max_file_descriptors":1048576,"cpu":{"percent":0,"total_in_millis":37998520},"mem":{"total_virtual_in_bytes":8281767936}},"jvm":{"timestamp":1511714497950,"uptime_in_millis":589198476,"mem":{"heap_used_in_bytes":1092031200,"heap_used_percent":25,"heap_committed_in_bytes":4260102144,"heap_max_in_bytes":4260102144,"non_heap_used_in_bytes":114726896,"non_heap_committed_in_bytes":121688064,"pools":{"young":{"used_in_bytes":158592080,"max_in_bytes":279183360,"peak_used_in_bytes":279183360,"peak_max_in_bytes":279183360},"survivor":{"used_in_bytes":2988992,"max_in_bytes":34865152,"peak_used_in_bytes":34865152,"peak_max_in_bytes":34865152},"old":{"used_in_bytes":930450128,"max_in_bytes":3946053632,"peak_used_in_bytes":3806199632,"peak_max_in_bytes":3946053632}}},"threads":{"count":60,"peak_count":185},"gc":{"collectors":{"young":{"collection_count":60237,"collection_time_in_millis":1196377},"old":{"collection_count":287,"collection_time_in_millis":38202}}},"buffer_pools":{"direct":{"count":40,"used_in_bytes":135831560,"total_capacity_in_bytes":135831559},"mapped":{"count":0,"used_in_bytes":0,"total_capacity_in_bytes":0}},"classes":{"current_loaded_count":13297,"total_loaded_count":13364,"total_unloaded_count":67}},"thread_pool":{"bulk":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":404400},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":8,"queue":0,"active":0,"rejected":0,"largest":128,"completed":765207},"get":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"index":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":5,"queue":0,"active":1,"rejected":0,"largest":5,"completed":1289143},"ml_autodetect":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"refresh":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"search":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1511714497951,"total":{"total_in_bytes":39836917760,"free_in_bytes":35574710272,"available_in_bytes":33527472128,"spins":"true"},"data":[{"path":"/usr/share/elasticsearch/data/nodes/0","mount":"/ (overlay)","type":"overlay","total_in_bytes":39836917760,"free_in_bytes":35574710272,"available_in_bytes":33527472128,"spins":"true"}],"io_stats":{}},"transport":{"server_open":135,"rx_count":5047176,"rx_size_in_bytes":154154850912,"tx_count":5049542,"tx_size_in_bytes":228013049059},"http":{"current_open":2,"total_opened":581038},"breakers":{"request":{"limit_size_in_bytes":2556061286,"limit_size":"2.3gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":2556061286,"limit_size":"2.3gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":4260102144,"limit_size":"3.9gb","estimated_size_in_bytes":1916,"estimated_size":"1.8kb","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":2982071500,"limit_size":"2.7gb","estimated_size_in_bytes":1916,"estimated_size":"1.8kb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0},"xpack_monitoring_2":{"count":0,"time_in_millis":0,"current":0,"failed":0}}}},"o9MvLOdySpmaelLxYnLJDg":{"timestamp":1511714498348,"name":"elasticmaster-01","transport_address":"10.0.0.150:9300","host":"elasticmaster-01","ip":"10.0.0.150:9300","roles":["master"],"attributes":{"ml.enabled":"true"},"indices":{"docs":{"count":0,"deleted":0},"store":{"size_in_bytes":0,"throttle_time_in_millis":0},"indexing":{"index_total":0,"index_time_in_millis":0,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":0},"refresh":{"total":0,"total_time_in_millis":0,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":0,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":0,"memory_in_bytes":0,"terms_memory_in_bytes":0,"stored_fields_memory_in_bytes":0,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":0,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":0,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-9223372036854775808,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"os":{"timestamp":1511714498349,"cpu":{"percent":44,"load_average":{"1m":0.25,"5m":0.33,"15m":0.25}},"mem":{"total_in_bytes":8375730176,"free_in_bytes":2545594368,"used_in_bytes":5830135808,"free_percent":30,"used_percent":70},"swap":{"total_in_bytes":1073737728,"free_in_bytes":1072058368,"used_in_bytes":1679360},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":20472909415977},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}}}},"process":{"timestamp":1511714498349,"open_file_descriptors":519,"max_file_descriptors":1048576,"cpu":{"percent":2,"total_in_millis":20472800},"mem":{"total_virtual_in_bytes":6048481280}},"jvm":{"timestamp":1511714498349,"uptime_in_millis":455012435,"mem":{"heap_used_in_bytes":1196945872,"heap_used_percent":56,"heap_committed_in_bytes":2112618496,"heap_max_in_bytes":2112618496,"non_heap_used_in_bytes":113206520,"non_heap_committed_in_bytes":120074240,"pools":{"young":{"used_in_bytes":109972848,"max_in_bytes":279183360,"peak_used_in_bytes":279183360,"peak_max_in_bytes":279183360},"survivor":{"used_in_bytes":2172240,"max_in_bytes":34865152,"peak_used_in_bytes":34865152,"peak_max_in_bytes":34865152},"old":{"used_in_bytes":1084800784,"max_in_bytes":1798569984,"peak_used_in_bytes":1798569984,"peak_max_in_bytes":1798569984}}},"threads":{"count":52,"peak_count":56},"gc":{"collectors":{"young":{"collection_count":32035,"collection_time_in_millis":355769},"old":{"collection_count":1002,"collection_time_in_millis":476417}}},"buffer_pools":{"direct":{"count":41,"used_in_bytes":135839401,"total_capacity_in_bytes":135839400},"mapped":{"count":0,"used_in_bytes":0,"total_capacity_in_bytes":0}},"classes":{"current_loaded_count":13299,"total_loaded_count":13359,"total_unloaded_count":60}},"thread_pool":{"bulk":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":590358},"get":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"index":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":5,"queue":0,"active":1,"rejected":0,"largest":5,"completed":949237},"ml_autodetect":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"refresh":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"search":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1511714498349,"total":{"total_in_bytes":39836917760,"free_in_bytes":27525136384,"available_in_bytes":25477898240,"spins":"true"},"data":[{"path":"/usr/share/elasticsearch/data/nodes/0","mount":"/ (overlay)","type":"overlay","total_in_bytes":39836917760,"free_in_bytes":27525136384,"available_in_bytes":25477898240,"spins":"true"}],"io_stats":{}},"transport":{"server_open":134,"rx_count":3128979,"rx_size_in_bytes":44609852501,"tx_count":3128980,"tx_size_in_bytes":91308571728},"http":{"current_open":2,"total_opened":407857},"breakers":{"request":{"limit_size_in_bytes":1267571097,"limit_size":"1.1gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":1267571097,"limit_size":"1.1gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":2112618496,"limit_size":"1.9gb","estimated_size_in_bytes":1916,"estimated_size":"1.8kb","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":1478832947,"limit_size":"1.3gb","estimated_size_in_bytes":1916,"estimated_size":"1.8kb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_2":{"count":0,"time_in_millis":0,"current":0,"failed":0},"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0}}}},"QJMwXyZDTVaEupifVTFAXg":{"timestamp":1511714498348,"name":"elasticmaster-03","transport_address":"10.0.0.57:9300","host":"elasticmaster-03","ip":"10.0.0.57:9300","roles":["master"],"attributes":{"ml.enabled":"true"},"indices":{"docs":{"count":0,"deleted":0},"store":{"size_in_bytes":0,"throttle_time_in_millis":0},"indexing":{"index_total":0,"index_time_in_millis":0,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":0},"refresh":{"total":0,"total_time_in_millis":0,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":0,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":0,"memory_in_bytes":0,"terms_memory_in_bytes":0,"stored_fields_memory_in_bytes":0,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":0,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":0,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-9223372036854775808,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"os":{"timestamp":1511714497945,"cpu":{"percent":23,"load_average":{"1m":0.81,"5m":0.67,"15m":0.53}},"mem":{"total_in_bytes":8375726080,"free_in_bytes":2463612928,"used_in_bytes":5912113152,"free_percent":29,"used_percent":71},"swap":{"total_in_bytes":1073737728,"free_in_bytes":1071788032,"used_in_bytes":1949696},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":72007272720599},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}}}},"process":{"timestamp":1511714497945,"open_file_descriptors":519,"max_file_descriptors":1048576,"cpu":{"percent":0,"total_in_millis":72007150},"mem":{"total_virtual_in_bytes":6073102336}},"jvm":{"timestamp":1511714497945,"uptime_in_millis":456828928,"mem":{"heap_used_in_bytes":830571920,"heap_used_percent":39,"heap_committed_in_bytes":2112618496,"heap_max_in_bytes":2112618496,"non_heap_used_in_bytes":131650000,"non_heap_committed_in_bytes":140623872,"pools":{"young":{"used_in_bytes":42273680,"max_in_bytes":279183360,"peak_used_in_bytes":279183360,"peak_max_in_bytes":279183360},"survivor":{"used_in_bytes":8297248,"max_in_bytes":34865152,"peak_used_in_bytes":34865152,"peak_max_in_bytes":34865152},"old":{"used_in_bytes":780000992,"max_in_bytes":1798569984,"peak_used_in_bytes":1798569984,"peak_max_in_bytes":1798569984}}},"threads":{"count":74,"peak_count":75},"gc":{"collectors":{"young":{"collection_count":187631,"collection_time_in_millis":2346463},"old":{"collection_count":1570,"collection_time_in_millis":494403}}},"buffer_pools":{"direct":{"count":41,"used_in_bytes":135839383,"total_capacity_in_bytes":135839382},"mapped":{"count":0,"used_in_bytes":0,"total_capacity_in_bytes":0}},"classes":{"current_loaded_count":14015,"total_loaded_count":14100,"total_unloaded_count":85}},"thread_pool":{"bulk":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":18,"queue":0,"active":1,"rejected":0,"largest":18,"completed":592984},"get":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"index":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":5,"queue":0,"active":1,"rejected":0,"largest":5,"completed":1026939},"ml_autodetect":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":5,"queue":0,"active":0,"rejected":0,"largest":5,"completed":5},"refresh":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"search":{"threads":2,"queue":0,"active":0,"rejected":0,"largest":2,"completed":2},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1511714497945,"total":{"total_in_bytes":39836917760,"free_in_bytes":31222030336,"available_in_bytes":29174792192,"spins":"true"},"data":[{"path":"/usr/share/elasticsearch/data/nodes/0","mount":"/ (overlay)","type":"overlay","total_in_bytes":39836917760,"free_in_bytes":31222030336,"available_in_bytes":29174792192,"spins":"true"}],"io_stats":{}},"transport":{"server_open":134,"rx_count":17417277,"rx_size_in_bytes":388077081117,"tx_count":17417313,"tx_size_in_bytes":320472005934},"http":{"current_open":2,"total_opened":407233},"breakers":{"request":{"limit_size_in_bytes":1267571097,"limit_size":"1.1gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":1267571097,"limit_size":"1.1gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":2112618496,"limit_size":"1.9gb","estimated_size_in_bytes":1916,"estimated_size":"1.8kb","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":1478832947,"limit_size":"1.3gb","estimated_size_in_bytes":1916,"estimated_size":"1.8kb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_2":{"count":0,"time_in_millis":0,"current":0,"failed":0},"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0}}}},"EN05ytfQQvStXdW4Q6RatA":{"timestamp":1511714498348,"name":"elasticdata-01","transport_address":"10.0.0.119:9300","host":"elasticdata-01","ip":"10.0.0.119:9300","roles":["data"],"attributes":{"ml.enabled":"true"},"indices":{"docs":{"count":375322138,"deleted":1037878},"store":{"size_in_bytes":259394317595,"throttle_time_in_millis":0},"indexing":{"index_total":448977978,"index_time_in_millis":118716971,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":11762,"time_in_millis":941,"exists_total":11762,"exists_time_in_millis":941,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":482173,"query_time_in_millis":3748653,"query_current":0,"fetch_total":21577,"fetch_time_in_millis":528409,"fetch_current":0,"scroll_total":2,"scroll_time_in_millis":188893,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":2,"current_docs":9550,"current_size_in_bytes":6050542,"total":169074,"total_time_in_millis":105409372,"total_docs":1390928712,"total_size_in_bytes":869934290826,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":50576302,"total_auto_throttle_in_bytes":14087997090},"refresh":{"total":1476283,"total_time_in_millis":27373898,"listeners":0},"flush":{"total":1184,"total_time_in_millis":518446},"warmer":{"current":0,"total":1441617,"total_time_in_millis":520582},"query_cache":{"memory_size_in_bytes":154620318,"total_count":1276959,"hit_count":655594,"miss_count":621365,"cache_size":8688,"cache_count":11271,"evictions":2583},"fielddata":{"memory_size_in_bytes":50488,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":4460,"memory_in_bytes":906650903,"terms_memory_in_bytes":814497094,"stored_fields_memory_in_bytes":62547264,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":8536576,"points_memory_in_bytes":4277057,"doc_values_memory_in_bytes":16792912,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":192,"max_unsafe_auto_id_timestamp":1511481600647,"file_sizes":{}},"translog":{"operations":3209732,"size_in_bytes":3144619388},"request_cache":{"memory_size_in_bytes":162916154,"evictions":12109,"hit_count":19313,"miss_count":37864},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":743800}},"os":{"timestamp":1511714497945,"cpu":{"percent":5,"load_average":{"1m":0.98,"5m":0.92,"15m":0.81}},"mem":{"total_in_bytes":33742192640,"free_in_bytes":1784082432,"used_in_bytes":31958110208,"free_percent":5,"used_percent":95},"swap":{"total_in_bytes":1073737728,"free_in_bytes":791388160,"used_in_bytes":282349568},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":377534011797418},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}}}},"process":{"timestamp":1511714497945,"open_file_descriptors":1341,"max_file_descriptors":1048576,"cpu":{"percent":4,"total_in_millis":377531950},"mem":{"total_virtual_in_bytes":281489690624}},"jvm":{"timestamp":1511714497946,"uptime_in_millis":456177136,"mem":{"heap_used_in_bytes":12360895776,"heap_used_percent":72,"heap_committed_in_bytes":17110138880,"heap_max_in_bytes":17110138880,"non_heap_used_in_bytes":169873944,"non_heap_committed_in_bytes":179277824,"pools":{"young":{"used_in_bytes":418031976,"max_in_bytes":558432256,"peak_used_in_bytes":558432256,"peak_max_in_bytes":558432256},"survivor":{"used_in_bytes":41567680,"max_in_bytes":69730304,"peak_used_in_bytes":69730304,"peak_max_in_bytes":69730304},"old":{"used_in_bytes":11901296120,"max_in_bytes":16481976320,"peak_used_in_bytes":12805122832,"peak_max_in_bytes":16481976320}}},"threads":{"count":134,"peak_count":141},"gc":{"collectors":{"young":{"collection_count":138863,"collection_time_in_millis":4901025},"old":{"collection_count":109,"collection_time_in_millis":28223}}},"buffer_pools":{"direct":{"count":153,"used_in_bytes":272389833,"total_capacity_in_bytes":272389832},"mapped":{"count":9987,"used_in_bytes":257693104518,"total_capacity_in_bytes":257693104518}},"classes":{"current_loaded_count":15279,"total_loaded_count":15425,"total_unloaded_count":146}},"thread_pool":{"bulk":{"threads":8,"queue":0,"active":0,"rejected":8829,"largest":8,"completed":4533781},"fetch_shard_started":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":1,"completed":1},"fetch_shard_store":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":16,"completed":527},"flush":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":183951},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":16,"queue":0,"active":0,"rejected":0,"largest":16,"completed":685858},"get":{"threads":8,"queue":0,"active":0,"rejected":0,"largest":8,"completed":11757},"index":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":5,"queue":0,"active":2,"rejected":0,"largest":5,"completed":1482328},"ml_autodetect":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"refresh":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":96747907},"search":{"threads":13,"queue":0,"active":0,"rejected":0,"largest":13,"completed":492085},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":3,"queue":0,"active":0,"rejected":0,"largest":3,"completed":1478002},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1511714497946,"total":{"total_in_bytes":528311836672,"free_in_bytes":259901870080,"available_in_bytes":233041600512,"spins":"true"},"data":[{"path":"/mnt/data/nodes/0","mount":"/mnt/data (/dev/sdb1)","type":"ext4","total_in_bytes":528311836672,"free_in_bytes":259901870080,"available_in_bytes":233041600512,"spins":"true"}],"io_stats":{"devices":[{"device_name":"sdb1","operations":21613740,"read_operations":757427,"write_operations":20856313,"read_kilobytes":82400388,"write_kilobytes":1355771052}],"total":{"operations":21613740,"read_operations":757427,"write_operations":20856313,"read_kilobytes":82400388,"write_kilobytes":1355771052}}},"transport":{"server_open":133,"rx_count":11869543,"rx_size_in_bytes":477850961639,"tx_count":11869509,"tx_size_in_bytes":538588051057},"http":{"current_open":2,"total_opened":396888},"breakers":{"request":{"limit_size_in_bytes":10266083328,"limit_size":"9.5gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":10266083328,"limit_size":"9.5gb","estimated_size_in_bytes":50488,"estimated_size":"49.3kb","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":17110138880,"limit_size":"15.9gb","estimated_size_in_bytes":38028,"estimated_size":"37.1kb","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":11977097216,"limit_size":"11.1gb","estimated_size_in_bytes":88516,"estimated_size":"86.4kb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_2":{"count":0,"time_in_millis":0,"current":0,"failed":0},"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0}}}},"CC7h3_tGQTm7sUk0sMAPjg":{"timestamp":1511714498349,"name":"elasticmaster-02","transport_address":"10.0.0.149:9300","host":"elasticmaster-02","ip":"10.0.0.149:9300","roles":["master"],"attributes":{"ml.enabled":"true"},"indices":{"docs":{"count":0,"deleted":0},"store":{"size_in_bytes":0,"throttle_time_in_millis":0},"indexing":{"index_total":0,"index_time_in_millis":0,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":0},"refresh":{"total":0,"total_time_in_millis":0,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":0,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":0,"memory_in_bytes":0,"terms_memory_in_bytes":0,"stored_fields_memory_in_bytes":0,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":0,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":0,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-9223372036854775808,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"os":{"timestamp":1511714497946,"cpu":{"percent":11,"load_average":{"1m":0.04,"5m":0.03,"15m":0.05}},"mem":{"total_in_bytes":8375726080,"free_in_bytes":2514419712,"used_in_bytes":5861306368,"free_percent":30,"used_percent":70},"swap":{"total_in_bytes":1073737728,"free_in_bytes":1070624768,"used_in_bytes":3112960},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":15116859468711},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}}}},"process":{"timestamp":1511714497946,"open_file_descriptors":519,"max_file_descriptors":1048576,"cpu":{"percent":0,"total_in_millis":15116720},"mem":{"total_virtual_in_bytes":6050123776}},"jvm":{"timestamp":1511714497946,"uptime_in_millis":439476155,"mem":{"heap_used_in_bytes":723824488,"heap_used_percent":34,"heap_committed_in_bytes":2112618496,"heap_max_in_bytes":2112618496,"non_heap_used_in_bytes":111904440,"non_heap_committed_in_bytes":119291904,"pools":{"young":{"used_in_bytes":215917352,"max_in_bytes":279183360,"peak_used_in_bytes":279183360,"peak_max_in_bytes":279183360},"survivor":{"used_in_bytes":6213480,"max_in_bytes":34865152,"peak_used_in_bytes":34865152,"peak_max_in_bytes":34865152},"old":{"used_in_bytes":501693656,"max_in_bytes":1798569984,"peak_used_in_bytes":1669293512,"peak_max_in_bytes":1798569984}}},"threads":{"count":52,"peak_count":57},"gc":{"collectors":{"young":{"collection_count":21247,"collection_time_in_millis":216235},"old":{"collection_count":155,"collection_time_in_millis":16680}}},"buffer_pools":{"direct":{"count":41,"used_in_bytes":135839407,"total_capacity_in_bytes":135839406},"mapped":{"count":0,"used_in_bytes":0,"total_capacity_in_bytes":0}},"classes":{"current_loaded_count":13220,"total_loaded_count":13275,"total_unloaded_count":55}},"thread_pool":{"bulk":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":570794},"get":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"index":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":5,"queue":0,"active":1,"rejected":0,"largest":5,"completed":896859},"ml_autodetect":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"refresh":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"search":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1511714497946,"total":{"total_in_bytes":39836917760,"free_in_bytes":24176267264,"available_in_bytes":22129029120,"spins":"true"},"data":[{"path":"/usr/share/elasticsearch/data/nodes/0","mount":"/ (overlay)","type":"overlay","total_in_bytes":39836917760,"free_in_bytes":24176267264,"available_in_bytes":22129029120,"spins":"true"}],"io_stats":{}},"transport":{"server_open":134,"rx_count":2973754,"rx_size_in_bytes":41620665024,"tx_count":2973754,"tx_size_in_bytes":68323082688},"http":{"current_open":2,"total_opened":389190},"breakers":{"request":{"limit_size_in_bytes":1267571097,"limit_size":"1.1gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":1267571097,"limit_size":"1.1gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":2112618496,"limit_size":"1.9gb","estimated_size_in_bytes":1916,"estimated_size":"1.8kb","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":1478832947,"limit_size":"1.3gb","estimated_size_in_bytes":1916,"estimated_size":"1.8kb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_2":{"count":0,"time_in_millis":0,"current":0,"failed":0},"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0}}}},"Pc2mK8pWQ9icfpJRpEqLWw":{"timestamp":1511714498348,"name":"elasticdata-04","transport_address":"10.0.0.56:9300","host":"elasticdata-04","ip":"10.0.0.56:9300","roles":["data"],"attributes":{"ml.enabled":"true"},"indices":{"docs":{"count":425699379,"deleted":1373715},"store":{"size_in_bytes":296033664114,"throttle_time_in_millis":0},"indexing":{"index_total":642934027,"index_time_in_millis":171016063,"index_current":0,"index_failed":35069830,"delete_total":1721,"delete_time_in_millis":132,"delete_current":0,"noop_update_total":2,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":15655,"time_in_millis":905,"exists_total":15647,"exists_time_in_millis":905,"missing_total":8,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":650749,"query_time_in_millis":3957392,"query_current":0,"fetch_total":21133,"fetch_time_in_millis":611629,"fetch_current":0,"scroll_total":49,"scroll_time_in_millis":2195819,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":208750,"total_time_in_millis":151039152,"total_docs":1916131698,"total_size_in_bytes":1226965745190,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":83417760,"total_auto_throttle_in_bytes":41028302003},"refresh":{"total":1825950,"total_time_in_millis":35474740,"listeners":0},"flush":{"total":3138,"total_time_in_millis":707216},"warmer":{"current":0,"total":1453839,"total_time_in_millis":657162},"query_cache":{"memory_size_in_bytes":87457278,"total_count":479101,"hit_count":109644,"miss_count":369457,"cache_size":15020,"cache_count":15792,"evictions":772},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":4558,"memory_in_bytes":1094352149,"terms_memory_in_bytes":997400697,"stored_fields_memory_in_bytes":72061816,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":8919296,"points_memory_in_bytes":2447676,"doc_values_memory_in_bytes":13522664,"index_writer_memory_in_bytes":2321128,"version_map_memory_in_bytes":10230,"fixed_bit_set_memory_in_bytes":96,"max_unsafe_auto_id_timestamp":1511222737106,"file_sizes":{}},"translog":{"operations":4076380,"size_in_bytes":3763408908},"request_cache":{"memory_size_in_bytes":522081,"evictions":0,"hit_count":1057,"miss_count":715},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":6095665}},"os":{"timestamp":1511714497945,"cpu":{"percent":8,"load_average":{"1m":0.49,"5m":0.75,"15m":0.83}},"mem":{"total_in_bytes":33742192640,"free_in_bytes":326279168,"used_in_bytes":33415913472,"free_percent":1,"used_percent":99},"swap":{"total_in_bytes":1073737728,"free_in_bytes":734015488,"used_in_bytes":339722240},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":505471512208338},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}}}},"process":{"timestamp":1511714497945,"open_file_descriptors":1495,"max_file_descriptors":1048576,"cpu":{"percent":8,"total_in_millis":505469110},"mem":{"total_virtual_in_bytes":317985972224}},"jvm":{"timestamp":1511714497946,"uptime_in_millis":584091461,"mem":{"heap_used_in_bytes":8628353304,"heap_used_percent":50,"heap_committed_in_bytes":17110138880,"heap_max_in_bytes":17110138880,"non_heap_used_in_bytes":182671192,"non_heap_committed_in_bytes":192577536,"pools":{"young":{"used_in_bytes":318839256,"max_in_bytes":558432256,"peak_used_in_bytes":558432256,"peak_max_in_bytes":558432256},"survivor":{"used_in_bytes":25041808,"max_in_bytes":69730304,"peak_used_in_bytes":69730304,"peak_max_in_bytes":69730304},"old":{"used_in_bytes":8284472240,"max_in_bytes":16481976320,"peak_used_in_bytes":16481976320,"peak_max_in_bytes":16481976320}}},"threads":{"count":140,"peak_count":220},"gc":{"collectors":{"young":{"collection_count":198328,"collection_time_in_millis":7115355},"old":{"collection_count":229,"collection_time_in_millis":602402}}},"buffer_pools":{"direct":{"count":143,"used_in_bytes":272254590,"total_capacity_in_bytes":272254589},"mapped":{"count":10120,"used_in_bytes":293958375802,"total_capacity_in_bytes":293958375802}},"classes":{"current_loaded_count":15336,"total_loaded_count":15495,"total_unloaded_count":159}},"thread_pool":{"bulk":{"threads":8,"queue":0,"active":0,"rejected":106834,"largest":8,"completed":6643785},"fetch_shard_started":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":16,"completed":2854},"fetch_shard_store":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":16,"completed":10424},"flush":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":234813},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":12,"queue":0,"active":0,"rejected":0,"largest":60,"completed":1065873},"get":{"threads":8,"queue":0,"active":0,"rejected":0,"largest":8,"completed":15629},"index":{"threads":8,"queue":0,"active":0,"rejected":0,"largest":8,"completed":12},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":5,"queue":0,"active":2,"rejected":0,"largest":5,"completed":1911527},"ml_autodetect":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"refresh":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":124094775},"search":{"threads":13,"queue":0,"active":0,"rejected":0,"largest":13,"completed":657456},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":1831272},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1511714497946,"total":{"total_in_bytes":528310788096,"free_in_bytes":219653083136,"available_in_bytes":219636305920,"spins":"true"},"data":[{"path":"/mnt/data/nodes/0","mount":"/mnt/data (/dev/sdb1)","type":"ext4","total_in_bytes":528310788096,"free_in_bytes":219653083136,"available_in_bytes":219636305920,"spins":"true"}],"io_stats":{"devices":[{"device_name":"sdb1","operations":34428907,"read_operations":4433749,"write_operations":29995158,"read_kilobytes":530811024,"write_kilobytes":2036811840}],"total":{"operations":34428907,"read_operations":4433749,"write_operations":29995158,"read_kilobytes":530811024,"write_kilobytes":2036811840}}},"transport":{"server_open":133,"rx_count":16198439,"rx_size_in_bytes":900601319307,"tx_count":16201772,"tx_size_in_bytes":1162809703365},"http":{"current_open":2,"total_opened":498058},"breakers":{"request":{"limit_size_in_bytes":10266083328,"limit_size":"9.5gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":10266083328,"limit_size":"9.5gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":17110138880,"limit_size":"15.9gb","estimated_size_in_bytes":38013,"estimated_size":"37.1kb","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":11977097216,"limit_size":"11.1gb","estimated_size_in_bytes":38013,"estimated_size":"37.1kb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0},"xpack_monitoring_2":{"count":0,"time_in_millis":0,"current":0,"failed":0}}}},"vQxBfSGXTuyFRZ0qVrNrDA":{"timestamp":1511714498348,"name":"elasticdata-05","transport_address":"10.0.0.98:9300","host":"elasticdata-05","ip":"10.0.0.98:9300","roles":["data"],"attributes":{"ml.enabled":"true"},"indices":{"docs":{"count":464562958,"deleted":1135485},"store":{"size_in_bytes":293883305118,"throttle_time_in_millis":0},"indexing":{"index_total":332603493,"index_time_in_millis":105361198,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":166531,"time_in_millis":13112,"exists_total":166531,"exists_time_in_millis":13112,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":654756,"query_time_in_millis":3925477,"query_current":0,"fetch_total":168250,"fetch_time_in_millis":168976,"fetch_current":0,"scroll_total":1,"scroll_time_in_millis":93623,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":166059,"total_time_in_millis":126117143,"total_docs":1332039112,"total_size_in_bytes":927972166158,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":71787253,"total_auto_throttle_in_bytes":9894986790},"refresh":{"total":1435483,"total_time_in_millis":25368823,"listeners":0},"flush":{"total":966,"total_time_in_millis":304725},"warmer":{"current":0,"total":1429821,"total_time_in_millis":655606},"query_cache":{"memory_size_in_bytes":58846620,"total_count":962195,"hit_count":493138,"miss_count":469057,"cache_size":15951,"cache_count":16868,"evictions":917},"fielddata":{"memory_size_in_bytes":50008,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":4349,"memory_in_bytes":1064790107,"terms_memory_in_bytes":968028700,"stored_fields_memory_in_bytes":69207552,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":8031040,"points_memory_in_bytes":4115219,"doc_values_memory_in_bytes":15407596,"index_writer_memory_in_bytes":2463588,"version_map_memory_in_bytes":9020,"fixed_bit_set_memory_in_bytes":680,"max_unsafe_auto_id_timestamp":1511291784471,"file_sizes":{}},"translog":{"operations":3779808,"size_in_bytes":3315625571},"request_cache":{"memory_size_in_bytes":163650616,"evictions":0,"hit_count":24539,"miss_count":33213},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":2115817}},"os":{"timestamp":1511714497945,"cpu":{"percent":9,"load_average":{"1m":0.78,"5m":0.81,"15m":0.96}},"mem":{"total_in_bytes":33742192640,"free_in_bytes":398262272,"used_in_bytes":33343930368,"free_percent":1,"used_percent":99},"swap":{"total_in_bytes":1073737728,"free_in_bytes":759992320,"used_in_bytes":313745408},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":354202797708211},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}}}},"process":{"timestamp":1511714497945,"open_file_descriptors":1342,"max_file_descriptors":1048576,"cpu":{"percent":6,"total_in_millis":354200650},"mem":{"total_virtual_in_bytes":315156033536}},"jvm":{"timestamp":1511714497946,"uptime_in_millis":431765693,"mem":{"heap_used_in_bytes":6319079512,"heap_used_percent":36,"heap_committed_in_bytes":17110138880,"heap_max_in_bytes":17110138880,"non_heap_used_in_bytes":170115336,"non_heap_committed_in_bytes":178569216,"pools":{"young":{"used_in_bytes":443763064,"max_in_bytes":558432256,"peak_used_in_bytes":558432256,"peak_max_in_bytes":558432256},"survivor":{"used_in_bytes":14138776,"max_in_bytes":69730304,"peak_used_in_bytes":69730304,"peak_max_in_bytes":69730304},"old":{"used_in_bytes":5861177672,"max_in_bytes":16481976320,"peak_used_in_bytes":12466824144,"peak_max_in_bytes":16481976320}}},"threads":{"count":123,"peak_count":129},"gc":{"collectors":{"young":{"collection_count":120635,"collection_time_in_millis":4020956},"old":{"collection_count":34,"collection_time_in_millis":7882}}},"buffer_pools":{"direct":{"count":121,"used_in_bytes":272138248,"total_capacity_in_bytes":272138247},"mapped":{"count":9931,"used_in_bytes":291373910869,"total_capacity_in_bytes":291373910869}},"classes":{"current_loaded_count":15157,"total_loaded_count":15278,"total_unloaded_count":121}},"thread_pool":{"bulk":{"threads":8,"queue":0,"active":0,"rejected":0,"largest":8,"completed":4880397},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":172938},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":6,"queue":0,"active":0,"rejected":0,"largest":6,"completed":988384},"get":{"threads":8,"queue":0,"active":0,"rejected":0,"largest":8,"completed":166525},"index":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":5,"queue":0,"active":4,"rejected":0,"largest":5,"completed":1392916},"ml_autodetect":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"refresh":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":95595890},"search":{"threads":13,"queue":0,"active":0,"rejected":0,"largest":13,"completed":656498},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":1436871},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1511714497946,"total":{"total_in_bytes":528310788096,"free_in_bytes":230955548672,"available_in_bytes":230938771456,"spins":"true"},"data":[{"path":"/mnt/data/nodes/0","mount":"/mnt/data (/dev/sdb1)","type":"ext4","total_in_bytes":528310788096,"free_in_bytes":230955548672,"available_in_bytes":230938771456,"spins":"true"}],"io_stats":{"devices":[{"device_name":"sdb1","operations":23957106,"read_operations":1813100,"write_operations":22144006,"read_kilobytes":208071952,"write_kilobytes":1567856356}],"total":{"operations":23957106,"read_operations":1813100,"write_operations":22144006,"read_kilobytes":208071952,"write_kilobytes":1567856356}}},"transport":{"server_open":133,"rx_count":11052974,"rx_size_in_bytes":548594647188,"tx_count":11052976,"tx_size_in_bytes":267372947055},"http":{"current_open":3,"total_opened":383162},"breakers":{"request":{"limit_size_in_bytes":10266083328,"limit_size":"9.5gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":10266083328,"limit_size":"9.5gb","estimated_size_in_bytes":50008,"estimated_size":"48.8kb","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":17110138880,"limit_size":"15.9gb","estimated_size_in_bytes":73996,"estimated_size":"72.2kb","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":11977097216,"limit_size":"11.1gb","estimated_size_in_bytes":124004,"estimated_size":"121kb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_2":{"count":0,"time_in_millis":0,"current":0,"failed":0},"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0}}}},"sJu6S4ZOSNKj2GewgLAA6w":{"timestamp":1511714498348,"name":"elasticin-01","transport_address":"10.0.0.109:9300","host":"elasticin-01","ip":"10.0.0.109:9300","roles":["ingest"],"attributes":{"ml.enabled":"true"},"indices":{"docs":{"count":0,"deleted":0},"store":{"size_in_bytes":0,"throttle_time_in_millis":0},"indexing":{"index_total":0,"index_time_in_millis":0,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":0},"refresh":{"total":0,"total_time_in_millis":0,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":0,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":0,"memory_in_bytes":0,"terms_memory_in_bytes":0,"stored_fields_memory_in_bytes":0,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":0,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":0,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-9223372036854775808,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"os":{"timestamp":1511714497945,"cpu":{"percent":5,"load_average":{"1m":0.33,"5m":0.37,"15m":0.32}},"mem":{"total_in_bytes":8375726080,"free_in_bytes":518225920,"used_in_bytes":7857500160,"free_percent":6,"used_percent":94},"swap":{"total_in_bytes":1073737728,"free_in_bytes":1073737728,"used_in_bytes":0},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":36799094034870},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}}}},"process":{"timestamp":1511714497945,"open_file_descriptors":507,"max_file_descriptors":1048576,"cpu":{"percent":0,"total_in_millis":36798970},"mem":{"total_virtual_in_bytes":8281767936}},"jvm":{"timestamp":1511714497945,"uptime_in_millis":589205044,"mem":{"heap_used_in_bytes":1052113704,"heap_used_percent":24,"heap_committed_in_bytes":4260102144,"heap_max_in_bytes":4260102144,"non_heap_used_in_bytes":115304704,"non_heap_committed_in_bytes":122564608,"pools":{"young":{"used_in_bytes":49586432,"max_in_bytes":279183360,"peak_used_in_bytes":279183360,"peak_max_in_bytes":279183360},"survivor":{"used_in_bytes":3992336,"max_in_bytes":34865152,"peak_used_in_bytes":34865152,"peak_max_in_bytes":34865152},"old":{"used_in_bytes":998591504,"max_in_bytes":3946053632,"peak_used_in_bytes":3585864320,"peak_max_in_bytes":3946053632}}},"threads":{"count":59,"peak_count":161},"gc":{"collectors":{"young":{"collection_count":57750,"collection_time_in_millis":1081864},"old":{"collection_count":257,"collection_time_in_millis":23972}}},"buffer_pools":{"direct":{"count":40,"used_in_bytes":135831560,"total_capacity_in_bytes":135831559},"mapped":{"count":0,"used_in_bytes":0,"total_capacity_in_bytes":0}},"classes":{"current_loaded_count":13399,"total_loaded_count":13478,"total_unloaded_count":79}},"thread_pool":{"bulk":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":404291},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":7,"queue":0,"active":0,"rejected":0,"largest":109,"completed":765856},"get":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"index":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":5,"queue":0,"active":1,"rejected":0,"largest":5,"completed":1288944},"ml_autodetect":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"refresh":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"search":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1511714497945,"total":{"total_in_bytes":39836917760,"free_in_bytes":35580149760,"available_in_bytes":33532911616,"spins":"true"},"data":[{"path":"/usr/share/elasticsearch/data/nodes/0","mount":"/ (overlay)","type":"overlay","total_in_bytes":39836917760,"free_in_bytes":35580149760,"available_in_bytes":33532911616,"spins":"true"}],"io_stats":{}},"transport":{"server_open":135,"rx_count":5045776,"rx_size_in_bytes":152482073745,"tx_count":5048384,"tx_size_in_bytes":224365671464},"http":{"current_open":2,"total_opened":580259},"breakers":{"request":{"limit_size_in_bytes":2556061286,"limit_size":"2.3gb","estimated_size_in_bytes":230160,"estimated_size":"224.7kb","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":2556061286,"limit_size":"2.3gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":4260102144,"limit_size":"3.9gb","estimated_size_in_bytes":1916,"estimated_size":"1.8kb","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":2982071500,"limit_size":"2.7gb","estimated_size_in_bytes":232076,"estimated_size":"226.6kb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0},"xpack_monitoring_2":{"count":0,"time_in_millis":0,"current":0,"failed":0}}}},"bGzxfiCWT5KcR7jF4ADJ_g":{"timestamp":1511714498349,"name":"elasticdata-03","transport_address":"10.0.0.55:9300","host":"elasticdata-03","ip":"10.0.0.55:9300","roles":["data"],"attributes":{"ml.enabled":"true"},"indices":{"docs":{"count":501080121,"deleted":1190750},"store":{"size_in_bytes":315723703383,"throttle_time_in_millis":0},"indexing":{"index_total":650070635,"index_time_in_millis":167204215,"index_current":0,"index_failed":1332739,"delete_total":1968,"delete_time_in_millis":194,"delete_current":0,"noop_update_total":133,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":30909,"time_in_millis":2520,"exists_total":30907,"exists_time_in_millis":2520,"missing_total":2,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":639532,"query_time_in_millis":4571412,"query_current":0,"fetch_total":37389,"fetch_time_in_millis":510596,"fetch_current":0,"scroll_total":38,"scroll_time_in_millis":1484669,"scroll_current":1,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":207892,"total_time_in_millis":156215892,"total_docs":1938519154,"total_size_in_bytes":1192900048810,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":85295109,"total_auto_throttle_in_bytes":56331279192},"refresh":{"total":1794344,"total_time_in_millis":35971432,"listeners":0},"flush":{"total":3365,"total_time_in_millis":678944},"warmer":{"current":0,"total":1484801,"total_time_in_millis":689654},"query_cache":{"memory_size_in_bytes":111403405,"total_count":556164,"hit_count":117910,"miss_count":438254,"cache_size":17962,"cache_count":19094,"evictions":1132},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":4518,"memory_in_bytes":1141279472,"terms_memory_in_bytes":1037548187,"stored_fields_memory_in_bytes":77990264,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":8918784,"points_memory_in_bytes":2803229,"doc_values_memory_in_bytes":14019008,"index_writer_memory_in_bytes":3135060,"version_map_memory_in_bytes":4650,"fixed_bit_set_memory_in_bytes":96,"max_unsafe_auto_id_timestamp":1511222421028,"file_sizes":{}},"translog":{"operations":3730929,"size_in_bytes":3098662483},"request_cache":{"memory_size_in_bytes":246594,"evictions":0,"hit_count":497,"miss_count":396},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":7727317}},"os":{"timestamp":1511714497945,"cpu":{"percent":7,"load_average":{"1m":0.57,"5m":0.47,"15m":0.66}},"mem":{"total_in_bytes":33742192640,"free_in_bytes":307798016,"used_in_bytes":33434394624,"free_percent":1,"used_percent":99},"swap":{"total_in_bytes":1073737728,"free_in_bytes":725217280,"used_in_bytes":348520448},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":511903359994882},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}}}},"process":{"timestamp":1511714497945,"open_file_descriptors":1518,"max_file_descriptors":1048576,"cpu":{"percent":5,"total_in_millis":511900740},"mem":{"total_virtual_in_bytes":338006835200}},"jvm":{"timestamp":1511714497946,"uptime_in_millis":584100083,"mem":{"heap_used_in_bytes":4294670120,"heap_used_percent":25,"heap_committed_in_bytes":17110138880,"heap_max_in_bytes":17110138880,"non_heap_used_in_bytes":179614824,"non_heap_committed_in_bytes":189874176,"pools":{"young":{"used_in_bytes":236457480,"max_in_bytes":558432256,"peak_used_in_bytes":558432256,"peak_max_in_bytes":558432256},"survivor":{"used_in_bytes":22430736,"max_in_bytes":69730304,"peak_used_in_bytes":69730304,"peak_max_in_bytes":69730304},"old":{"used_in_bytes":4035781904,"max_in_bytes":16481976320,"peak_used_in_bytes":13487381760,"peak_max_in_bytes":16481976320}}},"threads":{"count":136,"peak_count":273},"gc":{"collectors":{"young":{"collection_count":193711,"collection_time_in_millis":6942549},"old":{"collection_count":255,"collection_time_in_millis":56702}}},"buffer_pools":{"direct":{"count":111,"used_in_bytes":288779021,"total_capacity_in_bytes":288779020},"mapped":{"count":10210,"used_in_bytes":313880786534,"total_capacity_in_bytes":313880786534}},"classes":{"current_loaded_count":15315,"total_loaded_count":15459,"total_unloaded_count":144}},"thread_pool":{"bulk":{"threads":8,"queue":0,"active":0,"rejected":96063,"largest":8,"completed":6843393},"fetch_shard_started":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":16,"completed":2821},"fetch_shard_store":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":16,"completed":10417},"flush":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":235466},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":9,"queue":0,"active":0,"rejected":0,"largest":128,"completed":1203023},"get":{"threads":8,"queue":0,"active":0,"rejected":0,"largest":8,"completed":30308},"index":{"threads":8,"queue":0,"active":0,"rejected":0,"largest":8,"completed":1047},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":5,"queue":0,"active":3,"rejected":0,"largest":5,"completed":1911510},"ml_autodetect":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"refresh":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":122518082},"search":{"threads":13,"queue":0,"active":0,"rejected":0,"largest":13,"completed":647893},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":1799955},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1511714497946,"total":{"total_in_bytes":528310788096,"free_in_bytes":203463053312,"available_in_bytes":203446276096,"spins":"true"},"data":[{"path":"/mnt/data/nodes/0","mount":"/mnt/data (/dev/sdb1)","type":"ext4","total_in_bytes":528310788096,"free_in_bytes":203463053312,"available_in_bytes":203446276096,"spins":"true"}],"io_stats":{"devices":[{"device_name":"sdb1","operations":35923102,"read_operations":5207659,"write_operations":30715443,"read_kilobytes":618782872,"write_kilobytes":2076833544}],"total":{"operations":35923102,"read_operations":5207659,"write_operations":30715443,"read_kilobytes":618782872,"write_kilobytes":2076833544}}},"transport":{"server_open":133,"rx_count":17156365,"rx_size_in_bytes":1032986412750,"tx_count":17159929,"tx_size_in_bytes":933277781744},"http":{"current_open":2,"total_opened":500007},"breakers":{"request":{"limit_size_in_bytes":10266083328,"limit_size":"9.5gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":10266083328,"limit_size":"9.5gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":17110138880,"limit_size":"15.9gb","estimated_size_in_bytes":39799,"estimated_size":"38.8kb","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":11977097216,"limit_size":"11.1gb","estimated_size_in_bytes":39799,"estimated_size":"38.8kb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0},"xpack_monitoring_2":{"count":0,"time_in_millis":0,"current":0,"failed":0}}}},"mr05ujLDTdq-vCnCNuCL8Q":{"timestamp":1511714498348,"name":"elasticcli-01","transport_address":"10.0.0.115:9300","host":"elasticcli-01","ip":"10.0.0.115:9300","roles":[],"attributes":{"ml.enabled":"true"},"indices":{"docs":{"count":0,"deleted":0},"store":{"size_in_bytes":0,"throttle_time_in_millis":0},"indexing":{"index_total":0,"index_time_in_millis":0,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":0},"refresh":{"total":0,"total_time_in_millis":0,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":0,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":0,"memory_in_bytes":0,"terms_memory_in_bytes":0,"stored_fields_memory_in_bytes":0,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":0,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":0,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-9223372036854775808,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"os":{"timestamp":1511714497945,"cpu":{"percent":8,"load_average":{"1m":0.3,"5m":0.24,"15m":0.27}},"mem":{"total_in_bytes":8375726080,"free_in_bytes":252256256,"used_in_bytes":8123469824,"free_percent":3,"used_percent":97},"swap":{"total_in_bytes":1073737728,"free_in_bytes":726077440,"used_in_bytes":347660288},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":30184458419459},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}}}},"process":{"timestamp":1511714497945,"open_file_descriptors":518,"max_file_descriptors":1048576,"cpu":{"percent":2,"total_in_millis":30184300},"mem":{"total_virtual_in_bytes":6093246464}},"jvm":{"timestamp":1511714497945,"uptime_in_millis":445557994,"mem":{"heap_used_in_bytes":1203681360,"heap_used_percent":56,"heap_committed_in_bytes":2112618496,"heap_max_in_bytes":2112618496,"non_heap_used_in_bytes":122900392,"non_heap_committed_in_bytes":130781184,"pools":{"young":{"used_in_bytes":192372408,"max_in_bytes":279183360,"peak_used_in_bytes":279183360,"peak_max_in_bytes":279183360},"survivor":{"used_in_bytes":34865152,"max_in_bytes":34865152,"peak_used_in_bytes":34865152,"peak_max_in_bytes":34865152},"old":{"used_in_bytes":976443800,"max_in_bytes":1798569984,"peak_used_in_bytes":1798569944,"peak_max_in_bytes":1798569984}}},"threads":{"count":63,"peak_count":64},"gc":{"collectors":{"young":{"collection_count":47488,"collection_time_in_millis":897897},"old":{"collection_count":544,"collection_time_in_millis":140989}}},"buffer_pools":{"direct":{"count":41,"used_in_bytes":152608776,"total_capacity_in_bytes":152608775},"mapped":{"count":0,"used_in_bytes":0,"total_capacity_in_bytes":0}},"classes":{"current_loaded_count":13664,"total_loaded_count":13736,"total_unloaded_count":72}},"thread_pool":{"bulk":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":8,"queue":0,"active":0,"rejected":0,"largest":8,"completed":578181},"get":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"index":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":5,"queue":0,"active":1,"rejected":0,"largest":5,"completed":1268638},"ml_autodetect":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"refresh":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"search":{"threads":7,"queue":0,"active":0,"rejected":0,"largest":7,"completed":365840},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1511714497945,"total":{"total_in_bytes":39836917760,"free_in_bytes":21528715264,"available_in_bytes":19481477120,"spins":"true"},"data":[{"path":"/usr/share/elasticsearch/data/nodes/0","mount":"/ (overlay)","type":"overlay","total_in_bytes":39836917760,"free_in_bytes":21528715264,"available_in_bytes":19481477120,"spins":"true"}],"io_stats":{}},"transport":{"server_open":135,"rx_count":9063293,"rx_size_in_bytes":184591046718,"tx_count":9063303,"tx_size_in_bytes":82805398412},"http":{"current_open":14,"total_opened":410363},"breakers":{"request":{"limit_size_in_bytes":1267571097,"limit_size":"1.1gb","estimated_size_in_bytes":131520,"estimated_size":"128.4kb","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":1267571097,"limit_size":"1.1gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":2112618496,"limit_size":"1.9gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":1478832947,"limit_size":"1.3gb","estimated_size_in_bytes":131520,"estimated_size":"128.4kb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_2":{"count":0,"time_in_millis":0,"current":0,"failed":0},"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0}}}},"1rpMsJDnTFaSPdkBQM110g":{"timestamp":1511714498348,"name":"elasticdata-02","transport_address":"10.0.0.116:9300","host":"elasticdata-02","ip":"10.0.0.116:9300","roles":["data"],"attributes":{"ml.enabled":"true"},"indices":{"docs":{"count":408294223,"deleted":1074290},"store":{"size_in_bytes":257612662026,"throttle_time_in_millis":0},"indexing":{"index_total":568986485,"index_time_in_millis":135970122,"index_current":0,"index_failed":24361127,"delete_total":232,"delete_time_in_millis":29,"delete_current":0,"noop_update_total":113,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":15516,"time_in_millis":1369,"exists_total":15485,"exists_time_in_millis":1368,"missing_total":31,"missing_time_in_millis":1,"current":0},"search":{"open_contexts":0,"query_total":480400,"query_time_in_millis":4147683,"query_current":0,"fetch_total":25811,"fetch_time_in_millis":555392,"fetch_current":0,"scroll_total":19,"scroll_time_in_millis":1307018,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":199042,"total_time_in_millis":117076364,"total_docs":1647292265,"total_size_in_bytes":1026463665180,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":52910999,"total_auto_throttle_in_bytes":64807275536},"refresh":{"total":1782072,"total_time_in_millis":31882918,"listeners":0},"flush":{"total":2504,"total_time_in_millis":562585},"warmer":{"current":0,"total":1453580,"total_time_in_millis":429293},"query_cache":{"memory_size_in_bytes":167693059,"total_count":1256138,"hit_count":657110,"miss_count":599028,"cache_size":9740,"cache_count":11960,"evictions":2220},"fielddata":{"memory_size_in_bytes":46760,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":4310,"memory_in_bytes":890541030,"terms_memory_in_bytes":798812291,"stored_fields_memory_in_bytes":63063768,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":8041856,"points_memory_in_bytes":4360995,"doc_values_memory_in_bytes":16262120,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":344,"max_unsafe_auto_id_timestamp":1511654404456,"file_sizes":{}},"translog":{"operations":2491457,"size_in_bytes":2453361251},"request_cache":{"memory_size_in_bytes":150055283,"evictions":16383,"hit_count":19785,"miss_count":38600},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":7657996}},"os":{"timestamp":1511714497945,"cpu":{"percent":9,"load_average":{"1m":0.88,"5m":0.92,"15m":0.87}},"mem":{"total_in_bytes":33742192640,"free_in_bytes":657498112,"used_in_bytes":33084694528,"free_percent":2,"used_percent":98},"swap":{"total_in_bytes":1073737728,"free_in_bytes":762204160,"used_in_bytes":311533568},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":473118153915722},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}}}},"process":{"timestamp":1511714497945,"open_file_descriptors":1499,"max_file_descriptors":1048576,"cpu":{"percent":9,"total_in_millis":473115920},"mem":{"total_virtual_in_bytes":279946231808}},"jvm":{"timestamp":1511714497946,"uptime_in_millis":584148847,"mem":{"heap_used_in_bytes":11282849256,"heap_used_percent":65,"heap_committed_in_bytes":17110138880,"heap_max_in_bytes":17110138880,"non_heap_used_in_bytes":182476568,"non_heap_committed_in_bytes":192057344,"pools":{"young":{"used_in_bytes":386452168,"max_in_bytes":558432256,"peak_used_in_bytes":558432256,"peak_max_in_bytes":558432256},"survivor":{"used_in_bytes":29119144,"max_in_bytes":69730304,"peak_used_in_bytes":69730304,"peak_max_in_bytes":69730304},"old":{"used_in_bytes":10867277944,"max_in_bytes":16481976320,"peak_used_in_bytes":16388546600,"peak_max_in_bytes":16481976320}}},"threads":{"count":135,"peak_count":195},"gc":{"collectors":{"young":{"collection_count":175896,"collection_time_in_millis":6408288},"old":{"collection_count":146,"collection_time_in_millis":58079}}},"buffer_pools":{"direct":{"count":136,"used_in_bytes":272251175,"total_capacity_in_bytes":272251174},"mapped":{"count":9822,"used_in_bytes":256092821621,"total_capacity_in_bytes":256092821621}},"classes":{"current_loaded_count":15342,"total_loaded_count":15513,"total_unloaded_count":171}},"thread_pool":{"bulk":{"threads":8,"queue":0,"active":0,"rejected":99626,"largest":8,"completed":5768105},"fetch_shard_started":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":16,"completed":3316},"fetch_shard_store":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":16,"completed":10424},"flush":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":232408},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":8,"queue":0,"active":0,"rejected":0,"largest":52,"completed":1355815},"get":{"threads":8,"queue":0,"active":0,"rejected":0,"largest":8,"completed":15129},"index":{"threads":8,"queue":0,"active":0,"rejected":0,"largest":8,"completed":477},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":5,"queue":0,"active":3,"rejected":0,"largest":5,"completed":1911497},"ml_autodetect":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"refresh":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":123430269},"search":{"threads":13,"queue":0,"active":0,"rejected":0,"largest":13,"completed":492351},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":1788033},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1511714497946,"total":{"total_in_bytes":528311836672,"free_in_bytes":259594153984,"available_in_bytes":232733884416,"spins":"true"},"data":[{"path":"/mnt/data/nodes/0","mount":"/mnt/data (/dev/sdb1)","type":"ext4","total_in_bytes":528311836672,"free_in_bytes":259594153984,"available_in_bytes":232733884416,"spins":"true"}],"io_stats":{"devices":[{"device_name":"sdb1","operations":29499136,"read_operations":3305656,"write_operations":26193480,"read_kilobytes":412087356,"write_kilobytes":1819822768}],"total":{"operations":29499136,"read_operations":3305656,"write_operations":26193480,"read_kilobytes":412087356,"write_kilobytes":1819822768}}},"transport":{"server_open":133,"rx_count":15001696,"rx_size_in_bytes":1002526189002,"tx_count":15004766,"tx_size_in_bytes":1130024582664},"http":{"current_open":2,"total_opened":508442},"breakers":{"request":{"limit_size_in_bytes":10266083328,"limit_size":"9.5gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":10266083328,"limit_size":"9.5gb","estimated_size_in_bytes":46760,"estimated_size":"45.6kb","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":17110138880,"limit_size":"15.9gb","estimated_size_in_bytes":78944,"estimated_size":"77kb","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":11977097216,"limit_size":"11.1gb","estimated_size_in_bytes":125704,"estimated_size":"122.7kb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0},"xpack_monitoring_2":{"count":0,"time_in_millis":0,"current":0,"failed":0}}}},"mJtnri1LTJaymDIay6aJLQ":{"timestamp":1511714498349,"name":"elasticdata-06","transport_address":"10.0.0.97:9300","host":"elasticdata-06","ip":"10.0.0.97:9300","roles":["data"],"attributes":{"ml.enabled":"true"},"indices":{"docs":{"count":458706036,"deleted":1011663},"store":{"size_in_bytes":305879051264,"throttle_time_in_millis":0},"indexing":{"index_total":352418731,"index_time_in_millis":96827787,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":166624,"time_in_millis":12473,"exists_total":166624,"exists_time_in_millis":12473,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":482343,"query_time_in_millis":2076387,"query_current":0,"fetch_total":169199,"fetch_time_in_millis":184224,"fetch_current":0,"scroll_total":2,"scroll_time_in_millis":240038,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":182114,"total_time_in_millis":127605140,"total_docs":1363877914,"total_size_in_bytes":960500345231,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":73083213,"total_auto_throttle_in_bytes":9823313645},"refresh":{"total":1567704,"total_time_in_millis":26218140,"listeners":0},"flush":{"total":1045,"total_time_in_millis":321661},"warmer":{"current":0,"total":1568611,"total_time_in_millis":696377},"query_cache":{"memory_size_in_bytes":80475461,"total_count":786337,"hit_count":444550,"miss_count":341787,"cache_size":8871,"cache_count":10021,"evictions":1150},"fielddata":{"memory_size_in_bytes":55288,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":4465,"memory_in_bytes":1098390078,"terms_memory_in_bytes":996710745,"stored_fields_memory_in_bytes":72784232,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":8683072,"points_memory_in_bytes":4155561,"doc_values_memory_in_bytes":16056468,"index_writer_memory_in_bytes":911700,"version_map_memory_in_bytes":4650,"fixed_bit_set_memory_in_bytes":528,"max_unsafe_auto_id_timestamp":1511481600745,"file_sizes":{}},"translog":{"operations":3503036,"size_in_bytes":3357895432},"request_cache":{"memory_size_in_bytes":98505744,"evictions":0,"hit_count":26090,"miss_count":34723},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":1793510}},"os":{"timestamp":1511714497945,"cpu":{"percent":9,"load_average":{"1m":0.54,"5m":0.66,"15m":0.89}},"mem":{"total_in_bytes":33742192640,"free_in_bytes":329875456,"used_in_bytes":33412317184,"free_percent":1,"used_percent":99},"swap":{"total_in_bytes":1073737728,"free_in_bytes":755060736,"used_in_bytes":318676992},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":345265404353469},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}}}},"process":{"timestamp":1511714497945,"open_file_descriptors":1347,"max_file_descriptors":1048576,"cpu":{"percent":8,"total_in_millis":345263060},"mem":{"total_virtual_in_bytes":326659825664}},"jvm":{"timestamp":1511714497946,"uptime_in_millis":431203379,"mem":{"heap_used_in_bytes":6856054400,"heap_used_percent":40,"heap_committed_in_bytes":17110138880,"heap_max_in_bytes":17110138880,"non_heap_used_in_bytes":168673048,"non_heap_committed_in_bytes":177786880,"pools":{"young":{"used_in_bytes":481488392,"max_in_bytes":558432256,"peak_used_in_bytes":558432256,"peak_max_in_bytes":558432256},"survivor":{"used_in_bytes":21141648,"max_in_bytes":69730304,"peak_used_in_bytes":69730304,"peak_max_in_bytes":69730304},"old":{"used_in_bytes":6353424360,"max_in_bytes":16481976320,"peak_used_in_bytes":12677713896,"peak_max_in_bytes":16481976320}}},"threads":{"count":128,"peak_count":135},"gc":{"collectors":{"young":{"collection_count":127223,"collection_time_in_millis":4468108},"old":{"collection_count":35,"collection_time_in_millis":13393}}},"buffer_pools":{"direct":{"count":125,"used_in_bytes":272179208,"total_capacity_in_bytes":272179207},"mapped":{"count":10044,"used_in_bytes":302869020633,"total_capacity_in_bytes":302869020633}},"classes":{"current_loaded_count":15194,"total_loaded_count":15397,"total_unloaded_count":203}},"thread_pool":{"bulk":{"threads":8,"queue":0,"active":0,"rejected":656,"largest":8,"completed":5424968},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":172578},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":7,"queue":0,"active":0,"rejected":0,"largest":7,"completed":981787},"get":{"threads":8,"queue":0,"active":0,"rejected":0,"largest":8,"completed":166535},"index":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":4},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":5,"queue":0,"active":2,"rejected":0,"largest":5,"completed":1391304},"ml_autodetect":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"refresh":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":95745951},"search":{"threads":13,"queue":0,"active":0,"rejected":0,"largest":13,"completed":485078},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":1569132},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1511714497946,"total":{"total_in_bytes":528310788096,"free_in_bytes":218908598272,"available_in_bytes":218891821056,"spins":"true"},"data":[{"path":"/mnt/data/nodes/0","mount":"/mnt/data (/dev/sdb1)","type":"ext4","total_in_bytes":528310788096,"free_in_bytes":218908598272,"available_in_bytes":218891821056,"spins":"true"}],"io_stats":{"devices":[{"device_name":"sdb1","operations":25942355,"read_operations":1681165,"write_operations":24261190,"read_kilobytes":193190936,"write_kilobytes":1621218228}],"total":{"operations":25942355,"read_operations":1681165,"write_operations":24261190,"read_kilobytes":193190936,"write_kilobytes":1621218228}}},"transport":{"server_open":133,"rx_count":12260547,"rx_size_in_bytes":541703802431,"tx_count":12260545,"tx_size_in_bytes":346776082145},"http":{"current_open":2,"total_opened":381606},"breakers":{"request":{"limit_size_in_bytes":10266083328,"limit_size":"9.5gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":10266083328,"limit_size":"9.5gb","estimated_size_in_bytes":55288,"estimated_size":"53.9kb","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":17110138880,"limit_size":"15.9gb","estimated_size_in_bytes":37927,"estimated_size":"37kb","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":11977097216,"limit_size":"11.1gb","estimated_size_in_bytes":93215,"estimated_size":"91kb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_2":{"count":0,"time_in_millis":0,"current":0,"failed":0},"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0}}}},"UM8bpuowTXq2xX5B_w96jg":{"timestamp":1511714498349,"name":"elasticcli-02","transport_address":"10.0.0.114:9300","host":"elasticcli-02","ip":"10.0.0.114:9300","roles":[],"attributes":{"ml.enabled":"true"},"indices":{"docs":{"count":0,"deleted":0},"store":{"size_in_bytes":0,"throttle_time_in_millis":0},"indexing":{"index_total":0,"index_time_in_millis":0,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":0},"refresh":{"total":0,"total_time_in_millis":0,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":0,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":0,"memory_in_bytes":0,"terms_memory_in_bytes":0,"stored_fields_memory_in_bytes":0,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":0,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":0,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-9223372036854775808,"file_sizes":{}},"translog":{"operations":0,"size_in_bytes":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"os":{"timestamp":1511714497945,"cpu":{"percent":8,"load_average":{"1m":0.11,"5m":0.29,"15m":0.38}},"mem":{"total_in_bytes":8375726080,"free_in_bytes":242339840,"used_in_bytes":8133386240,"free_percent":3,"used_percent":97},"swap":{"total_in_bytes":1073737728,"free_in_bytes":666390528,"used_in_bytes":407347200},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":24933856576484},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}}}},"process":{"timestamp":1511714497945,"open_file_descriptors":516,"max_file_descriptors":1048576,"cpu":{"percent":0,"total_in_millis":24933720},"mem":{"total_virtual_in_bytes":6057439232}},"jvm":{"timestamp":1511714497945,"uptime_in_millis":439494501,"mem":{"heap_used_in_bytes":630212256,"heap_used_percent":29,"heap_committed_in_bytes":2112618496,"heap_max_in_bytes":2112618496,"non_heap_used_in_bytes":123008888,"non_heap_committed_in_bytes":130932736,"pools":{"young":{"used_in_bytes":43037928,"max_in_bytes":279183360,"peak_used_in_bytes":279183360,"peak_max_in_bytes":279183360},"survivor":{"used_in_bytes":28583072,"max_in_bytes":34865152,"peak_used_in_bytes":34865152,"peak_max_in_bytes":34865152},"old":{"used_in_bytes":558591256,"max_in_bytes":1798569984,"peak_used_in_bytes":1783141720,"peak_max_in_bytes":1798569984}}},"threads":{"count":59,"peak_count":62},"gc":{"collectors":{"young":{"collection_count":39584,"collection_time_in_millis":605986},"old":{"collection_count":200,"collection_time_in_millis":25256}}},"buffer_pools":{"direct":{"count":40,"used_in_bytes":135831560,"total_capacity_in_bytes":135831559},"mapped":{"count":0,"used_in_bytes":0,"total_capacity_in_bytes":0}},"classes":{"current_loaded_count":13655,"total_loaded_count":13724,"total_unloaded_count":69}},"thread_pool":{"bulk":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":570734},"get":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"index":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":5,"queue":0,"active":1,"rejected":0,"largest":5,"completed":1243282},"ml_autodetect":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"refresh":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"search":{"threads":7,"queue":0,"active":0,"rejected":0,"largest":7,"completed":339462},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1511714497946,"total":{"total_in_bytes":39836917760,"free_in_bytes":21595881472,"available_in_bytes":19548643328,"spins":"true"},"data":[{"path":"/usr/share/elasticsearch/data/nodes/0","mount":"/ (overlay)","type":"overlay","total_in_bytes":39836917760,"free_in_bytes":21595881472,"available_in_bytes":19548643328,"spins":"true"}],"io_stats":{}},"transport":{"server_open":135,"rx_count":8721285,"rx_size_in_bytes":169344861699,"tx_count":8721284,"tx_size_in_bytes":73698352750},"http":{"current_open":11,"total_opened":403280},"breakers":{"request":{"limit_size_in_bytes":1267571097,"limit_size":"1.1gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":1267571097,"limit_size":"1.1gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":2112618496,"limit_size":"1.9gb","estimated_size_in_bytes":1916,"estimated_size":"1.8kb","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":1478832947,"limit_size":"1.3gb","estimated_size_in_bytes":1916,"estimated_size":"1.8kb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_2":{"count":0,"time_in_millis":0,"current":0,"failed":0},"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0}}}}}}`, + tests := []struct { + name string + file string + want string + }{ + // { + // name: "5.4.2", + // file: "../fixtures/nodestats/5.4.2.json", + // want: ``, + // }, + { + name: "5.6.16", + file: "../fixtures/nodestats/5.6.16.json", + want: `# HELP elasticsearch_breakers_estimated_size_bytes Estimated size in bytes of breaker + # TYPE elasticsearch_breakers_estimated_size_bytes gauge + elasticsearch_breakers_estimated_size_bytes{breaker="fielddata",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + elasticsearch_breakers_estimated_size_bytes{breaker="in_flight_requests",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + elasticsearch_breakers_estimated_size_bytes{breaker="parent",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + elasticsearch_breakers_estimated_size_bytes{breaker="request",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_breakers_limit_size_bytes Limit size in bytes for breaker + # TYPE elasticsearch_breakers_limit_size_bytes gauge + elasticsearch_breakers_limit_size_bytes{breaker="fielddata",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 1.246652006e+09 + elasticsearch_breakers_limit_size_bytes{breaker="in_flight_requests",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 2.077753344e+09 + elasticsearch_breakers_limit_size_bytes{breaker="parent",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 1.45442734e+09 + elasticsearch_breakers_limit_size_bytes{breaker="request",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 1.246652006e+09 + # HELP elasticsearch_breakers_overhead Overhead of circuit breakers + # TYPE elasticsearch_breakers_overhead counter + elasticsearch_breakers_overhead{breaker="fielddata",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 1.03 + elasticsearch_breakers_overhead{breaker="in_flight_requests",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 1 + elasticsearch_breakers_overhead{breaker="parent",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 1 + elasticsearch_breakers_overhead{breaker="request",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 1 + # HELP elasticsearch_breakers_tripped tripped for breaker + # TYPE elasticsearch_breakers_tripped counter + elasticsearch_breakers_tripped{breaker="fielddata",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + elasticsearch_breakers_tripped{breaker="in_flight_requests",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + elasticsearch_breakers_tripped{breaker="parent",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + elasticsearch_breakers_tripped{breaker="request",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_filesystem_data_available_bytes Available space on block device in bytes + # TYPE elasticsearch_filesystem_data_available_bytes gauge + elasticsearch_filesystem_data_available_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",mount="/usr/share/elasticsearch/data (/dev/mapper/vg0-root)",name="bVrN1Hx",path="/usr/share/elasticsearch/data/nodes/0"} 7.7533405184e+10 + # HELP elasticsearch_filesystem_data_free_bytes Free space on block device in bytes + # TYPE elasticsearch_filesystem_data_free_bytes gauge + elasticsearch_filesystem_data_free_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",mount="/usr/share/elasticsearch/data (/dev/mapper/vg0-root)",name="bVrN1Hx",path="/usr/share/elasticsearch/data/nodes/0"} 7.7533405184e+10 + # HELP elasticsearch_filesystem_data_size_bytes Size of block device in bytes + # TYPE elasticsearch_filesystem_data_size_bytes gauge + elasticsearch_filesystem_data_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",mount="/usr/share/elasticsearch/data (/dev/mapper/vg0-root)",name="bVrN1Hx",path="/usr/share/elasticsearch/data/nodes/0"} 4.76630163456e+11 + # HELP elasticsearch_filesystem_io_stats_device_operations_count Count of disk operations + # TYPE elasticsearch_filesystem_io_stats_device_operations_count counter + elasticsearch_filesystem_io_stats_device_operations_count{cluster="elasticsearch",device="dm-2",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 2517 + # HELP elasticsearch_filesystem_io_stats_device_read_operations_count Count of disk read operations + # TYPE elasticsearch_filesystem_io_stats_device_read_operations_count counter + elasticsearch_filesystem_io_stats_device_read_operations_count{cluster="elasticsearch",device="dm-2",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 706 + # HELP elasticsearch_filesystem_io_stats_device_read_size_kilobytes_sum Total kilobytes read from disk + # TYPE elasticsearch_filesystem_io_stats_device_read_size_kilobytes_sum counter + elasticsearch_filesystem_io_stats_device_read_size_kilobytes_sum{cluster="elasticsearch",device="dm-2",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 12916 + # HELP elasticsearch_filesystem_io_stats_device_write_operations_count Count of disk write operations + # TYPE elasticsearch_filesystem_io_stats_device_write_operations_count counter + elasticsearch_filesystem_io_stats_device_write_operations_count{cluster="elasticsearch",device="dm-2",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 1811 + # HELP elasticsearch_filesystem_io_stats_device_write_size_kilobytes_sum Total kilobytes written to disk + # TYPE elasticsearch_filesystem_io_stats_device_write_size_kilobytes_sum counter + elasticsearch_filesystem_io_stats_device_write_size_kilobytes_sum{cluster="elasticsearch",device="dm-2",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 17760 + # HELP elasticsearch_indices_completion_size_in_bytes Completion in bytes + # TYPE elasticsearch_indices_completion_size_in_bytes counter + elasticsearch_indices_completion_size_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_docs Count of documents on this node + # TYPE elasticsearch_indices_docs gauge + elasticsearch_indices_docs{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 5 + # HELP elasticsearch_indices_docs_deleted Count of deleted documents on this node + # TYPE elasticsearch_indices_docs_deleted gauge + elasticsearch_indices_docs_deleted{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_fielddata_evictions Evictions from field data + # TYPE elasticsearch_indices_fielddata_evictions counter + elasticsearch_indices_fielddata_evictions{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_fielddata_memory_size_bytes Field data cache memory usage in bytes + # TYPE elasticsearch_indices_fielddata_memory_size_bytes gauge + elasticsearch_indices_fielddata_memory_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_filter_cache_evictions Evictions from filter cache + # TYPE elasticsearch_indices_filter_cache_evictions counter + elasticsearch_indices_filter_cache_evictions{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_filter_cache_memory_size_bytes Filter cache memory usage in bytes + # TYPE elasticsearch_indices_filter_cache_memory_size_bytes gauge + elasticsearch_indices_filter_cache_memory_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_flush_time_seconds Cumulative flush time in seconds + # TYPE elasticsearch_indices_flush_time_seconds counter + elasticsearch_indices_flush_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_flush_total Total flushes + # TYPE elasticsearch_indices_flush_total counter + elasticsearch_indices_flush_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_get_exists_time_seconds Total time get exists in seconds + # TYPE elasticsearch_indices_get_exists_time_seconds counter + elasticsearch_indices_get_exists_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_get_exists_total Total get exists operations + # TYPE elasticsearch_indices_get_exists_total counter + elasticsearch_indices_get_exists_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_get_missing_time_seconds Total time of get missing in seconds + # TYPE elasticsearch_indices_get_missing_time_seconds counter + elasticsearch_indices_get_missing_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_get_missing_total Total get missing + # TYPE elasticsearch_indices_get_missing_total counter + elasticsearch_indices_get_missing_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_get_time_seconds Total get time in seconds + # TYPE elasticsearch_indices_get_time_seconds counter + elasticsearch_indices_get_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_get_total Total get + # TYPE elasticsearch_indices_get_total counter + elasticsearch_indices_get_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_indexing_delete_time_seconds_total Total time indexing delete in seconds + # TYPE elasticsearch_indices_indexing_delete_time_seconds_total counter + elasticsearch_indices_indexing_delete_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_indexing_delete_total Total indexing deletes + # TYPE elasticsearch_indices_indexing_delete_total counter + elasticsearch_indices_indexing_delete_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_indexing_index_time_seconds_total Cumulative index time in seconds + # TYPE elasticsearch_indices_indexing_index_time_seconds_total counter + elasticsearch_indices_indexing_index_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0.039 + # HELP elasticsearch_indices_indexing_index_total Total index calls + # TYPE elasticsearch_indices_indexing_index_total counter + elasticsearch_indices_indexing_index_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 5 + # HELP elasticsearch_indices_indexing_is_throttled Indexing throttling + # TYPE elasticsearch_indices_indexing_is_throttled gauge + elasticsearch_indices_indexing_is_throttled{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_indexing_throttle_time_seconds_total Cumulative indexing throttling time + # TYPE elasticsearch_indices_indexing_throttle_time_seconds_total counter + elasticsearch_indices_indexing_throttle_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_merges_current Current merges + # TYPE elasticsearch_indices_merges_current gauge + elasticsearch_indices_merges_current{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_merges_current_size_in_bytes Size of a current merges in bytes + # TYPE elasticsearch_indices_merges_current_size_in_bytes gauge + elasticsearch_indices_merges_current_size_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_merges_docs_total Cumulative docs merged + # TYPE elasticsearch_indices_merges_docs_total counter + elasticsearch_indices_merges_docs_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_merges_total Total merges + # TYPE elasticsearch_indices_merges_total counter + elasticsearch_indices_merges_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_merges_total_size_bytes_total Total merge size in bytes + # TYPE elasticsearch_indices_merges_total_size_bytes_total counter + elasticsearch_indices_merges_total_size_bytes_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_merges_total_throttled_time_seconds_total Total throttled time of merges in seconds + # TYPE elasticsearch_indices_merges_total_throttled_time_seconds_total counter + elasticsearch_indices_merges_total_throttled_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_merges_total_time_seconds_total Total time spent merging in seconds + # TYPE elasticsearch_indices_merges_total_time_seconds_total counter + elasticsearch_indices_merges_total_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_query_cache_cache_size Query cache cache size + # TYPE elasticsearch_indices_query_cache_cache_size gauge + elasticsearch_indices_query_cache_cache_size{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_query_cache_cache_total Query cache cache count + # TYPE elasticsearch_indices_query_cache_cache_total counter + elasticsearch_indices_query_cache_cache_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_query_cache_count Query cache count + # TYPE elasticsearch_indices_query_cache_count counter + elasticsearch_indices_query_cache_count{cache="hit",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_query_cache_evictions Evictions from query cache + # TYPE elasticsearch_indices_query_cache_evictions counter + elasticsearch_indices_query_cache_evictions{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_query_cache_memory_size_bytes Query cache memory usage in bytes + # TYPE elasticsearch_indices_query_cache_memory_size_bytes gauge + elasticsearch_indices_query_cache_memory_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_query_cache_total Query cache total count + # TYPE elasticsearch_indices_query_cache_total counter + elasticsearch_indices_query_cache_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_query_miss_count Query miss count + # TYPE elasticsearch_indices_query_miss_count counter + elasticsearch_indices_query_miss_count{cache="miss",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_refresh_external_time_seconds_total Total time spent external refreshing in seconds + # TYPE elasticsearch_indices_refresh_external_time_seconds_total counter + elasticsearch_indices_refresh_external_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_refresh_external_total Total external refreshes + # TYPE elasticsearch_indices_refresh_external_total counter + elasticsearch_indices_refresh_external_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_refresh_time_seconds_total Total time spent refreshing in seconds + # TYPE elasticsearch_indices_refresh_time_seconds_total counter + elasticsearch_indices_refresh_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0.086 + # HELP elasticsearch_indices_refresh_total Total refreshes + # TYPE elasticsearch_indices_refresh_total counter + elasticsearch_indices_refresh_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 65 + # HELP elasticsearch_indices_request_cache_count Request cache count + # TYPE elasticsearch_indices_request_cache_count counter + elasticsearch_indices_request_cache_count{cache="hit",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_request_cache_evictions Evictions from request cache + # TYPE elasticsearch_indices_request_cache_evictions counter + elasticsearch_indices_request_cache_evictions{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_request_cache_memory_size_bytes Request cache memory usage in bytes + # TYPE elasticsearch_indices_request_cache_memory_size_bytes gauge + elasticsearch_indices_request_cache_memory_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_request_miss_count Request miss count + # TYPE elasticsearch_indices_request_miss_count counter + elasticsearch_indices_request_miss_count{cache="miss",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_search_fetch_time_seconds Total search fetch time in seconds + # TYPE elasticsearch_indices_search_fetch_time_seconds counter + elasticsearch_indices_search_fetch_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_search_fetch_total Total number of fetches + # TYPE elasticsearch_indices_search_fetch_total counter + elasticsearch_indices_search_fetch_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_search_query_time_seconds Total search query time in seconds + # TYPE elasticsearch_indices_search_query_time_seconds counter + elasticsearch_indices_search_query_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_search_query_total Total number of queries + # TYPE elasticsearch_indices_search_query_total counter + elasticsearch_indices_search_query_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_search_scroll_time_seconds Total scroll time in seconds + # TYPE elasticsearch_indices_search_scroll_time_seconds counter + elasticsearch_indices_search_scroll_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_search_scroll_total Total number of scrolls + # TYPE elasticsearch_indices_search_scroll_total counter + elasticsearch_indices_search_scroll_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_search_suggest_time_seconds Total suggest time in seconds + # TYPE elasticsearch_indices_search_suggest_time_seconds counter + elasticsearch_indices_search_suggest_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_search_suggest_total Total number of suggests + # TYPE elasticsearch_indices_search_suggest_total counter + elasticsearch_indices_search_suggest_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_segments_count Count of index segments on this node + # TYPE elasticsearch_indices_segments_count gauge + elasticsearch_indices_segments_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 5 + # HELP elasticsearch_indices_segments_doc_values_memory_in_bytes Count of doc values memory + # TYPE elasticsearch_indices_segments_doc_values_memory_in_bytes gauge + elasticsearch_indices_segments_doc_values_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 460 + # HELP elasticsearch_indices_segments_fixed_bit_set_memory_in_bytes Count of fixed bit set + # TYPE elasticsearch_indices_segments_fixed_bit_set_memory_in_bytes gauge + elasticsearch_indices_segments_fixed_bit_set_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_segments_index_writer_memory_in_bytes Count of memory for index writer on this node + # TYPE elasticsearch_indices_segments_index_writer_memory_in_bytes gauge + elasticsearch_indices_segments_index_writer_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_segments_memory_bytes Current memory size of segments in bytes + # TYPE elasticsearch_indices_segments_memory_bytes gauge + elasticsearch_indices_segments_memory_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 12940 + # HELP elasticsearch_indices_segments_norms_memory_in_bytes Count of memory used by norms + # TYPE elasticsearch_indices_segments_norms_memory_in_bytes gauge + elasticsearch_indices_segments_norms_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 960 + # HELP elasticsearch_indices_segments_points_memory_in_bytes Point values memory usage in bytes + # TYPE elasticsearch_indices_segments_points_memory_in_bytes gauge + elasticsearch_indices_segments_points_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_segments_stored_fields_memory_in_bytes Count of stored fields memory + # TYPE elasticsearch_indices_segments_stored_fields_memory_in_bytes gauge + elasticsearch_indices_segments_stored_fields_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 1560 + # HELP elasticsearch_indices_segments_term_vectors_memory_in_bytes Term vectors memory usage in bytes + # TYPE elasticsearch_indices_segments_term_vectors_memory_in_bytes gauge + elasticsearch_indices_segments_term_vectors_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_segments_terms_memory_in_bytes Count of terms in memory for this node + # TYPE elasticsearch_indices_segments_terms_memory_in_bytes gauge + elasticsearch_indices_segments_terms_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 9960 + # HELP elasticsearch_indices_segments_version_map_memory_in_bytes Version map memory usage in bytes + # TYPE elasticsearch_indices_segments_version_map_memory_in_bytes gauge + elasticsearch_indices_segments_version_map_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_store_size_bytes Current size of stored index data in bytes + # TYPE elasticsearch_indices_store_size_bytes gauge + elasticsearch_indices_store_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 5721 + # HELP elasticsearch_indices_store_throttle_time_seconds_total Throttle time for index store in seconds + # TYPE elasticsearch_indices_store_throttle_time_seconds_total counter + elasticsearch_indices_store_throttle_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_indices_translog_operations Total translog operations + # TYPE elasticsearch_indices_translog_operations counter + elasticsearch_indices_translog_operations{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 5 + # HELP elasticsearch_indices_translog_size_in_bytes Total translog size in bytes + # TYPE elasticsearch_indices_translog_size_in_bytes gauge + elasticsearch_indices_translog_size_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 1743 + # HELP elasticsearch_indices_warmer_time_seconds_total Total warmer time in seconds + # TYPE elasticsearch_indices_warmer_time_seconds_total counter + elasticsearch_indices_warmer_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0.001 + # HELP elasticsearch_indices_warmer_total Total warmer count + # TYPE elasticsearch_indices_warmer_total counter + elasticsearch_indices_warmer_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 35 + # HELP elasticsearch_jvm_buffer_pool_used_bytes JVM buffer currently used + # TYPE elasticsearch_jvm_buffer_pool_used_bytes gauge + elasticsearch_jvm_buffer_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="direct"} 2.52727869e+08 + elasticsearch_jvm_buffer_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="mapped"} 15007 + # HELP elasticsearch_jvm_gc_collection_seconds_count Count of JVM GC runs + # TYPE elasticsearch_jvm_gc_collection_seconds_count counter + elasticsearch_jvm_gc_collection_seconds_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",gc="old",host="127.0.0.1",name="bVrN1Hx"} 1 + elasticsearch_jvm_gc_collection_seconds_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",gc="young",host="127.0.0.1",name="bVrN1Hx"} 2 + # HELP elasticsearch_jvm_gc_collection_seconds_sum GC run time in seconds + # TYPE elasticsearch_jvm_gc_collection_seconds_sum counter + elasticsearch_jvm_gc_collection_seconds_sum{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",gc="old",host="127.0.0.1",name="bVrN1Hx"} 0.109 + elasticsearch_jvm_gc_collection_seconds_sum{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",gc="young",host="127.0.0.1",name="bVrN1Hx"} 0.143 + # HELP elasticsearch_jvm_memory_committed_bytes JVM memory currently committed by area + # TYPE elasticsearch_jvm_memory_committed_bytes gauge + elasticsearch_jvm_memory_committed_bytes{area="heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 2.077753344e+09 + elasticsearch_jvm_memory_committed_bytes{area="non-heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 7.5362304e+07 + # HELP elasticsearch_jvm_memory_max_bytes JVM memory max + # TYPE elasticsearch_jvm_memory_max_bytes gauge + elasticsearch_jvm_memory_max_bytes{area="heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 2.077753344e+09 + # HELP elasticsearch_jvm_memory_pool_max_bytes JVM memory max by pool + # TYPE elasticsearch_jvm_memory_pool_max_bytes counter + elasticsearch_jvm_memory_pool_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",pool="old"} 1.449590784e+09 + elasticsearch_jvm_memory_pool_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",pool="survivor"} 6.9730304e+07 + elasticsearch_jvm_memory_pool_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",pool="young"} 5.58432256e+08 + # HELP elasticsearch_jvm_memory_pool_peak_max_bytes JVM memory peak max by pool + # TYPE elasticsearch_jvm_memory_pool_peak_max_bytes counter + elasticsearch_jvm_memory_pool_peak_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",pool="old"} 1.449590784e+09 + elasticsearch_jvm_memory_pool_peak_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",pool="survivor"} 6.9730304e+07 + elasticsearch_jvm_memory_pool_peak_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",pool="young"} 5.58432256e+08 + # HELP elasticsearch_jvm_memory_pool_peak_used_bytes JVM memory peak used by pool + # TYPE elasticsearch_jvm_memory_pool_peak_used_bytes counter + elasticsearch_jvm_memory_pool_peak_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",pool="old"} 2.10051288e+08 + elasticsearch_jvm_memory_pool_peak_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",pool="survivor"} 6.9730304e+07 + elasticsearch_jvm_memory_pool_peak_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",pool="young"} 5.58432256e+08 + # HELP elasticsearch_jvm_memory_pool_used_bytes JVM memory currently used by pool + # TYPE elasticsearch_jvm_memory_pool_used_bytes gauge + elasticsearch_jvm_memory_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",pool="old"} 2.10051288e+08 + elasticsearch_jvm_memory_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",pool="survivor"} 6.9730304e+07 + elasticsearch_jvm_memory_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",pool="young"} 5.3925336e+07 + # HELP elasticsearch_jvm_memory_used_bytes JVM memory currently used by area + # TYPE elasticsearch_jvm_memory_used_bytes gauge + elasticsearch_jvm_memory_used_bytes{area="heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 3.33706928e+08 + elasticsearch_jvm_memory_used_bytes{area="non-heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 7.0212664e+07 + # HELP elasticsearch_jvm_uptime_seconds JVM process uptime in seconds + # TYPE elasticsearch_jvm_uptime_seconds gauge + elasticsearch_jvm_uptime_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="mapped"} 14.845 + # HELP elasticsearch_nodes_roles Node roles + # TYPE elasticsearch_nodes_roles gauge + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_cold"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_content"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_frozen"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_hot"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="data_warm"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="ingest"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="master"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="ml"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="remote_cluster_client"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="127.0.0.1",name="bVrN1Hx",role="transform"} 0 + # HELP elasticsearch_os_cpu_percent Percent CPU used by OS + # TYPE elasticsearch_os_cpu_percent gauge + elasticsearch_os_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 23 + # HELP elasticsearch_os_load1 Shortterm load average + # TYPE elasticsearch_os_load1 gauge + elasticsearch_os_load1{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 45.68 + # HELP elasticsearch_os_load15 Longterm load average + # TYPE elasticsearch_os_load15 gauge + elasticsearch_os_load15{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 96.01 + # HELP elasticsearch_os_load5 Midterm load average + # TYPE elasticsearch_os_load5 gauge + elasticsearch_os_load5{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 150.34 + # HELP elasticsearch_os_mem_actual_free_bytes Amount of free physical memory in bytes + # TYPE elasticsearch_os_mem_actual_free_bytes gauge + elasticsearch_os_mem_actual_free_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_os_mem_actual_used_bytes Amount of used physical memory in bytes + # TYPE elasticsearch_os_mem_actual_used_bytes gauge + elasticsearch_os_mem_actual_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_os_mem_free_bytes Amount of free physical memory in bytes + # TYPE elasticsearch_os_mem_free_bytes gauge + elasticsearch_os_mem_free_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 7.009173504e+09 + # HELP elasticsearch_os_mem_used_bytes Amount of used physical memory in bytes + # TYPE elasticsearch_os_mem_used_bytes gauge + elasticsearch_os_mem_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 2.6614063104e+10 + # HELP elasticsearch_process_cpu_percent Percent CPU used by process + # TYPE elasticsearch_process_cpu_percent gauge + elasticsearch_process_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 8 + # HELP elasticsearch_process_cpu_seconds_total Process CPU time in seconds + # TYPE elasticsearch_process_cpu_seconds_total counter + elasticsearch_process_cpu_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 14.51 + # HELP elasticsearch_process_max_files_descriptors Max file descriptors + # TYPE elasticsearch_process_max_files_descriptors gauge + elasticsearch_process_max_files_descriptors{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 1.048576e+06 + # HELP elasticsearch_process_mem_resident_size_bytes Resident memory in use by process in bytes + # TYPE elasticsearch_process_mem_resident_size_bytes gauge + elasticsearch_process_mem_resident_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_process_mem_share_size_bytes Shared memory in use by process in bytes + # TYPE elasticsearch_process_mem_share_size_bytes gauge + elasticsearch_process_mem_share_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_process_mem_virtual_size_bytes Total virtual memory used in bytes + # TYPE elasticsearch_process_mem_virtual_size_bytes gauge + elasticsearch_process_mem_virtual_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 8.293711872e+09 + # HELP elasticsearch_process_open_files_count Open file descriptors + # TYPE elasticsearch_process_open_files_count gauge + elasticsearch_process_open_files_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 308 + # HELP elasticsearch_thread_pool_active_count Thread Pool threads active + # TYPE elasticsearch_thread_pool_active_count gauge + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="bulk"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="flush"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="force_merge"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="generic"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="get"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="index"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="listener"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="management"} 1 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="refresh"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="search"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="snapshot"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="warmer"} 0 + # HELP elasticsearch_thread_pool_completed_count Thread Pool operations completed + # TYPE elasticsearch_thread_pool_completed_count counter + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="bulk"} 5 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="flush"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="force_merge"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="generic"} 38 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="get"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="index"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="listener"} 5 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="management"} 2 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="refresh"} 31 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="search"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="snapshot"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="warmer"} 0 + # HELP elasticsearch_thread_pool_largest_count Thread Pool largest threads count + # TYPE elasticsearch_thread_pool_largest_count gauge + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="bulk"} 5 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="flush"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="force_merge"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="generic"} 4 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="get"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="index"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="listener"} 4 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="management"} 1 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="refresh"} 1 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="search"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="snapshot"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="warmer"} 0 + # HELP elasticsearch_thread_pool_queue_count Thread Pool operations queued + # TYPE elasticsearch_thread_pool_queue_count gauge + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="bulk"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="flush"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="force_merge"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="generic"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="get"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="index"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="listener"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="management"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="refresh"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="search"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="snapshot"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="warmer"} 0 + # HELP elasticsearch_thread_pool_rejected_count Thread Pool operations rejected + # TYPE elasticsearch_thread_pool_rejected_count counter + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="bulk"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="flush"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="force_merge"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="generic"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="get"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="index"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="listener"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="management"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="refresh"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="search"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="snapshot"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="warmer"} 0 + # HELP elasticsearch_thread_pool_threads_count Thread Pool current threads count + # TYPE elasticsearch_thread_pool_threads_count gauge + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="bulk"} 5 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="flush"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="force_merge"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="generic"} 4 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="get"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="index"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="listener"} 4 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="management"} 1 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="refresh"} 1 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="search"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="snapshot"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx",type="warmer"} 0 + # HELP elasticsearch_transport_rx_packets_total Count of packets received + # TYPE elasticsearch_transport_rx_packets_total counter + elasticsearch_transport_rx_packets_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_transport_rx_size_bytes_total Total number of bytes received + # TYPE elasticsearch_transport_rx_size_bytes_total counter + elasticsearch_transport_rx_size_bytes_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_transport_tx_packets_total Count of packets sent + # TYPE elasticsearch_transport_tx_packets_total counter + elasticsearch_transport_tx_packets_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 + # HELP elasticsearch_transport_tx_size_bytes_total Total number of bytes sent + # TYPE elasticsearch_transport_tx_size_bytes_total counter + elasticsearch_transport_tx_size_bytes_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="127.0.0.1",name="bVrN1Hx"} 0 +`, + }, + { + name: "6.8.8", + file: "../fixtures/nodestats/6.8.8.json", + want: `# HELP elasticsearch_breakers_estimated_size_bytes Estimated size in bytes of breaker + # TYPE elasticsearch_breakers_estimated_size_bytes gauge + elasticsearch_breakers_estimated_size_bytes{breaker="accounting",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 8490 + elasticsearch_breakers_estimated_size_bytes{breaker="fielddata",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + elasticsearch_breakers_estimated_size_bytes{breaker="in_flight_requests",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + elasticsearch_breakers_estimated_size_bytes{breaker="parent",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 8490 + elasticsearch_breakers_estimated_size_bytes{breaker="request",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_breakers_limit_size_bytes Limit size in bytes for breaker + # TYPE elasticsearch_breakers_limit_size_bytes gauge + elasticsearch_breakers_limit_size_bytes{breaker="accounting",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 1.073741824e+09 + elasticsearch_breakers_limit_size_bytes{breaker="fielddata",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 6.44245094e+08 + elasticsearch_breakers_limit_size_bytes{breaker="in_flight_requests",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 1.073741824e+09 + elasticsearch_breakers_limit_size_bytes{breaker="parent",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 7.51619276e+08 + elasticsearch_breakers_limit_size_bytes{breaker="request",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 6.44245094e+08 + # HELP elasticsearch_breakers_overhead Overhead of circuit breakers + # TYPE elasticsearch_breakers_overhead counter + elasticsearch_breakers_overhead{breaker="accounting",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 1 + elasticsearch_breakers_overhead{breaker="fielddata",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 1.03 + elasticsearch_breakers_overhead{breaker="in_flight_requests",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 1 + elasticsearch_breakers_overhead{breaker="parent",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 1 + elasticsearch_breakers_overhead{breaker="request",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 1 + # HELP elasticsearch_breakers_tripped tripped for breaker + # TYPE elasticsearch_breakers_tripped counter + elasticsearch_breakers_tripped{breaker="accounting",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + elasticsearch_breakers_tripped{breaker="fielddata",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + elasticsearch_breakers_tripped{breaker="in_flight_requests",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + elasticsearch_breakers_tripped{breaker="parent",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + elasticsearch_breakers_tripped{breaker="request",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_filesystem_data_available_bytes Available space on block device in bytes + # TYPE elasticsearch_filesystem_data_available_bytes gauge + elasticsearch_filesystem_data_available_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",mount="/ (overlay)",name="9_P7yui",path="/usr/share/elasticsearch/data/nodes/0"} 7.753281536e+10 + # HELP elasticsearch_filesystem_data_free_bytes Free space on block device in bytes + # TYPE elasticsearch_filesystem_data_free_bytes gauge + elasticsearch_filesystem_data_free_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",mount="/ (overlay)",name="9_P7yui",path="/usr/share/elasticsearch/data/nodes/0"} 7.753281536e+10 + # HELP elasticsearch_filesystem_data_size_bytes Size of block device in bytes + # TYPE elasticsearch_filesystem_data_size_bytes gauge + elasticsearch_filesystem_data_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",mount="/ (overlay)",name="9_P7yui",path="/usr/share/elasticsearch/data/nodes/0"} 4.76630163456e+11 + # HELP elasticsearch_indices_completion_size_in_bytes Completion in bytes + # TYPE elasticsearch_indices_completion_size_in_bytes counter + elasticsearch_indices_completion_size_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_docs Count of documents on this node + # TYPE elasticsearch_indices_docs gauge + elasticsearch_indices_docs{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 5 + # HELP elasticsearch_indices_docs_deleted Count of deleted documents on this node + # TYPE elasticsearch_indices_docs_deleted gauge + elasticsearch_indices_docs_deleted{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_fielddata_evictions Evictions from field data + # TYPE elasticsearch_indices_fielddata_evictions counter + elasticsearch_indices_fielddata_evictions{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_fielddata_memory_size_bytes Field data cache memory usage in bytes + # TYPE elasticsearch_indices_fielddata_memory_size_bytes gauge + elasticsearch_indices_fielddata_memory_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_filter_cache_evictions Evictions from filter cache + # TYPE elasticsearch_indices_filter_cache_evictions counter + elasticsearch_indices_filter_cache_evictions{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_filter_cache_memory_size_bytes Filter cache memory usage in bytes + # TYPE elasticsearch_indices_filter_cache_memory_size_bytes gauge + elasticsearch_indices_filter_cache_memory_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_flush_time_seconds Cumulative flush time in seconds + # TYPE elasticsearch_indices_flush_time_seconds counter + elasticsearch_indices_flush_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_flush_total Total flushes + # TYPE elasticsearch_indices_flush_total counter + elasticsearch_indices_flush_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_get_exists_time_seconds Total time get exists in seconds + # TYPE elasticsearch_indices_get_exists_time_seconds counter + elasticsearch_indices_get_exists_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_get_exists_total Total get exists operations + # TYPE elasticsearch_indices_get_exists_total counter + elasticsearch_indices_get_exists_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_get_missing_time_seconds Total time of get missing in seconds + # TYPE elasticsearch_indices_get_missing_time_seconds counter + elasticsearch_indices_get_missing_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_get_missing_total Total get missing + # TYPE elasticsearch_indices_get_missing_total counter + elasticsearch_indices_get_missing_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_get_time_seconds Total get time in seconds + # TYPE elasticsearch_indices_get_time_seconds counter + elasticsearch_indices_get_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_get_total Total get + # TYPE elasticsearch_indices_get_total counter + elasticsearch_indices_get_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_indexing_delete_time_seconds_total Total time indexing delete in seconds + # TYPE elasticsearch_indices_indexing_delete_time_seconds_total counter + elasticsearch_indices_indexing_delete_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_indexing_delete_total Total indexing deletes + # TYPE elasticsearch_indices_indexing_delete_total counter + elasticsearch_indices_indexing_delete_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_indexing_index_time_seconds_total Cumulative index time in seconds + # TYPE elasticsearch_indices_indexing_index_time_seconds_total counter + elasticsearch_indices_indexing_index_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0.038 + # HELP elasticsearch_indices_indexing_index_total Total index calls + # TYPE elasticsearch_indices_indexing_index_total counter + elasticsearch_indices_indexing_index_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 5 + # HELP elasticsearch_indices_indexing_is_throttled Indexing throttling + # TYPE elasticsearch_indices_indexing_is_throttled gauge + elasticsearch_indices_indexing_is_throttled{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_indexing_throttle_time_seconds_total Cumulative indexing throttling time + # TYPE elasticsearch_indices_indexing_throttle_time_seconds_total counter + elasticsearch_indices_indexing_throttle_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_merges_current Current merges + # TYPE elasticsearch_indices_merges_current gauge + elasticsearch_indices_merges_current{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_merges_current_size_in_bytes Size of a current merges in bytes + # TYPE elasticsearch_indices_merges_current_size_in_bytes gauge + elasticsearch_indices_merges_current_size_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_merges_docs_total Cumulative docs merged + # TYPE elasticsearch_indices_merges_docs_total counter + elasticsearch_indices_merges_docs_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_merges_total Total merges + # TYPE elasticsearch_indices_merges_total counter + elasticsearch_indices_merges_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_merges_total_size_bytes_total Total merge size in bytes + # TYPE elasticsearch_indices_merges_total_size_bytes_total counter + elasticsearch_indices_merges_total_size_bytes_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_merges_total_throttled_time_seconds_total Total throttled time of merges in seconds + # TYPE elasticsearch_indices_merges_total_throttled_time_seconds_total counter + elasticsearch_indices_merges_total_throttled_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_merges_total_time_seconds_total Total time spent merging in seconds + # TYPE elasticsearch_indices_merges_total_time_seconds_total counter + elasticsearch_indices_merges_total_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_query_cache_cache_size Query cache cache size + # TYPE elasticsearch_indices_query_cache_cache_size gauge + elasticsearch_indices_query_cache_cache_size{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_query_cache_cache_total Query cache cache count + # TYPE elasticsearch_indices_query_cache_cache_total counter + elasticsearch_indices_query_cache_cache_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_query_cache_count Query cache count + # TYPE elasticsearch_indices_query_cache_count counter + elasticsearch_indices_query_cache_count{cache="hit",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_query_cache_evictions Evictions from query cache + # TYPE elasticsearch_indices_query_cache_evictions counter + elasticsearch_indices_query_cache_evictions{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_query_cache_memory_size_bytes Query cache memory usage in bytes + # TYPE elasticsearch_indices_query_cache_memory_size_bytes gauge + elasticsearch_indices_query_cache_memory_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_query_cache_total Query cache total count + # TYPE elasticsearch_indices_query_cache_total counter + elasticsearch_indices_query_cache_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_query_miss_count Query miss count + # TYPE elasticsearch_indices_query_miss_count counter + elasticsearch_indices_query_miss_count{cache="miss",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_refresh_external_time_seconds_total Total time spent external refreshing in seconds + # TYPE elasticsearch_indices_refresh_external_time_seconds_total counter + elasticsearch_indices_refresh_external_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_refresh_external_total Total external refreshes + # TYPE elasticsearch_indices_refresh_external_total counter + elasticsearch_indices_refresh_external_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_refresh_time_seconds_total Total time spent refreshing in seconds + # TYPE elasticsearch_indices_refresh_time_seconds_total counter + elasticsearch_indices_refresh_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0.103 + # HELP elasticsearch_indices_refresh_total Total refreshes + # TYPE elasticsearch_indices_refresh_total counter + elasticsearch_indices_refresh_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 65 + # HELP elasticsearch_indices_request_cache_count Request cache count + # TYPE elasticsearch_indices_request_cache_count counter + elasticsearch_indices_request_cache_count{cache="hit",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_request_cache_evictions Evictions from request cache + # TYPE elasticsearch_indices_request_cache_evictions counter + elasticsearch_indices_request_cache_evictions{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_request_cache_memory_size_bytes Request cache memory usage in bytes + # TYPE elasticsearch_indices_request_cache_memory_size_bytes gauge + elasticsearch_indices_request_cache_memory_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_request_miss_count Request miss count + # TYPE elasticsearch_indices_request_miss_count counter + elasticsearch_indices_request_miss_count{cache="miss",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_search_fetch_time_seconds Total search fetch time in seconds + # TYPE elasticsearch_indices_search_fetch_time_seconds counter + elasticsearch_indices_search_fetch_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_search_fetch_total Total number of fetches + # TYPE elasticsearch_indices_search_fetch_total counter + elasticsearch_indices_search_fetch_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_search_query_time_seconds Total search query time in seconds + # TYPE elasticsearch_indices_search_query_time_seconds counter + elasticsearch_indices_search_query_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_search_query_total Total number of queries + # TYPE elasticsearch_indices_search_query_total counter + elasticsearch_indices_search_query_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_search_scroll_time_seconds Total scroll time in seconds + # TYPE elasticsearch_indices_search_scroll_time_seconds counter + elasticsearch_indices_search_scroll_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_search_scroll_total Total number of scrolls + # TYPE elasticsearch_indices_search_scroll_total counter + elasticsearch_indices_search_scroll_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_search_suggest_time_seconds Total suggest time in seconds + # TYPE elasticsearch_indices_search_suggest_time_seconds counter + elasticsearch_indices_search_suggest_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_search_suggest_total Total number of suggests + # TYPE elasticsearch_indices_search_suggest_total counter + elasticsearch_indices_search_suggest_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_segments_count Count of index segments on this node + # TYPE elasticsearch_indices_segments_count gauge + elasticsearch_indices_segments_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 5 + # HELP elasticsearch_indices_segments_doc_values_memory_in_bytes Count of doc values memory + # TYPE elasticsearch_indices_segments_doc_values_memory_in_bytes gauge + elasticsearch_indices_segments_doc_values_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 340 + # HELP elasticsearch_indices_segments_fixed_bit_set_memory_in_bytes Count of fixed bit set + # TYPE elasticsearch_indices_segments_fixed_bit_set_memory_in_bytes gauge + elasticsearch_indices_segments_fixed_bit_set_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_segments_index_writer_memory_in_bytes Count of memory for index writer on this node + # TYPE elasticsearch_indices_segments_index_writer_memory_in_bytes gauge + elasticsearch_indices_segments_index_writer_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_segments_memory_bytes Current memory size of segments in bytes + # TYPE elasticsearch_indices_segments_memory_bytes gauge + elasticsearch_indices_segments_memory_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 8490 + # HELP elasticsearch_indices_segments_norms_memory_in_bytes Count of memory used by norms + # TYPE elasticsearch_indices_segments_norms_memory_in_bytes gauge + elasticsearch_indices_segments_norms_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 640 + # HELP elasticsearch_indices_segments_points_memory_in_bytes Point values memory usage in bytes + # TYPE elasticsearch_indices_segments_points_memory_in_bytes gauge + elasticsearch_indices_segments_points_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 5 + # HELP elasticsearch_indices_segments_stored_fields_memory_in_bytes Count of stored fields memory + # TYPE elasticsearch_indices_segments_stored_fields_memory_in_bytes gauge + elasticsearch_indices_segments_stored_fields_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 1560 + # HELP elasticsearch_indices_segments_term_vectors_memory_in_bytes Term vectors memory usage in bytes + # TYPE elasticsearch_indices_segments_term_vectors_memory_in_bytes gauge + elasticsearch_indices_segments_term_vectors_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_segments_terms_memory_in_bytes Count of terms in memory for this node + # TYPE elasticsearch_indices_segments_terms_memory_in_bytes gauge + elasticsearch_indices_segments_terms_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 5945 + # HELP elasticsearch_indices_segments_version_map_memory_in_bytes Version map memory usage in bytes + # TYPE elasticsearch_indices_segments_version_map_memory_in_bytes gauge + elasticsearch_indices_segments_version_map_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_store_size_bytes Current size of stored index data in bytes + # TYPE elasticsearch_indices_store_size_bytes gauge + elasticsearch_indices_store_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 7261 + # HELP elasticsearch_indices_store_throttle_time_seconds_total Throttle time for index store in seconds + # TYPE elasticsearch_indices_store_throttle_time_seconds_total counter + elasticsearch_indices_store_throttle_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_translog_operations Total translog operations + # TYPE elasticsearch_indices_translog_operations counter + elasticsearch_indices_translog_operations{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 5 + # HELP elasticsearch_indices_translog_size_in_bytes Total translog size in bytes + # TYPE elasticsearch_indices_translog_size_in_bytes gauge + elasticsearch_indices_translog_size_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 3753 + # HELP elasticsearch_indices_warmer_time_seconds_total Total warmer time in seconds + # TYPE elasticsearch_indices_warmer_time_seconds_total counter + elasticsearch_indices_warmer_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_indices_warmer_total Total warmer count + # TYPE elasticsearch_indices_warmer_total counter + elasticsearch_indices_warmer_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 35 + # HELP elasticsearch_jvm_buffer_pool_used_bytes JVM buffer currently used + # TYPE elasticsearch_jvm_buffer_pool_used_bytes gauge + elasticsearch_jvm_buffer_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="direct"} 1.68849056e+08 + elasticsearch_jvm_buffer_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="mapped"} 15179 + # HELP elasticsearch_jvm_gc_collection_seconds_count Count of JVM GC runs + # TYPE elasticsearch_jvm_gc_collection_seconds_count counter + elasticsearch_jvm_gc_collection_seconds_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",gc="old",host="172.17.0.2",name="9_P7yui"} 0 + elasticsearch_jvm_gc_collection_seconds_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",gc="young",host="172.17.0.2",name="9_P7yui"} 5 + # HELP elasticsearch_jvm_gc_collection_seconds_sum GC run time in seconds + # TYPE elasticsearch_jvm_gc_collection_seconds_sum counter + elasticsearch_jvm_gc_collection_seconds_sum{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",gc="old",host="172.17.0.2",name="9_P7yui"} 0 + elasticsearch_jvm_gc_collection_seconds_sum{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",gc="young",host="172.17.0.2",name="9_P7yui"} 0.08 + # HELP elasticsearch_jvm_memory_committed_bytes JVM memory currently committed by area + # TYPE elasticsearch_jvm_memory_committed_bytes gauge + elasticsearch_jvm_memory_committed_bytes{area="heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 1.073741824e+09 + elasticsearch_jvm_memory_committed_bytes{area="non-heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 1.179648e+08 + # HELP elasticsearch_jvm_memory_max_bytes JVM memory max + # TYPE elasticsearch_jvm_memory_max_bytes gauge + elasticsearch_jvm_memory_max_bytes{area="heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 1.073741824e+09 + # HELP elasticsearch_jvm_memory_pool_max_bytes JVM memory max by pool + # TYPE elasticsearch_jvm_memory_pool_max_bytes counter + elasticsearch_jvm_memory_pool_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",pool="old"} 1.073741824e+09 + elasticsearch_jvm_memory_pool_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",pool="survivor"} 0 + elasticsearch_jvm_memory_pool_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",pool="young"} 0 + # HELP elasticsearch_jvm_memory_pool_peak_max_bytes JVM memory peak max by pool + # TYPE elasticsearch_jvm_memory_pool_peak_max_bytes counter + elasticsearch_jvm_memory_pool_peak_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",pool="old"} 1.073741824e+09 + elasticsearch_jvm_memory_pool_peak_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",pool="survivor"} 0 + elasticsearch_jvm_memory_pool_peak_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",pool="young"} 0 + # HELP elasticsearch_jvm_memory_pool_peak_used_bytes JVM memory peak used by pool + # TYPE elasticsearch_jvm_memory_pool_peak_used_bytes counter + elasticsearch_jvm_memory_pool_peak_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",pool="old"} 2.55827968e+08 + elasticsearch_jvm_memory_pool_peak_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",pool="survivor"} 4.766816e+07 + elasticsearch_jvm_memory_pool_peak_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",pool="young"} 5.59417344e+08 + # HELP elasticsearch_jvm_memory_pool_used_bytes JVM memory currently used by pool + # TYPE elasticsearch_jvm_memory_pool_used_bytes gauge + elasticsearch_jvm_memory_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",pool="old"} 2.55827968e+08 + elasticsearch_jvm_memory_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",pool="survivor"} 1.1010048e+07 + elasticsearch_jvm_memory_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",pool="young"} 3.93216e+08 + # HELP elasticsearch_jvm_memory_used_bytes JVM memory currently used by area + # TYPE elasticsearch_jvm_memory_used_bytes gauge + elasticsearch_jvm_memory_used_bytes{area="heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 6.60054016e+08 + elasticsearch_jvm_memory_used_bytes{area="non-heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 1.08594112e+08 + # HELP elasticsearch_jvm_uptime_seconds JVM process uptime in seconds + # TYPE elasticsearch_jvm_uptime_seconds gauge + elasticsearch_jvm_uptime_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="mapped"} 16.456 + # HELP elasticsearch_nodes_roles Node roles + # TYPE elasticsearch_nodes_roles gauge + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_cold"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_content"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_frozen"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_hot"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="data_warm"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="ingest"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="master"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="ml"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="remote_cluster_client"} 0 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="9_P7yui",role="transform"} 0 + # HELP elasticsearch_os_cpu_percent Percent CPU used by OS + # TYPE elasticsearch_os_cpu_percent gauge + elasticsearch_os_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 30 + # HELP elasticsearch_os_load1 Shortterm load average + # TYPE elasticsearch_os_load1 gauge + elasticsearch_os_load1{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 27.55 + # HELP elasticsearch_os_load15 Longterm load average + # TYPE elasticsearch_os_load15 gauge + elasticsearch_os_load15{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 92.65 + # HELP elasticsearch_os_load5 Midterm load average + # TYPE elasticsearch_os_load5 gauge + elasticsearch_os_load5{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 134.28 + # HELP elasticsearch_os_mem_actual_free_bytes Amount of free physical memory in bytes + # TYPE elasticsearch_os_mem_actual_free_bytes gauge + elasticsearch_os_mem_actual_free_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_os_mem_actual_used_bytes Amount of used physical memory in bytes + # TYPE elasticsearch_os_mem_actual_used_bytes gauge + elasticsearch_os_mem_actual_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_os_mem_free_bytes Amount of free physical memory in bytes + # TYPE elasticsearch_os_mem_free_bytes gauge + elasticsearch_os_mem_free_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 7.651008512e+09 + # HELP elasticsearch_os_mem_used_bytes Amount of used physical memory in bytes + # TYPE elasticsearch_os_mem_used_bytes gauge + elasticsearch_os_mem_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 2.5972228096e+10 + # HELP elasticsearch_process_cpu_percent Percent CPU used by process + # TYPE elasticsearch_process_cpu_percent gauge + elasticsearch_process_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 17 + # HELP elasticsearch_process_cpu_seconds_total Process CPU time in seconds + # TYPE elasticsearch_process_cpu_seconds_total counter + elasticsearch_process_cpu_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 32.81 + # HELP elasticsearch_process_max_files_descriptors Max file descriptors + # TYPE elasticsearch_process_max_files_descriptors gauge + elasticsearch_process_max_files_descriptors{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 1.048576e+06 + # HELP elasticsearch_process_mem_resident_size_bytes Resident memory in use by process in bytes + # TYPE elasticsearch_process_mem_resident_size_bytes gauge + elasticsearch_process_mem_resident_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_process_mem_share_size_bytes Shared memory in use by process in bytes + # TYPE elasticsearch_process_mem_share_size_bytes gauge + elasticsearch_process_mem_share_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_process_mem_virtual_size_bytes Total virtual memory used in bytes + # TYPE elasticsearch_process_mem_virtual_size_bytes gauge + elasticsearch_process_mem_virtual_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 7.269961728e+09 + # HELP elasticsearch_process_open_files_count Open file descriptors + # TYPE elasticsearch_process_open_files_count gauge + elasticsearch_process_open_files_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 355 + # HELP elasticsearch_thread_pool_active_count Thread Pool threads active + # TYPE elasticsearch_thread_pool_active_count gauge + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="analyze"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ccr"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="flush"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="force_merge"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="generic"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="get"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="index"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="listener"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="management"} 1 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_autodetect"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_datafeed"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_utility"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="refresh"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="rollup_indexing"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="search"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="search_throttled"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="security-token-key"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="snapshot"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="warmer"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="watcher"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="write"} 0 + # HELP elasticsearch_thread_pool_completed_count Thread Pool operations completed + # TYPE elasticsearch_thread_pool_completed_count counter + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="analyze"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ccr"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="flush"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="force_merge"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="generic"} 87 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="get"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="index"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="listener"} 5 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="management"} 5 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_autodetect"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_datafeed"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_utility"} 1 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="refresh"} 32 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="rollup_indexing"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="search"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="search_throttled"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="security-token-key"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="snapshot"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="warmer"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="watcher"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="write"} 5 + # HELP elasticsearch_thread_pool_largest_count Thread Pool largest threads count + # TYPE elasticsearch_thread_pool_largest_count gauge + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="analyze"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ccr"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="flush"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="force_merge"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="generic"} 5 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="get"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="index"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="listener"} 4 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="management"} 2 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_autodetect"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_datafeed"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_utility"} 1 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="refresh"} 1 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="rollup_indexing"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="search"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="search_throttled"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="security-token-key"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="snapshot"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="warmer"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="watcher"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="write"} 5 + # HELP elasticsearch_thread_pool_queue_count Thread Pool operations queued + # TYPE elasticsearch_thread_pool_queue_count gauge + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="analyze"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ccr"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="flush"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="force_merge"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="generic"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="get"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="index"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="listener"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="management"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_autodetect"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_datafeed"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_utility"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="refresh"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="rollup_indexing"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="search"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="search_throttled"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="security-token-key"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="snapshot"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="warmer"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="watcher"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="write"} 0 + # HELP elasticsearch_thread_pool_rejected_count Thread Pool operations rejected + # TYPE elasticsearch_thread_pool_rejected_count counter + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="analyze"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ccr"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="flush"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="force_merge"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="generic"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="get"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="index"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="listener"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="management"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_autodetect"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_datafeed"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_utility"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="refresh"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="rollup_indexing"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="search"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="search_throttled"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="security-token-key"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="snapshot"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="warmer"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="watcher"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="write"} 0 + # HELP elasticsearch_thread_pool_threads_count Thread Pool current threads count + # TYPE elasticsearch_thread_pool_threads_count gauge + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="analyze"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ccr"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="flush"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="force_merge"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="generic"} 5 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="get"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="index"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="listener"} 4 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="management"} 2 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_autodetect"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_datafeed"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="ml_utility"} 1 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="refresh"} 1 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="rollup_indexing"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="search"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="search_throttled"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="security-token-key"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="snapshot"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="warmer"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="watcher"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui",type="write"} 5 + # HELP elasticsearch_transport_rx_packets_total Count of packets received + # TYPE elasticsearch_transport_rx_packets_total counter + elasticsearch_transport_rx_packets_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_transport_rx_size_bytes_total Total number of bytes received + # TYPE elasticsearch_transport_rx_size_bytes_total counter + elasticsearch_transport_rx_size_bytes_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_transport_tx_packets_total Count of packets sent + # TYPE elasticsearch_transport_tx_packets_total counter + elasticsearch_transport_tx_packets_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + # HELP elasticsearch_transport_tx_size_bytes_total Total number of bytes sent + # TYPE elasticsearch_transport_tx_size_bytes_total counter + elasticsearch_transport_tx_size_bytes_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="9_P7yui"} 0 + `, + }, + { + name: "7.13.1", + file: "../fixtures/nodestats/7.13.1.json", + want: `# HELP elasticsearch_breakers_estimated_size_bytes Estimated size in bytes of breaker + # TYPE elasticsearch_breakers_estimated_size_bytes gauge + elasticsearch_breakers_estimated_size_bytes{breaker="accounting",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 9380 + elasticsearch_breakers_estimated_size_bytes{breaker="fielddata",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + elasticsearch_breakers_estimated_size_bytes{breaker="in_flight_requests",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + elasticsearch_breakers_estimated_size_bytes{breaker="model_inference",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + elasticsearch_breakers_estimated_size_bytes{breaker="parent",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 1.56194432e+08 + elasticsearch_breakers_estimated_size_bytes{breaker="request",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_breakers_limit_size_bytes Limit size in bytes for breaker + # TYPE elasticsearch_breakers_limit_size_bytes gauge + elasticsearch_breakers_limit_size_bytes{breaker="accounting",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 7.88529152e+08 + elasticsearch_breakers_limit_size_bytes{breaker="fielddata",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 3.1541166e+08 + elasticsearch_breakers_limit_size_bytes{breaker="in_flight_requests",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 7.88529152e+08 + elasticsearch_breakers_limit_size_bytes{breaker="model_inference",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 3.94264576e+08 + elasticsearch_breakers_limit_size_bytes{breaker="parent",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 7.49102694e+08 + elasticsearch_breakers_limit_size_bytes{breaker="request",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 4.73117491e+08 + # HELP elasticsearch_breakers_overhead Overhead of circuit breakers + # TYPE elasticsearch_breakers_overhead counter + elasticsearch_breakers_overhead{breaker="accounting",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 1 + elasticsearch_breakers_overhead{breaker="fielddata",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 1.03 + elasticsearch_breakers_overhead{breaker="in_flight_requests",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 2 + elasticsearch_breakers_overhead{breaker="model_inference",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 1 + elasticsearch_breakers_overhead{breaker="parent",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 1 + elasticsearch_breakers_overhead{breaker="request",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 1 + # HELP elasticsearch_breakers_tripped tripped for breaker + # TYPE elasticsearch_breakers_tripped counter + elasticsearch_breakers_tripped{breaker="accounting",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + elasticsearch_breakers_tripped{breaker="fielddata",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + elasticsearch_breakers_tripped{breaker="in_flight_requests",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + elasticsearch_breakers_tripped{breaker="model_inference",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + elasticsearch_breakers_tripped{breaker="parent",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + elasticsearch_breakers_tripped{breaker="request",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_filesystem_data_available_bytes Available space on block device in bytes + # TYPE elasticsearch_filesystem_data_available_bytes gauge + elasticsearch_filesystem_data_available_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",mount="/ (overlay)",name="aaf5a8a0bceb",path="/usr/share/elasticsearch/data/nodes/0"} 6.3425642496e+10 + # HELP elasticsearch_filesystem_data_free_bytes Free space on block device in bytes + # TYPE elasticsearch_filesystem_data_free_bytes gauge + elasticsearch_filesystem_data_free_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",mount="/ (overlay)",name="aaf5a8a0bceb",path="/usr/share/elasticsearch/data/nodes/0"} 6.3425642496e+10 + # HELP elasticsearch_filesystem_data_size_bytes Size of block device in bytes + # TYPE elasticsearch_filesystem_data_size_bytes gauge + elasticsearch_filesystem_data_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",mount="/ (overlay)",name="aaf5a8a0bceb",path="/usr/share/elasticsearch/data/nodes/0"} 4.76630163456e+11 + # HELP elasticsearch_indexing_pressure_current_all_in_bytes Memory consumed, in bytes, by indexing requests in the coordinating, primary, or replica stage. + # TYPE elasticsearch_indexing_pressure_current_all_in_bytes gauge + elasticsearch_indexing_pressure_current_all_in_bytes{cluster="elasticsearch",host="172.17.0.2",indexing_pressure="memory",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indexing_pressure_limit_in_bytes Configured memory limit, in bytes, for the indexing requests + # TYPE elasticsearch_indexing_pressure_limit_in_bytes gauge + elasticsearch_indexing_pressure_limit_in_bytes{cluster="elasticsearch",host="172.17.0.2",indexing_pressure="memory",name="aaf5a8a0bceb"} 7.8852915e+07 + # HELP elasticsearch_indices_completion_size_in_bytes Completion in bytes + # TYPE elasticsearch_indices_completion_size_in_bytes counter + elasticsearch_indices_completion_size_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_docs Count of documents on this node + # TYPE elasticsearch_indices_docs gauge + elasticsearch_indices_docs{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 5 + # HELP elasticsearch_indices_docs_deleted Count of deleted documents on this node + # TYPE elasticsearch_indices_docs_deleted gauge + elasticsearch_indices_docs_deleted{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_fielddata_evictions Evictions from field data + # TYPE elasticsearch_indices_fielddata_evictions counter + elasticsearch_indices_fielddata_evictions{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_fielddata_memory_size_bytes Field data cache memory usage in bytes + # TYPE elasticsearch_indices_fielddata_memory_size_bytes gauge + elasticsearch_indices_fielddata_memory_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_filter_cache_evictions Evictions from filter cache + # TYPE elasticsearch_indices_filter_cache_evictions counter + elasticsearch_indices_filter_cache_evictions{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_filter_cache_memory_size_bytes Filter cache memory usage in bytes + # TYPE elasticsearch_indices_filter_cache_memory_size_bytes gauge + elasticsearch_indices_filter_cache_memory_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_flush_time_seconds Cumulative flush time in seconds + # TYPE elasticsearch_indices_flush_time_seconds counter + elasticsearch_indices_flush_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_flush_total Total flushes + # TYPE elasticsearch_indices_flush_total counter + elasticsearch_indices_flush_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_get_exists_time_seconds Total time get exists in seconds + # TYPE elasticsearch_indices_get_exists_time_seconds counter + elasticsearch_indices_get_exists_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_get_exists_total Total get exists operations + # TYPE elasticsearch_indices_get_exists_total counter + elasticsearch_indices_get_exists_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_get_missing_time_seconds Total time of get missing in seconds + # TYPE elasticsearch_indices_get_missing_time_seconds counter + elasticsearch_indices_get_missing_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_get_missing_total Total get missing + # TYPE elasticsearch_indices_get_missing_total counter + elasticsearch_indices_get_missing_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_get_time_seconds Total get time in seconds + # TYPE elasticsearch_indices_get_time_seconds counter + elasticsearch_indices_get_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_get_total Total get + # TYPE elasticsearch_indices_get_total counter + elasticsearch_indices_get_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_indexing_delete_time_seconds_total Total time indexing delete in seconds + # TYPE elasticsearch_indices_indexing_delete_time_seconds_total counter + elasticsearch_indices_indexing_delete_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_indexing_delete_total Total indexing deletes + # TYPE elasticsearch_indices_indexing_delete_total counter + elasticsearch_indices_indexing_delete_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_indexing_index_time_seconds_total Cumulative index time in seconds + # TYPE elasticsearch_indices_indexing_index_time_seconds_total counter + elasticsearch_indices_indexing_index_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0.014 + # HELP elasticsearch_indices_indexing_index_total Total index calls + # TYPE elasticsearch_indices_indexing_index_total counter + elasticsearch_indices_indexing_index_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 5 + # HELP elasticsearch_indices_indexing_is_throttled Indexing throttling + # TYPE elasticsearch_indices_indexing_is_throttled gauge + elasticsearch_indices_indexing_is_throttled{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_indexing_throttle_time_seconds_total Cumulative indexing throttling time + # TYPE elasticsearch_indices_indexing_throttle_time_seconds_total counter + elasticsearch_indices_indexing_throttle_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_merges_current Current merges + # TYPE elasticsearch_indices_merges_current gauge + elasticsearch_indices_merges_current{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_merges_current_size_in_bytes Size of a current merges in bytes + # TYPE elasticsearch_indices_merges_current_size_in_bytes gauge + elasticsearch_indices_merges_current_size_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_merges_docs_total Cumulative docs merged + # TYPE elasticsearch_indices_merges_docs_total counter + elasticsearch_indices_merges_docs_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_merges_total Total merges + # TYPE elasticsearch_indices_merges_total counter + elasticsearch_indices_merges_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_merges_total_size_bytes_total Total merge size in bytes + # TYPE elasticsearch_indices_merges_total_size_bytes_total counter + elasticsearch_indices_merges_total_size_bytes_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_merges_total_throttled_time_seconds_total Total throttled time of merges in seconds + # TYPE elasticsearch_indices_merges_total_throttled_time_seconds_total counter + elasticsearch_indices_merges_total_throttled_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_merges_total_time_seconds_total Total time spent merging in seconds + # TYPE elasticsearch_indices_merges_total_time_seconds_total counter + elasticsearch_indices_merges_total_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_query_cache_cache_size Query cache cache size + # TYPE elasticsearch_indices_query_cache_cache_size gauge + elasticsearch_indices_query_cache_cache_size{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_query_cache_cache_total Query cache cache count + # TYPE elasticsearch_indices_query_cache_cache_total counter + elasticsearch_indices_query_cache_cache_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_query_cache_count Query cache count + # TYPE elasticsearch_indices_query_cache_count counter + elasticsearch_indices_query_cache_count{cache="hit",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_query_cache_evictions Evictions from query cache + # TYPE elasticsearch_indices_query_cache_evictions counter + elasticsearch_indices_query_cache_evictions{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_query_cache_memory_size_bytes Query cache memory usage in bytes + # TYPE elasticsearch_indices_query_cache_memory_size_bytes gauge + elasticsearch_indices_query_cache_memory_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_query_cache_total Query cache total count + # TYPE elasticsearch_indices_query_cache_total counter + elasticsearch_indices_query_cache_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_query_miss_count Query miss count + # TYPE elasticsearch_indices_query_miss_count counter + elasticsearch_indices_query_miss_count{cache="miss",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_refresh_external_time_seconds_total Total time spent external refreshing in seconds + # TYPE elasticsearch_indices_refresh_external_time_seconds_total counter + elasticsearch_indices_refresh_external_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0.15 + # HELP elasticsearch_indices_refresh_external_total Total external refreshes + # TYPE elasticsearch_indices_refresh_external_total counter + elasticsearch_indices_refresh_external_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 17 + # HELP elasticsearch_indices_refresh_time_seconds_total Total time spent refreshing in seconds + # TYPE elasticsearch_indices_refresh_time_seconds_total counter + elasticsearch_indices_refresh_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0.148 + # HELP elasticsearch_indices_refresh_total Total refreshes + # TYPE elasticsearch_indices_refresh_total counter + elasticsearch_indices_refresh_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 17 + # HELP elasticsearch_indices_request_cache_count Request cache count + # TYPE elasticsearch_indices_request_cache_count counter + elasticsearch_indices_request_cache_count{cache="hit",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_request_cache_evictions Evictions from request cache + # TYPE elasticsearch_indices_request_cache_evictions counter + elasticsearch_indices_request_cache_evictions{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_request_cache_memory_size_bytes Request cache memory usage in bytes + # TYPE elasticsearch_indices_request_cache_memory_size_bytes gauge + elasticsearch_indices_request_cache_memory_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_request_miss_count Request miss count + # TYPE elasticsearch_indices_request_miss_count counter + elasticsearch_indices_request_miss_count{cache="miss",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_search_fetch_time_seconds Total search fetch time in seconds + # TYPE elasticsearch_indices_search_fetch_time_seconds counter + elasticsearch_indices_search_fetch_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_search_fetch_total Total number of fetches + # TYPE elasticsearch_indices_search_fetch_total counter + elasticsearch_indices_search_fetch_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_search_query_time_seconds Total search query time in seconds + # TYPE elasticsearch_indices_search_query_time_seconds counter + elasticsearch_indices_search_query_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_search_query_total Total number of queries + # TYPE elasticsearch_indices_search_query_total counter + elasticsearch_indices_search_query_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_search_scroll_time_seconds Total scroll time in seconds + # TYPE elasticsearch_indices_search_scroll_time_seconds counter + elasticsearch_indices_search_scroll_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_search_scroll_total Total number of scrolls + # TYPE elasticsearch_indices_search_scroll_total counter + elasticsearch_indices_search_scroll_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_search_suggest_time_seconds Total suggest time in seconds + # TYPE elasticsearch_indices_search_suggest_time_seconds counter + elasticsearch_indices_search_suggest_time_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_search_suggest_total Total number of suggests + # TYPE elasticsearch_indices_search_suggest_total counter + elasticsearch_indices_search_suggest_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_segments_count Count of index segments on this node + # TYPE elasticsearch_indices_segments_count gauge + elasticsearch_indices_segments_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 5 + # HELP elasticsearch_indices_segments_doc_values_memory_in_bytes Count of doc values memory + # TYPE elasticsearch_indices_segments_doc_values_memory_in_bytes gauge + elasticsearch_indices_segments_doc_values_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 380 + # HELP elasticsearch_indices_segments_fixed_bit_set_memory_in_bytes Count of fixed bit set + # TYPE elasticsearch_indices_segments_fixed_bit_set_memory_in_bytes gauge + elasticsearch_indices_segments_fixed_bit_set_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_segments_index_writer_memory_in_bytes Count of memory for index writer on this node + # TYPE elasticsearch_indices_segments_index_writer_memory_in_bytes gauge + elasticsearch_indices_segments_index_writer_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_segments_memory_bytes Current memory size of segments in bytes + # TYPE elasticsearch_indices_segments_memory_bytes gauge + elasticsearch_indices_segments_memory_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 9380 + # HELP elasticsearch_indices_segments_norms_memory_in_bytes Count of memory used by norms + # TYPE elasticsearch_indices_segments_norms_memory_in_bytes gauge + elasticsearch_indices_segments_norms_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 640 + # HELP elasticsearch_indices_segments_points_memory_in_bytes Point values memory usage in bytes + # TYPE elasticsearch_indices_segments_points_memory_in_bytes gauge + elasticsearch_indices_segments_points_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_segments_stored_fields_memory_in_bytes Count of stored fields memory + # TYPE elasticsearch_indices_segments_stored_fields_memory_in_bytes gauge + elasticsearch_indices_segments_stored_fields_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 2440 + # HELP elasticsearch_indices_segments_term_vectors_memory_in_bytes Term vectors memory usage in bytes + # TYPE elasticsearch_indices_segments_term_vectors_memory_in_bytes gauge + elasticsearch_indices_segments_term_vectors_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_segments_terms_memory_in_bytes Count of terms in memory for this node + # TYPE elasticsearch_indices_segments_terms_memory_in_bytes gauge + elasticsearch_indices_segments_terms_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 5920 + # HELP elasticsearch_indices_segments_version_map_memory_in_bytes Version map memory usage in bytes + # TYPE elasticsearch_indices_segments_version_map_memory_in_bytes gauge + elasticsearch_indices_segments_version_map_memory_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_store_size_bytes Current size of stored index data in bytes + # TYPE elasticsearch_indices_store_size_bytes gauge + elasticsearch_indices_store_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 22296 + # HELP elasticsearch_indices_store_throttle_time_seconds_total Throttle time for index store in seconds + # TYPE elasticsearch_indices_store_throttle_time_seconds_total counter + elasticsearch_indices_store_throttle_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_translog_operations Total translog operations + # TYPE elasticsearch_indices_translog_operations counter + elasticsearch_indices_translog_operations{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 5 + # HELP elasticsearch_indices_translog_size_in_bytes Total translog size in bytes + # TYPE elasticsearch_indices_translog_size_in_bytes gauge + elasticsearch_indices_translog_size_in_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 773 + # HELP elasticsearch_indices_warmer_time_seconds_total Total warmer time in seconds + # TYPE elasticsearch_indices_warmer_time_seconds_total counter + elasticsearch_indices_warmer_time_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_indices_warmer_total Total warmer count + # TYPE elasticsearch_indices_warmer_total counter + elasticsearch_indices_warmer_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 11 + # HELP elasticsearch_jvm_buffer_pool_used_bytes JVM buffer currently used + # TYPE elasticsearch_jvm_buffer_pool_used_bytes gauge + elasticsearch_jvm_buffer_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="direct"} 8.811046e+06 + elasticsearch_jvm_buffer_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="mapped"} 16868 + # HELP elasticsearch_jvm_gc_collection_seconds_count Count of JVM GC runs + # TYPE elasticsearch_jvm_gc_collection_seconds_count counter + elasticsearch_jvm_gc_collection_seconds_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",gc="old",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + elasticsearch_jvm_gc_collection_seconds_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",gc="young",host="172.17.0.2",name="aaf5a8a0bceb"} 11 + # HELP elasticsearch_jvm_gc_collection_seconds_sum GC run time in seconds + # TYPE elasticsearch_jvm_gc_collection_seconds_sum counter + elasticsearch_jvm_gc_collection_seconds_sum{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",gc="old",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + elasticsearch_jvm_gc_collection_seconds_sum{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",gc="young",host="172.17.0.2",name="aaf5a8a0bceb"} 0.113 + # HELP elasticsearch_jvm_memory_committed_bytes JVM memory currently committed by area + # TYPE elasticsearch_jvm_memory_committed_bytes gauge + elasticsearch_jvm_memory_committed_bytes{area="heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 7.88529152e+08 + elasticsearch_jvm_memory_committed_bytes{area="non-heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 1.42606336e+08 + # HELP elasticsearch_jvm_memory_max_bytes JVM memory max + # TYPE elasticsearch_jvm_memory_max_bytes gauge + elasticsearch_jvm_memory_max_bytes{area="heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 7.88529152e+08 + # HELP elasticsearch_jvm_memory_pool_max_bytes JVM memory max by pool + # TYPE elasticsearch_jvm_memory_pool_max_bytes counter + elasticsearch_jvm_memory_pool_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",pool="old"} 7.88529152e+08 + elasticsearch_jvm_memory_pool_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",pool="survivor"} 0 + elasticsearch_jvm_memory_pool_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",pool="young"} 0 + # HELP elasticsearch_jvm_memory_pool_peak_max_bytes JVM memory peak max by pool + # TYPE elasticsearch_jvm_memory_pool_peak_max_bytes counter + elasticsearch_jvm_memory_pool_peak_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",pool="old"} 7.88529152e+08 + elasticsearch_jvm_memory_pool_peak_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",pool="survivor"} 0 + elasticsearch_jvm_memory_pool_peak_max_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",pool="young"} 0 + # HELP elasticsearch_jvm_memory_pool_peak_used_bytes JVM memory peak used by pool + # TYPE elasticsearch_jvm_memory_pool_peak_used_bytes counter + elasticsearch_jvm_memory_pool_peak_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",pool="old"} 7.1059968e+07 + elasticsearch_jvm_memory_pool_peak_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",pool="survivor"} 5.4525952e+07 + elasticsearch_jvm_memory_pool_peak_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",pool="young"} 4.65567744e+08 + # HELP elasticsearch_jvm_memory_pool_used_bytes JVM memory currently used by pool + # TYPE elasticsearch_jvm_memory_pool_used_bytes gauge + elasticsearch_jvm_memory_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",pool="old"} 7.1059968e+07 + elasticsearch_jvm_memory_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",pool="survivor"} 3.0608512e+07 + elasticsearch_jvm_memory_pool_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",pool="young"} 5.4525952e+07 + # HELP elasticsearch_jvm_memory_used_bytes JVM memory currently used by area + # TYPE elasticsearch_jvm_memory_used_bytes gauge + elasticsearch_jvm_memory_used_bytes{area="heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 1.56194432e+08 + elasticsearch_jvm_memory_used_bytes{area="non-heap",cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 1.39526472e+08 + # HELP elasticsearch_jvm_uptime_seconds JVM process uptime in seconds + # TYPE elasticsearch_jvm_uptime_seconds gauge + elasticsearch_jvm_uptime_seconds{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="mapped"} 21.844 + # HELP elasticsearch_nodes_roles Node roles + # TYPE elasticsearch_nodes_roles gauge + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_cold"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_content"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_frozen"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_hot"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="data_warm"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="ingest"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="master"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="ml"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="remote_cluster_client"} 1 + elasticsearch_nodes_roles{cluster="elasticsearch",host="172.17.0.2",name="aaf5a8a0bceb",role="transform"} 1 + # HELP elasticsearch_os_cpu_percent Percent CPU used by OS + # TYPE elasticsearch_os_cpu_percent gauge + elasticsearch_os_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 37 + # HELP elasticsearch_os_load1 Shortterm load average + # TYPE elasticsearch_os_load1 gauge + elasticsearch_os_load1{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 2.74 + # HELP elasticsearch_os_load15 Longterm load average + # TYPE elasticsearch_os_load15 gauge + elasticsearch_os_load15{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 70.55 + # HELP elasticsearch_os_load5 Midterm load average + # TYPE elasticsearch_os_load5 gauge + elasticsearch_os_load5{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 44.07 + # HELP elasticsearch_os_mem_actual_free_bytes Amount of free physical memory in bytes + # TYPE elasticsearch_os_mem_actual_free_bytes gauge + elasticsearch_os_mem_actual_free_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_os_mem_actual_used_bytes Amount of used physical memory in bytes + # TYPE elasticsearch_os_mem_actual_used_bytes gauge + elasticsearch_os_mem_actual_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_os_mem_free_bytes Amount of free physical memory in bytes + # TYPE elasticsearch_os_mem_free_bytes gauge + elasticsearch_os_mem_free_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 1.24007424e+10 + # HELP elasticsearch_os_mem_used_bytes Amount of used physical memory in bytes + # TYPE elasticsearch_os_mem_used_bytes gauge + elasticsearch_os_mem_used_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 2.1222490112e+10 + # HELP elasticsearch_process_cpu_percent Percent CPU used by process + # TYPE elasticsearch_process_cpu_percent gauge + elasticsearch_process_cpu_percent{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 19 + # HELP elasticsearch_process_cpu_seconds_total Process CPU time in seconds + # TYPE elasticsearch_process_cpu_seconds_total counter + elasticsearch_process_cpu_seconds_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 50.16 + # HELP elasticsearch_process_max_files_descriptors Max file descriptors + # TYPE elasticsearch_process_max_files_descriptors gauge + elasticsearch_process_max_files_descriptors{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 1.048576e+06 + # HELP elasticsearch_process_mem_resident_size_bytes Resident memory in use by process in bytes + # TYPE elasticsearch_process_mem_resident_size_bytes gauge + elasticsearch_process_mem_resident_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_process_mem_share_size_bytes Shared memory in use by process in bytes + # TYPE elasticsearch_process_mem_share_size_bytes gauge + elasticsearch_process_mem_share_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_process_mem_virtual_size_bytes Total virtual memory used in bytes + # TYPE elasticsearch_process_mem_virtual_size_bytes gauge + elasticsearch_process_mem_virtual_size_bytes{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 6.819479552e+09 + # HELP elasticsearch_process_open_files_count Open file descriptors + # TYPE elasticsearch_process_open_files_count gauge + elasticsearch_process_open_files_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 314 + # HELP elasticsearch_thread_pool_active_count Thread Pool threads active + # TYPE elasticsearch_thread_pool_active_count gauge + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="analyze"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ccr"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="flush"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="force_merge"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="generic"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="get"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="listener"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="management"} 1 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_datafeed"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_job_comms"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_utility"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="refresh"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="rollup_indexing"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="search"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="search_throttled"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="searchable_snapshots_cache_fetch_async"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="searchable_snapshots_cache_prewarming"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="security-crypto"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="security-token-key"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="snapshot"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="system_read"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="system_write"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="transform_indexing"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="warmer"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="watcher"} 0 + elasticsearch_thread_pool_active_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="write"} 0 + # HELP elasticsearch_thread_pool_completed_count Thread Pool operations completed + # TYPE elasticsearch_thread_pool_completed_count counter + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="analyze"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ccr"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="flush"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="force_merge"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="generic"} 406 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="get"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="listener"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="management"} 9 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_datafeed"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_job_comms"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_utility"} 12 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="refresh"} 36 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="rollup_indexing"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="search"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="search_throttled"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="searchable_snapshots_cache_fetch_async"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="searchable_snapshots_cache_prewarming"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="security-crypto"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="security-token-key"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="snapshot"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="system_read"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="system_write"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="transform_indexing"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="warmer"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="watcher"} 0 + elasticsearch_thread_pool_completed_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="write"} 9 + # HELP elasticsearch_thread_pool_largest_count Thread Pool largest threads count + # TYPE elasticsearch_thread_pool_largest_count gauge + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="analyze"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ccr"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="flush"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="force_merge"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="generic"} 7 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="get"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="listener"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="management"} 2 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_datafeed"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_job_comms"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_utility"} 1 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="refresh"} 1 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="rollup_indexing"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="search"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="search_throttled"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="searchable_snapshots_cache_fetch_async"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="searchable_snapshots_cache_prewarming"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="security-crypto"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="security-token-key"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="snapshot"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="system_read"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="system_write"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="transform_indexing"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="warmer"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="watcher"} 0 + elasticsearch_thread_pool_largest_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="write"} 8 + # HELP elasticsearch_thread_pool_queue_count Thread Pool operations queued + # TYPE elasticsearch_thread_pool_queue_count gauge + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="analyze"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ccr"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="flush"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="force_merge"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="generic"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="get"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="listener"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="management"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_datafeed"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_job_comms"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_utility"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="refresh"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="rollup_indexing"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="search"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="search_throttled"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="searchable_snapshots_cache_fetch_async"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="searchable_snapshots_cache_prewarming"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="security-crypto"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="security-token-key"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="snapshot"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="system_read"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="system_write"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="transform_indexing"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="warmer"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="watcher"} 0 + elasticsearch_thread_pool_queue_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="write"} 0 + # HELP elasticsearch_thread_pool_rejected_count Thread Pool operations rejected + # TYPE elasticsearch_thread_pool_rejected_count counter + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="analyze"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ccr"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="flush"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="force_merge"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="generic"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="get"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="listener"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="management"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_datafeed"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_job_comms"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_utility"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="refresh"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="rollup_indexing"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="search"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="search_throttled"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="searchable_snapshots_cache_fetch_async"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="searchable_snapshots_cache_prewarming"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="security-crypto"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="security-token-key"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="snapshot"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="system_read"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="system_write"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="transform_indexing"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="warmer"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="watcher"} 0 + elasticsearch_thread_pool_rejected_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="write"} 0 + # HELP elasticsearch_thread_pool_threads_count Thread Pool current threads count + # TYPE elasticsearch_thread_pool_threads_count gauge + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="analyze"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ccr"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="fetch_shard_started"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="fetch_shard_store"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="flush"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="force_merge"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="generic"} 7 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="get"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="listener"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="management"} 2 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_datafeed"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_job_comms"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="ml_utility"} 1 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="refresh"} 1 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="rollup_indexing"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="search"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="search_throttled"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="searchable_snapshots_cache_fetch_async"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="searchable_snapshots_cache_prewarming"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="security-crypto"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="security-token-key"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="snapshot"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="system_read"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="system_write"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="transform_indexing"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="warmer"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="watcher"} 0 + elasticsearch_thread_pool_threads_count{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb",type="write"} 8 + # HELP elasticsearch_transport_rx_packets_total Count of packets received + # TYPE elasticsearch_transport_rx_packets_total counter + elasticsearch_transport_rx_packets_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_transport_rx_size_bytes_total Total number of bytes received + # TYPE elasticsearch_transport_rx_size_bytes_total counter + elasticsearch_transport_rx_size_bytes_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_transport_tx_packets_total Count of packets sent + # TYPE elasticsearch_transport_tx_packets_total counter + elasticsearch_transport_tx_packets_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 + # HELP elasticsearch_transport_tx_size_bytes_total Total number of bytes sent + # TYPE elasticsearch_transport_tx_size_bytes_total counter + elasticsearch_transport_tx_size_bytes_total{cluster="elasticsearch",es_client_node="true",es_data_node="true",es_ingest_node="true",es_master_node="true",host="172.17.0.2",name="aaf5a8a0bceb"} 0 +`, + }, } - for ver, out := range tcs { - for hn, handler := range map[string]http.Handler{ - "plain": http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, out) - }), - "basicauth": &basicAuth{ - User: "elastic", - Pass: "changeme", - Next: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, out) - }), - }, - } { - ts := httptest.NewServer(handler) + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f, err := os.Open(tt.file) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.Copy(w, f) + })) defer ts.Close() u, err := url.Parse(ts.URL) if err != nil { - t.Fatalf("Failed to parse URL: %s", err) + t.Fatal(err) } - u.User = url.UserPassword("elastic", "changeme") - c := NewNodes(log.NewNopLogger(), http.DefaultClient, u, true, "_local") - nsr, err := c.fetchAndDecodeNodeStats() + + c := NewNodes(promslog.NewNopLogger(), http.DefaultClient, u, true, "_local") if err != nil { - t.Fatalf("Failed to fetch or decode node stats: %s", err) + t.Fatal(err) } - t.Logf("[%s/%s] Node Stats Response: %+v", hn, ver, nsr) - if nsr.ClusterName == "elasticsearch" { - for _, nsnr := range nsr.Nodes { - if nsnr.Indices.Docs.Count > 0 { - t.Errorf("Wrong doc count") - } - } - } - if nsr.ClusterName == "multinode" { - for _, node := range nsr.Nodes { - labels := defaultNodeLabelValues(nsr.ClusterName, node) - esMasterNode := labels[3] - esDataNode := labels[4] - esIngestNode := labels[5] - esClientNode := labels[6] - t.Logf( - "Node: %s - Master: %s - Data: %s - Ingest: %s - Client: %s", - node.Name, - esMasterNode, - esDataNode, - esIngestNode, - esClientNode, - ) - if strings.HasPrefix(node.Name, "elasticmaster") { - if esMasterNode != "true" { - t.Errorf("Master should be master") - } - if esDataNode == "true" { - t.Errorf("Master should be not data") - } - if esIngestNode == "true" { - t.Errorf("Master should be not ingest") - } - } - if strings.HasPrefix(node.Name, "elasticdata") { - if esMasterNode == "true" { - t.Errorf("Data should not be master") - } - if esDataNode != "true" { - t.Errorf("Data should be data") - } - if esIngestNode == "true" { - t.Errorf("Data should be not ingest") - } - } - if strings.HasPrefix(node.Name, "elasticin") { - if esMasterNode == "true" { - t.Errorf("Ingest should not be master") - } - if esDataNode == "true" { - t.Errorf("Ingest should be data") - } - if esIngestNode != "true" { - t.Errorf("Ingest should be not ingest") - } - } - if strings.HasPrefix(node.Name, "elasticcli") { - if esMasterNode == "true" { - t.Errorf("CLI should not be master") - } - if esDataNode == "true" { - t.Errorf("CLI should be data") - } - if esIngestNode == "true" { - t.Errorf("CLI should be not ingest") - } - } - } - } - } - } -} - -type basicAuth struct { - User string - Pass string - Next http.Handler -} -func (h *basicAuth) checkAuth(w http.ResponseWriter, r *http.Request) bool { - s := strings.SplitN(r.Header.Get("Authorization"), " ", 2) - if len(s) != 2 { - return false - } - - b, err := base64.StdEncoding.DecodeString(s[1]) - if err != nil { - return false - } - - pair := strings.SplitN(string(b), ":", 2) - if len(pair) != 2 { - return false - } - - if h.User == pair[0] && h.Pass == pair[1] { - return true - } - return false -} - -func (h *basicAuth) ServeHTTP(w http.ResponseWriter, r *http.Request) { - if !h.checkAuth(w, r) { - w.Header().Set("WWW-Authenticate", "Basic realm=\"ES\"") - w.WriteHeader(401) - w.Write([]byte("401 Unauthorized\n")) - return + if err := testutil.CollectAndCompare(c, strings.NewReader(tt.want)); err != nil { + t.Fatal(err) + } + }) } - - h.Next.ServeHTTP(w, r) } diff --git a/collector/shards.go b/collector/shards.go new file mode 100644 index 00000000..d9b26820 --- /dev/null +++ b/collector/shards.go @@ -0,0 +1,214 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "encoding/json" + "fmt" + "log/slog" + "net/http" + "net/url" + "path" + + "github.com/prometheus-community/elasticsearch_exporter/pkg/clusterinfo" + + "github.com/prometheus/client_golang/prometheus" +) + +// ShardResponse has shard's node and index info +type ShardResponse struct { + Index string `json:"index"` + Shard string `json:"shard"` + State string `json:"state"` + Node string `json:"node"` +} + +// Shards information struct +type Shards struct { + logger *slog.Logger + client *http.Client + url *url.URL + clusterInfoCh chan *clusterinfo.Response + lastClusterInfo *clusterinfo.Response + + nodeShardMetrics []*nodeShardMetric + jsonParseFailures prometheus.Counter +} + +// ClusterLabelUpdates returns a pointer to a channel to receive cluster info updates. It implements the +// (not exported) clusterinfo.consumer interface +func (s *Shards) ClusterLabelUpdates() *chan *clusterinfo.Response { + return &s.clusterInfoCh +} + +// String implements the stringer interface. It is part of the clusterinfo.consumer interface +func (s *Shards) String() string { + return namespace + "shards" +} + +type nodeShardMetric struct { + Type prometheus.ValueType + Desc *prometheus.Desc + Value func(shards float64) float64 + Labels labels +} + +// NewShards defines Shards Prometheus metrics +func NewShards(logger *slog.Logger, client *http.Client, url *url.URL) *Shards { + + nodeLabels := labels{ + keys: func(...string) []string { + return []string{"node", "cluster"} + }, + values: func(lastClusterinfo *clusterinfo.Response, s ...string) []string { + if lastClusterinfo != nil { + return append(s, lastClusterinfo.ClusterName) + } + // this shouldn't happen, as the clusterinfo Retriever has a blocking + // Run method. It blocks until the first clusterinfo call has succeeded + return append(s, "unknown_cluster") + }, + } + + shards := &Shards{ + logger: logger, + client: client, + url: url, + + clusterInfoCh: make(chan *clusterinfo.Response), + lastClusterInfo: &clusterinfo.Response{ + ClusterName: "unknown_cluster", + }, + + nodeShardMetrics: []*nodeShardMetric{ + { + Type: prometheus.GaugeValue, + Desc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "node_shards", "total"), + "Total shards per node", + nodeLabels.keys(), nil, + ), + Value: func(shards float64) float64 { + return shards + }, + Labels: nodeLabels, + }}, + + jsonParseFailures: prometheus.NewCounter(prometheus.CounterOpts{ + Name: prometheus.BuildFQName(namespace, "node_shards", "json_parse_failures"), + Help: "Number of errors while parsing JSON.", + }), + } + + // start go routine to fetch clusterinfo updates and save them to lastClusterinfo + go func() { + logger.Debug("starting cluster info receive loop") + for ci := range shards.clusterInfoCh { + if ci != nil { + logger.Debug("received cluster info update", "cluster", ci.ClusterName) + shards.lastClusterInfo = ci + } + } + logger.Debug("exiting cluster info receive loop") + }() + + return shards +} + +// Describe Shards +func (s *Shards) Describe(ch chan<- *prometheus.Desc) { + ch <- s.jsonParseFailures.Desc() + + for _, metric := range s.nodeShardMetrics { + ch <- metric.Desc + } +} + +func (s *Shards) getAndParseURL(u *url.URL) ([]ShardResponse, error) { + res, err := s.client.Get(u.String()) + if err != nil { + return nil, fmt.Errorf("failed to get from %s://%s:%s%s: %s", + u.Scheme, u.Hostname(), u.Port(), u.Path, err) + } + + defer func() { + err = res.Body.Close() + if err != nil { + s.logger.Warn( + "failed to close http.Client", + "err", err, + ) + } + }() + + if res.StatusCode != http.StatusOK { + return nil, fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) + } + var sfr []ShardResponse + if err := json.NewDecoder(res.Body).Decode(&sfr); err != nil { + s.jsonParseFailures.Inc() + return nil, err + } + return sfr, nil +} + +func (s *Shards) fetchAndDecodeShards() ([]ShardResponse, error) { + + u := *s.url + u.Path = path.Join(u.Path, "/_cat/shards") + q := u.Query() + q.Set("format", "json") + u.RawQuery = q.Encode() + sfr, err := s.getAndParseURL(&u) + if err != nil { + return sfr, err + } + return sfr, err +} + +// Collect number of shards on each node +func (s *Shards) Collect(ch chan<- prometheus.Metric) { + + defer func() { + ch <- s.jsonParseFailures + }() + + sr, err := s.fetchAndDecodeShards() + if err != nil { + s.logger.Warn( + "failed to fetch and decode node shards stats", + "err", err, + ) + return + } + + nodeShards := make(map[string]float64) + + for _, shard := range sr { + if shard.State == "STARTED" { + nodeShards[shard.Node]++ + } + } + + for node, shards := range nodeShards { + for _, metric := range s.nodeShardMetrics { + ch <- prometheus.MustNewConstMetric( + metric.Desc, + metric.Type, + metric.Value(shards), + metric.Labels.values(s.lastClusterInfo, node)..., + ) + } + } +} diff --git a/collector/shards_test.go b/collector/shards_test.go new file mode 100644 index 00000000..14ba7a7b --- /dev/null +++ b/collector/shards_test.go @@ -0,0 +1,84 @@ +// Copyright 2024 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "io" + "net/http" + "net/http/httptest" + "net/url" + "os" + "path" + "strings" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/promslog" +) + +func TestShards(t *testing.T) { + // Testcases created using: + // docker run --rm -d -p 9200:9200 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:$VERSION + // curl -XPUT http://localhost:9200/testindex + // curl -XPUT http://localhost:9200/otherindex + // curl http://localhost:9200/_cat/shards?format=json > fixtures/shards/$VERSION.json + + tests := []struct { + name string + file string + want string + }{ + { + name: "7.15.0", + file: "7.15.0.json", + want: `# HELP elasticsearch_node_shards_json_parse_failures Number of errors while parsing JSON. + # TYPE elasticsearch_node_shards_json_parse_failures counter + elasticsearch_node_shards_json_parse_failures 0 + # HELP elasticsearch_node_shards_total Total shards per node + # TYPE elasticsearch_node_shards_total gauge + elasticsearch_node_shards_total{cluster="unknown_cluster",node="35dfca79831a"} 3 + `, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f, err := os.Open(path.Join("../fixtures/shards/", tt.file)) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.Copy(w, f) + })) + defer ts.Close() + + u, err := url.Parse(ts.URL) + if err != nil { + t.Fatalf("Failed to parse URL: %s", err) + } + + s := NewShards(promslog.NewNopLogger(), http.DefaultClient, u) + if err != nil { + t.Fatal(err) + } + + if err := testutil.CollectAndCompare(s, strings.NewReader(tt.want)); err != nil { + t.Fatal(err) + } + }) + + } +} diff --git a/collector/slm.go b/collector/slm.go new file mode 100644 index 00000000..35aee9f2 --- /dev/null +++ b/collector/slm.go @@ -0,0 +1,261 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + + "github.com/prometheus/client_golang/prometheus" +) + +var ( + statuses = []string{"RUNNING", "STOPPING", "STOPPED"} +) + +var ( + slmRetentionRunsTotal = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "slm_stats", "retention_runs_total"), + "Total retention runs", + nil, nil, + ) + slmRetentionFailedTotal = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "slm_stats", "retention_failed_total"), + "Total failed retention runs", + nil, nil, + ) + slmRetentionTimedOutTotal = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "slm_stats", "retention_timed_out_total"), + "Total timed out retention runs", + nil, nil, + ) + slmRetentionDeletionTimeSeconds = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "slm_stats", "retention_deletion_time_seconds"), + "Retention run deletion time", + nil, nil, + ) + slmTotalSnapshotsTaken = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "slm_stats", "total_snapshots_taken_total"), + "Total snapshots taken", + nil, nil, + ) + slmTotalSnapshotsFailed = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "slm_stats", "total_snapshots_failed_total"), + "Total snapshots failed", + nil, nil, + ) + slmTotalSnapshotsDeleted = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "slm_stats", "total_snapshots_deleted_total"), + "Total snapshots deleted", + nil, nil, + ) + slmTotalSnapshotsDeleteFailed = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "slm_stats", "total_snapshot_deletion_failures_total"), + "Total snapshot deletion failures", + nil, nil, + ) + + slmOperationMode = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "slm_stats", "operation_mode"), + "Operating status of SLM", + []string{"operation_mode"}, nil, + ) + + slmSnapshotsTaken = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "slm_stats", "snapshots_taken_total"), + "Total snapshots taken", + []string{"policy"}, nil, + ) + slmSnapshotsFailed = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "slm_stats", "snapshots_failed_total"), + "Total snapshots failed", + []string{"policy"}, nil, + ) + slmSnapshotsDeleted = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "slm_stats", "snapshots_deleted_total"), + "Total snapshots deleted", + []string{"policy"}, nil, + ) + slmSnapshotsDeletionFailure = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "slm_stats", "snapshot_deletion_failures_total"), + "Total snapshot deletion failures", + []string{"policy"}, nil, + ) +) + +func init() { + registerCollector("slm", defaultDisabled, NewSLM) +} + +// SLM information struct +type SLM struct { + logger *slog.Logger + hc *http.Client + u *url.URL +} + +// NewSLM defines SLM Prometheus metrics +func NewSLM(logger *slog.Logger, u *url.URL, hc *http.Client) (Collector, error) { + return &SLM{ + logger: logger, + hc: hc, + u: u, + }, nil +} + +// SLMStatsResponse is a representation of the SLM stats +type SLMStatsResponse struct { + RetentionRuns int64 `json:"retention_runs"` + RetentionFailed int64 `json:"retention_failed"` + RetentionTimedOut int64 `json:"retention_timed_out"` + RetentionDeletionTime string `json:"retention_deletion_time"` + RetentionDeletionTimeMillis int64 `json:"retention_deletion_time_millis"` + TotalSnapshotsTaken int64 `json:"total_snapshots_taken"` + TotalSnapshotsFailed int64 `json:"total_snapshots_failed"` + TotalSnapshotsDeleted int64 `json:"total_snapshots_deleted"` + TotalSnapshotDeletionFailures int64 `json:"total_snapshot_deletion_failures"` + PolicyStats []PolicyStats `json:"policy_stats"` +} + +// PolicyStats is a representation of SLM stats for specific policies +type PolicyStats struct { + Policy string `json:"policy"` + SnapshotsTaken int64 `json:"snapshots_taken"` + SnapshotsFailed int64 `json:"snapshots_failed"` + SnapshotsDeleted int64 `json:"snapshots_deleted"` + SnapshotDeletionFailures int64 `json:"snapshot_deletion_failures"` +} + +// SLMStatusResponse is a representation of the SLM status +type SLMStatusResponse struct { + OperationMode string `json:"operation_mode"` +} + +func (s *SLM) Update(ctx context.Context, ch chan<- prometheus.Metric) error { + u := s.u.ResolveReference(&url.URL{Path: "/_slm/status"}) + var slmStatusResp SLMStatusResponse + + resp, err := getURL(ctx, s.hc, s.logger, u.String()) + if err != nil { + return err + } + + err = json.Unmarshal(resp, &slmStatusResp) + if err != nil { + return err + } + + u = s.u.ResolveReference(&url.URL{Path: "/_slm/stats"}) + var slmStatsResp SLMStatsResponse + + resp, err = getURL(ctx, s.hc, s.logger, u.String()) + if err != nil { + return err + } + + err = json.Unmarshal(resp, &slmStatsResp) + if err != nil { + return err + } + + for _, status := range statuses { + var value float64 = 0 + if slmStatusResp.OperationMode == status { + value = 1 + } + ch <- prometheus.MustNewConstMetric( + slmOperationMode, + prometheus.GaugeValue, + value, + status, + ) + } + + ch <- prometheus.MustNewConstMetric( + slmRetentionRunsTotal, + prometheus.CounterValue, + float64(slmStatsResp.RetentionRuns), + ) + + ch <- prometheus.MustNewConstMetric( + slmRetentionFailedTotal, + prometheus.CounterValue, + float64(slmStatsResp.RetentionFailed), + ) + + ch <- prometheus.MustNewConstMetric( + slmRetentionTimedOutTotal, + prometheus.CounterValue, + float64(slmStatsResp.RetentionTimedOut), + ) + ch <- prometheus.MustNewConstMetric( + slmRetentionDeletionTimeSeconds, + prometheus.GaugeValue, + float64(slmStatsResp.RetentionDeletionTimeMillis)/1000, + ) + ch <- prometheus.MustNewConstMetric( + slmTotalSnapshotsTaken, + prometheus.CounterValue, + float64(slmStatsResp.TotalSnapshotsTaken), + ) + ch <- prometheus.MustNewConstMetric( + slmTotalSnapshotsFailed, + prometheus.CounterValue, + float64(slmStatsResp.TotalSnapshotsFailed), + ) + ch <- prometheus.MustNewConstMetric( + slmTotalSnapshotsDeleted, + prometheus.CounterValue, + float64(slmStatsResp.TotalSnapshotsDeleted), + ) + ch <- prometheus.MustNewConstMetric( + slmTotalSnapshotsDeleteFailed, + prometheus.CounterValue, + float64(slmStatsResp.TotalSnapshotDeletionFailures), + ) + + for _, policy := range slmStatsResp.PolicyStats { + ch <- prometheus.MustNewConstMetric( + slmSnapshotsTaken, + prometheus.CounterValue, + float64(policy.SnapshotsTaken), + policy.Policy, + ) + ch <- prometheus.MustNewConstMetric( + slmSnapshotsFailed, + prometheus.CounterValue, + float64(policy.SnapshotsFailed), + policy.Policy, + ) + ch <- prometheus.MustNewConstMetric( + slmSnapshotsDeleted, + prometheus.CounterValue, + float64(policy.SnapshotsDeleted), + policy.Policy, + ) + ch <- prometheus.MustNewConstMetric( + slmSnapshotsDeletionFailure, + prometheus.CounterValue, + float64(policy.SnapshotDeletionFailures), + policy.Policy, + ) + + } + + return nil + +} diff --git a/collector/slm_test.go b/collector/slm_test.go new file mode 100644 index 00000000..36e41328 --- /dev/null +++ b/collector/slm_test.go @@ -0,0 +1,138 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "io" + "net/http" + "net/http/httptest" + "net/url" + "os" + "path" + "strings" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/promslog" +) + +func TestSLM(t *testing.T) { + // Testcases created using: + + // docker run -d -p 9200:9200 -e discovery.type=single-node -e path.repo=/tmp/backups docker.elastic.co/elasticsearch/elasticsearch:7.15.0-arm64 + // curl -XPUT http://127.0.0.1:9200/_snapshot/my_repository -H 'Content-Type: application/json' -d '{"type":"url","settings":{"url":"file:/tmp/backups"}}' + // curl -XPUT http://127.0.0.1:9200/_slm/policy/everything -H 'Content-Type: application/json' -d '{"schedule":"0 */15 * * * ?","name":"","repository":"my_repository","config":{"indices":".*","include_global_state":true,"ignore_unavailable":true},"retention":{"expire_after":"7d"}}' + // curl http://127.0.0.1:9200/_slm/stats (Numbers manually tweaked) + + tests := []struct { + name string + file string + want string + }{ + { + name: "7.15.0", + file: "7.15.0.json", + want: `# HELP elasticsearch_slm_stats_operation_mode Operating status of SLM + # TYPE elasticsearch_slm_stats_operation_mode gauge + elasticsearch_slm_stats_operation_mode{operation_mode="RUNNING"} 0 + elasticsearch_slm_stats_operation_mode{operation_mode="STOPPED"} 0 + elasticsearch_slm_stats_operation_mode{operation_mode="STOPPING"} 0 + # HELP elasticsearch_slm_stats_retention_deletion_time_seconds Retention run deletion time + # TYPE elasticsearch_slm_stats_retention_deletion_time_seconds gauge + elasticsearch_slm_stats_retention_deletion_time_seconds 72.491 + # HELP elasticsearch_slm_stats_retention_failed_total Total failed retention runs + # TYPE elasticsearch_slm_stats_retention_failed_total counter + elasticsearch_slm_stats_retention_failed_total 0 + # HELP elasticsearch_slm_stats_retention_runs_total Total retention runs + # TYPE elasticsearch_slm_stats_retention_runs_total counter + elasticsearch_slm_stats_retention_runs_total 9 + # HELP elasticsearch_slm_stats_retention_timed_out_total Total timed out retention runs + # TYPE elasticsearch_slm_stats_retention_timed_out_total counter + elasticsearch_slm_stats_retention_timed_out_total 0 + # HELP elasticsearch_slm_stats_snapshot_deletion_failures_total Total snapshot deletion failures + # TYPE elasticsearch_slm_stats_snapshot_deletion_failures_total counter + elasticsearch_slm_stats_snapshot_deletion_failures_total{policy="everything"} 0 + # HELP elasticsearch_slm_stats_snapshots_deleted_total Total snapshots deleted + # TYPE elasticsearch_slm_stats_snapshots_deleted_total counter + elasticsearch_slm_stats_snapshots_deleted_total{policy="everything"} 20 + # HELP elasticsearch_slm_stats_snapshots_failed_total Total snapshots failed + # TYPE elasticsearch_slm_stats_snapshots_failed_total counter + elasticsearch_slm_stats_snapshots_failed_total{policy="everything"} 2 + # HELP elasticsearch_slm_stats_snapshots_taken_total Total snapshots taken + # TYPE elasticsearch_slm_stats_snapshots_taken_total counter + elasticsearch_slm_stats_snapshots_taken_total{policy="everything"} 50 + # HELP elasticsearch_slm_stats_total_snapshot_deletion_failures_total Total snapshot deletion failures + # TYPE elasticsearch_slm_stats_total_snapshot_deletion_failures_total counter + elasticsearch_slm_stats_total_snapshot_deletion_failures_total 0 + # HELP elasticsearch_slm_stats_total_snapshots_deleted_total Total snapshots deleted + # TYPE elasticsearch_slm_stats_total_snapshots_deleted_total counter + elasticsearch_slm_stats_total_snapshots_deleted_total 20 + # HELP elasticsearch_slm_stats_total_snapshots_failed_total Total snapshots failed + # TYPE elasticsearch_slm_stats_total_snapshots_failed_total counter + elasticsearch_slm_stats_total_snapshots_failed_total 2 + # HELP elasticsearch_slm_stats_total_snapshots_taken_total Total snapshots taken + # TYPE elasticsearch_slm_stats_total_snapshots_taken_total counter + elasticsearch_slm_stats_total_snapshots_taken_total 103 + `, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fStatsPath := path.Join("../fixtures/slm/stats/", tt.file) + fStats, err := os.Open(fStatsPath) + if err != nil { + t.Fatal(err) + } + defer fStats.Close() + + fStatusPath := path.Join("../fixtures/slm/status/", tt.file) + fStatus, err := os.Open(fStatusPath) + if err != nil { + t.Fatal(err) + } + defer fStatus.Close() + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.RequestURI { + case "/_slm/stats": + io.Copy(w, fStats) + return + case "/_slm/status": + io.Copy(w, fStatus) + return + } + + http.Error(w, "Not Found", http.StatusNotFound) + })) + defer ts.Close() + + u, err := url.Parse(ts.URL) + if err != nil { + t.Fatalf("Failed to parse URL: %s", err) + } + + s, err := NewSLM(promslog.NewNopLogger(), u, http.DefaultClient) + if err != nil { + t.Fatal(err) + } + + if err := testutil.CollectAndCompare(wrapCollector{s}, strings.NewReader(tt.want)); err != nil { + t.Fatal(err) + } + }) + + } + +} diff --git a/collector/snapshots.go b/collector/snapshots.go index f5785889..42cfc50a 100644 --- a/collector/snapshots.go +++ b/collector/snapshots.go @@ -1,31 +1,30 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector import ( + "context" "encoding/json" "fmt" + "log/slog" "net/http" "net/url" "path" - "github.com/go-kit/kit/log" - "github.com/go-kit/kit/log/level" "github.com/prometheus/client_golang/prometheus" ) -type snapshotMetric struct { - Type prometheus.ValueType - Desc *prometheus.Desc - Value func(snapshotStats SnapshotStatDataResponse) float64 - Labels func(repositoryName string, snapshotStats SnapshotStatDataResponse) []string -} - -type repositoryMetric struct { - Type prometheus.ValueType - Desc *prometheus.Desc - Value func(snapshotsStats SnapshotStatsResponse) float64 - Labels func(repositoryName string) []string -} - var ( defaultSnapshotLabels = []string{"repository", "state", "version"} defaultSnapshotLabelValues = func(repositoryName string, snapshotStats SnapshotStatDataResponse) []string { @@ -37,261 +36,195 @@ var ( } ) -// Snapshots information struct -type Snapshots struct { - logger log.Logger - client *http.Client - url *url.URL +var ( + numIndices = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "snapshot_stats", "snapshot_number_of_indices"), + "Number of indices in the last snapshot", + defaultSnapshotLabels, nil, + ) + snapshotStartTimestamp = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "snapshot_stats", "snapshot_start_time_timestamp"), + "Last snapshot start timestamp", + defaultSnapshotLabels, nil, + ) + snapshotEndTimestamp = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "snapshot_stats", "snapshot_end_time_timestamp"), + "Last snapshot end timestamp", + defaultSnapshotLabels, nil, + ) + snapshotNumFailures = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "snapshot_stats", "snapshot_number_of_failures"), + "Last snapshot number of failures", + defaultSnapshotLabels, nil, + ) + snapshotNumShards = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "snapshot_stats", "snapshot_total_shards"), + "Last snapshot total shards", + defaultSnapshotLabels, nil, + ) + snapshotFailedShards = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "snapshot_stats", "snapshot_failed_shards"), + "Last snapshot failed shards", + defaultSnapshotLabels, nil, + ) + snapshotSuccessfulShards = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "snapshot_stats", "snapshot_successful_shards"), + "Last snapshot successful shards", + defaultSnapshotLabels, nil, + ) + + numSnapshots = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "snapshot_stats", "number_of_snapshots"), + "Number of snapshots in a repository", + defaultSnapshotRepositoryLabels, nil, + ) + oldestSnapshotTimestamp = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "snapshot_stats", "oldest_snapshot_timestamp"), + "Timestamp of the oldest snapshot", + defaultSnapshotRepositoryLabels, nil, + ) + latestSnapshotTimestamp = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "snapshot_stats", "latest_snapshot_timestamp_seconds"), + "Timestamp of the latest SUCCESS or PARTIAL snapshot", + defaultSnapshotRepositoryLabels, nil, + ) +) - up prometheus.Gauge - totalScrapes, jsonParseFailures prometheus.Counter +func init() { + registerCollector("snapshots", defaultDisabled, NewSnapshots) +} - snapshotMetrics []*snapshotMetric - repositoryMetrics []*repositoryMetric +// Snapshots information struct +type Snapshots struct { + logger *slog.Logger + hc *http.Client + u *url.URL } // NewSnapshots defines Snapshots Prometheus metrics -func NewSnapshots(logger log.Logger, client *http.Client, url *url.URL) *Snapshots { +func NewSnapshots(logger *slog.Logger, u *url.URL, hc *http.Client) (Collector, error) { return &Snapshots{ logger: logger, - client: client, - url: url, - - up: prometheus.NewGauge(prometheus.GaugeOpts{ - Name: prometheus.BuildFQName(namespace, "snapshot_stats", "up"), - Help: "Was the last scrape of the ElasticSearch snapshots endpoint successful.", - }), - totalScrapes: prometheus.NewCounter(prometheus.CounterOpts{ - Name: prometheus.BuildFQName(namespace, "snapshot_stats", "total_scrapes"), - Help: "Current total ElasticSearch snapshots scrapes.", - }), - jsonParseFailures: prometheus.NewCounter(prometheus.CounterOpts{ - Name: prometheus.BuildFQName(namespace, "snapshot_stats", "json_parse_failures"), - Help: "Number of errors while parsing JSON.", - }), - snapshotMetrics: []*snapshotMetric{ - { - Type: prometheus.GaugeValue, - Desc: prometheus.NewDesc( - prometheus.BuildFQName(namespace, "snapshot_stats", "snapshot_number_of_indices"), - "Number of indices in the last snapshot", - defaultSnapshotLabels, nil, - ), - Value: func(snapshotStats SnapshotStatDataResponse) float64 { - return float64(len(snapshotStats.Indices)) - }, - Labels: defaultSnapshotLabelValues, - }, - { - Type: prometheus.GaugeValue, - Desc: prometheus.NewDesc( - prometheus.BuildFQName(namespace, "snapshot_stats", "snapshot_start_time_timestamp"), - "Last snapshot start timestamp", - defaultSnapshotLabels, nil, - ), - Value: func(snapshotStats SnapshotStatDataResponse) float64 { - return float64(snapshotStats.StartTimeInMillis / 1000) - }, - Labels: defaultSnapshotLabelValues, - }, - { - Type: prometheus.GaugeValue, - Desc: prometheus.NewDesc( - prometheus.BuildFQName(namespace, "snapshot_stats", "snapshot_end_time_timestamp"), - "Last snapshot end timestamp", - defaultSnapshotLabels, nil, - ), - Value: func(snapshotStats SnapshotStatDataResponse) float64 { - return float64(snapshotStats.EndTimeInMillis / 1000) - }, - Labels: defaultSnapshotLabelValues, - }, - { - Type: prometheus.GaugeValue, - Desc: prometheus.NewDesc( - prometheus.BuildFQName(namespace, "snapshot_stats", "snapshot_number_of_failures"), - "Last snapshot number of failures", - defaultSnapshotLabels, nil, - ), - Value: func(snapshotStats SnapshotStatDataResponse) float64 { - return float64(len(snapshotStats.Failures)) - }, - Labels: defaultSnapshotLabelValues, - }, - { - Type: prometheus.GaugeValue, - Desc: prometheus.NewDesc( - prometheus.BuildFQName(namespace, "snapshot_stats", "snapshot_total_shards"), - "Last snapshot total shards", - defaultSnapshotLabels, nil, - ), - Value: func(snapshotStats SnapshotStatDataResponse) float64 { - return float64(snapshotStats.Shards.Total) - }, - Labels: defaultSnapshotLabelValues, - }, - { - Type: prometheus.GaugeValue, - Desc: prometheus.NewDesc( - prometheus.BuildFQName(namespace, "snapshot_stats", "snapshot_failed_shards"), - "Last snapshot failed shards", - defaultSnapshotLabels, nil, - ), - Value: func(snapshotStats SnapshotStatDataResponse) float64 { - return float64(snapshotStats.Shards.Failed) - }, - Labels: defaultSnapshotLabelValues, - }, - { - Type: prometheus.GaugeValue, - Desc: prometheus.NewDesc( - prometheus.BuildFQName(namespace, "snapshot_stats", "snapshot_successful_shards"), - "Last snapshot successful shards", - defaultSnapshotLabels, nil, - ), - Value: func(snapshotStats SnapshotStatDataResponse) float64 { - return float64(snapshotStats.Shards.Successful) - }, - Labels: defaultSnapshotLabelValues, - }, - }, - repositoryMetrics: []*repositoryMetric{ - { - Type: prometheus.GaugeValue, - Desc: prometheus.NewDesc( - prometheus.BuildFQName(namespace, "snapshot_stats", "number_of_snapshots"), - "Number of snapshots in a repository", - defaultSnapshotRepositoryLabels, nil, - ), - Value: func(snapshotsStats SnapshotStatsResponse) float64 { - return float64(len(snapshotsStats.Snapshots)) - }, - Labels: defaultSnapshotRepositoryLabelValues, - }, - { - Type: prometheus.GaugeValue, - Desc: prometheus.NewDesc( - prometheus.BuildFQName(namespace, "snapshot_stats", "oldest_snapshot_timestamp"), - "Timestamp of the oldest snapshot", - defaultSnapshotRepositoryLabels, nil, - ), - Value: func(snapshotsStats SnapshotStatsResponse) float64 { - if len(snapshotsStats.Snapshots) == 0 { - return 0 - } - return float64(snapshotsStats.Snapshots[0].StartTimeInMillis / 1000) - }, - Labels: defaultSnapshotRepositoryLabelValues, - }, - }, - } + u: u, + hc: hc, + }, nil } -// Describe add Snapshots metrics descriptions -func (s *Snapshots) Describe(ch chan<- *prometheus.Desc) { - for _, metric := range s.snapshotMetrics { - ch <- metric.Desc - } - ch <- s.up.Desc() - ch <- s.totalScrapes.Desc() - ch <- s.jsonParseFailures.Desc() -} +func (c *Snapshots) Update(ctx context.Context, ch chan<- prometheus.Metric) error { + // indices + snapshotsStatsResp := make(map[string]SnapshotStatsResponse) + u := c.u.ResolveReference(&url.URL{Path: "/_snapshot"}) -func (s *Snapshots) getAndParseURL(u *url.URL, data interface{}) error { - res, err := s.client.Get(u.String()) + var srr SnapshotRepositoriesResponse + resp, err := getURL(ctx, c.hc, c.logger, u.String()) if err != nil { - return fmt.Errorf("failed to get from %s://%s:%s%s: %s", - u.Scheme, u.Hostname(), u.Port(), u.Path, err) - } - - defer func() { - err = res.Body.Close() - if err != nil { - _ = level.Warn(s.logger).Log( - "msg", "failed to close http.Client", - "err", err, - ) - } - }() - - if res.StatusCode != http.StatusOK { - return fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) - } - - if err := json.NewDecoder(res.Body).Decode(data); err != nil { - s.jsonParseFailures.Inc() return err } - return nil -} -func (s *Snapshots) fetchAndDecodeSnapshotsStats() (map[string]SnapshotStatsResponse, error) { - mssr := make(map[string]SnapshotStatsResponse) - - u := *s.url - u.Path = path.Join(u.Path, "/_snapshot") - var srr SnapshotRepositoriesResponse - err := s.getAndParseURL(&u, &srr) + err = json.Unmarshal(resp, &srr) if err != nil { - return nil, err + return fmt.Errorf("failed to unmarshal JSON: %v", err) } + for repository := range srr { - u := *s.url - u.Path = path.Join(u.Path, "/_snapshot", repository, "/_all") + pathPart := path.Join("/_snapshot", repository, "/_all") + u := c.u.ResolveReference(&url.URL{Path: pathPart}) var ssr SnapshotStatsResponse - err := s.getAndParseURL(&u, &ssr) + resp, err := getURL(ctx, c.hc, c.logger, u.String()) if err != nil { continue } - mssr[repository] = ssr + err = json.Unmarshal(resp, &ssr) + if err != nil { + return fmt.Errorf("failed to unmarshal JSON: %v", err) + } + snapshotsStatsResp[repository] = ssr } - return mssr, nil -} + // Snapshots stats + for repositoryName, snapshotStats := range snapshotsStatsResp { -// Collect gets Snapshots metric values -func (s *Snapshots) Collect(ch chan<- prometheus.Metric) { - s.totalScrapes.Inc() - defer func() { - ch <- s.up - ch <- s.totalScrapes - ch <- s.jsonParseFailures - }() + ch <- prometheus.MustNewConstMetric( + numSnapshots, + prometheus.GaugeValue, + float64(len(snapshotStats.Snapshots)), + defaultSnapshotRepositoryLabelValues(repositoryName)..., + ) - // indices - snapshotsStatsResp, err := s.fetchAndDecodeSnapshotsStats() - if err != nil { - s.up.Set(0) - _ = level.Warn(s.logger).Log( - "msg", "failed to fetch and decode snapshot stats", - "err", err, + oldest := float64(0) + if len(snapshotStats.Snapshots) > 0 { + oldest = float64(snapshotStats.Snapshots[0].StartTimeInMillis / 1000) + } + ch <- prometheus.MustNewConstMetric( + oldestSnapshotTimestamp, + prometheus.GaugeValue, + oldest, + defaultSnapshotRepositoryLabelValues(repositoryName)..., ) - return - } - s.up.Set(1) - // Snapshots stats - for repositoryName, snapshotStats := range snapshotsStatsResp { - for _, metric := range s.repositoryMetrics { - ch <- prometheus.MustNewConstMetric( - metric.Desc, - metric.Type, - metric.Value(snapshotStats), - metric.Labels(repositoryName)..., - ) + latest := float64(0) + for i := len(snapshotStats.Snapshots) - 1; i >= 0; i-- { + var snap = snapshotStats.Snapshots[i] + if snap.State == "SUCCESS" || snap.State == "PARTIAL" { + latest = float64(snap.StartTimeInMillis / 1000) + break + } } + ch <- prometheus.MustNewConstMetric( + latestSnapshotTimestamp, + prometheus.GaugeValue, + latest, + defaultSnapshotRepositoryLabelValues(repositoryName)..., + ) + if len(snapshotStats.Snapshots) == 0 { continue } lastSnapshot := snapshotStats.Snapshots[len(snapshotStats.Snapshots)-1] - for _, metric := range s.snapshotMetrics { - ch <- prometheus.MustNewConstMetric( - metric.Desc, - metric.Type, - metric.Value(lastSnapshot), - metric.Labels(repositoryName, lastSnapshot)..., - ) - } + ch <- prometheus.MustNewConstMetric( + numIndices, + prometheus.GaugeValue, + float64(len(lastSnapshot.Indices)), + defaultSnapshotLabelValues(repositoryName, lastSnapshot)..., + ) + ch <- prometheus.MustNewConstMetric( + snapshotStartTimestamp, + prometheus.GaugeValue, + float64(lastSnapshot.StartTimeInMillis/1000), + defaultSnapshotLabelValues(repositoryName, lastSnapshot)..., + ) + ch <- prometheus.MustNewConstMetric( + snapshotEndTimestamp, + prometheus.GaugeValue, + float64(lastSnapshot.EndTimeInMillis/1000), + defaultSnapshotLabelValues(repositoryName, lastSnapshot)..., + ) + ch <- prometheus.MustNewConstMetric( + snapshotNumFailures, + prometheus.GaugeValue, + float64(len(lastSnapshot.Failures)), + defaultSnapshotLabelValues(repositoryName, lastSnapshot)..., + ) + ch <- prometheus.MustNewConstMetric( + snapshotNumShards, + prometheus.GaugeValue, + float64(lastSnapshot.Shards.Total), + defaultSnapshotLabelValues(repositoryName, lastSnapshot)..., + ) + ch <- prometheus.MustNewConstMetric( + snapshotFailedShards, + prometheus.GaugeValue, + float64(lastSnapshot.Shards.Failed), + defaultSnapshotLabelValues(repositoryName, lastSnapshot)..., + ) + ch <- prometheus.MustNewConstMetric( + snapshotSuccessfulShards, + prometheus.GaugeValue, + float64(lastSnapshot.Shards.Successful), + defaultSnapshotLabelValues(repositoryName, lastSnapshot)..., + ) } + + return nil } diff --git a/collector/snapshots_reponse.go b/collector/snapshots_reponse.go index 791f8dc5..09bc57f8 100644 --- a/collector/snapshots_reponse.go +++ b/collector/snapshots_reponse.go @@ -1,3 +1,16 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector import "time" @@ -9,18 +22,18 @@ type SnapshotStatsResponse struct { // SnapshotStatDataResponse is a representation of the single snapshot stat type SnapshotStatDataResponse struct { - Snapshot string `json:"snapshot"` - UUID string `json:"uuid"` - VersionID int64 `json:"version_id"` - Version string `json:"version"` - Indices []string `json:"indices"` - State string `json:"state"` - StartTime time.Time `json:"start_time"` - StartTimeInMillis int64 `json:"start_time_in_millis"` - EndTime time.Time `json:"end_time"` - EndTimeInMillis int64 `json:"end_time_in_millis"` - DurationInMillis int64 `json:"duration_in_millis"` - Failures []string `json:"failures"` + Snapshot string `json:"snapshot"` + UUID string `json:"uuid"` + VersionID int64 `json:"version_id"` + Version string `json:"version"` + Indices []string `json:"indices"` + State string `json:"state"` + StartTime time.Time `json:"start_time"` + StartTimeInMillis int64 `json:"start_time_in_millis"` + EndTime time.Time `json:"end_time"` + EndTimeInMillis int64 `json:"end_time_in_millis"` + DurationInMillis int64 `json:"duration_in_millis"` + Failures []interface{} `json:"failures"` Shards struct { Total int64 `json:"total"` Failed int64 `json:"failed"` @@ -30,6 +43,5 @@ type SnapshotStatDataResponse struct { // SnapshotRepositoriesResponse is a representation snapshots repositories type SnapshotRepositoriesResponse map[string]struct { - Type string `json:"type"` - Settings map[string]string `json:"settings"` + Type string `json:"type"` } diff --git a/collector/snapshots_test.go b/collector/snapshots_test.go index 74a4c5a9..cf4b2d6a 100644 --- a/collector/snapshots_test.go +++ b/collector/snapshots_test.go @@ -1,13 +1,30 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package collector import ( "fmt" + "io" "net/http" "net/http/httptest" "net/url" + "os" + "strings" "testing" - "github.com/go-kit/kit/log" + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/promslog" ) func TestSnapshots(t *testing.T) { @@ -24,52 +41,182 @@ func TestSnapshots(t *testing.T) { // curl http://localhost:9200/_snapshot/ // curl http://localhost:9200/_snapshot/test1/_all - tcs := map[string][]string{ - "1.7.6": []string{`{"test1":{"type":"fs","settings":{"location":"/tmp/test1"}}}`, `{"snapshots":[{"snapshot":"snapshot_1","version_id":1070699,"version":"1.7.6","indices":["foo_1","foo_2"],"state":"SUCCESS","start_time":"2018-09-04T09:09:02.427Z","start_time_in_millis":1536052142427,"end_time":"2018-09-04T09:09:02.755Z","end_time_in_millis":1536052142755,"duration_in_millis":328,"failures":[],"shards":{"total":10,"failed":0,"successful":10}}]}`}, - "2.4.5": []string{`{"test1":{"type":"fs","settings":{"location":"/tmp/test1"}}}`, `{"snapshots":[{"snapshot":"snapshot_1","version_id":2040599,"version":"2.4.5","indices":["foo_2","foo_1"],"state":"SUCCESS","start_time":"2018-09-04T09:25:25.818Z","start_time_in_millis":1536053125818,"end_time":"2018-09-04T09:25:26.326Z","end_time_in_millis":1536053126326,"duration_in_millis":508,"failures":[],"shards":{"total":10,"failed":0,"successful":10}}]}`}, - "5.4.2": []string{`{"test1":{"type":"fs","settings":{"location":"/tmp/test1"}}}`, `{"snapshots":[{"snapshot":"snapshot_1","uuid":"VZ_c_kKISAW8rpcqiwSg0w","version_id":5040299,"version":"5.4.2","indices":["foo_2","foo_1"],"state":"SUCCESS","start_time":"2018-09-04T09:29:13.971Z","start_time_in_millis":1536053353971,"end_time":"2018-09-04T09:29:14.477Z","end_time_in_millis":1536053354477,"duration_in_millis":506,"failures":[],"shards":{"total":10,"failed":0,"successful":10}}]}`}, + tests := []struct { + name string + file string + want string + }{ + { + name: "1.7.6", + file: "../fixtures/snapshots/1.7.6.json", + want: `# HELP elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds Timestamp of the latest SUCCESS or PARTIAL snapshot + # TYPE elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds gauge + elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds{repository="test1"} 1.536052142e+09 + # HELP elasticsearch_snapshot_stats_number_of_snapshots Number of snapshots in a repository + # TYPE elasticsearch_snapshot_stats_number_of_snapshots gauge + elasticsearch_snapshot_stats_number_of_snapshots{repository="test1"} 1 + # HELP elasticsearch_snapshot_stats_oldest_snapshot_timestamp Timestamp of the oldest snapshot + # TYPE elasticsearch_snapshot_stats_oldest_snapshot_timestamp gauge + elasticsearch_snapshot_stats_oldest_snapshot_timestamp{repository="test1"} 1.536052142e+09 + # HELP elasticsearch_snapshot_stats_snapshot_end_time_timestamp Last snapshot end timestamp + # TYPE elasticsearch_snapshot_stats_snapshot_end_time_timestamp gauge + elasticsearch_snapshot_stats_snapshot_end_time_timestamp{repository="test1",state="SUCCESS",version="1.7.6"} 1.536052142e+09 + # HELP elasticsearch_snapshot_stats_snapshot_failed_shards Last snapshot failed shards + # TYPE elasticsearch_snapshot_stats_snapshot_failed_shards gauge + elasticsearch_snapshot_stats_snapshot_failed_shards{repository="test1",state="SUCCESS",version="1.7.6"} 0 + # HELP elasticsearch_snapshot_stats_snapshot_number_of_failures Last snapshot number of failures + # TYPE elasticsearch_snapshot_stats_snapshot_number_of_failures gauge + elasticsearch_snapshot_stats_snapshot_number_of_failures{repository="test1",state="SUCCESS",version="1.7.6"} 0 + # HELP elasticsearch_snapshot_stats_snapshot_number_of_indices Number of indices in the last snapshot + # TYPE elasticsearch_snapshot_stats_snapshot_number_of_indices gauge + elasticsearch_snapshot_stats_snapshot_number_of_indices{repository="test1",state="SUCCESS",version="1.7.6"} 2 + # HELP elasticsearch_snapshot_stats_snapshot_start_time_timestamp Last snapshot start timestamp + # TYPE elasticsearch_snapshot_stats_snapshot_start_time_timestamp gauge + elasticsearch_snapshot_stats_snapshot_start_time_timestamp{repository="test1",state="SUCCESS",version="1.7.6"} 1.536052142e+09 + # HELP elasticsearch_snapshot_stats_snapshot_successful_shards Last snapshot successful shards + # TYPE elasticsearch_snapshot_stats_snapshot_successful_shards gauge + elasticsearch_snapshot_stats_snapshot_successful_shards{repository="test1",state="SUCCESS",version="1.7.6"} 10 + # HELP elasticsearch_snapshot_stats_snapshot_total_shards Last snapshot total shards + # TYPE elasticsearch_snapshot_stats_snapshot_total_shards gauge + elasticsearch_snapshot_stats_snapshot_total_shards{repository="test1",state="SUCCESS",version="1.7.6"} 10 +`, + }, + { + name: "2.4.5", + file: "../fixtures/snapshots/2.4.5.json", + want: `# HELP elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds Timestamp of the latest SUCCESS or PARTIAL snapshot + # TYPE elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds gauge + elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds{repository="test1"} 1.536053125e+09 + # HELP elasticsearch_snapshot_stats_number_of_snapshots Number of snapshots in a repository + # TYPE elasticsearch_snapshot_stats_number_of_snapshots gauge + elasticsearch_snapshot_stats_number_of_snapshots{repository="test1"} 1 + # HELP elasticsearch_snapshot_stats_oldest_snapshot_timestamp Timestamp of the oldest snapshot + # TYPE elasticsearch_snapshot_stats_oldest_snapshot_timestamp gauge + elasticsearch_snapshot_stats_oldest_snapshot_timestamp{repository="test1"} 1.536053125e+09 + # HELP elasticsearch_snapshot_stats_snapshot_end_time_timestamp Last snapshot end timestamp + # TYPE elasticsearch_snapshot_stats_snapshot_end_time_timestamp gauge + elasticsearch_snapshot_stats_snapshot_end_time_timestamp{repository="test1",state="SUCCESS",version="2.4.5"} 1.536053126e+09 + # HELP elasticsearch_snapshot_stats_snapshot_failed_shards Last snapshot failed shards + # TYPE elasticsearch_snapshot_stats_snapshot_failed_shards gauge + elasticsearch_snapshot_stats_snapshot_failed_shards{repository="test1",state="SUCCESS",version="2.4.5"} 0 + # HELP elasticsearch_snapshot_stats_snapshot_number_of_failures Last snapshot number of failures + # TYPE elasticsearch_snapshot_stats_snapshot_number_of_failures gauge + elasticsearch_snapshot_stats_snapshot_number_of_failures{repository="test1",state="SUCCESS",version="2.4.5"} 0 + # HELP elasticsearch_snapshot_stats_snapshot_number_of_indices Number of indices in the last snapshot + # TYPE elasticsearch_snapshot_stats_snapshot_number_of_indices gauge + elasticsearch_snapshot_stats_snapshot_number_of_indices{repository="test1",state="SUCCESS",version="2.4.5"} 2 + # HELP elasticsearch_snapshot_stats_snapshot_start_time_timestamp Last snapshot start timestamp + # TYPE elasticsearch_snapshot_stats_snapshot_start_time_timestamp gauge + elasticsearch_snapshot_stats_snapshot_start_time_timestamp{repository="test1",state="SUCCESS",version="2.4.5"} 1.536053125e+09 + # HELP elasticsearch_snapshot_stats_snapshot_successful_shards Last snapshot successful shards + # TYPE elasticsearch_snapshot_stats_snapshot_successful_shards gauge + elasticsearch_snapshot_stats_snapshot_successful_shards{repository="test1",state="SUCCESS",version="2.4.5"} 10 + # HELP elasticsearch_snapshot_stats_snapshot_total_shards Last snapshot total shards + # TYPE elasticsearch_snapshot_stats_snapshot_total_shards gauge + elasticsearch_snapshot_stats_snapshot_total_shards{repository="test1",state="SUCCESS",version="2.4.5"} 10 + `, + }, + { + name: "5.4.2", + file: "../fixtures/snapshots/5.4.2.json", + want: `# HELP elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds Timestamp of the latest SUCCESS or PARTIAL snapshot + # TYPE elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds gauge + elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds{repository="test1"} 1.536053353e+09 + # HELP elasticsearch_snapshot_stats_number_of_snapshots Number of snapshots in a repository + # TYPE elasticsearch_snapshot_stats_number_of_snapshots gauge + elasticsearch_snapshot_stats_number_of_snapshots{repository="test1"} 1 + # HELP elasticsearch_snapshot_stats_oldest_snapshot_timestamp Timestamp of the oldest snapshot + # TYPE elasticsearch_snapshot_stats_oldest_snapshot_timestamp gauge + elasticsearch_snapshot_stats_oldest_snapshot_timestamp{repository="test1"} 1.536053353e+09 + # HELP elasticsearch_snapshot_stats_snapshot_end_time_timestamp Last snapshot end timestamp + # TYPE elasticsearch_snapshot_stats_snapshot_end_time_timestamp gauge + elasticsearch_snapshot_stats_snapshot_end_time_timestamp{repository="test1",state="SUCCESS",version="5.4.2"} 1.536053354e+09 + # HELP elasticsearch_snapshot_stats_snapshot_failed_shards Last snapshot failed shards + # TYPE elasticsearch_snapshot_stats_snapshot_failed_shards gauge + elasticsearch_snapshot_stats_snapshot_failed_shards{repository="test1",state="SUCCESS",version="5.4.2"} 0 + # HELP elasticsearch_snapshot_stats_snapshot_number_of_failures Last snapshot number of failures + # TYPE elasticsearch_snapshot_stats_snapshot_number_of_failures gauge + elasticsearch_snapshot_stats_snapshot_number_of_failures{repository="test1",state="SUCCESS",version="5.4.2"} 0 + # HELP elasticsearch_snapshot_stats_snapshot_number_of_indices Number of indices in the last snapshot + # TYPE elasticsearch_snapshot_stats_snapshot_number_of_indices gauge + elasticsearch_snapshot_stats_snapshot_number_of_indices{repository="test1",state="SUCCESS",version="5.4.2"} 2 + # HELP elasticsearch_snapshot_stats_snapshot_start_time_timestamp Last snapshot start timestamp + # TYPE elasticsearch_snapshot_stats_snapshot_start_time_timestamp gauge + elasticsearch_snapshot_stats_snapshot_start_time_timestamp{repository="test1",state="SUCCESS",version="5.4.2"} 1.536053353e+09 + # HELP elasticsearch_snapshot_stats_snapshot_successful_shards Last snapshot successful shards + # TYPE elasticsearch_snapshot_stats_snapshot_successful_shards gauge + elasticsearch_snapshot_stats_snapshot_successful_shards{repository="test1",state="SUCCESS",version="5.4.2"} 10 + # HELP elasticsearch_snapshot_stats_snapshot_total_shards Last snapshot total shards + # TYPE elasticsearch_snapshot_stats_snapshot_total_shards gauge + elasticsearch_snapshot_stats_snapshot_total_shards{repository="test1",state="SUCCESS",version="5.4.2"} 10 + `, + }, + { + name: "5.4.2-failure", + file: "../fixtures/snapshots/5.4.2-failed.json", + want: `# HELP elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds Timestamp of the latest SUCCESS or PARTIAL snapshot + # TYPE elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds gauge + elasticsearch_snapshot_stats_latest_snapshot_timestamp_seconds{repository="test1"} 1.536053353e+09 + # HELP elasticsearch_snapshot_stats_number_of_snapshots Number of snapshots in a repository + # TYPE elasticsearch_snapshot_stats_number_of_snapshots gauge + elasticsearch_snapshot_stats_number_of_snapshots{repository="test1"} 1 + # HELP elasticsearch_snapshot_stats_oldest_snapshot_timestamp Timestamp of the oldest snapshot + # TYPE elasticsearch_snapshot_stats_oldest_snapshot_timestamp gauge + elasticsearch_snapshot_stats_oldest_snapshot_timestamp{repository="test1"} 1.536053353e+09 + # HELP elasticsearch_snapshot_stats_snapshot_end_time_timestamp Last snapshot end timestamp + # TYPE elasticsearch_snapshot_stats_snapshot_end_time_timestamp gauge + elasticsearch_snapshot_stats_snapshot_end_time_timestamp{repository="test1",state="SUCCESS",version="5.4.2"} 1.536053354e+09 + # HELP elasticsearch_snapshot_stats_snapshot_failed_shards Last snapshot failed shards + # TYPE elasticsearch_snapshot_stats_snapshot_failed_shards gauge + elasticsearch_snapshot_stats_snapshot_failed_shards{repository="test1",state="SUCCESS",version="5.4.2"} 1 + # HELP elasticsearch_snapshot_stats_snapshot_number_of_failures Last snapshot number of failures + # TYPE elasticsearch_snapshot_stats_snapshot_number_of_failures gauge + elasticsearch_snapshot_stats_snapshot_number_of_failures{repository="test1",state="SUCCESS",version="5.4.2"} 1 + # HELP elasticsearch_snapshot_stats_snapshot_number_of_indices Number of indices in the last snapshot + # TYPE elasticsearch_snapshot_stats_snapshot_number_of_indices gauge + elasticsearch_snapshot_stats_snapshot_number_of_indices{repository="test1",state="SUCCESS",version="5.4.2"} 2 + # HELP elasticsearch_snapshot_stats_snapshot_start_time_timestamp Last snapshot start timestamp + # TYPE elasticsearch_snapshot_stats_snapshot_start_time_timestamp gauge + elasticsearch_snapshot_stats_snapshot_start_time_timestamp{repository="test1",state="SUCCESS",version="5.4.2"} 1.536053353e+09 + # HELP elasticsearch_snapshot_stats_snapshot_successful_shards Last snapshot successful shards + # TYPE elasticsearch_snapshot_stats_snapshot_successful_shards gauge + elasticsearch_snapshot_stats_snapshot_successful_shards{repository="test1",state="SUCCESS",version="5.4.2"} 10 + # HELP elasticsearch_snapshot_stats_snapshot_total_shards Last snapshot total shards + # TYPE elasticsearch_snapshot_stats_snapshot_total_shards gauge + elasticsearch_snapshot_stats_snapshot_total_shards{repository="test1",state="SUCCESS",version="5.4.2"} 10 + `, + }, } - for ver, out := range tcs { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.RequestURI == "/_snapshot" { - fmt.Fprint(w, out[0]) - return + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f, err := os.Open(tt.file) + if err != nil { + t.Fatal(err) } - fmt.Fprint(w, out[1]) - })) - defer ts.Close() + defer f.Close() - u, err := url.Parse(ts.URL) - if err != nil { - t.Fatalf("Failed to parse URL: %s", err) - } - s := NewSnapshots(log.NewNopLogger(), http.DefaultClient, u) - stats, err := s.fetchAndDecodeSnapshotsStats() - if err != nil { - t.Fatalf("Failed to fetch or decode snapshots stats: %s", err) - } - t.Logf("[%s] Snapshots Response: %+v", ver, stats) - repositoryStats := stats["test1"] - snapshotStats := repositoryStats.Snapshots[0] + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.RequestURI == "/_snapshot" { + fmt.Fprint(w, `{"test1":{"type":"fs","settings":{"location":"/tmp/test1"}}}`) + return + } + io.Copy(w, f) + })) + defer ts.Close() - if len(snapshotStats.Indices) != 2 { - t.Errorf("Bad number of snapshot indices") - } - if len(snapshotStats.Failures) != 0 { - t.Errorf("Bad number of snapshot failures") - } - if snapshotStats.Shards.Total != 10 { - t.Errorf("Bad number of snapshot shards total") - } - if snapshotStats.Shards.Failed != 0 { - t.Errorf("Bad number of snapshot shards failed") - } - if snapshotStats.Shards.Successful != 10 { - t.Errorf("Bad number of snapshot shards successful") - } - if len(repositoryStats.Snapshots) != 1 { - t.Errorf("Bad number of repository snapshots") - } - } + u, err := url.Parse(ts.URL) + if err != nil { + t.Fatal(err) + } + c, err := NewSnapshots(promslog.NewNopLogger(), u, http.DefaultClient) + if err != nil { + t.Fatal(err) + } + + if err := testutil.CollectAndCompare(wrapCollector{c}, strings.NewReader(tt.want)); err != nil { + t.Fatal(err) + } + }) + } } diff --git a/collector/tasks.go b/collector/tasks.go new file mode 100644 index 00000000..faaef2da --- /dev/null +++ b/collector/tasks.go @@ -0,0 +1,142 @@ +// Copyright 2023 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + + "github.com/alecthomas/kingpin/v2" + "github.com/prometheus/client_golang/prometheus" +) + +// filterByTask global required because collector interface doesn't expose any way to take +// constructor args. +var actionFilter string + +var taskActionDesc = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "task_stats", "action"), + "Number of tasks of a certain action", + []string{"action"}, nil) + +func init() { + kingpin.Flag("tasks.actions", + "Filter on task actions. Used in same way as Task API actions param"). + Default("indices:*").StringVar(&actionFilter) + registerCollector("tasks", defaultDisabled, NewTaskCollector) +} + +// Task Information Struct +type TaskCollector struct { + logger *slog.Logger + hc *http.Client + u *url.URL +} + +// NewTaskCollector defines Task Prometheus metrics +func NewTaskCollector(logger *slog.Logger, u *url.URL, hc *http.Client) (Collector, error) { + logger.Info("task collector created", + "actionFilter", actionFilter, + ) + + return &TaskCollector{ + logger: logger, + hc: hc, + u: u, + }, nil +} + +func (t *TaskCollector) Update(ctx context.Context, ch chan<- prometheus.Metric) error { + tasks, err := t.fetchTasks(ctx) + if err != nil { + return fmt.Errorf("failed to fetch and decode task stats: %w", err) + } + + stats := AggregateTasks(tasks) + for action, count := range stats.CountByAction { + ch <- prometheus.MustNewConstMetric( + taskActionDesc, + prometheus.GaugeValue, + float64(count), + action, + ) + } + return nil +} + +func (t *TaskCollector) fetchTasks(_ context.Context) (tasksResponse, error) { + u := t.u.ResolveReference(&url.URL{Path: "_tasks"}) + q := u.Query() + q.Set("group_by", "none") + q.Set("actions", actionFilter) + u.RawQuery = q.Encode() + + var tr tasksResponse + res, err := t.hc.Get(u.String()) + if err != nil { + return tr, fmt.Errorf("failed to get data stream stats health from %s://%s:%s%s: %s", + u.Scheme, u.Hostname(), u.Port(), u.Path, err) + } + + defer func() { + err = res.Body.Close() + if err != nil { + t.logger.Warn( + "failed to close http.Client", + "err", err, + ) + } + }() + + if res.StatusCode != http.StatusOK { + return tr, fmt.Errorf("HTTP Request to %v failed with code %d", u.String(), res.StatusCode) + } + + bts, err := io.ReadAll(res.Body) + if err != nil { + return tr, err + } + + err = json.Unmarshal(bts, &tr) + return tr, err +} + +// tasksResponse is a representation of the Task management API. +type tasksResponse struct { + Tasks []taskResponse `json:"tasks"` +} + +// taskResponse is a representation of the individual task item returned by task API endpoint. +// +// We only parse a very limited amount of this API for use in aggregation. +type taskResponse struct { + Action string `json:"action"` +} + +type aggregatedTaskStats struct { + CountByAction map[string]int64 +} + +func AggregateTasks(t tasksResponse) aggregatedTaskStats { + actions := map[string]int64{} + for _, task := range t.Tasks { + actions[task.Action]++ + } + return aggregatedTaskStats{CountByAction: actions} +} diff --git a/collector/tasks_test.go b/collector/tasks_test.go new file mode 100644 index 00000000..e471eba4 --- /dev/null +++ b/collector/tasks_test.go @@ -0,0 +1,78 @@ +// Copyright 2023 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "fmt" + "net/http" + "net/http/httptest" + "net/url" + "strings" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/promslog" +) + +func TestTasks(t *testing.T) { + // Test data was collected by running the following: + // # create container + // docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.17.11 + // sleep 15 + // # start some busy work in background + // for i in $(seq 1 500) + // do + // curl -o /dev/null -sX POST "localhost:9200/a1/_doc" -H 'Content-Type: application/json' -d'{"a1": "'"$i"'"}' + // sleep .01 + // curl -o /dev/null -sX POST "localhost:9200/a1/_doc" -H 'Content-Type: application/json' -d'{"a2": "'"$i"'"}' + // sleep .01 + // curl -o /dev/null -sX POST "localhost:9200/a1/_doc" -H 'Content-Type: application/json' -d'{"a3": "'"$i"'"}' + // sleep .01 + // done & + // # try and collect a good sample + // curl -X GET 'localhost:9200/_tasks?group_by=none&actions=indices:*' + // # cleanup + // docker rm --force elasticsearch + tcs := map[string]string{ + "7.17": `{"tasks":[{"node":"9lWCm1y_QkujaAg75bVx7A","id":70,"type":"transport","action":"indices:admin/index_template/put","start_time_in_millis":1695900464655,"running_time_in_nanos":308640039,"cancellable":false,"headers":{}},{"node":"9lWCm1y_QkujaAg75bVx7A","id":73,"type":"transport","action":"indices:admin/index_template/put","start_time_in_millis":1695900464683,"running_time_in_nanos":280672000,"cancellable":false,"headers":{}},{"node":"9lWCm1y_QkujaAg75bVx7A","id":76,"type":"transport","action":"indices:admin/index_template/put","start_time_in_millis":1695900464711,"running_time_in_nanos":253247906,"cancellable":false,"headers":{}},{"node":"9lWCm1y_QkujaAg75bVx7A","id":93,"type":"transport","action":"indices:admin/index_template/put","start_time_in_millis":1695900464904,"running_time_in_nanos":60230460,"cancellable":false,"headers":{}},{"node":"9lWCm1y_QkujaAg75bVx7A","id":50,"type":"transport","action":"indices:data/write/index","start_time_in_millis":1695900464229,"running_time_in_nanos":734480468,"cancellable":false,"headers":{}},{"node":"9lWCm1y_QkujaAg75bVx7A","id":51,"type":"transport","action":"indices:admin/auto_create","start_time_in_millis":1695900464235,"running_time_in_nanos":729223933,"cancellable":false,"headers":{}}]}`, + } + want := `# HELP elasticsearch_task_stats_action Number of tasks of a certain action +# TYPE elasticsearch_task_stats_action gauge +elasticsearch_task_stats_action{action="indices:admin/auto_create"} 1 +elasticsearch_task_stats_action{action="indices:admin/index_template/put"} 4 +elasticsearch_task_stats_action{action="indices:data/write/index"} 1 +` + for ver, out := range tcs { + t.Run(ver, func(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + fmt.Fprintln(w, out) + })) + defer ts.Close() + + u, err := url.Parse(ts.URL) + if err != nil { + t.Fatalf("Failed to parse URL: %s", err) + } + + c, err := NewTaskCollector(promslog.NewNopLogger(), u, ts.Client()) + if err != nil { + t.Fatalf("Failed to create collector: %v", err) + } + + if err := testutil.CollectAndCompare(wrapCollector{c}, strings.NewReader(want)); err != nil { + t.Fatalf("Metrics did not match: %v", err) + } + }) + } +} diff --git a/collector/util.go b/collector/util.go new file mode 100644 index 00000000..a2df06ed --- /dev/null +++ b/collector/util.go @@ -0,0 +1,55 @@ +// Copyright 2023 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "context" + "fmt" + "io" + "log/slog" + "net/http" +) + +func getURL(ctx context.Context, hc *http.Client, log *slog.Logger, u string) ([]byte, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil) + if err != nil { + return nil, err + } + + resp, err := hc.Do(req) + if err != nil { + return nil, fmt.Errorf("failed to get %s: %v", u, err) + } + + defer func() { + err = resp.Body.Close() + if err != nil { + log.Warn( + "failed to close response body", + "err", err, + ) + } + }() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("HTTP Request failed with code %d", resp.StatusCode) + } + + b, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + return b, nil +} diff --git a/elasticsearch-mixin/README.md b/elasticsearch-mixin/README.md new file mode 100644 index 00000000..4f41eb2d --- /dev/null +++ b/elasticsearch-mixin/README.md @@ -0,0 +1,29 @@ +# Elasticsearch Exporter Mixin + +This is a mixin for the elasticsearch_exporter to define dashboards, alerts, and monitoring queries for use with this exporter. + +Good example of upstream mixin for reference: https://github.com/kubernetes-monitoring/kubernetes-mixin + +## Development + +### JSONNET +https://jsonnet.org/ + +```go install github.com/google/go-jsonnet/cmd/jsonnet@latest``` + +### JSONNET BUNDLER +jsonnet bundler is a package manager for jsonnet + +https://github.com/jsonnet-bundler/jsonnet-bundler + +```go install -a github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb@latest``` + +### Grafonnet +Grafana libraries for jsonnet: https://grafana.github.io/grafonnet/ + +```jb install github.com/grafana/grafonnet/gen/grafonnet-latest@main``` + +### Run the build +```bash +./scripts/compile-mixin.sh +``` diff --git a/elasticsearch-mixin/compiled/alerts.yaml b/elasticsearch-mixin/compiled/alerts.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/elasticsearch-mixin/compiled/alerts.yaml @@ -0,0 +1 @@ +{} diff --git a/elasticsearch-mixin/compiled/dashboards/cluster.json b/elasticsearch-mixin/compiled/dashboards/cluster.json new file mode 100644 index 00000000..37c919b6 --- /dev/null +++ b/elasticsearch-mixin/compiled/dashboards/cluster.json @@ -0,0 +1,687 @@ +{ + "graphTooltip": 1, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "panels": [ ], + "title": "Overview", + "type": "row" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 8, + "x": 0, + "y": 1 + }, + "id": 2, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(\n elasticsearch_cluster_health_number_of_nodes{cluster=~\"$cluster\"}\n)\n" + } + ], + "title": "Nodes", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 8, + "x": 8, + "y": 1 + }, + "id": 3, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(\n elasticsearch_cluster_health_number_of_data_nodes{cluster=~\"$cluster\"}\n)\n" + } + ], + "title": "Data Nodes", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 8, + "x": 16, + "y": 1 + }, + "id": 4, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(\n elasticsearch_cluster_health_number_of_pending_tasks{cluster=~\"$cluster\"}\n)\n" + } + ], + "title": "Pending Tasks", + "type": "stat" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 5 + }, + "id": 5, + "panels": [ ], + "title": "Shards", + "type": "row" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 0, + "y": 6 + }, + "id": 6, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(\n elasticsearch_cluster_health_active_shards{cluster=~\"$cluster\"}\n)\n" + } + ], + "title": "Active", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 4, + "y": 6 + }, + "id": 7, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(\n elasticsearch_cluster_health_active_primary_shards{cluster=~\"$cluster\"}\n)\n" + } + ], + "title": "Active Primary", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 8, + "y": 6 + }, + "id": 8, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(\n elasticsearch_cluster_health_initializing_shards{cluster=~\"$cluster\"}\n)\n" + } + ], + "title": "Initializing", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 12, + "y": 6 + }, + "id": 9, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(\n elasticsearch_cluster_health_reloacting_shards{cluster=~\"$cluster\"}\n)\n" + } + ], + "title": "Relocating", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 16, + "y": 6 + }, + "id": 10, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(\n elasticsearch_cluster_health_unassigned_shards{cluster=~\"$cluster\"}\n)\n" + } + ], + "title": "Unassigned", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 20, + "y": 6 + }, + "id": 11, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(\n elasticsearch_cluster_health_delayed_unassigned_shards{cluster=~\"$cluster\"}\n)\n" + } + ], + "title": "DelayedUnassigned", + "type": "stat" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 12, + "panels": [ ], + "title": "Documents", + "type": "row" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 0, + "y": 11 + }, + "id": 13, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "elasticsearch_indices_docs{cluster=~\"$cluster\"}\n" + } + ], + "title": "Indexed Documents", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "bytes" + } + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 4, + "y": 11 + }, + "id": 14, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "elasticsearch_indices_store_size_bytes{cluster=~\"$cluster\"}\n" + } + ], + "title": "Index Size", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 8, + "y": 11 + }, + "id": 15, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(elasticsearch_indices_indexing_index_total{cluster=~\"$cluster\"}[$__rate_interval])\n", + "legendFormat": "{{name}}" + } + ], + "title": "Index Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 12, + "y": 11 + }, + "id": 16, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(elasticsearch_indices_search_query_total{cluster=~\"$cluster\"}[$__rate_interval])\n", + "legendFormat": "{{name}}" + } + ], + "title": "Query Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 16, + "y": 11 + }, + "id": 17, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(elasticsearch_thread_pool_queue_count{cluster=~\"$cluster\",type!=\"management\"}) by (type)\n", + "legendFormat": "{{type}}" + } + ], + "title": "Queue Count", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 15 + }, + "id": 18, + "panels": [ ], + "title": "Memory", + "type": "row" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "bytes" + } + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 0, + "y": 16 + }, + "id": 19, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "elasticsearch_jvm_memory_used_bytes{cluster=~\"$cluster\"}\n", + "legendFormat": "{{name}} {{area}}" + } + ], + "title": "Memory Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "max": 1, + "min": 0, + "unit": "percentunit" + } + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 6, + "y": 16 + }, + "id": 20, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "avg_over_time(\n elasticsearch_jvm_memory_used_bytes{cluster=~\"$cluster\"}[15m]\n) /\nelasticsearch_jvm_memory_max_bytes{cluster=~\"$cluster\"}\n", + "legendFormat": "{{name}} {{area}}" + } + ], + "title": "Memory 15m Avg", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "bytes" + } + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 12, + "y": 16 + }, + "id": 21, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "elasticsearch_jvm_memory_max_bytes{cluster=~\"$cluster\"}\n", + "legendFormat": "{{name}} {{area}}" + } + ], + "title": "Memory Max", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "s" + } + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 16 + }, + "id": 22, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(\n elasticsearch_jvm_gc_collection_seconds_sum{cluster=~\"$cluster\"}[$__rate_interval]\n)\n", + "legendFormat": "{{name}} {{gc}}" + } + ], + "title": "GC Rate", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 23, + "panels": [ ], + "title": "Threads", + "type": "row" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 12, + "x": 0, + "y": 21 + }, + "id": 24, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "elasticsearch_thread_pool_active_count{cluster=~\"$cluster\"}\n", + "legendFormat": "{{type}}" + } + ], + "title": "Thread Pools", + "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "gridPos": { + "h": 4, + "w": 12, + "x": 12, + "y": 21 + }, + "id": 25, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "elasticsearch_thread_pool_rejected_count{cluster=~\"$cluster\"}\n", + "legendFormat": "{{name}} {{type}}" + } + ], + "title": "Thread Pool Rejections", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 25 + }, + "id": 26, + "panels": [ ], + "title": "Network", + "type": "row" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "bytes" + } + }, + "gridPos": { + "h": 4, + "w": 24, + "x": 0, + "y": 26 + }, + "id": 27, + "pluginVersion": "v10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(\n elasticsearch_transport_rx_size_bytes_total{cluster=~\"$cluster\"}[$__rate_interval]\n)\n", + "legendFormat": "{{name}} TX" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "rate(\n elasticsearch_transport_tx_size_bytes_total{cluster=~\"$cluster\"}[$__rate_interval]\n)\n", + "legendFormat": "{{name}} RX" + } + ], + "title": "Transport Rate", + "type": "timeseries" + } + ], + "refresh": "1m", + "schemaVersion": 36, + "tags": [ + "elasticsearch-exporter-mixin" + ], + "templating": { + "list": [ + { + "name": "datasource", + "query": "prometheus", + "type": "datasource" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "name": "cluster", + "query": "label_values(elasticsearch_cluster_health_status, cluster)", + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timezone": "utc", + "title": "Elasticsearch Exporter / Cluster" + } \ No newline at end of file diff --git a/elasticsearch-mixin/compiled/rules.yaml b/elasticsearch-mixin/compiled/rules.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/elasticsearch-mixin/compiled/rules.yaml @@ -0,0 +1 @@ +{} diff --git a/elasticsearch-mixin/config.libsonnet b/elasticsearch-mixin/config.libsonnet new file mode 100644 index 00000000..3cf4a4f9 --- /dev/null +++ b/elasticsearch-mixin/config.libsonnet @@ -0,0 +1,6 @@ +{ + _config+:: { + dashboardNamePrefix: 'Elasticsearch Exporter / ', + dashboardTags: ['elasticsearch-exporter-mixin'], + }, +} diff --git a/elasticsearch-mixin/dashboards.jsonnet b/elasticsearch-mixin/dashboards.jsonnet new file mode 100644 index 00000000..9a03074e --- /dev/null +++ b/elasticsearch-mixin/dashboards.jsonnet @@ -0,0 +1,3 @@ +local dashboards = (import 'mixin.libsonnet').grafanaDashboards; + +{ [name]: dashboards[name] for name in std.objectFields(dashboards) } diff --git a/elasticsearch-mixin/dashboards/cluster.libsonnet b/elasticsearch-mixin/dashboards/cluster.libsonnet new file mode 100644 index 00000000..ac32d75e --- /dev/null +++ b/elasticsearch-mixin/dashboards/cluster.libsonnet @@ -0,0 +1,67 @@ +local g = import 'g.libsonnet'; + +local dashboard = g.dashboard; +local row = g.panel.row; + +local panels = import './panels.libsonnet'; +local queries = import './queries.libsonnet'; +local variables = import './variables.libsonnet'; +local util = import './util.libsonnet'; + +{ + grafanaDashboards+:: { + 'cluster.json': + dashboard.new('%s Cluster' % $._config.dashboardNamePrefix) + + dashboard.withTags($._config.dashboardTags) + + dashboard.withRefresh('1m') + + dashboard.time.withFrom(value='now-1h') + + dashboard.graphTooltip.withSharedCrosshair() + + dashboard.withVariables([ + variables.datasource, + variables.cluster, + ]) + + dashboard.withPanels( + util.makeGrid([ + row.new('Overview') + + row.withPanels([ + panels.stat.nodes('Nodes', queries.runningNodes), + panels.stat.nodes('Data Nodes', queries.dataNodes), + panels.stat.nodes('Pending Tasks', queries.pendingTasks), + ]), + row.new('Shards') + + row.withPanels([ + panels.stat.nodes('Active', queries.activeShards), + panels.stat.nodes('Active Primary', queries.activePrimaryShards), + panels.stat.nodes('Initializing', queries.initializingShards), + panels.stat.nodes('Relocating', queries.reloactingShards), + panels.stat.nodes('Unassigned', queries.unassignedShards), + panels.stat.nodes('DelayedUnassigned', queries.delayedUnassignedShards), + ]), + row.new('Documents') + + row.withPanels([ + panels.timeSeries.base('Indexed Documents', queries.indexedDocuments), + panels.timeSeries.bytes('Index Size', queries.indexSize), + panels.timeSeries.base('Index Rate', queries.indexRate), + panels.timeSeries.base('Query Rate', queries.queryRate), + panels.timeSeries.base('Queue Count', queries.queueCount), + ]), + row.new('Memory') + + row.withPanels([ + panels.timeSeries.bytes('Memory Usage', queries.memoryUsage), + panels.timeSeries.ratioMax1('Memory 15m Avg', queries.memoryUsageAverage15), + panels.timeSeries.bytes('Memory Max', queries.memoryMax), + panels.timeSeries.seconds('GC Rate', queries.gcSeconds), + ]), + row.new('Threads') + + row.withPanels([ + panels.timeSeries.base('Thread Pools', queries.threadPoolActive), + panels.timeSeries.base('Thread Pool Rejections', queries.threadPoolRejections), + ]), + row.new('Network') + + row.withPanels([ + panels.timeSeries.bytes('Transport Rate', [queries.transportTXRate, queries.transportRXRate]), + ]), + ]), + ), + }, +} diff --git a/elasticsearch-mixin/dashboards/dashboards.libsonnet b/elasticsearch-mixin/dashboards/dashboards.libsonnet new file mode 100644 index 00000000..16802c25 --- /dev/null +++ b/elasticsearch-mixin/dashboards/dashboards.libsonnet @@ -0,0 +1 @@ +(import 'cluster.libsonnet') diff --git a/elasticsearch-mixin/dashboards/g.libsonnet b/elasticsearch-mixin/dashboards/g.libsonnet new file mode 100644 index 00000000..69aac830 --- /dev/null +++ b/elasticsearch-mixin/dashboards/g.libsonnet @@ -0,0 +1 @@ +import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet' diff --git a/elasticsearch-mixin/dashboards/panels.libsonnet b/elasticsearch-mixin/dashboards/panels.libsonnet new file mode 100644 index 00000000..f5f24d45 --- /dev/null +++ b/elasticsearch-mixin/dashboards/panels.libsonnet @@ -0,0 +1,38 @@ +local g = import 'g.libsonnet'; + +{ + stat: { + local stat = g.panel.stat, + + base(title, targets): + stat.new(title) + + stat.queryOptions.withTargets(targets), + + nodes: self.base, + }, + + timeSeries: { + local timeSeries = g.panel.timeSeries, + + base(title, targets): + timeSeries.new(title) + + timeSeries.queryOptions.withTargets(targets), + + ratio(title, targets): + self.base(title, targets) + + timeSeries.standardOptions.withUnit('percentunit'), + + ratioMax1(title, targets): + self.ratio(title, targets) + + timeSeries.standardOptions.withMax(1) + + timeSeries.standardOptions.withMin(0), + + bytes(title, targets): + self.base(title, targets) + + timeSeries.standardOptions.withUnit('bytes'), + + seconds(title, targets): + self.base(title, targets) + + timeSeries.standardOptions.withUnit('s'), + }, +} diff --git a/elasticsearch-mixin/dashboards/queries.libsonnet b/elasticsearch-mixin/dashboards/queries.libsonnet new file mode 100644 index 00000000..d7a8e661 --- /dev/null +++ b/elasticsearch-mixin/dashboards/queries.libsonnet @@ -0,0 +1,11 @@ +local g = import './g.libsonnet'; +local prometheusQuery = g.query.prometheus; + +local variables = import './variables.libsonnet'; + +(import './queries/general.libsonnet') + +(import './queries/shard.libsonnet') + +(import './queries/document.libsonnet') + +(import './queries/memory.libsonnet') + +(import './queries/threads.libsonnet') + +(import './queries/network.libsonnet') diff --git a/elasticsearch-mixin/dashboards/queries/document.libsonnet b/elasticsearch-mixin/dashboards/queries/document.libsonnet new file mode 100644 index 00000000..369ce885 --- /dev/null +++ b/elasticsearch-mixin/dashboards/queries/document.libsonnet @@ -0,0 +1,50 @@ +local g = import '../g.libsonnet'; +local prometheusQuery = g.query.prometheus; + +local variables = import '../variables.libsonnet'; + +{ + indexedDocuments: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + elasticsearch_indices_docs{cluster=~"$cluster"} + ||| + ), + + indexSize: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + elasticsearch_indices_store_size_bytes{cluster=~"$cluster"} + ||| + ), + + indexRate: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + rate(elasticsearch_indices_indexing_index_total{cluster=~"$cluster"}[$__rate_interval]) + ||| + ) + + prometheusQuery.withLegendFormat('{{name}}'), + + queryRate: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + rate(elasticsearch_indices_search_query_total{cluster=~"$cluster"}[$__rate_interval]) + ||| + ) + + prometheusQuery.withLegendFormat('{{name}}'), + + queueCount: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum(elasticsearch_thread_pool_queue_count{cluster=~"$cluster",type!="management"}) by (type) + ||| + ) + + prometheusQuery.withLegendFormat('{{type}}'), + +} diff --git a/elasticsearch-mixin/dashboards/queries/general.libsonnet b/elasticsearch-mixin/dashboards/queries/general.libsonnet new file mode 100644 index 00000000..053207ac --- /dev/null +++ b/elasticsearch-mixin/dashboards/queries/general.libsonnet @@ -0,0 +1,35 @@ +local g = import '../g.libsonnet'; +local prometheusQuery = g.query.prometheus; + +local variables = import '../variables.libsonnet'; + +{ + runningNodes: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + elasticsearch_cluster_health_number_of_nodes{cluster=~"$cluster"} + ) + ||| + ), + dataNodes: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + elasticsearch_cluster_health_number_of_data_nodes{cluster=~"$cluster"} + ) + ||| + ), + + pendingTasks: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + elasticsearch_cluster_health_number_of_pending_tasks{cluster=~"$cluster"} + ) + ||| + ), +} diff --git a/elasticsearch-mixin/dashboards/queries/memory.libsonnet b/elasticsearch-mixin/dashboards/queries/memory.libsonnet new file mode 100644 index 00000000..59e8d274 --- /dev/null +++ b/elasticsearch-mixin/dashboards/queries/memory.libsonnet @@ -0,0 +1,47 @@ +local g = import '../g.libsonnet'; +local prometheusQuery = g.query.prometheus; + +local variables = import '../variables.libsonnet'; + +{ + memoryUsage: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + elasticsearch_jvm_memory_used_bytes{cluster=~"$cluster"} + ||| + ) + + prometheusQuery.withLegendFormat('{{name}} {{area}}'), + + memoryUsageAverage15: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + avg_over_time( + elasticsearch_jvm_memory_used_bytes{cluster=~"$cluster"}[15m] + ) / + elasticsearch_jvm_memory_max_bytes{cluster=~"$cluster"} + ||| + ) + + prometheusQuery.withLegendFormat('{{name}} {{area}}'), + + memoryMax: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + elasticsearch_jvm_memory_max_bytes{cluster=~"$cluster"} + ||| + ) + + prometheusQuery.withLegendFormat('{{name}} {{area}}'), + + gcSeconds: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + rate( + elasticsearch_jvm_gc_collection_seconds_sum{cluster=~"$cluster"}[$__rate_interval] + ) + ||| + ) + + prometheusQuery.withLegendFormat('{{name}} {{gc}}'), +} diff --git a/elasticsearch-mixin/dashboards/queries/network.libsonnet b/elasticsearch-mixin/dashboards/queries/network.libsonnet new file mode 100644 index 00000000..76aab2b5 --- /dev/null +++ b/elasticsearch-mixin/dashboards/queries/network.libsonnet @@ -0,0 +1,28 @@ +local g = import '../g.libsonnet'; +local prometheusQuery = g.query.prometheus; + +local variables = import '../variables.libsonnet'; + +{ + transportTXRate: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + rate( + elasticsearch_transport_rx_size_bytes_total{cluster=~"$cluster"}[$__rate_interval] + ) + ||| + ) + + prometheusQuery.withLegendFormat('{{name}} TX'), + + transportRXRate: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + rate( + elasticsearch_transport_tx_size_bytes_total{cluster=~"$cluster"}[$__rate_interval] + ) + ||| + ) + + prometheusQuery.withLegendFormat('{{name}} RX'), +} diff --git a/elasticsearch-mixin/dashboards/queries/shard.libsonnet b/elasticsearch-mixin/dashboards/queries/shard.libsonnet new file mode 100644 index 00000000..6bebb4e6 --- /dev/null +++ b/elasticsearch-mixin/dashboards/queries/shard.libsonnet @@ -0,0 +1,66 @@ +local g = import '../g.libsonnet'; +local prometheusQuery = g.query.prometheus; + +local variables = import '../variables.libsonnet'; + +{ + activeShards: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + elasticsearch_cluster_health_active_shards{cluster=~"$cluster"} + ) + ||| + ), + + activePrimaryShards: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + elasticsearch_cluster_health_active_primary_shards{cluster=~"$cluster"} + ) + ||| + ), + + initializingShards: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + elasticsearch_cluster_health_initializing_shards{cluster=~"$cluster"} + ) + ||| + ), + + reloactingShards: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + elasticsearch_cluster_health_reloacting_shards{cluster=~"$cluster"} + ) + ||| + ), + + unassignedShards: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + elasticsearch_cluster_health_unassigned_shards{cluster=~"$cluster"} + ) + ||| + ), + + delayedUnassignedShards: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + elasticsearch_cluster_health_delayed_unassigned_shards{cluster=~"$cluster"} + ) + ||| + ), +} diff --git a/elasticsearch-mixin/dashboards/queries/threads.libsonnet b/elasticsearch-mixin/dashboards/queries/threads.libsonnet new file mode 100644 index 00000000..1fdb3e63 --- /dev/null +++ b/elasticsearch-mixin/dashboards/queries/threads.libsonnet @@ -0,0 +1,24 @@ +local g = import '../g.libsonnet'; +local prometheusQuery = g.query.prometheus; + +local variables = import '../variables.libsonnet'; + +{ + threadPoolActive: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + elasticsearch_thread_pool_active_count{cluster=~"$cluster"} + ||| + ) + + prometheusQuery.withLegendFormat('{{type}}'), + + threadPoolRejections: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + elasticsearch_thread_pool_rejected_count{cluster=~"$cluster"} + ||| + ) + + prometheusQuery.withLegendFormat('{{name}} {{type}}'), +} diff --git a/elasticsearch-mixin/dashboards/util.libsonnet b/elasticsearch-mixin/dashboards/util.libsonnet new file mode 100644 index 00000000..388b06ae --- /dev/null +++ b/elasticsearch-mixin/dashboards/util.libsonnet @@ -0,0 +1,66 @@ +local g = import 'g.libsonnet'; +local panelUtil = g.util.panel; + +{ + local gridWidth = 24, + + // makeGrid returns an array of panels organized into a grid layout. + // This is a modified version of the grafonnet makeGrid function to + // calculate the width of each panel based on the number of panels. + makeGrid(panels, panelHeight=4, startY=0): + local sanitizePanels(ps) = + // Figure out the number of panels and the width of each panel + local numPanels = std.length(ps); + local panelWidth = std.floor(gridWidth / numPanels); + + // Sanitize the panels, this ensures tht the panels have the valid gridPos + std.map( + function(p) + local sanePanel = panelUtil.sanitizePanel(p, defaultHeight=panelHeight); + ( + if p.type == 'row' + then sanePanel { + panels: sanitizePanels(sanePanel.panels), + } + else sanePanel { + gridPos+: { + w: panelWidth, + }, + } + ), + ps + ); + + local sanitizedPanels = sanitizePanels(panels); + + local grouped = panelUtil.groupPanelsInRows(sanitizedPanels); + + local panelsBeforeRows = panelUtil.getPanelsBeforeNextRow(grouped); + local rowPanels = + std.filter( + function(p) p.type == 'row', + grouped + ); + + + local CalculateXforPanel(index, panel) = + local panelsPerRow = std.floor(gridWidth / panel.gridPos.w); + local col = std.mod(index, panelsPerRow); + panel { gridPos+: { x: panel.gridPos.w * col } }; + + + local panelsBeforeRowsWithX = std.mapWithIndex(CalculateXforPanel, panelsBeforeRows); + + local rowPanelsWithX = + std.map( + function(row) + row { panels: std.mapWithIndex(CalculateXforPanel, row.panels) }, + rowPanels + ); + + local uncollapsed = panelUtil.resolveCollapsedFlagOnRows(panelsBeforeRowsWithX + rowPanelsWithX); + + local normalized = panelUtil.normalizeY(uncollapsed); + + std.map(function(p) p { gridPos+: { y+: startY } }, normalized), +} diff --git a/elasticsearch-mixin/dashboards/variables.libsonnet b/elasticsearch-mixin/dashboards/variables.libsonnet new file mode 100644 index 00000000..53233a23 --- /dev/null +++ b/elasticsearch-mixin/dashboards/variables.libsonnet @@ -0,0 +1,15 @@ +local g = import './g.libsonnet'; +local var = g.dashboard.variable; + +{ + datasource: + var.datasource.new('datasource', 'prometheus'), + + cluster: + var.query.new('cluster') + + var.query.withDatasourceFromVariable(self.datasource) + + var.query.queryTypes.withLabelValues( + 'cluster', + 'elasticsearch_cluster_health_status', + ), +} diff --git a/elasticsearch-mixin/jsonnetfile.json b/elasticsearch-mixin/jsonnetfile.json new file mode 100644 index 00000000..2414c867 --- /dev/null +++ b/elasticsearch-mixin/jsonnetfile.json @@ -0,0 +1,15 @@ +{ + "version": 1, + "dependencies": [ + { + "source": { + "git": { + "remote": "https://github.com/grafana/grafonnet.git", + "subdir": "gen/grafonnet-latest" + } + }, + "version": "main" + } + ], + "legacyImports": true +} diff --git a/elasticsearch-mixin/jsonnetfile.lock.json b/elasticsearch-mixin/jsonnetfile.lock.json new file mode 100644 index 00000000..31b59c22 --- /dev/null +++ b/elasticsearch-mixin/jsonnetfile.lock.json @@ -0,0 +1,46 @@ +{ + "version": 1, + "dependencies": [ + { + "source": { + "git": { + "remote": "https://github.com/grafana/grafonnet.git", + "subdir": "gen/grafonnet-latest" + } + }, + "version": "1c56af39815c4903e47c27194444456f005f65df", + "sum": "GxEO83uxgsDclLp/fmlUJZDbSGpeUZY6Ap3G2cgdL1g=" + }, + { + "source": { + "git": { + "remote": "https://github.com/grafana/grafonnet.git", + "subdir": "gen/grafonnet-v10.4.0" + } + }, + "version": "1c56af39815c4903e47c27194444456f005f65df", + "sum": "DKj+Sn+rlI48g/aoJpzkfPge46ya0jLk5kcZoiZ2X/I=" + }, + { + "source": { + "git": { + "remote": "https://github.com/jsonnet-libs/docsonnet.git", + "subdir": "doc-util" + } + }, + "version": "6ac6c69685b8c29c54515448eaca583da2d88150", + "sum": "BrAL/k23jq+xy9oA7TWIhUx07dsA/QLm3g7ktCwe//U=" + }, + { + "source": { + "git": { + "remote": "https://github.com/jsonnet-libs/xtd.git", + "subdir": "" + } + }, + "version": "63d430b69a95741061c2f7fc9d84b1a778511d9c", + "sum": "qiZi3axUSXCVzKUF83zSAxklwrnitMmrDK4XAfjPMdE=" + } + ], + "legacyImports": false +} diff --git a/elasticsearch-mixin/mixin.libsonnet b/elasticsearch-mixin/mixin.libsonnet new file mode 100644 index 00000000..7083cb16 --- /dev/null +++ b/elasticsearch-mixin/mixin.libsonnet @@ -0,0 +1,3 @@ +// (import 'alerts/alerts.libsonnet') + +(import 'dashboards/dashboards.libsonnet') + +(import 'config.libsonnet') diff --git a/examples/grafana/dashboard.json b/examples/grafana/dashboard.json deleted file mode 100644 index 00c6f152..00000000 --- a/examples/grafana/dashboard.json +++ /dev/null @@ -1,2250 +0,0 @@ -{ - "__inputs": [], - "__requires": [ - { - "type": "grafana", - "id": "grafana", - "name": "Grafana", - "version": "5.4.0" - }, - { - "type": "panel", - "id": "graph", - "name": "Graph", - "version": "5.0.0" - }, - { - "type": "datasource", - "id": "prometheus", - "name": "Prometheus", - "version": "5.0.0" - }, - { - "type": "panel", - "id": "singlestat", - "name": "Singlestat", - "version": "5.0.0" - } - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 1, - "id": null, - "iteration": 1549021227642, - "links": [], - "panels": [ - { - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 90, - "title": "Cluster", - "type": "row" - }, - { - "cacheTimeout": null, - "colorBackground": true, - "colorPostfix": false, - "colorPrefix": false, - "colorValue": false, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 12, - "x": 0, - "y": 1 - }, - "id": 92, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": false - }, - "tableColumn": "Value", - "targets": [ - { - "expr": "scalar(elasticsearch_cluster_health_status{color=\"green\",cluster=~\"$cluster\"}) + scalar(elasticsearch_cluster_health_status{color=\"yellow\",cluster=~\"$cluster\"}) * 2 + scalar(elasticsearch_cluster_health_status{color=\"red\",cluster=~\"$cluster\"}) * 3", - "format": "time_series", - "instant": false, - "intervalFactor": 1, - "legendFormat": "", - "refId": "A" - } - ], - "thresholds": "2,3", - "title": "Cluster Status", - "type": "singlestat", - "valueFontSize": "120%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - }, - { - "op": "=", - "text": "green", - "value": "1" - }, - { - "op": "=", - "text": "yellow", - "value": "2" - }, - { - "op": "=", - "text": "red", - "value": "3" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(245, 54, 54, 0.9)", - "rgba(237, 129, 40, 0.89)", - "rgba(50, 172, 45, 0.97)" - ], - "datasource": "$server", - "editable": true, - "error": false, - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 12, - "y": 1 - }, - "id": 8, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "sum(elasticsearch_cluster_health_number_of_nodes{cluster=~\"$cluster\"})/count(elasticsearch_cluster_health_number_of_nodes{cluster=~\"$cluster\"})", - "format": "time_series", - "interval": "", - "intervalFactor": 2, - "legendFormat": "", - "metric": "elasticsearch_cluster_health_number_of_nodes", - "refId": "A", - "step": 1800 - } - ], - "thresholds": "", - "timeFrom": null, - "timeShift": null, - "title": "Running Nodes", - "type": "singlestat", - "valueFontSize": "120%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 16, - "y": 1 - }, - "id": 94, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "elasticsearch_cluster_health_number_of_data_nodes{cluster=~\"$cluster\"}", - "format": "time_series", - "intervalFactor": 1, - "refId": "A" - } - ], - "thresholds": "", - "title": "Active Data Nodes", - "type": "singlestat", - "valueFontSize": "120%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": true, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 20, - "y": 1 - }, - "id": 96, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "elasticsearch_cluster_health_number_of_pending_tasks{cluster=~\"$cluster\"}", - "format": "time_series", - "intervalFactor": 1, - "refId": "A" - } - ], - "thresholds": "0.5,1", - "title": "Pending Tasks", - "type": "singlestat", - "valueFontSize": "120%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 4 - }, - "id": 76, - "panels": [], - "title": "Shards", - "type": "row" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 0, - "y": 5 - }, - "id": 78, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "elasticsearch_cluster_health_active_shards{cluster=~\"$cluster\"}", - "format": "time_series", - "intervalFactor": 1, - "refId": "A" - } - ], - "thresholds": "", - "title": "Active Shards", - "transparent": false, - "type": "singlestat", - "valueFontSize": "120%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 4, - "y": 5 - }, - "id": 80, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "elasticsearch_cluster_health_active_primary_shards{cluster=~\"$cluster\"}", - "format": "time_series", - "intervalFactor": 1, - "refId": "A" - } - ], - "thresholds": "", - "title": "Active Primary Shards", - "type": "singlestat", - "valueFontSize": "120%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": true, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 8, - "y": 5 - }, - "id": 82, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "elasticsearch_cluster_health_initializing_shards{cluster=~\"$cluster\"}", - "format": "time_series", - "intervalFactor": 1, - "refId": "A" - } - ], - "thresholds": "0.5,1", - "title": "Initializing Shards", - "type": "singlestat", - "valueFontSize": "120%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": true, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 12, - "y": 5 - }, - "id": 84, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "elasticsearch_cluster_health_relocating_shards{cluster=~\"$cluster\"}", - "format": "time_series", - "intervalFactor": 1, - "refId": "A" - } - ], - "thresholds": "0.5,1", - "title": "Relocating Shards", - "type": "singlestat", - "valueFontSize": "120%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": true, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 16, - "y": 5 - }, - "id": 86, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "elasticsearch_cluster_health_unassigned_shards{cluster=~\"$cluster\"}", - "format": "time_series", - "intervalFactor": 1, - "refId": "A" - } - ], - "thresholds": "0.5,1", - "title": "Unassigned Shards", - "type": "singlestat", - "valueFontSize": "120%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": true, - "colors": [ - "#299c46", - "rgba(237, 129, 40, 0.89)", - "#d44a3a" - ], - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 20, - "y": 5 - }, - "id": 88, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "elasticsearch_cluster_health_delayed_unassigned_shards{cluster=~\"$cluster\"}", - "format": "time_series", - "intervalFactor": 1, - "refId": "A" - } - ], - "thresholds": "0.5,1", - "title": "Delayed Unassigned Shards", - "type": "singlestat", - "valueFontSize": "120%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 8 - }, - "id": 70, - "panels": [], - "title": "Documents", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$server", - "editable": true, - "error": false, - "fill": 1, - "grid": {}, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 9 - }, - "id": 3, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "max": true, - "min": true, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(elasticsearch_indices_docs{cluster=~\"$cluster\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Documents", - "refId": "A", - "step": 240 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Documents indexed", - "tooltip": { - "msResolution": true, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$server", - "editable": true, - "error": false, - "fill": 1, - "grid": {}, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 9 - }, - "id": 4, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "max": true, - "min": true, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(elasticsearch_indices_store_size_bytes{cluster=~\"$cluster\"})", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Index Size", - "refId": "A", - "step": 240 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Index Size", - "tooltip": { - "msResolution": true, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "bytes", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "fill": 1, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 18 - }, - "id": 72, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "max": true, - "min": true, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(elasticsearch_indices_indexing_index_total{cluster=~\"$cluster\"}[1h])", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{name}}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Documents Indexed Rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": "Documents/s", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "fill": 1, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 18 - }, - "id": 74, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "max": true, - "min": true, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(elasticsearch_indices_search_fetch_total{cluster=~\"$cluster\"}[1h])", - "format": "time_series", - "intervalFactor": 1, - "legendFormat": "{{name}}", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Query Rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": "Queris/s", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$server", - "editable": true, - "error": false, - "fill": 1, - "grid": {}, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 27 - }, - "height": "", - "id": 64, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(elasticsearch_thread_pool_queue_count{cluster=~\"$cluster\", type!=\"management\"}) by (type)", - "interval": "", - "intervalFactor": 2, - "legendFormat": "Type: {{type}}", - "refId": "A", - "step": 240 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Queue Count", - "tooltip": { - "msResolution": true, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 35 - }, - "id": 68, - "panels": [], - "title": "System", - "type": "row" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(245, 54, 54, 0.9)", - "rgba(237, 129, 40, 0.89)", - "rgba(50, 172, 45, 0.97)" - ], - "datasource": "$server", - "editable": true, - "error": false, - "format": "bytes", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 8, - "x": 0, - "y": 36 - }, - "height": "", - "id": 12, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "sum(node_memory_MemTotal{cluster=~\"$cluster\"})", - "intervalFactor": 2, - "legendFormat": "", - "metric": "", - "refId": "A", - "step": 1800 - } - ], - "thresholds": "", - "title": "Total Memory", - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(245, 54, 54, 0.9)", - "rgba(237, 129, 40, 0.89)", - "rgba(50, 172, 45, 0.97)" - ], - "datasource": "$server", - "editable": true, - "error": false, - "format": "bytes", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 8, - "x": 8, - "y": 36 - }, - "height": "", - "id": 13, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "sum(node_memory_MemFree{cluster=~\"$cluster\"})", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 1800 - } - ], - "thresholds": "", - "title": "Total Memory Free", - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(245, 54, 54, 0.9)", - "rgba(237, 129, 40, 0.89)", - "rgba(50, 172, 45, 0.97)" - ], - "datasource": "$server", - "editable": true, - "error": false, - "format": "bytes", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 8, - "x": 16, - "y": 36 - }, - "height": "", - "id": 14, - "interval": null, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": false, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "expr": "sum(node_memory_MemAvailable{cluster=~\"$cluster\"})", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A", - "step": 1800 - } - ], - "thresholds": "", - "title": "Total Memory Available", - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "current" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$server", - "editable": true, - "error": false, - "fill": 1, - "grid": {}, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 39 - }, - "id": 1, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(elasticsearch_thread_pool_active_count{cluster=~\"$cluster\", type!=\"management\"}) by (type)", - "format": "time_series", - "interval": "", - "intervalFactor": 2, - "legendFormat": "Type: {{ type }}", - "refId": "A", - "step": 240 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Thread Pools", - "tooltip": { - "msResolution": true, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$server", - "editable": true, - "error": false, - "fill": 1, - "grid": {}, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 39 - }, - "id": 66, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "rate(elasticsearch_thread_pool_rejected_count{cluster=~\"$cluster\", type!=\"management\"}[5m])", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{ name }} {{ type }}", - "refId": "A", - "step": 240 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Thread pool rejections", - "tooltip": { - "msResolution": true, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$server", - "fill": 1, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 47 - }, - "id": 57, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "bucketAggs": [ - { - "id": "2", - "settings": { - "interval": "auto" - }, - "type": "date_histogram" - } - ], - "dsType": "elasticsearch", - "expr": "avg(irate(node_cpu{cluster=~\"$cluster\"}[10s])) by(mode) *100", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{ mode }}", - "metric": "elasticsearch_breakers_tripped", - "metrics": [ - { - "id": "1", - "type": "count" - } - ], - "refId": "A", - "step": 240, - "timeField": "failure_tstamp" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Avg. CPU Usage", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": "", - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$server", - "editable": true, - "error": false, - "fill": 1, - "grid": {}, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 47 - }, - "id": 28, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "max": true, - "min": true, - "rightSide": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "avg_over_time(elasticsearch_jvm_memory_used_bytes{area=\"heap\",cluster=~\"$cluster\"}[15m]) / elasticsearch_jvm_memory_max_bytes{area=\"heap\",cluster=~\"$cluster\"}", - "format": "time_series", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{ name }}", - "refId": "A", - "step": 240 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Avg Heap in 15min", - "tooltip": { - "msResolution": true, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "label": "", - "logBase": 1, - "max": 1, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": false - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$server", - "editable": true, - "error": false, - "fill": 1, - "grid": {}, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 56 - }, - "id": 5, - "legend": { - "alignAsTable": true, - "avg": true, - "current": true, - "max": true, - "min": true, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum(rate(elasticsearch_transport_rx_packets_total{cluster=~\"$cluster\"}[5m]))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "RX", - "refId": "A", - "step": 240 - }, - { - "expr": "sum(rate(elasticsearch_transport_tx_packets_total{cluster=~\"$cluster\"}[5m])) * -1", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "TX", - "refId": "B", - "step": 240 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "RX/TX Rate 5m", - "tooltip": { - "msResolution": true, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$server", - "editable": true, - "error": false, - "fill": 1, - "grid": {}, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 56 - }, - "id": 65, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "irate(elasticsearch_jvm_gc_collection_seconds_sum{cluster=~\"$cluster\"}[1m])", - "interval": "", - "intervalFactor": 2, - "legendFormat": "{{ name }} {{ gc }}", - "refId": "A", - "step": 240 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "GC seconds", - "tooltip": { - "msResolution": true, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - } - ], - "refresh": "1m", - "schemaVersion": 16, - "style": "dark", - "tags": [ - "infra", - "b2c", - "elastic" - ], - "templating": { - "list": [ - { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, - "label": "Server", - "name": "server", - "options": [], - "query": "prometheus", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "type": "datasource" - }, - { - "allValue": null, - "current": {}, - "datasource": "$server", - "definition": "", - "hide": 0, - "includeAll": true, - "label": null, - "multi": true, - "name": "cluster", - "options": [], - "query": "label_values(elasticsearch_cluster_health_status,cluster)", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-12h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ] - }, - "timezone": "utc", - "title": "ElasticSearch Example", - "uid": "n_nxrE_mk", - "version": 1 -} diff --git a/examples/kubernetes/deployment.yml b/examples/kubernetes/deployment.yml index abf5ada6..19ca7fed 100644 --- a/examples/kubernetes/deployment.yml +++ b/examples/kubernetes/deployment.yml @@ -1,7 +1,8 @@ +--- apiVersion: apps/v1 kind: Deployment metadata: - name: p8s-elastic-exporter + name: elastic-exporter spec: replicas: 1 strategy: @@ -11,60 +12,62 @@ spec: type: RollingUpdate selector: matchLabels: - app: p8s-elastic-exporter + app: elastic-exporter template: metadata: labels: - app: p8s-elastic-exporter + app: elastic-exporter spec: - securityContext: - runAsNonRoot: true - runAsUser: 1000 containers: - - command: - - /bin/elasticsearch_exporter - - -es.uri=http://elasticsearch:9200 - - -es.all=true - - -web.listen-address=:9114 - image: justwatch/elasticsearch_exporter:1.0.2 - securityContext: - capabilities: - drop: - - SETPCAP - - MKNOD - - AUDIT_WRITE - - CHOWN - - NET_RAW - - DAC_OVERRIDE - - FOWNER - - FSETID - - KILL - - SETGID - - SETUID - - NET_BIND_SERVICE - - SYS_CHROOT - - SETFCAP - readOnlyRootFilesystem: true - livenessProbe: - httpGet: - path: /health - port: 9114 - initialDelaySeconds: 30 - timeoutSeconds: 10 - name: p8s-elastic-exporter - ports: - - containerPort: 9114 - readinessProbe: - httpGet: - path: /health - port: 9114 - initialDelaySeconds: 10 - timeoutSeconds: 10 - resources: - limits: - cpu: 100m - memory: 128Mi - requests: - cpu: 25m - memory: 64Mi + - command: + - /bin/elasticsearch_exporter + - --es.uri=http://elasticsearch:9200 + - --es.all + image: quay.io/prometheuscommunity/elasticsearch-exporter:latest + securityContext: + capabilities: + drop: + - SETPCAP + - MKNOD + - AUDIT_WRITE + - CHOWN + - NET_RAW + - DAC_OVERRIDE + - FOWNER + - FSETID + - KILL + - SETGID + - SETUID + - NET_BIND_SERVICE + - SYS_CHROOT + - SETFCAP + readOnlyRootFilesystem: true + livenessProbe: + httpGet: + path: /healthz + port: 9114 + initialDelaySeconds: 30 + timeoutSeconds: 10 + name: elastic-exporter + ports: + - containerPort: 9114 + name: http + readinessProbe: + httpGet: + path: /healthz + port: 9114 + initialDelaySeconds: 10 + timeoutSeconds: 10 + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 25m + memory: 64Mi restartPolicy: Always + securityContext: + runAsNonRoot: true + runAsGroup: 10000 + runAsUser: 10000 + fsGroup: 10000 diff --git a/examples/prometheus/elasticsearch.rules b/examples/prometheus/elasticsearch.rules index a7922357..05109067 100644 --- a/examples/prometheus/elasticsearch.rules +++ b/examples/prometheus/elasticsearch.rules @@ -7,11 +7,11 @@ ALERT ElasticsearchTooFewNodesRunning IF elasticsearch_cluster_health_number_of_nodes < 3 FOR 5m LABELS {severity="critical"} - ANNOTATIONS {description="There are only {{$value}} < 3 ElasticSearch nodes running", summary="ElasticSearch running on less than 3 nodes"} + ANNOTATIONS {description="There are only {{$value}} < 3 Elasticsearch nodes running", summary="Elasticsearch running on less than 3 nodes"} # alert if heap usage is over 90% ALERT ElasticsearchHeapTooHigh IF elasticsearch_jvm_memory_used_bytes{area="heap"} / elasticsearch_jvm_memory_max_bytes{area="heap"} > 0.9 FOR 15m LABELS {severity="critical"} - ANNOTATIONS {description="The heap usage is over 90% for 15m", summary="ElasticSearch node {{$labels.node}} heap usage is high"} + ANNOTATIONS {description="The heap usage is over 90% for 15m", summary="Elasticsearch node {{$labels.node}} heap usage is high"} diff --git a/examples/prometheus/elasticsearch.rules.yml b/examples/prometheus/elasticsearch.rules.yml index fd650c85..d29f0b75 100644 --- a/examples/prometheus/elasticsearch.rules.yml +++ b/examples/prometheus/elasticsearch.rules.yml @@ -1,25 +1,25 @@ groups: -- name: elasticsearch - rules: - - record: elasticsearch_filesystem_data_used_percent - expr: 100 * (elasticsearch_filesystem_data_size_bytes - elasticsearch_filesystem_data_free_bytes) - / elasticsearch_filesystem_data_size_bytes - - record: elasticsearch_filesystem_data_free_percent - expr: 100 - elasticsearch_filesystem_data_used_percent - - alert: ElasticsearchTooFewNodesRunning - expr: elasticsearch_cluster_health_number_of_nodes < 3 - for: 5m - labels: - severity: critical - annotations: - description: There are only {{$value}} < 3 ElasticSearch nodes running - summary: ElasticSearch running on less than 3 nodes - - alert: ElasticsearchHeapTooHigh - expr: elasticsearch_jvm_memory_used_bytes{area="heap"} / elasticsearch_jvm_memory_max_bytes{area="heap"} - > 0.9 - for: 15m - labels: - severity: critical - annotations: - description: The heap usage is over 90% for 15m - summary: ElasticSearch node {{$labels.node}} heap usage is high + - name: elasticsearch + rules: + - record: elasticsearch_filesystem_data_used_percent + expr: 100 * (elasticsearch_filesystem_data_size_bytes - elasticsearch_filesystem_data_free_bytes) + / elasticsearch_filesystem_data_size_bytes + - record: elasticsearch_filesystem_data_free_percent + expr: 100 - elasticsearch_filesystem_data_used_percent + - alert: ElasticsearchTooFewNodesRunning + expr: elasticsearch_cluster_health_number_of_nodes < 3 + for: 5m + labels: + severity: critical + annotations: + description: There are only {{$value}} < 3 Elasticsearch nodes running + summary: Elasticsearch running on less than 3 nodes + - alert: ElasticsearchHeapTooHigh + expr: elasticsearch_jvm_memory_used_bytes{area="heap"} / elasticsearch_jvm_memory_max_bytes{area="heap"} + > 0.9 + for: 15m + labels: + severity: critical + annotations: + description: The heap usage is over 90% for 15m + summary: Elasticsearch node {{$labels.node}} heap usage is high diff --git a/fixtures/clusterhealth/1.7.6.json b/fixtures/clusterhealth/1.7.6.json new file mode 100644 index 00000000..39d3a368 --- /dev/null +++ b/fixtures/clusterhealth/1.7.6.json @@ -0,0 +1,15 @@ +{ + "cluster_name": "elasticsearch", + "status": "yellow", + "timed_out": false, + "number_of_nodes": 1, + "number_of_data_nodes": 1, + "active_primary_shards": 5, + "active_shards": 5, + "relocating_shards": 0, + "initializing_shards": 0, + "unassigned_shards": 5, + "delayed_unassigned_shards": 0, + "number_of_pending_tasks": 0, + "number_of_in_flight_fetch": 0 +} diff --git a/fixtures/clusterhealth/2.4.5.json b/fixtures/clusterhealth/2.4.5.json new file mode 100644 index 00000000..170f8616 --- /dev/null +++ b/fixtures/clusterhealth/2.4.5.json @@ -0,0 +1,17 @@ +{ + "cluster_name": "elasticsearch", + "status": "yellow", + "timed_out": false, + "number_of_nodes": 1, + "number_of_data_nodes": 1, + "active_primary_shards": 5, + "active_shards": 5, + "relocating_shards": 0, + "initializing_shards": 0, + "unassigned_shards": 5, + "delayed_unassigned_shards": 0, + "number_of_pending_tasks": 0, + "number_of_in_flight_fetch": 0, + "task_max_waiting_in_queue_millis": 12, + "active_shards_percent_as_number": 50.0 +} diff --git a/fixtures/clusterhealth/5.4.2.json b/fixtures/clusterhealth/5.4.2.json new file mode 100644 index 00000000..170f8616 --- /dev/null +++ b/fixtures/clusterhealth/5.4.2.json @@ -0,0 +1,17 @@ +{ + "cluster_name": "elasticsearch", + "status": "yellow", + "timed_out": false, + "number_of_nodes": 1, + "number_of_data_nodes": 1, + "active_primary_shards": 5, + "active_shards": 5, + "relocating_shards": 0, + "initializing_shards": 0, + "unassigned_shards": 5, + "delayed_unassigned_shards": 0, + "number_of_pending_tasks": 0, + "number_of_in_flight_fetch": 0, + "task_max_waiting_in_queue_millis": 12, + "active_shards_percent_as_number": 50.0 +} diff --git a/fixtures/clusterinfo/2.4.5.json b/fixtures/clusterinfo/2.4.5.json new file mode 100644 index 00000000..8f6599a8 --- /dev/null +++ b/fixtures/clusterinfo/2.4.5.json @@ -0,0 +1,13 @@ +{ + "name" : "Mys-Tech", + "cluster_name" : "elasticsearch", + "cluster_uuid" : "3qps7bcWTqyzV49ApmPVfw", + "version" : { + "number" : "2.4.5", + "build_hash" : "c849dd13904f53e63e88efc33b2ceeda0b6a1276", + "build_timestamp" : "2017-04-24T16:18:17Z", + "build_snapshot" : false, + "lucene_version" : "5.5.4" + }, + "tagline" : "You Know, for Search" +} diff --git a/fixtures/clusterinfo/5.4.2.json b/fixtures/clusterinfo/5.4.2.json new file mode 100644 index 00000000..11be93e2 --- /dev/null +++ b/fixtures/clusterinfo/5.4.2.json @@ -0,0 +1,13 @@ +{ + "name" : "gOHPUga", + "cluster_name" : "elasticsearch", + "cluster_uuid" : "kbqi7yhQT-WlPdGL2m0xJg", + "version" : { + "number" : "5.4.2", + "build_hash" : "929b078", + "build_date" : "2017-06-15T02:29:28.122Z", + "build_snapshot" : false, + "lucene_version" : "6.5.1" + }, + "tagline" : "You Know, for Search" +} diff --git a/fixtures/clusterinfo/7.13.1.json b/fixtures/clusterinfo/7.13.1.json new file mode 100644 index 00000000..3b6e412c --- /dev/null +++ b/fixtures/clusterinfo/7.13.1.json @@ -0,0 +1,17 @@ +{ + "name" : "e0630cfd8e1e", + "cluster_name" : "docker-cluster", + "cluster_uuid" : "aCMrCY1VQpqJ6U4Sw_xdiw", + "version" : { + "number" : "7.13.1", + "build_flavor" : "default", + "build_type" : "docker", + "build_hash" : "9a7758028e4ea59bcab41c12004603c5a7dd84a9", + "build_date" : "2021-05-28T17:40:59.346932922Z", + "build_snapshot" : false, + "lucene_version" : "8.8.2", + "minimum_wire_compatibility_version" : "6.8.0", + "minimum_index_compatibility_version" : "6.0.0-beta1" + }, + "tagline" : "You Know, for Search" +} diff --git a/fixtures/datastream/7.15.0.json b/fixtures/datastream/7.15.0.json new file mode 100644 index 00000000..5287aac6 --- /dev/null +++ b/fixtures/datastream/7.15.0.json @@ -0,0 +1,24 @@ +{ + "_shards": { + "total": 30, + "successful": 30, + "failed": 0 + }, + "data_stream_count": 2, + "backing_indices": 7, + "total_store_size_bytes": 1103028116, + "data_streams": [ + { + "data_stream": "foo", + "backing_indices": 5, + "store_size_bytes": 429205396, + "maximum_timestamp": 1656079894000 + }, + { + "data_stream": "bar", + "backing_indices": 2, + "store_size_bytes": 673822720, + "maximum_timestamp": 1656028796000 + } + ] +} diff --git a/fixtures/ilm_indices/6.6.0.json b/fixtures/ilm_indices/6.6.0.json new file mode 100644 index 00000000..73fb55a2 --- /dev/null +++ b/fixtures/ilm_indices/6.6.0.json @@ -0,0 +1,20 @@ +{ + "indices": { + "twitter": { + "index": "twitter", + "managed": false + }, + "facebook": { + "index": "facebook", + "managed": true, + "policy": "my_policy", + "lifecycle_date_millis": 1660799138565, + "phase": "new", + "phase_time_millis": 1660799138651, + "action": "complete", + "action_time_millis": 1660799138651, + "step": "complete", + "step_time_millis": 1660799138651 + } + } +} diff --git a/fixtures/ilm_status/6.6.0.json b/fixtures/ilm_status/6.6.0.json new file mode 100644 index 00000000..6bf7b691 --- /dev/null +++ b/fixtures/ilm_status/6.6.0.json @@ -0,0 +1,3 @@ +{ + "operation_mode": "RUNNING" +} diff --git a/fixtures/indices/1.7.6.json b/fixtures/indices/1.7.6.json new file mode 100644 index 00000000..b17fea60 --- /dev/null +++ b/fixtures/indices/1.7.6.json @@ -0,0 +1,681 @@ +{ + "_shards": { + "total": 20, + "successful": 10, + "failed": 0 + }, + "_all": { + "primaries": { + "docs": { + "count": 5, + "deleted": 0 + }, + "store": { + "size_in_bytes": 13798, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 5, + "index_time_in_millis": 52, + "index_current": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0 + }, + "refresh": { + "total": 5, + "total_time_in_millis": 163 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 30, + "total_time_in_millis": 42 + }, + "filter_cache": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "id_cache": { + "memory_size_in_bytes": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "percolate": { + "total": 0, + "time_in_millis": 0, + "current": 0, + "memory_size_in_bytes": -1, + "memory_size": "-1b", + "queries": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 5, + "memory_in_bytes": 18410, + "index_writer_memory_in_bytes": 0, + "index_writer_max_memory_in_bytes": 671088640, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0 + }, + "translog": { + "operations": 5, + "size_in_bytes": 102 + }, + "suggest": { + "total": 0, + "time_in_millis": 0, + "current": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 5, + "deleted": 0 + }, + "store": { + "size_in_bytes": 13798, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 5, + "index_time_in_millis": 52, + "index_current": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0 + }, + "refresh": { + "total": 5, + "total_time_in_millis": 163 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 30, + "total_time_in_millis": 42 + }, + "filter_cache": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "id_cache": { + "memory_size_in_bytes": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "percolate": { + "total": 0, + "time_in_millis": 0, + "current": 0, + "memory_size_in_bytes": -1, + "memory_size": "-1b", + "queries": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 5, + "memory_in_bytes": 18410, + "index_writer_memory_in_bytes": 0, + "index_writer_max_memory_in_bytes": 671088640, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0 + }, + "translog": { + "operations": 5, + "size_in_bytes": 102 + }, + "suggest": { + "total": 0, + "time_in_millis": 0, + "current": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + }, + "indices": { + "foo_2": { + "primaries": { + "docs": { + "count": 3, + "deleted": 0 + }, + "store": { + "size_in_bytes": 8207, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 3, + "index_time_in_millis": 6, + "index_current": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0 + }, + "refresh": { + "total": 3, + "total_time_in_millis": 38 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 16, + "total_time_in_millis": 0 + }, + "filter_cache": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "id_cache": { + "memory_size_in_bytes": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "percolate": { + "total": 0, + "time_in_millis": 0, + "current": 0, + "memory_size_in_bytes": -1, + "memory_size": "-1b", + "queries": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 3, + "memory_in_bytes": 11046, + "index_writer_memory_in_bytes": 0, + "index_writer_max_memory_in_bytes": 335544320, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0 + }, + "translog": { + "operations": 3, + "size_in_bytes": 102 + }, + "suggest": { + "total": 0, + "time_in_millis": 0, + "current": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 3, + "deleted": 0 + }, + "store": { + "size_in_bytes": 8207, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 3, + "index_time_in_millis": 6, + "index_current": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0 + }, + "refresh": { + "total": 3, + "total_time_in_millis": 38 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 16, + "total_time_in_millis": 0 + }, + "filter_cache": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "id_cache": { + "memory_size_in_bytes": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "percolate": { + "total": 0, + "time_in_millis": 0, + "current": 0, + "memory_size_in_bytes": -1, + "memory_size": "-1b", + "queries": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 3, + "memory_in_bytes": 11046, + "index_writer_memory_in_bytes": 0, + "index_writer_max_memory_in_bytes": 335544320, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0 + }, + "translog": { + "operations": 3, + "size_in_bytes": 102 + }, + "suggest": { + "total": 0, + "time_in_millis": 0, + "current": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + }, + "foo_1": { + "primaries": { + "docs": { + "count": 2, + "deleted": 0 + }, + "store": { + "size_in_bytes": 5591, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 2, + "index_time_in_millis": 46, + "index_current": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0 + }, + "refresh": { + "total": 2, + "total_time_in_millis": 125 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 14, + "total_time_in_millis": 42 + }, + "filter_cache": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "id_cache": { + "memory_size_in_bytes": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "percolate": { + "total": 0, + "time_in_millis": 0, + "current": 0, + "memory_size_in_bytes": -1, + "memory_size": "-1b", + "queries": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 2, + "memory_in_bytes": 7364, + "index_writer_memory_in_bytes": 0, + "index_writer_max_memory_in_bytes": 335544320, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0 + }, + "translog": { + "operations": 2, + "size_in_bytes": 17 + }, + "suggest": { + "total": 0, + "time_in_millis": 0, + "current": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 2, + "deleted": 0 + }, + "store": { + "size_in_bytes": 5591, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 2, + "index_time_in_millis": 46, + "index_current": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0 + }, + "refresh": { + "total": 2, + "total_time_in_millis": 125 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 14, + "total_time_in_millis": 42 + }, + "filter_cache": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "id_cache": { + "memory_size_in_bytes": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "percolate": { + "total": 0, + "time_in_millis": 0, + "current": 0, + "memory_size_in_bytes": -1, + "memory_size": "-1b", + "queries": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 2, + "memory_in_bytes": 7364, + "index_writer_memory_in_bytes": 0, + "index_writer_max_memory_in_bytes": 335544320, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0 + }, + "translog": { + "operations": 2, + "size_in_bytes": 17 + }, + "suggest": { + "total": 0, + "time_in_millis": 0, + "current": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + } + } +} diff --git a/fixtures/indices/2.4.5.json b/fixtures/indices/2.4.5.json new file mode 100644 index 00000000..ba1bdd92 --- /dev/null +++ b/fixtures/indices/2.4.5.json @@ -0,0 +1,765 @@ +{ + "_shards": { + "total": 20, + "successful": 10, + "failed": 0 + }, + "_all": { + "primaries": { + "docs": { + "count": 5, + "deleted": 0 + }, + "store": { + "size_in_bytes": 3610, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 5, + "index_time_in_millis": 40, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 209715200 + }, + "refresh": { + "total": 5, + "total_time_in_millis": 171 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 30, + "total_time_in_millis": 12 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "percolate": { + "total": 0, + "time_in_millis": 0, + "current": 0, + "memory_size_in_bytes": -1, + "memory_size": "-1b", + "queries": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 5, + "memory_in_bytes": 10530, + "terms_memory_in_bytes": 7550, + "stored_fields_memory_in_bytes": 1560, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 960, + "doc_values_memory_in_bytes": 460, + "index_writer_memory_in_bytes": 0, + "index_writer_max_memory_in_bytes": 103887660, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0 + }, + "translog": { + "operations": 5, + "size_in_bytes": 843 + }, + "suggest": { + "total": 0, + "time_in_millis": 0, + "current": 0 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 5, + "deleted": 0 + }, + "store": { + "size_in_bytes": 3610, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 5, + "index_time_in_millis": 40, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 209715200 + }, + "refresh": { + "total": 5, + "total_time_in_millis": 171 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 30, + "total_time_in_millis": 12 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "percolate": { + "total": 0, + "time_in_millis": 0, + "current": 0, + "memory_size_in_bytes": -1, + "memory_size": "-1b", + "queries": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 5, + "memory_in_bytes": 10530, + "terms_memory_in_bytes": 7550, + "stored_fields_memory_in_bytes": 1560, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 960, + "doc_values_memory_in_bytes": 460, + "index_writer_memory_in_bytes": 0, + "index_writer_max_memory_in_bytes": 103887660, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0 + }, + "translog": { + "operations": 5, + "size_in_bytes": 843 + }, + "suggest": { + "total": 0, + "time_in_millis": 0, + "current": 0 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + }, + "indices": { + "foo_2": { + "primaries": { + "docs": { + "count": 3, + "deleted": 0 + }, + "store": { + "size_in_bytes": 3350, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 3, + "index_time_in_millis": 6, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 104857600 + }, + "refresh": { + "total": 3, + "total_time_in_millis": 34 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 16, + "total_time_in_millis": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "percolate": { + "total": 0, + "time_in_millis": 0, + "current": 0, + "memory_size_in_bytes": -1, + "memory_size": "-1b", + "queries": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 3, + "memory_in_bytes": 6318, + "terms_memory_in_bytes": 4530, + "stored_fields_memory_in_bytes": 936, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 576, + "doc_values_memory_in_bytes": 276, + "index_writer_memory_in_bytes": 0, + "index_writer_max_memory_in_bytes": 51943830, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0 + }, + "translog": { + "operations": 3, + "size_in_bytes": 470 + }, + "suggest": { + "total": 0, + "time_in_millis": 0, + "current": 0 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 3, + "deleted": 0 + }, + "store": { + "size_in_bytes": 3350, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 3, + "index_time_in_millis": 6, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 104857600 + }, + "refresh": { + "total": 3, + "total_time_in_millis": 34 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 16, + "total_time_in_millis": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "percolate": { + "total": 0, + "time_in_millis": 0, + "current": 0, + "memory_size_in_bytes": -1, + "memory_size": "-1b", + "queries": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 3, + "memory_in_bytes": 6318, + "terms_memory_in_bytes": 4530, + "stored_fields_memory_in_bytes": 936, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 576, + "doc_values_memory_in_bytes": 276, + "index_writer_memory_in_bytes": 0, + "index_writer_max_memory_in_bytes": 51943830, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0 + }, + "translog": { + "operations": 3, + "size_in_bytes": 470 + }, + "suggest": { + "total": 0, + "time_in_millis": 0, + "current": 0 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + }, + "foo_1": { + "primaries": { + "docs": { + "count": 2, + "deleted": 0 + }, + "store": { + "size_in_bytes": 260, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 2, + "index_time_in_millis": 34, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 104857600 + }, + "refresh": { + "total": 2, + "total_time_in_millis": 137 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 14, + "total_time_in_millis": 12 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "percolate": { + "total": 0, + "time_in_millis": 0, + "current": 0, + "memory_size_in_bytes": -1, + "memory_size": "-1b", + "queries": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 2, + "memory_in_bytes": 4212, + "terms_memory_in_bytes": 3020, + "stored_fields_memory_in_bytes": 624, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 384, + "doc_values_memory_in_bytes": 184, + "index_writer_memory_in_bytes": 0, + "index_writer_max_memory_in_bytes": 51943830, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0 + }, + "translog": { + "operations": 2, + "size_in_bytes": 373 + }, + "suggest": { + "total": 0, + "time_in_millis": 0, + "current": 0 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 2, + "deleted": 0 + }, + "store": { + "size_in_bytes": 260, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 2, + "index_time_in_millis": 34, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 104857600 + }, + "refresh": { + "total": 2, + "total_time_in_millis": 137 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 14, + "total_time_in_millis": 12 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "percolate": { + "total": 0, + "time_in_millis": 0, + "current": 0, + "memory_size_in_bytes": -1, + "memory_size": "-1b", + "queries": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 2, + "memory_in_bytes": 4212, + "terms_memory_in_bytes": 3020, + "stored_fields_memory_in_bytes": 624, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 384, + "doc_values_memory_in_bytes": 184, + "index_writer_memory_in_bytes": 0, + "index_writer_max_memory_in_bytes": 51943830, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0 + }, + "translog": { + "operations": 2, + "size_in_bytes": 373 + }, + "suggest": { + "total": 0, + "time_in_millis": 0, + "current": 0 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + } + } +} diff --git a/fixtures/indices/5.4.2.json b/fixtures/indices/5.4.2.json new file mode 100644 index 00000000..06effc4e --- /dev/null +++ b/fixtures/indices/5.4.2.json @@ -0,0 +1,1437 @@ +{ + "_shards": { + "total": 26, + "successful": 13, + "failed": 0 + }, + "_all": { + "primaries": { + "docs": { + "count": 76, + "deleted": 0 + }, + "store": { + "size_in_bytes": 128534, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 78, + "index_time_in_millis": 1598, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 272629760 + }, + "refresh": { + "total": 15, + "total_time_in_millis": 1361, + "listeners": 0 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 26, + "total_time_in_millis": 124 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 13, + "memory_in_bytes": 56523, + "terms_memory_in_bytes": 44419, + "stored_fields_memory_in_bytes": 4056, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 2880, + "points_memory_in_bytes": 652, + "doc_values_memory_in_bytes": 4516, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 78, + "size_in_bytes": 56679 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 76, + "deleted": 0 + }, + "store": { + "size_in_bytes": 128534, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 78, + "index_time_in_millis": 1598, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 272629760 + }, + "refresh": { + "total": 15, + "total_time_in_millis": 1361, + "listeners": 0 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 26, + "total_time_in_millis": 124 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 13, + "memory_in_bytes": 56523, + "terms_memory_in_bytes": 44419, + "stored_fields_memory_in_bytes": 4056, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 2880, + "points_memory_in_bytes": 652, + "doc_values_memory_in_bytes": 4516, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 78, + "size_in_bytes": 56679 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + }, + "indices": { + ".monitoring-es-2-2017.08.23": { + "primaries": { + "docs": { + "count": 65, + "deleted": 0 + }, + "store": { + "size_in_bytes": 68917, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 65, + "index_time_in_millis": 106, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 20971520 + }, + "refresh": { + "total": 3, + "total_time_in_millis": 390, + "listeners": 0 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 4, + "total_time_in_millis": 15 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 3, + "memory_in_bytes": 23830, + "terms_memory_in_bytes": 18474, + "stored_fields_memory_in_bytes": 936, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 320, + "points_memory_in_bytes": 648, + "doc_values_memory_in_bytes": 3452, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 65, + "size_in_bytes": 37990 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 65, + "deleted": 0 + }, + "store": { + "size_in_bytes": 68917, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 65, + "index_time_in_millis": 106, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 20971520 + }, + "refresh": { + "total": 3, + "total_time_in_millis": 390, + "listeners": 0 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 4, + "total_time_in_millis": 15 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 3, + "memory_in_bytes": 23830, + "terms_memory_in_bytes": 18474, + "stored_fields_memory_in_bytes": 936, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 320, + "points_memory_in_bytes": 648, + "doc_values_memory_in_bytes": 3452, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 65, + "size_in_bytes": 37990 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + }, + ".monitoring-data-2": { + "primaries": { + "docs": { + "count": 2, + "deleted": 0 + }, + "store": { + "size_in_bytes": 4226, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 4, + "index_time_in_millis": 13, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 20971520 + }, + "refresh": { + "total": 2, + "total_time_in_millis": 74, + "listeners": 0 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 3, + "total_time_in_millis": 2 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 1, + "memory_in_bytes": 1335, + "terms_memory_in_bytes": 787, + "stored_fields_memory_in_bytes": 312, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 0, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 236, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 4, + "size_in_bytes": 6738 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 2, + "deleted": 0 + }, + "store": { + "size_in_bytes": 4226, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 4, + "index_time_in_millis": 13, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 20971520 + }, + "refresh": { + "total": 2, + "total_time_in_millis": 74, + "listeners": 0 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 3, + "total_time_in_millis": 2 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 1, + "memory_in_bytes": 1335, + "terms_memory_in_bytes": 787, + "stored_fields_memory_in_bytes": 312, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 0, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 236, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 4, + "size_in_bytes": 6738 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + }, + "foo_2": { + "primaries": { + "docs": { + "count": 3, + "deleted": 0 + }, + "store": { + "size_in_bytes": 11909, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 3, + "index_time_in_millis": 12, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 104857600 + }, + "refresh": { + "total": 3, + "total_time_in_millis": 42, + "listeners": 0 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 8, + "total_time_in_millis": 4 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 3, + "memory_in_bytes": 7764, + "terms_memory_in_bytes": 5976, + "stored_fields_memory_in_bytes": 936, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 576, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 276, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 3, + "size_in_bytes": 494 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 3, + "deleted": 0 + }, + "store": { + "size_in_bytes": 11909, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 3, + "index_time_in_millis": 12, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 104857600 + }, + "refresh": { + "total": 3, + "total_time_in_millis": 42, + "listeners": 0 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 8, + "total_time_in_millis": 4 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 3, + "memory_in_bytes": 7764, + "terms_memory_in_bytes": 5976, + "stored_fields_memory_in_bytes": 936, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 576, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 276, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 3, + "size_in_bytes": 494 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + }, + "foo_1": { + "primaries": { + "docs": { + "count": 2, + "deleted": 0 + }, + "store": { + "size_in_bytes": 8038, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 2, + "index_time_in_millis": 46, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 104857600 + }, + "refresh": { + "total": 2, + "total_time_in_millis": 84, + "listeners": 0 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 7, + "total_time_in_millis": 94 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 2, + "memory_in_bytes": 5176, + "terms_memory_in_bytes": 3984, + "stored_fields_memory_in_bytes": 624, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 384, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 184, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 2, + "size_in_bytes": 389 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 2, + "deleted": 0 + }, + "store": { + "size_in_bytes": 8038, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 2, + "index_time_in_millis": 46, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 104857600 + }, + "refresh": { + "total": 2, + "total_time_in_millis": 84, + "listeners": 0 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 7, + "total_time_in_millis": 94 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 2, + "memory_in_bytes": 5176, + "terms_memory_in_bytes": 3984, + "stored_fields_memory_in_bytes": 624, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 384, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 184, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 2, + "size_in_bytes": 389 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + }, + ".watches": { + "primaries": { + "docs": { + "count": 4, + "deleted": 0 + }, + "store": { + "size_in_bytes": 35444, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 4, + "index_time_in_millis": 1421, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 20971520 + }, + "refresh": { + "total": 5, + "total_time_in_millis": 771, + "listeners": 0 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 4, + "total_time_in_millis": 9 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 4, + "memory_in_bytes": 18418, + "terms_memory_in_bytes": 15198, + "stored_fields_memory_in_bytes": 1248, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 1600, + "points_memory_in_bytes": 4, + "doc_values_memory_in_bytes": 368, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 4, + "size_in_bytes": 11068 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 4, + "deleted": 0 + }, + "store": { + "size_in_bytes": 35444, + "throttle_time_in_millis": 0 + }, + "indexing": { + "index_total": 4, + "index_time_in_millis": 1421, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 20971520 + }, + "refresh": { + "total": 5, + "total_time_in_millis": 771, + "listeners": 0 + }, + "flush": { + "total": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 4, + "total_time_in_millis": 9 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 4, + "memory_in_bytes": 18418, + "terms_memory_in_bytes": 15198, + "stored_fields_memory_in_bytes": 1248, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 1600, + "points_memory_in_bytes": 4, + "doc_values_memory_in_bytes": 368, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 4, + "size_in_bytes": 11068 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + } + } +} diff --git a/fixtures/indices/7.17.3.json b/fixtures/indices/7.17.3.json new file mode 100644 index 00000000..c1015084 --- /dev/null +++ b/fixtures/indices/7.17.3.json @@ -0,0 +1,1303 @@ +{ + "_shards": { + "total": 7, + "successful": 4, + "failed": 0 + }, + "_all": { + "primaries": { + "docs": { + "count": 43, + "deleted": 0 + }, + "shard_stats": { + "total_count": 4 + }, + "store": { + "size_in_bytes": 39917364, + "total_data_set_size_in_bytes": 39917364, + "reserved_in_bytes": 0 + }, + "indexing": { + "index_total": 43, + "index_time_in_millis": 741, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 43, + "query_time_in_millis": 71, + "query_current": 0, + "fetch_total": 43, + "fetch_time_in_millis": 96, + "fetch_current": 0, + "scroll_total": 3, + "scroll_time_in_millis": 60, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 83886080 + }, + "refresh": { + "total": 18, + "total_time_in_millis": 76, + "external_total": 15, + "external_total_time_in_millis": 73, + "listeners": 0 + }, + "flush": { + "total": 4, + "periodic": 0, + "total_time_in_millis": 150 + }, + "warmer": { + "current": 0, + "total": 11, + "total_time_in_millis": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 7, + "memory_in_bytes": 9996, + "terms_memory_in_bytes": 5600, + "stored_fields_memory_in_bytes": 3480, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 384, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 532, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 3, + "size_in_bytes": 487, + "uncommitted_operations": 3, + "uncommitted_size_in_bytes": 487, + "earliest_last_modified_age": 35855 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 43, + "deleted": 0 + }, + "shard_stats": { + "total_count": 4 + }, + "store": { + "size_in_bytes": 39917364, + "total_data_set_size_in_bytes": 39917364, + "reserved_in_bytes": 0 + }, + "indexing": { + "index_total": 43, + "index_time_in_millis": 741, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 43, + "query_time_in_millis": 71, + "query_current": 0, + "fetch_total": 43, + "fetch_time_in_millis": 96, + "fetch_current": 0, + "scroll_total": 3, + "scroll_time_in_millis": 60, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 83886080 + }, + "refresh": { + "total": 18, + "total_time_in_millis": 76, + "external_total": 15, + "external_total_time_in_millis": 73, + "listeners": 0 + }, + "flush": { + "total": 4, + "periodic": 0, + "total_time_in_millis": 150 + }, + "warmer": { + "current": 0, + "total": 11, + "total_time_in_millis": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 7, + "memory_in_bytes": 9996, + "terms_memory_in_bytes": 5600, + "stored_fields_memory_in_bytes": 3480, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 384, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 532, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 3, + "size_in_bytes": 487, + "uncommitted_operations": 3, + "uncommitted_size_in_bytes": 487, + "earliest_last_modified_age": 35855 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + }, + "indices": { + ".geoip_databases": { + "uuid": "AbBfA8RRRLGfbIPGIAQs7A", + "primaries": { + "docs": { + "count": 40, + "deleted": 0 + }, + "shard_stats": { + "total_count": 1 + }, + "store": { + "size_in_bytes": 39904033, + "total_data_set_size_in_bytes": 39904033, + "reserved_in_bytes": 0 + }, + "indexing": { + "index_total": 40, + "index_time_in_millis": 738, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 43, + "query_time_in_millis": 71, + "query_current": 0, + "fetch_total": 43, + "fetch_time_in_millis": 96, + "fetch_current": 0, + "scroll_total": 3, + "scroll_time_in_millis": 60, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 20971520 + }, + "refresh": { + "total": 9, + "total_time_in_millis": 50, + "external_total": 6, + "external_total_time_in_millis": 45, + "listeners": 0 + }, + "flush": { + "total": 4, + "periodic": 0, + "total_time_in_millis": 150 + }, + "warmer": { + "current": 0, + "total": 5, + "total_time_in_millis": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 4, + "memory_in_bytes": 4368, + "terms_memory_in_bytes": 2048, + "stored_fields_memory_in_bytes": 2016, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 0, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 304, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 0, + "size_in_bytes": 55, + "uncommitted_operations": 0, + "uncommitted_size_in_bytes": 55, + "earliest_last_modified_age": 406186 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 40, + "deleted": 0 + }, + "shard_stats": { + "total_count": 1 + }, + "store": { + "size_in_bytes": 39904033, + "total_data_set_size_in_bytes": 39904033, + "reserved_in_bytes": 0 + }, + "indexing": { + "index_total": 40, + "index_time_in_millis": 738, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 43, + "query_time_in_millis": 71, + "query_current": 0, + "fetch_total": 43, + "fetch_time_in_millis": 96, + "fetch_current": 0, + "scroll_total": 3, + "scroll_time_in_millis": 60, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 20971520 + }, + "refresh": { + "total": 9, + "total_time_in_millis": 50, + "external_total": 6, + "external_total_time_in_millis": 45, + "listeners": 0 + }, + "flush": { + "total": 4, + "periodic": 0, + "total_time_in_millis": 150 + }, + "warmer": { + "current": 0, + "total": 5, + "total_time_in_millis": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 4, + "memory_in_bytes": 4368, + "terms_memory_in_bytes": 2048, + "stored_fields_memory_in_bytes": 2016, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 0, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 304, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 0, + "size_in_bytes": 55, + "uncommitted_operations": 0, + "uncommitted_size_in_bytes": 55, + "earliest_last_modified_age": 406186 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + }, + "foo_2": { + "uuid": "JnYmxu4DStKroXSy6BHYcQ", + "primaries": { + "docs": { + "count": 1, + "deleted": 0 + }, + "shard_stats": { + "total_count": 1 + }, + "store": { + "size_in_bytes": 4459, + "total_data_set_size_in_bytes": 4459, + "reserved_in_bytes": 0 + }, + "indexing": { + "index_total": 1, + "index_time_in_millis": 1, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 20971520 + }, + "refresh": { + "total": 3, + "total_time_in_millis": 9, + "external_total": 3, + "external_total_time_in_millis": 10, + "listeners": 0 + }, + "flush": { + "total": 0, + "periodic": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 2, + "total_time_in_millis": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 1, + "memory_in_bytes": 1876, + "terms_memory_in_bytes": 1184, + "stored_fields_memory_in_bytes": 488, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 128, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 76, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 1, + "size_in_bytes": 146, + "uncommitted_operations": 1, + "uncommitted_size_in_bytes": 146, + "earliest_last_modified_age": 36079 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 1, + "deleted": 0 + }, + "shard_stats": { + "total_count": 1 + }, + "store": { + "size_in_bytes": 4459, + "total_data_set_size_in_bytes": 4459, + "reserved_in_bytes": 0 + }, + "indexing": { + "index_total": 1, + "index_time_in_millis": 1, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 20971520 + }, + "refresh": { + "total": 3, + "total_time_in_millis": 9, + "external_total": 3, + "external_total_time_in_millis": 10, + "listeners": 0 + }, + "flush": { + "total": 0, + "periodic": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 2, + "total_time_in_millis": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 1, + "memory_in_bytes": 1876, + "terms_memory_in_bytes": 1184, + "stored_fields_memory_in_bytes": 488, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 128, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 76, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 1, + "size_in_bytes": 146, + "uncommitted_operations": 1, + "uncommitted_size_in_bytes": 146, + "earliest_last_modified_age": 36079 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + }, + "foo_1": { + "uuid": "9itiRXMuQym8eTdKygV3Kw", + "primaries": { + "docs": { + "count": 1, + "deleted": 0 + }, + "shard_stats": { + "total_count": 1 + }, + "store": { + "size_in_bytes": 4413, + "total_data_set_size_in_bytes": 4413, + "reserved_in_bytes": 0 + }, + "indexing": { + "index_total": 1, + "index_time_in_millis": 1, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 20971520 + }, + "refresh": { + "total": 3, + "total_time_in_millis": 8, + "external_total": 3, + "external_total_time_in_millis": 8, + "listeners": 0 + }, + "flush": { + "total": 0, + "periodic": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 2, + "total_time_in_millis": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 1, + "memory_in_bytes": 1876, + "terms_memory_in_bytes": 1184, + "stored_fields_memory_in_bytes": 488, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 128, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 76, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 1, + "size_in_bytes": 140, + "uncommitted_operations": 1, + "uncommitted_size_in_bytes": 140, + "earliest_last_modified_age": 36364 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 1, + "deleted": 0 + }, + "shard_stats": { + "total_count": 1 + }, + "store": { + "size_in_bytes": 4413, + "total_data_set_size_in_bytes": 4413, + "reserved_in_bytes": 0 + }, + "indexing": { + "index_total": 1, + "index_time_in_millis": 1, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 20971520 + }, + "refresh": { + "total": 3, + "total_time_in_millis": 8, + "external_total": 3, + "external_total_time_in_millis": 8, + "listeners": 0 + }, + "flush": { + "total": 0, + "periodic": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 2, + "total_time_in_millis": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 1, + "memory_in_bytes": 1876, + "terms_memory_in_bytes": 1184, + "stored_fields_memory_in_bytes": 488, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 128, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 76, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 1, + "size_in_bytes": 140, + "uncommitted_operations": 1, + "uncommitted_size_in_bytes": 140, + "earliest_last_modified_age": 36364 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + }, + "foo_3": { + "uuid": "a2-lU19tRuKUPgarKpqoCg", + "primaries": { + "docs": { + "count": 1, + "deleted": 0 + }, + "shard_stats": { + "total_count": 1 + }, + "store": { + "size_in_bytes": 4459, + "total_data_set_size_in_bytes": 4459, + "reserved_in_bytes": 0 + }, + "indexing": { + "index_total": 1, + "index_time_in_millis": 1, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 20971520 + }, + "refresh": { + "total": 3, + "total_time_in_millis": 9, + "external_total": 3, + "external_total_time_in_millis": 10, + "listeners": 0 + }, + "flush": { + "total": 0, + "periodic": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 2, + "total_time_in_millis": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 1, + "memory_in_bytes": 1876, + "terms_memory_in_bytes": 1184, + "stored_fields_memory_in_bytes": 488, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 128, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 76, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 1, + "size_in_bytes": 146, + "uncommitted_operations": 1, + "uncommitted_size_in_bytes": 146, + "earliest_last_modified_age": 35855 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + }, + "total": { + "docs": { + "count": 1, + "deleted": 0 + }, + "shard_stats": { + "total_count": 1 + }, + "store": { + "size_in_bytes": 4459, + "total_data_set_size_in_bytes": 4459, + "reserved_in_bytes": 0 + }, + "indexing": { + "index_total": 1, + "index_time_in_millis": 1, + "index_current": 0, + "index_failed": 0, + "delete_total": 0, + "delete_time_in_millis": 0, + "delete_current": 0, + "noop_update_total": 0, + "is_throttled": false, + "throttle_time_in_millis": 0 + }, + "get": { + "total": 0, + "time_in_millis": 0, + "exists_total": 0, + "exists_time_in_millis": 0, + "missing_total": 0, + "missing_time_in_millis": 0, + "current": 0 + }, + "search": { + "open_contexts": 0, + "query_total": 0, + "query_time_in_millis": 0, + "query_current": 0, + "fetch_total": 0, + "fetch_time_in_millis": 0, + "fetch_current": 0, + "scroll_total": 0, + "scroll_time_in_millis": 0, + "scroll_current": 0, + "suggest_total": 0, + "suggest_time_in_millis": 0, + "suggest_current": 0 + }, + "merges": { + "current": 0, + "current_docs": 0, + "current_size_in_bytes": 0, + "total": 0, + "total_time_in_millis": 0, + "total_docs": 0, + "total_size_in_bytes": 0, + "total_stopped_time_in_millis": 0, + "total_throttled_time_in_millis": 0, + "total_auto_throttle_in_bytes": 20971520 + }, + "refresh": { + "total": 3, + "total_time_in_millis": 9, + "external_total": 3, + "external_total_time_in_millis": 10, + "listeners": 0 + }, + "flush": { + "total": 0, + "periodic": 0, + "total_time_in_millis": 0 + }, + "warmer": { + "current": 0, + "total": 2, + "total_time_in_millis": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 1, + "memory_in_bytes": 1876, + "terms_memory_in_bytes": 1184, + "stored_fields_memory_in_bytes": 488, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 128, + "points_memory_in_bytes": 0, + "doc_values_memory_in_bytes": 76, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + }, + "translog": { + "operations": 1, + "size_in_bytes": 146, + "uncommitted_operations": 1, + "uncommitted_size_in_bytes": 146, + "earliest_last_modified_age": 35855 + }, + "request_cache": { + "memory_size_in_bytes": 0, + "evictions": 0, + "hit_count": 0, + "miss_count": 0 + }, + "recovery": { + "current_as_source": 0, + "current_as_target": 0, + "throttle_time_in_millis": 0 + } + } + } + } +} diff --git a/fixtures/indices/alias/1.7.6.json b/fixtures/indices/alias/1.7.6.json new file mode 100644 index 00000000..a16f9b3d --- /dev/null +++ b/fixtures/indices/alias/1.7.6.json @@ -0,0 +1,20 @@ +{ + "foo_1": { + "aliases": {} + }, + "foo_2": { + "aliases": { + "foo_alias_2_1": {} + } + }, + "foo_3": { + "aliases": { + "foo_alias_3_1": { + "index_routing": "title", + "search_routing": "title", + "is_write_index": true + }, + "foo_alias_3_2": {} + } + } +} diff --git a/fixtures/indices/alias/2.4.5.json b/fixtures/indices/alias/2.4.5.json new file mode 100644 index 00000000..a16f9b3d --- /dev/null +++ b/fixtures/indices/alias/2.4.5.json @@ -0,0 +1,20 @@ +{ + "foo_1": { + "aliases": {} + }, + "foo_2": { + "aliases": { + "foo_alias_2_1": {} + } + }, + "foo_3": { + "aliases": { + "foo_alias_3_1": { + "index_routing": "title", + "search_routing": "title", + "is_write_index": true + }, + "foo_alias_3_2": {} + } + } +} diff --git a/fixtures/indices/alias/5.4.2.json b/fixtures/indices/alias/5.4.2.json new file mode 100644 index 00000000..a16f9b3d --- /dev/null +++ b/fixtures/indices/alias/5.4.2.json @@ -0,0 +1,20 @@ +{ + "foo_1": { + "aliases": {} + }, + "foo_2": { + "aliases": { + "foo_alias_2_1": {} + } + }, + "foo_3": { + "aliases": { + "foo_alias_3_1": { + "index_routing": "title", + "search_routing": "title", + "is_write_index": true + }, + "foo_alias_3_2": {} + } + } +} diff --git a/fixtures/indices/alias/7.17.3.json b/fixtures/indices/alias/7.17.3.json new file mode 100644 index 00000000..a16f9b3d --- /dev/null +++ b/fixtures/indices/alias/7.17.3.json @@ -0,0 +1,20 @@ +{ + "foo_1": { + "aliases": {} + }, + "foo_2": { + "aliases": { + "foo_alias_2_1": {} + } + }, + "foo_3": { + "aliases": { + "foo_alias_3_1": { + "index_routing": "title", + "search_routing": "title", + "is_write_index": true + }, + "foo_alias_3_2": {} + } + } +} diff --git a/fixtures/indices_mappings/7.8.0.json b/fixtures/indices_mappings/7.8.0.json new file mode 100644 index 00000000..eb96f35b --- /dev/null +++ b/fixtures/indices_mappings/7.8.0.json @@ -0,0 +1,43 @@ +{ + "facebook": { + "mappings": { + "properties": { + "contact": { + "properties": { + "email": { + "type": "text", + "fields": { + "raw": { + "type": "keyword" + } + } + }, + "phone": { + "type": "text" + } + } + }, + "name": { + "type": "text", + "fields": { + "raw": { + "type": "keyword" + } + } + } + } + } + }, + "twitter": { + "mappings": { + "properties": { + "email": { + "type": "keyword" + }, + "phone": { + "type": "keyword" + } + } + } + } +} diff --git a/fixtures/indices_mappings/counts.json b/fixtures/indices_mappings/counts.json new file mode 100644 index 00000000..4550a79f --- /dev/null +++ b/fixtures/indices_mappings/counts.json @@ -0,0 +1,183 @@ +{ + "test-data-2023.01.20": { + "mappings": { + "properties": { + "data": { + "type": "object", + "properties": { + "field1": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field10": { + "type": "long" + }, + "field2": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field3": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field4": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field5": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field6": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field7": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field8": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field9": { + "type": "long" + } + } + }, + "data2": { + "properties": { + "field1": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field2": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field3": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field4": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field5": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "nested_field6": { + "properties": { + "field1": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field2": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field3": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field4": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "field5": { + "type": "long" + } + } + } + } + } + } + } + } +} diff --git a/fixtures/nodestats/5.6.16.json b/fixtures/nodestats/5.6.16.json new file mode 100644 index 00000000..b677fdcb --- /dev/null +++ b/fixtures/nodestats/5.6.16.json @@ -0,0 +1 @@ +{"_nodes":{"total":1,"successful":1,"failed":0},"cluster_name":"elasticsearch","nodes":{"bVrN1HxvQLy795ZLNg2XNw":{"timestamp":1622148141237,"name":"bVrN1Hx","transport_address":"127.0.0.1:9300","host":"127.0.0.1","ip":"127.0.0.1:9300","roles":["master","data","ingest"],"indices":{"docs":{"count":5,"deleted":0},"store":{"size_in_bytes":5721,"throttle_time_in_millis":0},"indexing":{"index_total":5,"index_time_in_millis":39,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":629145600},"refresh":{"total":65,"total_time_in_millis":86,"listeners":0},"flush":{"total":0,"total_time_in_millis":0},"warmer":{"current":0,"total":35,"total_time_in_millis":1},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":5,"memory_in_bytes":12940,"terms_memory_in_bytes":9960,"stored_fields_memory_in_bytes":1560,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":960,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":460,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":5,"size_in_bytes":1743},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"os":{"timestamp":1622148141242,"cpu":{"percent":23,"load_average":{"1m":45.68,"5m":150.34,"15m":96.01}},"mem":{"total_in_bytes":33623236608,"free_in_bytes":7009173504,"used_in_bytes":26614063104,"free_percent":21,"used_percent":79},"swap":{"total_in_bytes":2147479552,"free_in_bytes":86630400,"used_in_bytes":2060849152}},"process":{"timestamp":1622148141242,"open_file_descriptors":308,"max_file_descriptors":1048576,"cpu":{"percent":8,"total_in_millis":14510},"mem":{"total_virtual_in_bytes":8293711872}},"jvm":{"timestamp":1622148141243,"uptime_in_millis":14845,"mem":{"heap_used_in_bytes":333706928,"heap_used_percent":16,"heap_committed_in_bytes":2077753344,"heap_max_in_bytes":2077753344,"non_heap_used_in_bytes":70212664,"non_heap_committed_in_bytes":75362304,"pools":{"young":{"used_in_bytes":53925336,"max_in_bytes":558432256,"peak_used_in_bytes":558432256,"peak_max_in_bytes":558432256},"survivor":{"used_in_bytes":69730304,"max_in_bytes":69730304,"peak_used_in_bytes":69730304,"peak_max_in_bytes":69730304},"old":{"used_in_bytes":210051288,"max_in_bytes":1449590784,"peak_used_in_bytes":210051288,"peak_max_in_bytes":1449590784}}},"threads":{"count":60,"peak_count":60},"gc":{"collectors":{"young":{"collection_count":2,"collection_time_in_millis":143},"old":{"collection_count":1,"collection_time_in_millis":109}}},"buffer_pools":{"direct":{"count":47,"used_in_bytes":252727869,"total_capacity_in_bytes":252727868},"mapped":{"count":5,"used_in_bytes":15007,"total_capacity_in_bytes":15007}},"classes":{"current_loaded_count":10502,"total_loaded_count":10502,"total_unloaded_count":0}},"thread_pool":{"bulk":{"threads":5,"queue":0,"active":0,"rejected":0,"largest":5,"completed":5},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":38},"get":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"index":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":5},"management":{"threads":1,"queue":0,"active":1,"rejected":0,"largest":1,"completed":2},"refresh":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":1,"completed":31},"search":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0}},"fs":{"timestamp":1622148141244,"total":{"total_in_bytes":476630163456,"free_in_bytes":77533405184,"available_in_bytes":77533405184,"spins":"true"},"data":[{"path":"/usr/share/elasticsearch/data/nodes/0","mount":"/usr/share/elasticsearch/data (/dev/mapper/vg0-root)","type":"xfs","total_in_bytes":476630163456,"free_in_bytes":77533405184,"available_in_bytes":77533405184,"spins":"true"}],"io_stats":{"devices":[{"device_name":"dm-2","operations":2517,"read_operations":706,"write_operations":1811,"read_kilobytes":12916,"write_kilobytes":17760}],"total":{"operations":2517,"read_operations":706,"write_operations":1811,"read_kilobytes":12916,"write_kilobytes":17760}}},"transport":{"server_open":0,"rx_count":0,"rx_size_in_bytes":0,"tx_count":0,"tx_size_in_bytes":0},"http":{"current_open":1,"total_opened":16},"breakers":{"request":{"limit_size_in_bytes":1246652006,"limit_size":"1.1gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":1246652006,"limit_size":"1.1gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":2077753344,"limit_size":"1.9gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":1454427340,"limit_size":"1.3gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0}},"script":{"compilations":0,"cache_evictions":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{}}}}} \ No newline at end of file diff --git a/fixtures/nodestats/6.8.8.json b/fixtures/nodestats/6.8.8.json new file mode 100644 index 00000000..87d6aac1 --- /dev/null +++ b/fixtures/nodestats/6.8.8.json @@ -0,0 +1 @@ +{"_nodes":{"total":1,"successful":1,"failed":0},"cluster_name":"elasticsearch","nodes":{"9_P7yuiySjG7OAN6NRbBRA":{"timestamp":1622148180536,"name":"9_P7yui","transport_address":"172.17.0.2:9300","host":"172.17.0.2","ip":"172.17.0.2:9300","roles":["master","data","ingest"],"attributes":{"ml.machine_memory":"33623236608","xpack.installed":"true","ml.max_open_jobs":"20","ml.enabled":"true"},"indices":{"docs":{"count":5,"deleted":0},"store":{"size_in_bytes":7261},"indexing":{"index_total":5,"index_time_in_millis":38,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":629145600},"refresh":{"total":65,"total_time_in_millis":103,"listeners":0},"flush":{"total":0,"periodic":0,"total_time_in_millis":0},"warmer":{"current":0,"total":35,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":5,"memory_in_bytes":8490,"terms_memory_in_bytes":5945,"stored_fields_memory_in_bytes":1560,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":640,"points_memory_in_bytes":5,"doc_values_memory_in_bytes":340,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":5,"size_in_bytes":3753,"uncommitted_operations":5,"uncommitted_size_in_bytes":3753,"earliest_last_modified_age":0},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"os":{"timestamp":1622148180547,"cpu":{"percent":30,"load_average":{"1m":27.55,"5m":134.28,"15m":92.65}},"mem":{"total_in_bytes":33623236608,"free_in_bytes":7651008512,"used_in_bytes":25972228096,"free_percent":23,"used_percent":77},"swap":{"total_in_bytes":2147479552,"free_in_bytes":109174784,"used_in_bytes":2038304768},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":33206615382},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}},"memory":{"control_group":"/","limit_in_bytes":"9223372036854771712","usage_in_bytes":"1634058240"}}},"process":{"timestamp":1622148180547,"open_file_descriptors":355,"max_file_descriptors":1048576,"cpu":{"percent":17,"total_in_millis":32810},"mem":{"total_virtual_in_bytes":7269961728}},"jvm":{"timestamp":1622148180548,"uptime_in_millis":16456,"mem":{"heap_used_in_bytes":660054016,"heap_used_percent":61,"heap_committed_in_bytes":1073741824,"heap_max_in_bytes":1073741824,"non_heap_used_in_bytes":108594112,"non_heap_committed_in_bytes":117964800,"pools":{"young":{"used_in_bytes":393216000,"max_in_bytes":0,"peak_used_in_bytes":559417344,"peak_max_in_bytes":0},"old":{"used_in_bytes":255827968,"max_in_bytes":1073741824,"peak_used_in_bytes":255827968,"peak_max_in_bytes":1073741824},"survivor":{"used_in_bytes":11010048,"max_in_bytes":0,"peak_used_in_bytes":47668160,"peak_max_in_bytes":0}}},"threads":{"count":54,"peak_count":54},"gc":{"collectors":{"young":{"collection_count":5,"collection_time_in_millis":80},"old":{"collection_count":0,"collection_time_in_millis":0}}},"buffer_pools":{"mapped":{"count":5,"used_in_bytes":15179,"total_capacity_in_bytes":15179},"direct":{"count":42,"used_in_bytes":168849056,"total_capacity_in_bytes":168849055},"mapped - 'non-volatile memory'":{"count":0,"used_in_bytes":0,"total_capacity_in_bytes":0}},"classes":{"current_loaded_count":16278,"total_loaded_count":16278,"total_unloaded_count":0}},"thread_pool":{"analyze":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ccr":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":5,"queue":0,"active":0,"rejected":0,"largest":5,"completed":87},"get":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"index":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":4,"queue":0,"active":0,"rejected":0,"largest":4,"completed":5},"management":{"threads":2,"queue":0,"active":1,"rejected":0,"largest":2,"completed":5},"ml_autodetect":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":1,"completed":1},"refresh":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":1,"completed":32},"rollup_indexing":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"search":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"search_throttled":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"security-token-key":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"write":{"threads":5,"queue":0,"active":0,"rejected":0,"largest":5,"completed":5}},"fs":{"timestamp":1622148180551,"total":{"total_in_bytes":476630163456,"free_in_bytes":77532815360,"available_in_bytes":77532815360},"data":[{"path":"/usr/share/elasticsearch/data/nodes/0","mount":"/ (overlay)","type":"overlay","total_in_bytes":476630163456,"free_in_bytes":77532815360,"available_in_bytes":77532815360}],"io_stats":{}},"transport":{"server_open":0,"rx_count":0,"rx_size_in_bytes":0,"tx_count":0,"tx_size_in_bytes":0},"http":{"current_open":1,"total_opened":16},"breakers":{"request":{"limit_size_in_bytes":644245094,"limit_size":"614.3mb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":644245094,"limit_size":"614.3mb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":1073741824,"limit_size":"1gb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"accounting":{"limit_size_in_bytes":1073741824,"limit_size":"1gb","estimated_size_in_bytes":8490,"estimated_size":"8.2kb","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":751619276,"limit_size":"716.7mb","estimated_size_in_bytes":8490,"estimated_size":"8.2kb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0},"discovery":{},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_2":{"count":0,"time_in_millis":0,"current":0,"failed":0,"processors":[{"script":{"count":0,"time_in_millis":0,"current":0,"failed":0}},{"rename":{"count":0,"time_in_millis":0,"current":0,"failed":0}},{"set":{"count":0,"time_in_millis":0,"current":0,"failed":0}},{"gsub":{"count":0,"time_in_millis":0,"current":0,"failed":0}}]},"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0,"processors":[]}}},"adaptive_selection":{}}}} \ No newline at end of file diff --git a/fixtures/nodestats/7.13.1.json b/fixtures/nodestats/7.13.1.json new file mode 100644 index 00000000..a5b58001 --- /dev/null +++ b/fixtures/nodestats/7.13.1.json @@ -0,0 +1 @@ +{"_nodes":{"total":1,"successful":1,"failed":0},"cluster_name":"elasticsearch","nodes":{"byoDEtBRSRGZyMKaIpmhCQ":{"timestamp":1622732353195,"name":"aaf5a8a0bceb","transport_address":"172.17.0.2:9300","host":"172.17.0.2","ip":"172.17.0.2:9300","roles":["data","data_cold","data_content","data_frozen","data_hot","data_warm","ingest","master","ml","remote_cluster_client","transform"],"attributes":{"ml.machine_memory":"33623232512","xpack.installed":"true","transform.node":"true","ml.max_open_jobs":"512","ml.max_jvm_size":"788529152"},"indices":{"docs":{"count":5,"deleted":0},"store":{"size_in_bytes":22296,"total_data_set_size_in_bytes":22296,"reserved_in_bytes":0},"indexing":{"index_total":5,"index_time_in_millis":14,"index_current":0,"index_failed":0,"delete_total":0,"delete_time_in_millis":0,"delete_current":0,"noop_update_total":0,"is_throttled":false,"throttle_time_in_millis":0},"get":{"total":0,"time_in_millis":0,"exists_total":0,"exists_time_in_millis":0,"missing_total":0,"missing_time_in_millis":0,"current":0},"search":{"open_contexts":0,"query_total":0,"query_time_in_millis":0,"query_current":0,"fetch_total":0,"fetch_time_in_millis":0,"fetch_current":0,"scroll_total":0,"scroll_time_in_millis":0,"scroll_current":0,"suggest_total":0,"suggest_time_in_millis":0,"suggest_current":0},"merges":{"current":0,"current_docs":0,"current_size_in_bytes":0,"total":0,"total_time_in_millis":0,"total_docs":0,"total_size_in_bytes":0,"total_stopped_time_in_millis":0,"total_throttled_time_in_millis":0,"total_auto_throttle_in_bytes":125829120},"refresh":{"total":17,"total_time_in_millis":148,"external_total":17,"external_total_time_in_millis":150,"listeners":0},"flush":{"total":0,"periodic":0,"total_time_in_millis":0},"warmer":{"current":0,"total":11,"total_time_in_millis":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":5,"memory_in_bytes":9380,"terms_memory_in_bytes":5920,"stored_fields_memory_in_bytes":2440,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":640,"points_memory_in_bytes":0,"doc_values_memory_in_bytes":380,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}},"translog":{"operations":5,"size_in_bytes":773,"uncommitted_operations":5,"uncommitted_size_in_bytes":773,"earliest_last_modified_age":1118},"request_cache":{"memory_size_in_bytes":0,"evictions":0,"hit_count":0,"miss_count":0},"recovery":{"current_as_source":0,"current_as_target":0,"throttle_time_in_millis":0}},"os":{"timestamp":1622732353199,"cpu":{"percent":37,"load_average":{"1m":2.74,"5m":44.07,"15m":70.55}},"mem":{"total_in_bytes":33623232512,"free_in_bytes":12400742400,"used_in_bytes":21222490112,"free_percent":37,"used_percent":63},"swap":{"total_in_bytes":2147479552,"free_in_bytes":928747520,"used_in_bytes":1218732032},"cgroup":{"cpuacct":{"control_group":"/","usage_nanos":52445263941},"cpu":{"control_group":"/","cfs_period_micros":100000,"cfs_quota_micros":-1,"stat":{"number_of_elapsed_periods":0,"number_of_times_throttled":0,"time_throttled_nanos":0}},"memory":{"control_group":"/","limit_in_bytes":"9223372036854771712","usage_in_bytes":"1110376448"}}},"process":{"timestamp":1622732353199,"open_file_descriptors":314,"max_file_descriptors":1048576,"cpu":{"percent":19,"total_in_millis":50160},"mem":{"total_virtual_in_bytes":6819479552}},"jvm":{"timestamp":1622732353200,"uptime_in_millis":21844,"mem":{"heap_used_in_bytes":156194432,"heap_used_percent":19,"heap_committed_in_bytes":788529152,"heap_max_in_bytes":788529152,"non_heap_used_in_bytes":139526472,"non_heap_committed_in_bytes":142606336,"pools":{"young":{"used_in_bytes":54525952,"max_in_bytes":0,"peak_used_in_bytes":465567744,"peak_max_in_bytes":0},"old":{"used_in_bytes":71059968,"max_in_bytes":788529152,"peak_used_in_bytes":71059968,"peak_max_in_bytes":788529152},"survivor":{"used_in_bytes":30608512,"max_in_bytes":0,"peak_used_in_bytes":54525952,"peak_max_in_bytes":0}}},"threads":{"count":49,"peak_count":49},"gc":{"collectors":{"young":{"collection_count":11,"collection_time_in_millis":113},"old":{"collection_count":0,"collection_time_in_millis":0}}},"buffer_pools":{"mapped":{"count":5,"used_in_bytes":16868,"total_capacity_in_bytes":16868},"direct":{"count":33,"used_in_bytes":8811046,"total_capacity_in_bytes":8811045},"mapped - 'non-volatile memory'":{"count":0,"used_in_bytes":0,"total_capacity_in_bytes":0}},"classes":{"current_loaded_count":21909,"total_loaded_count":21909,"total_unloaded_count":0}},"thread_pool":{"analyze":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ccr":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_started":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"fetch_shard_store":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"flush":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"force_merge":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"generic":{"threads":7,"queue":0,"active":0,"rejected":0,"largest":7,"completed":406},"get":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"listener":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"management":{"threads":2,"queue":0,"active":1,"rejected":0,"largest":2,"completed":9},"ml_datafeed":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_job_comms":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"ml_utility":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":1,"completed":12},"refresh":{"threads":1,"queue":0,"active":0,"rejected":0,"largest":1,"completed":36},"rollup_indexing":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"search":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"search_throttled":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"searchable_snapshots_cache_fetch_async":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"searchable_snapshots_cache_prewarming":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"security-crypto":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"security-token-key":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"snapshot":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"system_read":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"system_write":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"transform_indexing":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"warmer":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"watcher":{"threads":0,"queue":0,"active":0,"rejected":0,"largest":0,"completed":0},"write":{"threads":8,"queue":0,"active":0,"rejected":0,"largest":8,"completed":9}},"fs":{"timestamp":1622732353202,"total":{"total_in_bytes":476630163456,"free_in_bytes":63425642496,"available_in_bytes":63425642496},"data":[{"path":"/usr/share/elasticsearch/data/nodes/0","mount":"/ (overlay)","type":"overlay","total_in_bytes":476630163456,"free_in_bytes":63425642496,"available_in_bytes":63425642496}],"io_stats":{}},"transport":{"server_open":0,"total_outbound_connections":0,"rx_count":0,"rx_size_in_bytes":0,"tx_count":0,"tx_size_in_bytes":0},"http":{"current_open":1,"total_opened":16,"clients":[{"id":789026726,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49438","last_uri":"/foo_2/type1/1?refresh=wait_for","opened_time_millis":1622732349747,"closed_time_millis":1622732350948,"last_request_time_millis":1622732349747,"request_count":1,"request_size_bytes":39},{"id":150912494,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49458","last_uri":"/_all/_stats","opened_time_millis":1622732353149,"closed_time_millis":1622732353149,"last_request_time_millis":1622732353149,"request_count":1,"request_size_bytes":0},{"id":1204144009,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49442","last_uri":"/foo_2/type1/2?refresh=wait_for","opened_time_millis":1622732350948,"closed_time_millis":1622732351948,"last_request_time_millis":1622732350948,"request_count":1,"request_size_bytes":39},{"id":832608635,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49402","last_uri":"/twitter","opened_time_millis":1622732343337,"closed_time_millis":1622732345338,"last_request_time_millis":1622732343337,"request_count":1,"request_size_bytes":0},{"id":1787075320,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49454","last_uri":"/_all/_settings","opened_time_millis":1622732353149,"closed_time_millis":1622732353149,"last_request_time_millis":1622732353149,"request_count":1,"request_size_bytes":0},{"id":1263458828,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49416","last_uri":"/viber","opened_time_millis":1622732346538,"closed_time_millis":1622732347139,"last_request_time_millis":1622732346538,"request_count":1,"request_size_bytes":0},{"id":186367096,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49450","last_uri":"/_cluster/health","opened_time_millis":1622732352949,"closed_time_millis":1622732352949,"last_request_time_millis":1622732352949,"request_count":1,"request_size_bytes":0},{"id":1263584333,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49398","last_uri":"/","opened_time_millis":1622732343337,"closed_time_millis":1622732343337,"last_request_time_millis":1622732343337,"request_count":1,"request_size_bytes":0},{"id":1290037325,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49420","last_uri":"/instagram/_settings","opened_time_millis":1622732347139,"closed_time_millis":1622732347339,"last_request_time_millis":1622732347139,"request_count":1,"request_size_bytes":124},{"id":170704265,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49462","last_uri":"/_nodes/stats","opened_time_millis":1622732353149,"last_request_time_millis":1622732353149,"request_count":1,"request_size_bytes":0},{"id":1002191851,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49428","last_uri":"/foo_1/type1/1?refresh=wait_for","opened_time_millis":1622732347539,"closed_time_millis":1622732348747,"last_request_time_millis":1622732347539,"request_count":1,"request_size_bytes":33},{"id":119489056,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49424","last_uri":"/twitter/_settings","opened_time_millis":1622732347339,"closed_time_millis":1622732347539,"last_request_time_millis":1622732347339,"request_count":1,"request_size_bytes":124},{"id":562495253,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49446","last_uri":"/foo_2/type1/3?refresh=wait_for","opened_time_millis":1622732351948,"closed_time_millis":1622732352949,"last_request_time_millis":1622732351948,"request_count":1,"request_size_bytes":39},{"id":1052374837,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49412","last_uri":"/instagram","opened_time_millis":1622732345938,"closed_time_millis":1622732346538,"last_request_time_millis":1622732345938,"request_count":1,"request_size_bytes":0},{"id":1677987869,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49408","last_uri":"/facebook","opened_time_millis":1622732345338,"closed_time_millis":1622732345938,"last_request_time_millis":1622732345338,"request_count":1,"request_size_bytes":0},{"id":977313322,"agent":"curl/7.68.0","local_address":"172.17.0.2:9200","remote_address":"172.17.0.1:49432","last_uri":"/foo_1/type1/2?refresh=wait_for","opened_time_millis":1622732348747,"closed_time_millis":1622732349747,"last_request_time_millis":1622732348747,"request_count":1,"request_size_bytes":33}]},"breakers":{"request":{"limit_size_in_bytes":473117491,"limit_size":"451.1mb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"fielddata":{"limit_size_in_bytes":315411660,"limit_size":"300.7mb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.03,"tripped":0},"in_flight_requests":{"limit_size_in_bytes":788529152,"limit_size":"752mb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":2.0,"tripped":0},"model_inference":{"limit_size_in_bytes":394264576,"limit_size":"376mb","estimated_size_in_bytes":0,"estimated_size":"0b","overhead":1.0,"tripped":0},"accounting":{"limit_size_in_bytes":788529152,"limit_size":"752mb","estimated_size_in_bytes":9380,"estimated_size":"9.1kb","overhead":1.0,"tripped":0},"parent":{"limit_size_in_bytes":749102694,"limit_size":"714.3mb","estimated_size_in_bytes":156194432,"estimated_size":"148.9mb","overhead":1.0,"tripped":0}},"script":{"compilations":1,"cache_evictions":0,"compilation_limit_triggered":0},"discovery":{"cluster_state_queue":{"total":0,"pending":0,"committed":0},"published_cluster_states":{"full_states":2,"incompatible_diffs":0,"compatible_diffs":49}},"ingest":{"total":{"count":0,"time_in_millis":0,"current":0,"failed":0},"pipelines":{"xpack_monitoring_6":{"count":0,"time_in_millis":0,"current":0,"failed":0,"processors":[{"script":{"type":"script","stats":{"count":0,"time_in_millis":0,"current":0,"failed":0}}},{"gsub":{"type":"gsub","stats":{"count":0,"time_in_millis":0,"current":0,"failed":0}}}]},"xpack_monitoring_7":{"count":0,"time_in_millis":0,"current":0,"failed":0,"processors":[]}}},"adaptive_selection":{},"script_cache":{"sum":{"compilations":1,"cache_evictions":0,"compilation_limit_triggered":0},"contexts":[{"context":"aggregation_selector","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"aggs","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"aggs_combine","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"aggs_init","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"aggs_map","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"aggs_reduce","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"analysis","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"boolean_field","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"bucket_aggregation","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"date_field","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"double_field","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"field","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"filter","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"geo_point_field","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"ingest","compilations":1,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"ingest_template","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"interval","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"ip_field","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"keyword_field","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"long_field","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"moving-function","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"number_sort","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"painless_test","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"processor_conditional","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"score","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"script_heuristic","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"similarity","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"similarity_weight","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"string_sort","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"template","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"terms_set","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"update","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"watcher_condition","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"watcher_transform","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0},{"context":"xpack_template","compilations":0,"cache_evictions":0,"compilation_limit_triggered":0}]},"indexing_pressure":{"memory":{"current":{"combined_coordinating_and_primary_in_bytes":0,"coordinating_in_bytes":0,"primary_in_bytes":0,"replica_in_bytes":0,"all_in_bytes":0},"total":{"combined_coordinating_and_primary_in_bytes":1423,"coordinating_in_bytes":1423,"primary_in_bytes":1463,"replica_in_bytes":0,"all_in_bytes":1423,"coordinating_rejections":0,"primary_rejections":0,"replica_rejections":0},"limit_in_bytes":78852915}}}}} \ No newline at end of file diff --git a/fixtures/settings-5.4.2.json b/fixtures/settings-5.4.2.json new file mode 100644 index 00000000..b684ecf4 --- /dev/null +++ b/fixtures/settings-5.4.2.json @@ -0,0 +1,661 @@ +{ + "persistent": {}, + "transient": {}, + "defaults": { + "cluster": { + "routing": { + "rebalance": { + "enable": "ALL" + }, + "allocation": { + "node_concurrent_incoming_recoveries": "2", + "node_initial_primaries_recoveries": "4", + "same_shard": { + "host": "false" + }, + "total_shards_per_node": "-1", + "type": "balanced", + "disk": { + "threshold_enabled": "true", + "watermark": { + "low": "85%", + "high": "90%" + }, + "include_relocations": "true", + "reroute_interval": "60s" + }, + "awareness": { + "attributes": "" + }, + "balance": { + "index": "0.55", + "threshold": "1.0", + "shard": "0.45" + }, + "enable": "ALL", + "node_concurrent_outgoing_recoveries": "2", + "allow_rebalance": "indices_all_active", + "cluster_concurrent_rebalance": "2", + "node_concurrent_recoveries": "2", + "snapshot": { + "relocation_enabled": "false" + } + } + }, + "indices": { + "close": { + "enable": "true" + } + }, + "nodes": { + "reconnect_interval": "10s" + }, + "blocks": { + "read_only": "false" + }, + "service": { + "slow_task_logging_threshold": "30s" + }, + "name": "elasticsearch", + "info": { + "update": { + "interval": "30s", + "timeout": "15s" + } + } + }, + "logger": { + "level": "INFO" + }, + "bootstrap": { + "ctrlhandler": "true", + "memory_lock": "false", + "system_call_filter": "true", + "seccomp": "true" + }, + "processors": "4", + "network": { + "host": [ + "_local_" + ], + "tcp": { + "reuse_address": "true", + "connect_timeout": "30s", + "blocking": "false", + "blocking_server": "false", + "no_delay": "true", + "blocking_client": "false", + "keep_alive": "true", + "receive_buffer_size": "-1b", + "send_buffer_size": "-1b" + }, + "bind_host": [ + "_local_" + ], + "server": "true", + "breaker": { + "inflight_requests": { + "limit": "100%", + "overhead": "1.0" + } + }, + "publish_host": [ + "_local_" + ] + }, + "pidfile": "", + "path": { + "conf": "", + "scripts": "", + "logs": "/usr/share/elasticsearch/logs", + "shared_data": "", + "home": "/usr/share/elasticsearch" + }, + "default": { + "path": { + "logs": "", + "conf": "" + } + }, + "search": { + "default_search_timeout": "-1", + "highlight": { + "term_vector_multi_value": "true" + }, + "low_level_cancellation": "false", + "keep_alive_interval": "1m", + "remote": { + "node": { + "attr": "" + }, + "initial_connect_timeout": "30s", + "connect": "true", + "connections_per_cluster": "3" + }, + "default_keep_alive": "5m" + }, + "security": { + "manager": { + "filter_bad_defaults": "true" + } + }, + "repositories": { + "fs": { + "compress": "false", + "chunk_size": "-1b", + "location": "" + }, + "url": { + "supported_protocols": [ + "http", + "https", + "ftp", + "file", + "jar" + ], + "url": "http:" + } + }, + "action": { + "auto_create_index": "true", + "search": { + "shard_count": { + "limit": "9223372036854775807" + } + }, + "destructive_requires_name": "false", + "master": { + "force_local": "false" + } + }, + "client": { + "type": "node", + "transport": { + "ignore_cluster_name": "false", + "nodes_sampler_interval": "5s", + "sniff": "false", + "ping_timeout": "5s" + } + }, + "rest": { + "action": { + "multi": { + "allow_explicit_index": "true" + } + } + }, + "cache": { + "recycler": { + "page": { + "limit": { + "heap": "10%" + }, + "type": "CONCURRENT", + "weight": { + "longs": "1.0", + "ints": "1.0", + "bytes": "1.0", + "objects": "0.1" + } + } + } + }, + "resource": { + "reload": { + "enabled": "true", + "interval": { + "low": "60s", + "high": "5s", + "medium": "30s" + } + } + }, + "thread_pool": { + "force_merge": { + "queue_size": "-1", + "size": "1" + }, + "fetch_shard_started": { + "core": "1", + "max": "8", + "keep_alive": "5m" + }, + "listener": { + "queue_size": "-1", + "size": "2" + }, + "index": { + "queue_size": "200", + "size": "4" + }, + "refresh": { + "core": "1", + "max": "2", + "keep_alive": "5m" + }, + "generic": { + "core": "4", + "max": "128", + "keep_alive": "30s" + }, + "warmer": { + "core": "1", + "max": "2", + "keep_alive": "5m" + }, + "search": { + "queue_size": "1000", + "size": "7" + }, + "fetch_shard_store": { + "core": "1", + "max": "8", + "keep_alive": "5m" + }, + "flush": { + "core": "1", + "max": "2", + "keep_alive": "5m" + }, + "management": { + "core": "1", + "max": "5", + "keep_alive": "5m" + }, + "get": { + "queue_size": "1000", + "size": "4" + }, + "bulk": { + "queue_size": "200", + "size": "4" + }, + "estimated_time_interval": "200ms", + "snapshot": { + "core": "1", + "max": "2", + "keep_alive": "5m" + } + }, + "index": { + "codec": "default", + "store": { + "type": "", + "fs": { + "fs_lock": "native" + } + } + }, + "monitor": { + "jvm": { + "gc": { + "enabled": "true", + "overhead": { + "warn": "50", + "debug": "10", + "info": "25" + }, + "refresh_interval": "1s" + }, + "refresh_interval": "1s" + }, + "process": { + "refresh_interval": "1s" + }, + "os": { + "refresh_interval": "1s" + }, + "fs": { + "refresh_interval": "1s" + } + }, + "transport": { + "tcp": { + "reuse_address": "true", + "connect_timeout": "30s", + "compress": "false", + "port": "9300-9400", + "blocking_server": "false", + "blocking_client": "false", + "keep_alive": "true", + "receive_buffer_size": "-1b", + "send_buffer_size": "-1b" + }, + "ping_schedule": "-1", + "publish_port": "-1", + "connections_per_node": { + "recovery": "2", + "state": "1", + "bulk": "3", + "reg": "6", + "ping": "1" + }, + "tcp_no_delay": "true", + "tracer": { + "exclude": [ + "internal:discovery/zen/fd*", + "cluster:monitor/nodes/liveness" + ] + }, + "type": "", + "netty": { + "max_composite_buffer_components": "-1", + "worker_count": "8", + "receive_predictor_size": "512kb", + "receive_predictor_max": "512kb", + "receive_predictor_min": "512kb", + "boss_count": "1", + "max_cumulation_buffer_capacity": "-1b" + }, + "type.default": "netty4" + }, + "script": { + "cache": { + "max_size": "100", + "expire": "0ms" + }, + "painless": { + "regex": { + "enabled": "false" + } + }, + "legacy": { + "default_lang": "groovy" + }, + "max_size_in_bytes": "65535", + "update": "false", + "max_compilations_per_minute": "15", + "ingest": "false", + "search": "false", + "file": "true", + "inline": "false", + "auto_reload_enabled": "true", + "engine": { + "painless": { + "file.ingest": "true", + "file.update": "true", + "file.aggs": "true", + "inline.ingest": "true", + "file": "true", + "inline": "true", + "inline.update": "true", + "stored.search": "true", + "inline.aggs": "true", + "file.search": "true", + "stored": "true", + "stored.ingest": "true", + "stored.aggs": "true", + "stored.update": "true", + "inline.search": "true" + }, + "expression": { + "file.ingest": "true", + "file.update": "true", + "file.aggs": "true", + "inline.ingest": "true", + "file": "true", + "inline": "true", + "inline.update": "true", + "stored.search": "true", + "inline.aggs": "true", + "file.search": "true", + "stored": "true", + "stored.ingest": "true", + "stored.aggs": "true", + "stored.update": "true", + "inline.search": "true" + }, + "groovy": { + "file.ingest": "true", + "file.update": "true", + "file.aggs": "true", + "inline.ingest": "false", + "file": "true", + "inline": "false", + "inline.update": "false", + "stored.search": "false", + "inline.aggs": "false", + "file.search": "true", + "stored": "false", + "stored.ingest": "false", + "stored.aggs": "false", + "stored.update": "false", + "inline.search": "false" + }, + "mustache": { + "file.ingest": "true", + "file.update": "true", + "file.aggs": "true", + "inline.ingest": "true", + "file": "true", + "inline": "true", + "inline.update": "true", + "stored.search": "true", + "inline.aggs": "true", + "file.search": "true", + "stored": "true", + "stored.ingest": "true", + "stored.aggs": "true", + "stored.update": "true", + "inline.search": "true" + } + }, + "stored": "false", + "aggs": "false" + }, + "node": { + "data": "true", + "enable_lucene_segment_infos_trace": "false", + "local_storage": "true", + "max_local_storage_nodes": "1", + "name": "DK8-2Lc", + "id": { + "seed": "0" + }, + "add_lock_id_to_custom_path": "true", + "portsfile": "false", + "ingest": "true", + "master": "true" + }, + "indices": { + "cache": { + "cleanup_interval": "1m" + }, + "mapping": { + "dynamic_timeout": "30s" + }, + "memory": { + "interval": "5s", + "max_index_buffer_size": "-1b", + "shard_inactive_time": "5m", + "index_buffer_size": "10%", + "min_index_buffer_size": "48mb" + }, + "breaker": { + "request": { + "limit": "60%", + "type": "memory", + "overhead": "1.0" + }, + "total": { + "limit": "70%" + }, + "fielddata": { + "limit": "60%", + "type": "memory", + "overhead": "1.03" + }, + "type": "hierarchy" + }, + "fielddata": { + "cache": { + "size": "-1b" + } + }, + "query": { + "bool": { + "max_clause_count": "1024" + }, + "query_string": { + "analyze_wildcard": "false", + "allowLeadingWildcard": "true" + } + }, + "recovery": { + "recovery_activity_timeout": "1800000ms", + "retry_delay_network": "5s", + "internal_action_timeout": "15m", + "retry_delay_state_sync": "500ms", + "internal_action_long_timeout": "1800000ms", + "max_bytes_per_sec": "40mb" + }, + "requests": { + "cache": { + "size": "1%", + "expire": "0ms" + } + }, + "store": { + "delete": { + "shard": { + "timeout": "30s" + } + }, + "throttle": { + "type": "NONE", + "max_bytes_per_sec": "0b" + } + }, + "analysis": { + "hunspell": { + "dictionary": { + "ignore_case": "false", + "lazy": "false" + } + } + }, + "queries": { + "cache": { + "count": "10000", + "size": "10%", + "all_segments": "false" + } + }, + "ttl": { + "interval": "60s" + } + }, + "discovery": { + "type": "zen", + "zen": { + "commit_timeout": "30s", + "no_master_block": "write", + "join_retry_delay": "100ms", + "join_retry_attempts": "3", + "ping": { + "unicast": { + "concurrent_connects": "10", + "hosts": { + "resolve_timeout": "5s" + } + } + }, + "master_election": { + "ignore_non_master_pings": "false", + "wait_for_joins_timeout": "30000ms" + }, + "send_leave_request": "true", + "ping_timeout": "3s", + "join_timeout": "60000ms", + "publish_diff": { + "enable": "true" + }, + "minimum_master_nodes": "-1", + "hosts_provider": null, + "publish_timeout": "30s", + "fd": { + "connect_on_network_disconnect": "false", + "ping_interval": "1s", + "ping_retries": "3", + "register_connection_listener": "true", + "ping_timeout": "30s" + }, + "max_pings_from_another_master": "3" + }, + "initial_state_timeout": "30s" + }, + "tribe": { + "name": "", + "on_conflict": "any", + "blocks": { + "write": "false", + "metadata": "false" + } + }, + "http": { + "tcp": { + "reuse_address": "true", + "keep_alive": "true", + "blocking_server": "false", + "receive_buffer_size": "-1b", + "send_buffer_size": "-1b" + }, + "bind_host": [ + "0.0.0.0" + ], + "cors": { + "max-age": "1728000", + "allow-origin": "", + "allow-headers": "X-Requested-With,Content-Type,Content-Length", + "allow-credentials": "false", + "allow-methods": "OPTIONS,HEAD,GET,POST,PUT,DELETE", + "enabled": "false" + }, + "max_chunk_size": "8kb", + "compression_level": "3", + "reset_cookies": "false", + "max_initial_line_length": "4kb", + "type": "", + "pipelining": "true", + "enabled": "true", + "type.default": "netty4", + "detailed_errors": { + "enabled": "true" + }, + "content_type": { + "required": "false" + }, + "port": "9200-9300", + "host": [ + "0.0.0.0" + ], + "publish_port": "-1", + "max_header_size": "8kb", + "pipelining.max_events": "10000", + "tcp_no_delay": "true", + "compression": "true", + "publish_host": [ + "0.0.0.0" + ], + "max_content_length": "100mb", + "netty": { + "receive_predictor_size": "64kb", + "max_composite_buffer_components": "-1", + "receive_predictor_max": "64kb", + "worker_count": "8", + "receive_predictor_min": "64kb", + "max_cumulation_buffer_capacity": "-1b" + } + }, + "gateway": { + "recover_after_master_nodes": "0", + "expected_nodes": "-1", + "recover_after_data_nodes": "-1", + "initial_shards": "quorum", + "expected_data_nodes": "-1", + "recover_after_time": "0ms", + "expected_master_nodes": "-1", + "recover_after_nodes": "-1" + } + } +} diff --git a/fixtures/settings-7.3.0.json b/fixtures/settings-7.3.0.json new file mode 100644 index 00000000..94be09d1 --- /dev/null +++ b/fixtures/settings-7.3.0.json @@ -0,0 +1,1096 @@ +{ + "persistent": {}, + "transient": {}, + "defaults": { + "cluster": { + "max_voting_config_exclusions": "10", + "auto_shrink_voting_configuration": "true", + "election": { + "duration": "500ms", + "initial_timeout": "100ms", + "max_timeout": "10s", + "back_off_time": "100ms", + "strategy": "supports_voting_only" + }, + "no_master_block": "write", + "persistent_tasks": { + "allocation": { + "enable": "all", + "recheck_interval": "30s" + } + }, + "blocks": { + "read_only_allow_delete": "false", + "read_only": "false" + }, + "remote": { + "node": { + "attr": "" + }, + "initial_connect_timeout": "30s", + "connect": "true", + "connections_per_cluster": "3" + }, + "follower_lag": { + "timeout": "90000ms" + }, + "routing": { + "use_adaptive_replica_selection": "true", + "rebalance": { + "enable": "all" + }, + "allocation": { + "node_concurrent_incoming_recoveries": "2", + "node_initial_primaries_recoveries": "4", + "same_shard": { + "host": "false" + }, + "total_shards_per_node": "-1", + "type": "balanced", + "disk": { + "threshold_enabled": "false", + "watermark": { + "low": "0.85", + "flood_stage": "0.95", + "high": "0.9" + }, + "include_relocations": "true", + "reroute_interval": "60s" + }, + "awareness": { + "attributes": [] + }, + "balance": { + "index": "0.55", + "threshold": "1.0", + "shard": "0.45" + }, + "enable": "all", + "node_concurrent_outgoing_recoveries": "2", + "allow_rebalance": "indices_all_active", + "cluster_concurrent_rebalance": "2", + "node_concurrent_recoveries": "2" + } + }, + "indices": { + "tombstones": { + "size": "500" + }, + "close": { + "enable": "true" + } + }, + "nodes": { + "reconnect_interval": "10s" + }, + "service": { + "slow_task_logging_threshold": "30s" + }, + "publish": { + "timeout": "30000ms" + }, + "name": "docker-cluster", + "fault_detection": { + "leader_check": { + "interval": "1000ms", + "timeout": "10000ms", + "retry_count": "3" + }, + "follower_check": { + "interval": "1000ms", + "timeout": "10000ms", + "retry_count": "3" + } + }, + "join": { + "timeout": "60000ms" + }, + "max_shards_per_node": "1000", + "initial_master_nodes": [], + "info": { + "update": { + "interval": "30s", + "timeout": "15s" + } + } + }, + "no": { + "model": { + "state": { + "persist": "false" + } + } + }, + "logger": { + "level": "INFO" + }, + "data_frame": { + "task_thread_pool": { + "queue_size": "4", + "size": "4" + } + }, + "bootstrap": { + "memory_lock": "false", + "system_call_filter": "true", + "ctrlhandler": "true" + }, + "processors": "8", + "ingest": { + "geoip": { + "cache_size": "1000" + }, + "grok": { + "watchdog": { + "max_execution_time": "1s", + "interval": "1s" + } + } + }, + "network": { + "host": [ + "0.0.0.0" + ], + "tcp": { + "reuse_address": "true", + "keep_alive": "true", + "connect_timeout": "30s", + "receive_buffer_size": "-1b", + "no_delay": "true", + "send_buffer_size": "-1b" + }, + "bind_host": [ + "0.0.0.0" + ], + "server": "true", + "breaker": { + "inflight_requests": { + "limit": "100%", + "overhead": "2.0" + } + }, + "publish_host": [ + "0.0.0.0" + ] + }, + "pidfile": "", + "path": { + "data": [], + "logs": "/usr/share/elasticsearch/logs", + "shared_data": "", + "home": "/usr/share/elasticsearch", + "repo": [] + }, + "search": { + "default_search_timeout": "-1", + "highlight": { + "term_vector_multi_value": "true" + }, + "default_allow_partial_results": "true", + "max_open_scroll_context": "500", + "max_buckets": "10000", + "low_level_cancellation": "true", + "keep_alive_interval": "1m", + "remote": { + "node": { + "attr": "" + }, + "initial_connect_timeout": "30s", + "connect": "true", + "connections_per_cluster": "3" + }, + "default_keep_alive": "5m", + "max_keep_alive": "24h" + }, + "security": { + "manager": { + "filter_bad_defaults": "true" + } + }, + "ccr": { + "wait_for_metadata_timeout": "60s", + "indices": { + "recovery": { + "recovery_activity_timeout": "60s", + "chunk_size": "1mb", + "internal_action_timeout": "60s", + "max_bytes_per_sec": "40mb", + "max_concurrent_file_chunks": "5" + } + }, + "auto_follow": { + "wait_for_metadata_timeout": "60s" + } + }, + "repositories": { + "fs": { + "compress": "false", + "chunk_size": "9223372036854775807b", + "location": "" + }, + "url": { + "supported_protocols": [ + "http", + "https", + "ftp", + "file", + "jar" + ], + "allowed_urls": [], + "url": "http:" + } + }, + "action": { + "auto_create_index": "true", + "search": { + "shard_count": { + "limit": "9223372036854775807" + } + }, + "destructive_requires_name": "false" + }, + "client": { + "type": "node", + "transport": { + "ignore_cluster_name": "false", + "nodes_sampler_interval": "5s", + "sniff": "false", + "ping_timeout": "5s" + } + }, + "xpack": { + "flattened": { + "enabled": "true" + }, + "watcher": { + "execution": { + "scroll": { + "size": "0", + "timeout": "" + }, + "default_throttle_period": "5s" + }, + "internal": { + "ops": { + "bulk": { + "default_timeout": "" + }, + "index": { + "default_timeout": "" + }, + "search": { + "default_timeout": "" + } + } + }, + "thread_pool": { + "queue_size": "1000", + "size": "40" + }, + "index": { + "rest": { + "direct_access": "" + } + }, + "history": { + "cleaner_service": { + "enabled": "true" + } + }, + "trigger": { + "schedule": { + "ticker": { + "tick_interval": "500ms" + } + } + }, + "enabled": "true", + "input": { + "search": { + "default_timeout": "" + } + }, + "encrypt_sensitive_data": "false", + "transform": { + "search": { + "default_timeout": "" + } + }, + "stop": { + "timeout": "30s" + }, + "watch": { + "scroll": { + "size": "0" + } + }, + "bulk": { + "concurrent_requests": "0", + "flush_interval": "1s", + "size": "1mb", + "actions": "1" + }, + "actions": { + "bulk": { + "default_timeout": "" + }, + "index": { + "default_timeout": "" + } + } + }, + "data_frame": { + "enabled": "true" + }, + "ilm": { + "enabled": "true" + }, + "monitoring": { + "collection": { + "cluster": { + "stats": { + "timeout": "10s" + } + }, + "node": { + "stats": { + "timeout": "10s" + } + }, + "indices": [], + "ccr": { + "stats": { + "timeout": "10s" + } + }, + "index": { + "stats": { + "timeout": "10s" + }, + "recovery": { + "active_only": "false", + "timeout": "10s" + } + }, + "interval": "10s", + "enabled": "false", + "ml": { + "job": { + "stats": { + "timeout": "10s" + } + } + } + }, + "history": { + "duration": "168h" + }, + "elasticsearch": { + "collection": { + "enabled": "true" + } + }, + "enabled": "true" + }, + "graph": { + "enabled": "true" + }, + "rollup": { + "enabled": "true", + "task_thread_pool": { + "queue_size": "4", + "size": "4" + } + }, + "sql": { + "enabled": "true" + }, + "license": { + "self_generated": { + "type": "basic" + } + }, + "logstash": { + "enabled": "true" + }, + "notification": { + "pagerduty": { + "default_account": "" + }, + "email": { + "default_account": "", + "html": { + "sanitization": { + "allow": [ + "body", + "head", + "_tables", + "_links", + "_blocks", + "_formatting", + "img:embedded" + ], + "disallow": [], + "enabled": "true" + } + } + }, + "reporting": { + "retries": "40", + "interval": "15s" + }, + "jira": { + "default_account": "" + }, + "slack": { + "default_account": "" + } + }, + "security": { + "dls_fls": { + "enabled": "true" + }, + "dls": { + "bitset": { + "cache": { + "size": "50mb", + "ttl": "168h" + } + } + }, + "transport": { + "filter": { + "allow": [], + "deny": [], + "enabled": "true" + }, + "ssl": { + "enabled": "false" + } + }, + "enabled": "true", + "filter": { + "always_allow_bound_address": "true" + }, + "encryption": { + "algorithm": "AES/CTR/NoPadding" + }, + "audit": { + "enabled": "false", + "logfile": { + "emit_node_id": "true", + "emit_node_host_name": "false", + "emit_node_name": "false", + "events": { + "emit_request_body": "false", + "include": [ + "ACCESS_DENIED", + "ACCESS_GRANTED", + "ANONYMOUS_ACCESS_DENIED", + "AUTHENTICATION_FAILED", + "CONNECTION_DENIED", + "TAMPERED_REQUEST", + "RUN_AS_DENIED", + "RUN_AS_GRANTED" + ], + "exclude": [] + }, + "emit_node_host_address": "false" + } + }, + "authc": { + "password_hashing": { + "algorithm": "bcrypt" + }, + "success_cache": { + "size": "10000", + "enabled": "true", + "expire_after_access": "1h" + }, + "api_key": { + "cache": { + "hash_algo": "ssha256", + "max_keys": "10000", + "ttl": "24h" + }, + "delete": { + "interval": "24h", + "timeout": "-1" + }, + "enabled": "false", + "hashing": { + "algorithm": "pbkdf2" + } + }, + "anonymous": { + "authz_exception": "true", + "roles": [], + "username": "_anonymous" + }, + "run_as": { + "enabled": "true" + }, + "reserved_realm": { + "enabled": "true" + }, + "token": { + "delete": { + "interval": "30m", + "timeout": "-1" + }, + "enabled": "false", + "thread_pool": { + "queue_size": "1000", + "size": "1" + }, + "timeout": "20m" + } + }, + "fips_mode": { + "enabled": "false" + }, + "encryption_key": { + "length": "128", + "algorithm": "AES" + }, + "http": { + "filter": { + "allow": [], + "deny": [], + "enabled": "true" + }, + "ssl": { + "enabled": "false" + } + }, + "automata": { + "max_determinized_states": "100000", + "cache": { + "size": "10000", + "ttl": "48h", + "enabled": "true" + } + }, + "user": null, + "authz": { + "store": { + "roles": { + "index": { + "cache": { + "ttl": "20m", + "max_size": "10000" + } + }, + "cache": { + "max_size": "10000" + }, + "negative_lookup_cache": { + "max_size": "10000" + }, + "field_permissions": { + "cache": { + "max_size_in_bytes": "104857600" + } + } + } + } + } + }, + "vectors": { + "enabled": "true" + }, + "ccr": { + "enabled": "true", + "ccr_thread_pool": { + "queue_size": "100", + "size": "32" + } + }, + "http": { + "default_connection_timeout": "10s", + "proxy": { + "host": "", + "scheme": "", + "port": "0" + }, + "whitelist": [ + "*" + ], + "default_read_timeout": "10s", + "max_response_size": "10mb" + }, + "ml": { + "utility_thread_pool": { + "core": "1", + "max": "2048", + "keep_alive": "10m" + }, + "max_anomaly_records": "500", + "enable_config_migration": "true", + "max_open_jobs": "20", + "min_disk_space_off_heap": "5gb", + "node_concurrent_job_allocations": "2", + "max_model_memory_limit": "0b", + "enabled": "true", + "max_lazy_ml_nodes": "0", + "max_machine_memory_percent": "30", + "autodetect_process": "true", + "datafeed_thread_pool": { + "core": "1", + "max": "512", + "keep_alive": "1m" + }, + "process_connect_timeout": "10s", + "job_comms_thread_pool": { + "core": "4", + "max": "2048", + "keep_alive": "1m" + } + } + }, + "rest": { + "action": { + "multi": { + "allow_explicit_index": "true" + } + } + }, + "cache": { + "recycler": { + "page": { + "limit": { + "heap": "10%" + }, + "type": "CONCURRENT", + "weight": { + "longs": "1.0", + "ints": "1.0", + "bytes": "1.0", + "objects": "0.1" + } + } + } + }, + "reindex": { + "remote": { + "whitelist": [] + } + }, + "resource": { + "reload": { + "enabled": "true", + "interval": { + "low": "60s", + "high": "5s", + "medium": "30s" + } + } + }, + "thread_pool": { + "force_merge": { + "queue_size": "-1", + "size": "1" + }, + "fetch_shard_started": { + "core": "1", + "max": "16", + "keep_alive": "5m" + }, + "listener": { + "queue_size": "-1", + "size": "4" + }, + "refresh": { + "core": "1", + "max": "4", + "keep_alive": "5m" + }, + "generic": { + "core": "4", + "max": "128", + "keep_alive": "30s" + }, + "warmer": { + "core": "1", + "max": "4", + "keep_alive": "5m" + }, + "search": { + "max_queue_size": "1000", + "queue_size": "1000", + "size": "13", + "auto_queue_frame_size": "2000", + "target_response_time": "1s", + "min_queue_size": "1000" + }, + "fetch_shard_store": { + "core": "1", + "max": "16", + "keep_alive": "5m" + }, + "flush": { + "core": "1", + "max": "4", + "keep_alive": "5m" + }, + "management": { + "core": "1", + "max": "5", + "keep_alive": "5m" + }, + "analyze": { + "queue_size": "16", + "size": "1" + }, + "get": { + "queue_size": "1000", + "size": "8" + }, + "estimated_time_interval": "200ms", + "write": { + "queue_size": "200", + "size": "8" + }, + "snapshot": { + "core": "1", + "max": "4", + "keep_alive": "5m" + }, + "search_throttled": { + "max_queue_size": "100", + "queue_size": "100", + "size": "1", + "auto_queue_frame_size": "200", + "target_response_time": "1s", + "min_queue_size": "100" + } + }, + "index": { + "codec": "default", + "store": { + "type": "", + "fs": { + "fs_lock": "native" + }, + "preload": [] + } + }, + "monitor": { + "jvm": { + "gc": { + "enabled": "true", + "overhead": { + "warn": "50", + "debug": "10", + "info": "25" + }, + "refresh_interval": "1s" + }, + "refresh_interval": "1s" + }, + "process": { + "refresh_interval": "1s" + }, + "os": { + "refresh_interval": "1s" + }, + "fs": { + "refresh_interval": "1s" + } + }, + "transport": { + "tcp": { + "reuse_address": "true", + "connect_timeout": "30s", + "compress": "false", + "port": "9300-9400", + "no_delay": "true", + "keep_alive": "true", + "receive_buffer_size": "-1b", + "send_buffer_size": "-1b" + }, + "bind_host": [], + "connect_timeout": "30s", + "compress": "false", + "ping_schedule": "-1", + "connections_per_node": { + "recovery": "2", + "state": "1", + "bulk": "3", + "reg": "6", + "ping": "1" + }, + "tracer": { + "include": [], + "exclude": [ + "internal:discovery/zen/fd*", + "internal:coordination/fault_detection/*", + "cluster:monitor/nodes/liveness" + ] + }, + "type": "security4", + "type.default": "netty4", + "features": { + "x-pack": "true" + }, + "port": "9300-9400", + "host": [], + "publish_port": "-1", + "tcp_no_delay": "true", + "publish_host": [], + "netty": { + "receive_predictor_size": "64kb", + "receive_predictor_max": "64kb", + "worker_count": "16", + "receive_predictor_min": "64kb", + "boss_count": "1" + } + }, + "script": { + "allowed_contexts": [], + "max_compilations_rate": "75/5m", + "cache": { + "max_size": "100", + "expire": "0ms" + }, + "painless": { + "regex": { + "enabled": "false" + } + }, + "max_size_in_bytes": "65535", + "allowed_types": [] + }, + "node": { + "data": "true", + "max_local_storage_nodes": "1", + "store": { + "allow_mmap": "true" + }, + "ingest": "true", + "master": "true", + "enable_lucene_segment_infos_trace": "false", + "local_storage": "true", + "name": "2c26cd7c415b", + "id": { + "seed": "0" + }, + "voting_only": "false", + "attr": { + "xpack": { + "installed": "true" + }, + "ml": { + "machine_memory": "8255340544", + "max_open_jobs": "20" + } + }, + "portsfile": "false", + "ml": "true" + }, + "indices": { + "lifecycle": { + "poll_interval": "10m" + }, + "cache": { + "cleanup_interval": "1m" + }, + "mapping": { + "dynamic_timeout": "30s" + }, + "memory": { + "interval": "5s", + "max_index_buffer_size": "-1", + "shard_inactive_time": "5m", + "index_buffer_size": "10%", + "min_index_buffer_size": "48mb" + }, + "breaker": { + "request": { + "limit": "60%", + "type": "memory", + "overhead": "1.0" + }, + "total": { + "limit": "95%", + "use_real_memory": "true" + }, + "accounting": { + "limit": "100%", + "overhead": "1.0" + }, + "fielddata": { + "limit": "40%", + "type": "memory", + "overhead": "1.03" + }, + "type": "hierarchy" + }, + "fielddata": { + "cache": { + "size": "-1b" + } + }, + "query": { + "bool": { + "max_clause_count": "1024" + }, + "query_string": { + "analyze_wildcard": "false", + "allowLeadingWildcard": "true" + } + }, + "recovery": { + "recovery_activity_timeout": "1800000ms", + "retry_delay_network": "5s", + "internal_action_timeout": "15m", + "retry_delay_state_sync": "500ms", + "internal_action_long_timeout": "1800000ms", + "max_bytes_per_sec": "40mb", + "max_concurrent_file_chunks": "2" + }, + "requests": { + "cache": { + "size": "1%", + "expire": "0ms" + } + }, + "store": { + "delete": { + "shard": { + "timeout": "30s" + } + } + }, + "analysis": { + "hunspell": { + "dictionary": { + "ignore_case": "false", + "lazy": "false" + } + } + }, + "queries": { + "cache": { + "count": "10000", + "size": "10%", + "all_segments": "false" + } + } + }, + "plugin": { + "mandatory": [] + }, + "discovery": { + "seed_hosts": [], + "unconfigured_bootstrap_timeout": "3s", + "request_peers_timeout": "3000ms", + "zen": { + "commit_timeout": "30s", + "no_master_block": "write", + "join_retry_delay": "100ms", + "join_retry_attempts": "3", + "ping": { + "unicast": { + "concurrent_connects": "10", + "hosts": [], + "hosts.resolve_timeout": "5s" + } + }, + "master_election": { + "ignore_non_master_pings": "false", + "wait_for_joins_timeout": "30000ms" + }, + "send_leave_request": "true", + "ping_timeout": "3s", + "bwc_ping_timeout": "3s", + "join_timeout": "60000ms", + "publish_diff": { + "enable": "true" + }, + "publish": { + "max_pending_cluster_states": "25" + }, + "minimum_master_nodes": "-1", + "unsafe_rolling_upgrades_enabled": "true", + "hosts_provider": [], + "publish_timeout": "30s", + "fd": { + "connect_on_network_disconnect": "false", + "ping_interval": "1s", + "ping_retries": "3", + "register_connection_listener": "true", + "ping_timeout": "30s" + }, + "max_pings_from_another_master": "3" + }, + "initial_state_timeout": "30s", + "cluster_formation_warning_timeout": "10000ms", + "seed_providers": [], + "type": "single-node", + "seed_resolver": { + "max_concurrent_resolvers": "10", + "timeout": "5s" + }, + "find_peers_interval": "1000ms" + }, + "http": { + "tcp": { + "reuse_address": "true", + "keep_alive": "true", + "receive_buffer_size": "-1b", + "no_delay": "true", + "send_buffer_size": "-1b" + }, + "bind_host": [], + "cors": { + "max-age": "1728000", + "allow-origin": "", + "allow-headers": "X-Requested-With,Content-Type,Content-Length", + "allow-credentials": "false", + "allow-methods": "OPTIONS,HEAD,GET,POST,PUT,DELETE", + "enabled": "false" + }, + "max_chunk_size": "8kb", + "compression_level": "3", + "reset_cookies": "false", + "max_initial_line_length": "4kb", + "max_warning_header_count": "-1", + "type": "security4", + "pipelining": { + "max_events": "10000" + }, + "max_warning_header_size": "-1b", + "type.default": "netty4", + "detailed_errors": { + "enabled": "true" + }, + "content_type": { + "required": "true" + }, + "port": "9200-9300", + "host": [], + "publish_port": "-1", + "max_header_size": "8kb", + "tcp_no_delay": "true", + "compression": "true", + "read_timeout": "0ms", + "publish_host": [], + "max_content_length": "100mb", + "netty": { + "receive_predictor_size": "64kb", + "max_composite_buffer_components": "69905", + "worker_count": "16" + } + }, + "gateway": { + "recover_after_master_nodes": "0", + "expected_nodes": "-1", + "recover_after_data_nodes": "-1", + "expected_data_nodes": "-1", + "recover_after_time": "0ms", + "expected_master_nodes": "-1", + "recover_after_nodes": "-1" + } + } +} diff --git a/fixtures/settings-merge-5.4.2.json b/fixtures/settings-merge-5.4.2.json new file mode 100644 index 00000000..2d6e0909 --- /dev/null +++ b/fixtures/settings-merge-5.4.2.json @@ -0,0 +1,668 @@ +{ + "persistent": {}, + "transient": { + "cluster": { + "routing": { + "allocation": { + "enable": "ALL" + } + } + } + }, + "defaults": { + "cluster": { + "routing": { + "rebalance": { + "enable": "ALL" + }, + "none": { + "node_concurrent_incoming_recoveries": "2", + "node_initial_primaries_recoveries": "4", + "same_shard": { + "host": "false" + }, + "total_shards_per_node": "-1", + "type": "balanced", + "disk": { + "threshold_enabled": "true", + "watermark": { + "low": "85%", + "high": "90%" + }, + "include_relocations": "true", + "reroute_interval": "60s" + }, + "awareness": { + "attributes": "" + }, + "balance": { + "index": "0.55", + "threshold": "1.0", + "shard": "0.45" + }, + "node_concurrent_outgoing_recoveries": "2", + "allow_rebalance": "indices_all_active", + "cluster_concurrent_rebalance": "2", + "node_concurrent_recoveries": "2", + "snapshot": { + "relocation_enabled": "false" + } + } + }, + "indices": { + "close": { + "enable": "true" + } + }, + "nodes": { + "reconnect_interval": "10s" + }, + "blocks": { + "read_only": "false" + }, + "service": { + "slow_task_logging_threshold": "30s" + }, + "name": "elasticsearch", + "info": { + "update": { + "interval": "30s", + "timeout": "15s" + } + } + }, + "logger": { + "level": "INFO" + }, + "bootstrap": { + "ctrlhandler": "true", + "memory_lock": "false", + "system_call_filter": "true", + "seccomp": "true" + }, + "processors": "4", + "network": { + "host": [ + "_local_" + ], + "tcp": { + "reuse_address": "true", + "connect_timeout": "30s", + "blocking": "false", + "blocking_server": "false", + "no_delay": "true", + "blocking_client": "false", + "keep_alive": "true", + "receive_buffer_size": "-1b", + "send_buffer_size": "-1b" + }, + "bind_host": [ + "_local_" + ], + "server": "true", + "breaker": { + "inflight_requests": { + "limit": "100%", + "overhead": "1.0" + } + }, + "publish_host": [ + "_local_" + ] + }, + "pidfile": "", + "path": { + "conf": "", + "scripts": "", + "logs": "/usr/share/elasticsearch/logs", + "shared_data": "", + "home": "/usr/share/elasticsearch" + }, + "default": { + "path": { + "logs": "", + "conf": "" + } + }, + "search": { + "default_search_timeout": "-1", + "highlight": { + "term_vector_multi_value": "true" + }, + "low_level_cancellation": "false", + "keep_alive_interval": "1m", + "remote": { + "node": { + "attr": "" + }, + "initial_connect_timeout": "30s", + "connect": "true", + "connections_per_cluster": "3" + }, + "default_keep_alive": "5m" + }, + "security": { + "manager": { + "filter_bad_defaults": "true" + } + }, + "repositories": { + "fs": { + "compress": "false", + "chunk_size": "-1b", + "location": "" + }, + "url": { + "supported_protocols": [ + "http", + "https", + "ftp", + "file", + "jar" + ], + "url": "http:" + } + }, + "action": { + "auto_create_index": "true", + "search": { + "shard_count": { + "limit": "9223372036854775807" + } + }, + "destructive_requires_name": "false", + "master": { + "force_local": "false" + } + }, + "client": { + "type": "node", + "transport": { + "ignore_cluster_name": "false", + "nodes_sampler_interval": "5s", + "sniff": "false", + "ping_timeout": "5s" + } + }, + "rest": { + "action": { + "multi": { + "allow_explicit_index": "true" + } + } + }, + "cache": { + "recycler": { + "page": { + "limit": { + "heap": "10%" + }, + "type": "CONCURRENT", + "weight": { + "longs": "1.0", + "ints": "1.0", + "bytes": "1.0", + "objects": "0.1" + } + } + } + }, + "resource": { + "reload": { + "enabled": "true", + "interval": { + "low": "60s", + "high": "5s", + "medium": "30s" + } + } + }, + "thread_pool": { + "force_merge": { + "queue_size": "-1", + "size": "1" + }, + "fetch_shard_started": { + "core": "1", + "max": "8", + "keep_alive": "5m" + }, + "listener": { + "queue_size": "-1", + "size": "2" + }, + "index": { + "queue_size": "200", + "size": "4" + }, + "refresh": { + "core": "1", + "max": "2", + "keep_alive": "5m" + }, + "generic": { + "core": "4", + "max": "128", + "keep_alive": "30s" + }, + "warmer": { + "core": "1", + "max": "2", + "keep_alive": "5m" + }, + "search": { + "queue_size": "1000", + "size": "7" + }, + "fetch_shard_store": { + "core": "1", + "max": "8", + "keep_alive": "5m" + }, + "flush": { + "core": "1", + "max": "2", + "keep_alive": "5m" + }, + "management": { + "core": "1", + "max": "5", + "keep_alive": "5m" + }, + "get": { + "queue_size": "1000", + "size": "4" + }, + "bulk": { + "queue_size": "200", + "size": "4" + }, + "estimated_time_interval": "200ms", + "snapshot": { + "core": "1", + "max": "2", + "keep_alive": "5m" + } + }, + "index": { + "codec": "default", + "store": { + "type": "", + "fs": { + "fs_lock": "native" + } + } + }, + "monitor": { + "jvm": { + "gc": { + "enabled": "true", + "overhead": { + "warn": "50", + "debug": "10", + "info": "25" + }, + "refresh_interval": "1s" + }, + "refresh_interval": "1s" + }, + "process": { + "refresh_interval": "1s" + }, + "os": { + "refresh_interval": "1s" + }, + "fs": { + "refresh_interval": "1s" + } + }, + "transport": { + "tcp": { + "reuse_address": "true", + "connect_timeout": "30s", + "compress": "false", + "port": "9300-9400", + "blocking_server": "false", + "blocking_client": "false", + "keep_alive": "true", + "receive_buffer_size": "-1b", + "send_buffer_size": "-1b" + }, + "ping_schedule": "-1", + "publish_port": "-1", + "connections_per_node": { + "recovery": "2", + "state": "1", + "bulk": "3", + "reg": "6", + "ping": "1" + }, + "tcp_no_delay": "true", + "tracer": { + "exclude": [ + "internal:discovery/zen/fd*", + "cluster:monitor/nodes/liveness" + ] + }, + "type": "", + "netty": { + "max_composite_buffer_components": "-1", + "worker_count": "8", + "receive_predictor_size": "512kb", + "receive_predictor_max": "512kb", + "receive_predictor_min": "512kb", + "boss_count": "1", + "max_cumulation_buffer_capacity": "-1b" + }, + "type.default": "netty4" + }, + "script": { + "cache": { + "max_size": "100", + "expire": "0ms" + }, + "painless": { + "regex": { + "enabled": "false" + } + }, + "legacy": { + "default_lang": "groovy" + }, + "max_size_in_bytes": "65535", + "update": "false", + "max_compilations_per_minute": "15", + "ingest": "false", + "search": "false", + "file": "true", + "inline": "false", + "auto_reload_enabled": "true", + "engine": { + "painless": { + "file.ingest": "true", + "file.update": "true", + "file.aggs": "true", + "inline.ingest": "true", + "file": "true", + "inline": "true", + "inline.update": "true", + "stored.search": "true", + "inline.aggs": "true", + "file.search": "true", + "stored": "true", + "stored.ingest": "true", + "stored.aggs": "true", + "stored.update": "true", + "inline.search": "true" + }, + "expression": { + "file.ingest": "true", + "file.update": "true", + "file.aggs": "true", + "inline.ingest": "true", + "file": "true", + "inline": "true", + "inline.update": "true", + "stored.search": "true", + "inline.aggs": "true", + "file.search": "true", + "stored": "true", + "stored.ingest": "true", + "stored.aggs": "true", + "stored.update": "true", + "inline.search": "true" + }, + "groovy": { + "file.ingest": "true", + "file.update": "true", + "file.aggs": "true", + "inline.ingest": "false", + "file": "true", + "inline": "false", + "inline.update": "false", + "stored.search": "false", + "inline.aggs": "false", + "file.search": "true", + "stored": "false", + "stored.ingest": "false", + "stored.aggs": "false", + "stored.update": "false", + "inline.search": "false" + }, + "mustache": { + "file.ingest": "true", + "file.update": "true", + "file.aggs": "true", + "inline.ingest": "true", + "file": "true", + "inline": "true", + "inline.update": "true", + "stored.search": "true", + "inline.aggs": "true", + "file.search": "true", + "stored": "true", + "stored.ingest": "true", + "stored.aggs": "true", + "stored.update": "true", + "inline.search": "true" + } + }, + "stored": "false", + "aggs": "false" + }, + "node": { + "data": "true", + "enable_lucene_segment_infos_trace": "false", + "local_storage": "true", + "max_local_storage_nodes": "1", + "name": "DK8-2Lc", + "id": { + "seed": "0" + }, + "add_lock_id_to_custom_path": "true", + "portsfile": "false", + "ingest": "true", + "master": "true" + }, + "indices": { + "cache": { + "cleanup_interval": "1m" + }, + "mapping": { + "dynamic_timeout": "30s" + }, + "memory": { + "interval": "5s", + "max_index_buffer_size": "-1b", + "shard_inactive_time": "5m", + "index_buffer_size": "10%", + "min_index_buffer_size": "48mb" + }, + "breaker": { + "request": { + "limit": "60%", + "type": "memory", + "overhead": "1.0" + }, + "total": { + "limit": "70%" + }, + "fielddata": { + "limit": "60%", + "type": "memory", + "overhead": "1.03" + }, + "type": "hierarchy" + }, + "fielddata": { + "cache": { + "size": "-1b" + } + }, + "query": { + "bool": { + "max_clause_count": "1024" + }, + "query_string": { + "analyze_wildcard": "false", + "allowLeadingWildcard": "true" + } + }, + "recovery": { + "recovery_activity_timeout": "1800000ms", + "retry_delay_network": "5s", + "internal_action_timeout": "15m", + "retry_delay_state_sync": "500ms", + "internal_action_long_timeout": "1800000ms", + "max_bytes_per_sec": "40mb" + }, + "requests": { + "cache": { + "size": "1%", + "expire": "0ms" + } + }, + "store": { + "delete": { + "shard": { + "timeout": "30s" + } + }, + "throttle": { + "type": "NONE", + "max_bytes_per_sec": "0b" + } + }, + "analysis": { + "hunspell": { + "dictionary": { + "ignore_case": "false", + "lazy": "false" + } + } + }, + "queries": { + "cache": { + "count": "10000", + "size": "10%", + "all_segments": "false" + } + }, + "ttl": { + "interval": "60s" + } + }, + "discovery": { + "type": "zen", + "zen": { + "commit_timeout": "30s", + "no_master_block": "write", + "join_retry_delay": "100ms", + "join_retry_attempts": "3", + "ping": { + "unicast": { + "concurrent_connects": "10", + "hosts": { + "resolve_timeout": "5s" + } + } + }, + "master_election": { + "ignore_non_master_pings": "false", + "wait_for_joins_timeout": "30000ms" + }, + "send_leave_request": "true", + "ping_timeout": "3s", + "join_timeout": "60000ms", + "publish_diff": { + "enable": "true" + }, + "minimum_master_nodes": "-1", + "hosts_provider": null, + "publish_timeout": "30s", + "fd": { + "connect_on_network_disconnect": "false", + "ping_interval": "1s", + "ping_retries": "3", + "register_connection_listener": "true", + "ping_timeout": "30s" + }, + "max_pings_from_another_master": "3" + }, + "initial_state_timeout": "30s" + }, + "tribe": { + "name": "", + "on_conflict": "any", + "blocks": { + "write": "false", + "metadata": "false" + } + }, + "http": { + "tcp": { + "reuse_address": "true", + "keep_alive": "true", + "blocking_server": "false", + "receive_buffer_size": "-1b", + "send_buffer_size": "-1b" + }, + "bind_host": [ + "0.0.0.0" + ], + "cors": { + "max-age": "1728000", + "allow-origin": "", + "allow-headers": "X-Requested-With,Content-Type,Content-Length", + "allow-credentials": "false", + "allow-methods": "OPTIONS,HEAD,GET,POST,PUT,DELETE", + "enabled": "false" + }, + "max_chunk_size": "8kb", + "compression_level": "3", + "reset_cookies": "false", + "max_initial_line_length": "4kb", + "type": "", + "pipelining": "true", + "enabled": "true", + "type.default": "netty4", + "detailed_errors": { + "enabled": "true" + }, + "content_type": { + "required": "false" + }, + "port": "9200-9300", + "host": [ + "0.0.0.0" + ], + "publish_port": "-1", + "max_header_size": "8kb", + "pipelining.max_events": "10000", + "tcp_no_delay": "true", + "compression": "true", + "publish_host": [ + "0.0.0.0" + ], + "max_content_length": "100mb", + "netty": { + "receive_predictor_size": "64kb", + "max_composite_buffer_components": "-1", + "receive_predictor_max": "64kb", + "worker_count": "8", + "receive_predictor_min": "64kb", + "max_cumulation_buffer_capacity": "-1b" + } + }, + "gateway": { + "recover_after_master_nodes": "0", + "expected_nodes": "-1", + "recover_after_data_nodes": "-1", + "initial_shards": "quorum", + "expected_data_nodes": "-1", + "recover_after_time": "0ms", + "expected_master_nodes": "-1", + "recover_after_nodes": "-1" + } + } +} diff --git a/fixtures/settings-persistent-clustermaxshardspernode-7.17.5.json b/fixtures/settings-persistent-clustermaxshardspernode-7.17.5.json new file mode 100644 index 00000000..52c489f8 --- /dev/null +++ b/fixtures/settings-persistent-clustermaxshardspernode-7.17.5.json @@ -0,0 +1,1527 @@ +{ + "persistent": { + "cluster": { + "max_shards_per_node": "1000" + } + }, + "transient": {}, + "defaults": { + "cluster": { + "max_voting_config_exclusions": "10", + "auto_shrink_voting_configuration": "true", + "election": { + "duration": "500ms", + "initial_timeout": "100ms", + "max_timeout": "10s", + "back_off_time": "100ms", + "strategy": "supports_voting_only" + }, + "no_master_block": "write", + "persistent_tasks": { + "allocation": { + "enable": "all", + "recheck_interval": "30s" + } + }, + "blocks": { + "read_only_allow_delete": "false", + "read_only": "false" + }, + "remote": { + "node": { + "attr": "" + }, + "initial_connect_timeout": "30s", + "connect": "true", + "connections_per_cluster": "3" + }, + "follower_lag": { + "timeout": "90000ms" + }, + "routing": { + "use_adaptive_replica_selection": "true", + "rebalance": { + "enable": "all" + }, + "allocation": { + "enforce_default_tier_preference": "false", + "node_concurrent_incoming_recoveries": "2", + "include": { + "_tier": "" + }, + "node_initial_primaries_recoveries": "4", + "same_shard": { + "host": "false" + }, + "total_shards_per_node": "-1", + "require": { + "_tier": "" + }, + "shard_state": { + "reroute": { + "priority": "NORMAL" + } + }, + "type": "balanced", + "disk": { + "threshold_enabled": "true", + "watermark": { + "flood_stage.frozen.max_headroom": "20GB", + "flood_stage": "100b", + "high": "200gb", + "low": "50mb", + "enable_for_single_data_node": "false", + "flood_stage.frozen": "95%" + }, + "include_relocations": "true", + "reroute_interval": "60s" + }, + "awareness": { + "attributes": [] + }, + "balance": { + "index": "0.55", + "threshold": "1.0", + "shard": "0.45" + }, + "enable": "all", + "node_concurrent_outgoing_recoveries": "2", + "allow_rebalance": "indices_all_active", + "cluster_concurrent_rebalance": "2", + "node_concurrent_recoveries": "2", + "exclude": { + "_tier": "" + } + } + }, + "indices": { + "tombstones": { + "size": "500" + }, + "close": { + "enable": "true" + } + }, + "nodes": { + "reconnect_interval": "10s" + }, + "service": { + "master_service_starvation_logging_threshold": "5m", + "slow_master_task_logging_threshold": "10s", + "slow_task_logging_threshold": "30s" + }, + "publish": { + "timeout": "30000ms", + "info_timeout": "10000ms" + }, + "name": "docker-cluster", + "fault_detection": { + "leader_check": { + "interval": "1000ms", + "timeout": "10000ms", + "retry_count": "3" + }, + "follower_check": { + "interval": "1000ms", + "timeout": "10000ms", + "retry_count": "3" + } + }, + "join": { + "timeout": "60000ms" + }, + "max_shards_per_node": { + "frozen": "3000" + }, + "initial_master_nodes": [], + "deprecation_indexing": { + "enabled": "true", + "x_opaque_id_used": { + "enabled": "true" + } + }, + "snapshot": { + "info": { + "max_concurrent_fetches": "5" + } + }, + "info": { + "update": { + "interval": "30s", + "timeout": "15s" + } + } + }, + "stack": { + "templates": { + "enabled": "true" + } + }, + "logger": { + "level": "INFO" + }, + "bootstrap": { + "memory_lock": "false", + "system_call_filter": "true", + "ctrlhandler": "true" + }, + "processors": "12", + "ingest": { + "user_agent": { + "cache_size": "1000" + }, + "geoip": { + "cache_size": "1000", + "downloader": { + "enabled": "true", + "endpoint": "https://geoip.elastic.co/v1/database", + "poll": { + "interval": "3d" + } + } + }, + "grok": { + "watchdog": { + "max_execution_time": "1s", + "interval": "1s" + } + } + }, + "network": { + "host": [ + "0.0.0.0" + ], + "tcp": { + "reuse_address": "true", + "keep_count": "-1", + "connect_timeout": "30s", + "keep_interval": "-1", + "no_delay": "true", + "keep_alive": "true", + "receive_buffer_size": "-1b", + "keep_idle": "-1", + "send_buffer_size": "-1b" + }, + "bind_host": [ + "0.0.0.0" + ], + "server": "true", + "breaker": { + "inflight_requests": { + "limit": "100%", + "overhead": "2.0" + } + }, + "publish_host": [ + "0.0.0.0" + ] + }, + "pidfile": "", + "searchable_snapshots": { + "blob_cache": { + "periodic_cleanup": { + "interval": "1h", + "batch_size": "100", + "pit_keep_alive": "10m", + "retention_period": "1h" + } + } + }, + "path": { + "data": [], + "logs": "/usr/share/elasticsearch/logs", + "shared_data": "", + "home": "/usr/share/elasticsearch", + "repo": [] + }, + "search": { + "default_search_timeout": "-1", + "max_open_scroll_context": "500", + "max_buckets": "65536", + "max_async_search_response_size": "-1b", + "keep_alive_interval": "1m", + "remote": { + "node": { + "attr": "" + }, + "initial_connect_timeout": "30s", + "connect": "true", + "connections_per_cluster": "3" + }, + "max_keep_alive": "24h", + "highlight": { + "term_vector_multi_value": "true" + }, + "default_allow_partial_results": "true", + "low_level_cancellation": "true", + "allow_expensive_queries": "true", + "default_keep_alive": "5m", + "aggs": { + "rewrite_to_filter_by_filter": "true" + } + }, + "security": { + "manager": { + "filter_bad_defaults": "true" + } + }, + "ccr": { + "wait_for_metadata_timeout": "60s", + "indices": { + "recovery": { + "recovery_activity_timeout": "60s", + "chunk_size": "1mb", + "internal_action_timeout": "60s", + "max_bytes_per_sec": "40mb", + "max_concurrent_file_chunks": "5" + } + }, + "auto_follow": { + "wait_for_metadata_timeout": "60s" + } + }, + "repositories": { + "fs": { + "compress": "false", + "chunk_size": "9223372036854775807b", + "location": "" + }, + "url": { + "supported_protocols": [ + "http", + "https", + "ftp", + "file", + "jar" + ], + "allowed_urls": [], + "url": "http:" + } + }, + "action": { + "auto_create_index": "true", + "search": { + "pre_filter_shard_size": { + "default": "128" + }, + "shard_count": { + "limit": "9223372036854775807" + } + }, + "destructive_requires_name": "false" + }, + "client": { + "type": "node", + "transport": { + "ignore_cluster_name": "false", + "nodes_sampler_interval": "5s", + "sniff": "false", + "ping_timeout": "5s" + } + }, + "enrich": { + "max_force_merge_attempts": "3", + "cleanup_period": "15m", + "fetch_size": "10000", + "cache_size": "1000", + "coordinator_proxy": { + "max_concurrent_requests": "8", + "max_lookups_per_request": "128", + "queue_capacity": "1024" + }, + "max_concurrent_policy_executions": "50" + }, + "xpack": { + "flattened": { + "enabled": "true" + }, + "watcher": { + "execution": { + "scroll": { + "size": "0", + "timeout": "" + }, + "default_throttle_period": "5s" + }, + "internal": { + "ops": { + "bulk": { + "default_timeout": "" + }, + "index": { + "default_timeout": "" + }, + "search": { + "default_timeout": "" + } + } + }, + "thread_pool": { + "queue_size": "1000", + "size": "50" + }, + "index": { + "rest": { + "direct_access": "" + } + }, + "use_ilm_index_management": "true", + "history": { + "cleaner_service": { + "enabled": "true" + } + }, + "trigger": { + "schedule": { + "ticker": { + "tick_interval": "500ms" + } + } + }, + "enabled": "true", + "input": { + "search": { + "default_timeout": "" + } + }, + "encrypt_sensitive_data": "false", + "transform": { + "search": { + "default_timeout": "" + } + }, + "stop": { + "timeout": "30s" + }, + "watch": { + "scroll": { + "size": "0" + } + }, + "bulk": { + "concurrent_requests": "0", + "flush_interval": "1s", + "size": "1mb", + "actions": "1" + }, + "actions": { + "bulk": { + "default_timeout": "" + }, + "index": { + "default_timeout": "" + } + } + }, + "eql": { + "enabled": "true" + }, + "data_frame": { + "enabled": "true" + }, + "ilm": { + "enabled": "true" + }, + "monitoring": { + "migration": { + "decommission_alerts": "false" + }, + "collection": { + "cluster": { + "stats": { + "timeout": "10s" + } + }, + "node": { + "stats": { + "timeout": "10s" + } + }, + "indices": [], + "ccr": { + "stats": { + "timeout": "10s" + } + }, + "enrich": { + "stats": { + "timeout": "10s" + } + }, + "index": { + "stats": { + "timeout": "10s" + }, + "recovery": { + "active_only": "false", + "timeout": "10s" + } + }, + "interval": "10s", + "enabled": "false", + "ml": { + "job": { + "stats": { + "timeout": "10s" + } + } + } + }, + "history": { + "duration": "168h" + }, + "elasticsearch": { + "collection": { + "enabled": "true" + } + }, + "enabled": "true" + }, + "graph": { + "enabled": "true" + }, + "searchable": { + "snapshot": { + "allocate_on_rolling_restart": "false", + "cache": { + "range_size": "32mb", + "sync": { + "max_files": "10000", + "interval": "60s", + "shutdown_timeout": "10s" + }, + "recovery_range_size": "128kb" + }, + "shared_cache": { + "recovery_range_size": "128kb", + "region_size": "16mb", + "size": "0", + "min_time_delta": "60s", + "decay": { + "interval": "60s" + }, + "size.max_headroom": "-1", + "range_size": "16mb", + "max_freq": "100" + } + } + }, + "rollup": { + "enabled": "true", + "task_thread_pool": { + "queue_size": "-1", + "size": "1" + } + }, + "sql": { + "enabled": "true" + }, + "searchable_snapshots": { + "cache_fetch_async_thread_pool": { + "core": "0", + "max": "36", + "keep_alive": "30s" + }, + "cache_prewarming_thread_pool": { + "core": "0", + "max": "16", + "keep_alive": "30s" + } + }, + "license": { + "upload": { + "types": [ + "standard", + "gold", + "platinum", + "enterprise", + "trial" + ] + }, + "self_generated": { + "type": "basic" + } + }, + "logstash": { + "enabled": "true" + }, + "notification": { + "pagerduty": { + "default_account": "" + }, + "email": { + "account": { + "domain_allowlist": [ + "*" + ] + }, + "default_account": "", + "html": { + "sanitization": { + "allow": [ + "body", + "head", + "_tables", + "_links", + "_blocks", + "_formatting", + "img:embedded" + ], + "disallow": [], + "enabled": "true" + } + } + }, + "reporting": { + "retries": "40", + "warning": { + "enabled": "true" + }, + "interval": "15s" + }, + "jira": { + "default_account": "" + }, + "slack": { + "default_account": "" + } + }, + "security": { + "operator_privileges": { + "enabled": "false" + }, + "dls_fls": { + "enabled": "true" + }, + "dls": { + "bitset": { + "cache": { + "size": "10%", + "ttl": "2h" + } + } + }, + "transport": { + "filter": { + "allow": [], + "deny": [], + "enabled": "true" + }, + "ssl": { + "enabled": "false" + } + }, + "ssl": { + "diagnose": { + "trust": "true" + } + }, + "enabled": "true", + "crypto": { + "thread_pool": { + "queue_size": "1000", + "size": "6" + } + }, + "filter": { + "always_allow_bound_address": "true" + }, + "encryption": { + "algorithm": "AES/CTR/NoPadding" + }, + "audit": { + "enabled": "false", + "logfile": { + "emit_node_id": "true", + "emit_node_host_name": "false", + "emit_node_name": "false", + "events": { + "emit_request_body": "false", + "include": [ + "ACCESS_DENIED", + "ACCESS_GRANTED", + "ANONYMOUS_ACCESS_DENIED", + "AUTHENTICATION_FAILED", + "CONNECTION_DENIED", + "TAMPERED_REQUEST", + "RUN_AS_DENIED", + "RUN_AS_GRANTED", + "SECURITY_CONFIG_CHANGE" + ], + "exclude": [] + }, + "emit_node_host_address": "false" + } + }, + "authc": { + "password_hashing": { + "algorithm": "bcrypt" + }, + "success_cache": { + "size": "10000", + "enabled": "true", + "expire_after_access": "1h" + }, + "api_key": { + "doc_cache": { + "ttl": "5m" + }, + "cache": { + "hash_algo": "ssha256", + "max_keys": "25000", + "ttl": "24h" + }, + "delete": { + "interval": "24h", + "timeout": "-1" + }, + "enabled": "false", + "hashing": { + "algorithm": "pbkdf2" + } + }, + "anonymous": { + "authz_exception": "true", + "roles": [], + "username": "_anonymous" + }, + "run_as": { + "enabled": "true" + }, + "reserved_realm": { + "enabled": "true" + }, + "service_token": { + "cache": { + "hash_algo": "ssha256", + "max_tokens": "100000", + "ttl": "20m" + } + }, + "token": { + "delete": { + "interval": "30m", + "timeout": "-1" + }, + "enabled": "false", + "thread_pool": { + "queue_size": "1000", + "size": "1" + }, + "timeout": "20m" + } + }, + "fips_mode": { + "enabled": "false" + }, + "encryption_key": { + "length": "128", + "algorithm": "AES" + }, + "http": { + "filter": { + "allow": [], + "deny": [], + "enabled": "true" + }, + "ssl": { + "enabled": "false" + } + }, + "automata": { + "max_determinized_states": "100000", + "cache": { + "size": "10000", + "ttl": "48h", + "enabled": "true" + } + }, + "user": null, + "authz": { + "timer": { + "indices": { + "enabled": "false", + "threshold": { + "warn": "200ms", + "debug": "20ms", + "info": "100ms" + } + } + }, + "store": { + "privileges": { + "cache": { + "ttl": "24h", + "max_size": "10000" + } + }, + "roles": { + "index": { + "cache": { + "ttl": "20m", + "max_size": "10000" + } + }, + "cache": { + "max_size": "10000" + }, + "negative_lookup_cache": { + "max_size": "10000" + }, + "field_permissions": { + "cache": { + "max_size_in_bytes": "104857600" + } + } + } + } + } + }, + "transform": { + "num_transform_failure_retries": "10", + "enabled": "true" + }, + "vectors": { + "enabled": "true" + }, + "ccr": { + "enabled": "true", + "ccr_thread_pool": { + "queue_size": "100", + "size": "32" + } + }, + "idp": { + "privileges": { + "application": "", + "cache": { + "size": "100", + "ttl": "90m" + } + }, + "metadata": { + "signing": { + "keystore": { + "alias": "" + } + } + }, + "slo_endpoint": { + "post": "https:", + "redirect": "https:" + }, + "defaults": { + "nameid_format": "urn:oasis:names:tc:SAML:2.0:nameid-format:transient", + "authn_expiry": "5m" + }, + "allowed_nameid_formats": [ + "urn:oasis:names:tc:SAML:2.0:nameid-format:transient" + ], + "contact": { + "given_name": "", + "email": "", + "surname": "" + }, + "organization": { + "display_name": "", + "name": "", + "url": "http:" + }, + "sso_endpoint": { + "post": "https:", + "redirect": "https:" + }, + "entity_id": "", + "signing": { + "keystore": { + "alias": "" + } + }, + "sp": { + "cache": { + "size": "1000", + "ttl": "60m" + }, + "wildcard": { + "path": "wildcard_services.json" + } + }, + "enabled": "false" + }, + "slm": { + "enabled": "true" + }, + "enrich": { + "enabled": "true" + }, + "http": { + "tcp": { + "keep_alive": "true" + }, + "default_connection_timeout": "10s", + "proxy": { + "host": "", + "scheme": "", + "port": "0" + }, + "connection_pool_ttl": "-1", + "max_response_size": "10mb", + "whitelist": [ + "*" + ], + "default_read_timeout": "10s" + }, + "autoscaling": { + "memory": { + "monitor": { + "timeout": "15s" + } + } + }, + "ml": { + "utility_thread_pool": { + "core": "1", + "max": "2048", + "keep_alive": "10m" + }, + "max_anomaly_records": "500", + "enable_config_migration": "true", + "max_open_jobs": "512", + "delayed_data_check_freq": "15m", + "min_disk_space_off_heap": "5gb", + "use_auto_machine_memory_percent": "false", + "inference_model": { + "cache_size": "40%", + "time_to_live": "5m" + }, + "nightly_maintenance_requests_per_second": "-1.0", + "node_concurrent_job_allocations": "2", + "max_model_memory_limit": "0b", + "enabled": "true", + "max_lazy_ml_nodes": "0", + "max_ml_node_size": "0b", + "max_machine_memory_percent": "30", + "persist_results_max_retries": "20", + "autodetect_process": "true", + "datafeed_thread_pool": { + "core": "1", + "max": "512", + "keep_alive": "1m" + }, + "max_inference_processors": "50", + "process_connect_timeout": "10s", + "job_comms_thread_pool": { + "core": "4", + "max": "2048", + "keep_alive": "1m" + } + } + }, + "rest": { + "action": { + "multi": { + "allow_explicit_index": "true" + } + } + }, + "cache": { + "recycler": { + "page": { + "limit": { + "heap": "10%" + }, + "type": "CONCURRENT", + "weight": { + "longs": "1.0", + "ints": "1.0", + "bytes": "1.0", + "objects": "0.1" + } + } + } + }, + "async_search": { + "index_cleanup_interval": "1h" + }, + "reindex": { + "remote": { + "whitelist": [] + } + }, + "resource": { + "reload": { + "enabled": "true", + "interval": { + "low": "60s", + "high": "5s", + "medium": "30s" + } + } + }, + "thread_pool": { + "force_merge": { + "queue_size": "-1", + "size": "1" + }, + "search_coordination": { + "queue_size": "1000", + "size": "5" + }, + "snapshot_meta": { + "core": "1", + "max": "36", + "keep_alive": "30s" + }, + "fetch_shard_started": { + "core": "1", + "max": "24", + "keep_alive": "5m" + }, + "listener": { + "queue_size": "-1", + "size": "6" + }, + "estimated_time_interval.warn_threshold": "5s", + "scheduler": { + "warn_threshold": "5s" + }, + "search": { + "max_queue_size": "1000", + "queue_size": "1000", + "size": "19", + "auto_queue_frame_size": "2000", + "target_response_time": "1s", + "min_queue_size": "1000" + }, + "fetch_shard_store": { + "core": "1", + "max": "24", + "keep_alive": "5m" + }, + "flush": { + "core": "1", + "max": "5", + "keep_alive": "5m" + }, + "vectortile": { + "queue_size": "-1", + "size": "1" + }, + "get": { + "queue_size": "1000", + "size": "12" + }, + "system_read": { + "queue_size": "2000", + "size": "5" + }, + "system_critical_read": { + "queue_size": "2000", + "size": "5" + }, + "estimated_time_interval": "200ms", + "write": { + "queue_size": "10000", + "size": "12" + }, + "system_critical_write": { + "queue_size": "1500", + "size": "5" + }, + "refresh": { + "core": "1", + "max": "6", + "keep_alive": "5m" + }, + "system_write": { + "queue_size": "1000", + "size": "5" + }, + "generic": { + "core": "4", + "max": "128", + "keep_alive": "30s" + }, + "warmer": { + "core": "1", + "max": "5", + "keep_alive": "5m" + }, + "auto_complete": { + "queue_size": "100", + "size": "3" + }, + "management": { + "core": "1", + "max": "5", + "keep_alive": "5m" + }, + "analyze": { + "queue_size": "16", + "size": "1" + }, + "snapshot": { + "core": "1", + "max": "5", + "keep_alive": "5m" + }, + "search_throttled": { + "max_queue_size": "100", + "queue_size": "100", + "size": "1", + "auto_queue_frame_size": "200", + "target_response_time": "1s", + "min_queue_size": "100" + } + }, + "index": { + "codec": "default", + "recovery": { + "type": "" + }, + "store": { + "type": "", + "fs": { + "fs_lock": "native" + }, + "preload": [], + "snapshot": { + "uncached_chunk_size": "-1b", + "cache": { + "excluded_file_types": [] + } + } + } + }, + "monitor": { + "jvm": { + "gc": { + "enabled": "true", + "overhead": { + "warn": "50", + "debug": "10", + "info": "25" + }, + "refresh_interval": "1s" + }, + "refresh_interval": "1s" + }, + "process": { + "refresh_interval": "1s" + }, + "os": { + "refresh_interval": "1s" + }, + "fs": { + "health": { + "enabled": "true", + "refresh_interval": "120s", + "slow_path_logging_threshold": "5s" + }, + "refresh_interval": "1s" + } + }, + "runtime_fields": { + "grok": { + "watchdog": { + "max_execution_time": "1s", + "interval": "1s" + } + } + }, + "transport": { + "tcp": { + "reuse_address": "true", + "keep_count": "-1", + "connect_timeout": "30s", + "keep_interval": "-1", + "compress": "FALSE", + "port": "9300-9400", + "no_delay": "true", + "keep_alive": "true", + "receive_buffer_size": "-1b", + "keep_idle": "-1", + "send_buffer_size": "-1b" + }, + "bind_host": [], + "connect_timeout": "30s", + "compress": "FALSE", + "ping_schedule": "-1", + "connections_per_node": { + "recovery": "2", + "state": "1", + "bulk": "3", + "reg": "6", + "ping": "1" + }, + "tracer": { + "include": [], + "exclude": [ + "internal:discovery/zen/fd*", + "internal:coordination/fault_detection/*", + "cluster:monitor/nodes/liveness" + ] + }, + "type": "security4", + "slow_operation_logging_threshold": "5s", + "type.default": "netty4", + "features": { + "x-pack": "true" + }, + "port": "9300-9400", + "compression_scheme": "DEFLATE", + "host": [], + "publish_port": "-1", + "tcp_no_delay": "true", + "publish_host": [], + "netty": { + "receive_predictor_size": "64kb", + "receive_predictor_max": "64kb", + "worker_count": "12", + "receive_predictor_min": "64kb", + "boss_count": "1" + } + }, + "deprecation": { + "skip_deprecated_settings": [] + }, + "script": { + "allowed_contexts": [], + "max_compilations_rate": "150/5m", + "cache": { + "max_size": "3000", + "expire": "0ms" + }, + "painless": { + "regex": { + "enabled": "limited", + "limit-factor": "6" + } + }, + "max_size_in_bytes": "65535", + "allowed_types": [], + "disable_max_compilations_rate": "false" + }, + "indexing_pressure": { + "memory": { + "limit": "10%" + } + }, + "node": { + "data": "true", + "bandwidth": { + "recovery": { + "disk": { + "write": "-1", + "read": "-1" + }, + "operator": { + "factor.read": "0.4", + "factor.write": "0.4", + "factor": "0.4", + "factor.max_overcommit": "100.0" + }, + "network": "-1" + } + }, + "roles": [ + "data_frozen", + "data_warm", + "transform", + "data", + "remote_cluster_client", + "data_cold", + "data_content", + "data_hot", + "ingest", + "master", + "ml" + ], + "max_local_storage_nodes": "1", + "processors": "12", + "store": { + "allow_mmap": "true" + }, + "ingest": "true", + "master": "true", + "pidfile": "", + "transform": "true", + "remote_cluster_client": "true", + "enable_lucene_segment_infos_trace": "false", + "local_storage": "true", + "name": "36ac32055483", + "id": { + "seed": "0" + }, + "voting_only": "false", + "attr": { + "transform": { + "node": "true" + }, + "xpack": { + "installed": "true" + }, + "ml": { + "max_jvm_size": "8392802304", + "machine_memory": "16784928768", + "max_open_jobs": "512" + } + }, + "portsfile": "false", + "ml": "true" + }, + "indices": { + "replication": { + "retry_timeout": "60s", + "initial_retry_backoff_bound": "50ms" + }, + "cache": { + "cleanup_interval": "1m" + }, + "mapping": { + "dynamic_timeout": "30s", + "max_in_flight_updates": "10" + }, + "memory": { + "interval": "5s", + "max_index_buffer_size": "-1", + "shard_inactive_time": "5m", + "index_buffer_size": "10%", + "min_index_buffer_size": "48mb" + }, + "breaker": { + "request": { + "limit": "60%", + "type": "memory", + "overhead": "1.0" + }, + "total": { + "limit": "95%", + "use_real_memory": "true" + }, + "accounting": { + "limit": "100%", + "overhead": "1.0" + }, + "fielddata": { + "limit": "40%", + "type": "memory", + "overhead": "1.03" + }, + "type": "hierarchy" + }, + "query": { + "bool": { + "max_nested_depth": "20", + "max_clause_count": "1024" + }, + "query_string": { + "analyze_wildcard": "false", + "allowLeadingWildcard": "true" + } + }, + "id_field_data": { + "enabled": "true" + }, + "recovery": { + "internal_action_retry_timeout": "1m", + "recovery_activity_timeout": "1800000ms", + "retry_delay_network": "5s", + "internal_action_timeout": "15m", + "max_concurrent_snapshot_file_downloads_per_node": "25", + "retry_delay_state_sync": "500ms", + "max_concurrent_snapshot_file_downloads": "5", + "internal_action_long_timeout": "1800000ms", + "max_concurrent_operations": "1", + "use_snapshots": "true", + "max_bytes_per_sec": "40mb", + "max_concurrent_file_chunks": "2" + }, + "requests": { + "cache": { + "size": "1%", + "expire": "0ms" + } + }, + "store": { + "delete": { + "shard": { + "timeout": "30s" + } + } + }, + "analysis": { + "hunspell": { + "dictionary": { + "ignore_case": "false", + "lazy": "false" + } + } + }, + "queries": { + "cache": { + "count": "10000", + "size": "10%", + "all_segments": "false" + } + }, + "lifecycle": { + "history_index_enabled": "true", + "poll_interval": "10m", + "step": { + "master_timeout": "30s" + } + }, + "fielddata": { + "cache": { + "size": "-1b" + } + } + }, + "plugin": { + "mandatory": [] + }, + "slm": { + "minimum_interval": "15m", + "retention_schedule": "0 30 1 * * ?", + "retention_duration": "1h", + "history_index_enabled": "true" + }, + "discovery": { + "seed_hosts": [], + "unconfigured_bootstrap_timeout": "3s", + "request_peers_timeout": "3000ms", + "zen": { + "commit_timeout": "30s", + "no_master_block": "write", + "join_retry_delay": "100ms", + "join_retry_attempts": "3", + "ping": { + "unicast": { + "concurrent_connects": "10", + "hosts": [], + "hosts.resolve_timeout": "5s" + } + }, + "master_election": { + "ignore_non_master_pings": "false", + "wait_for_joins_timeout": "30000ms" + }, + "send_leave_request": "true", + "ping_timeout": "3s", + "bwc_ping_timeout": "3s", + "join_timeout": "60000ms", + "publish_diff": { + "enable": "true" + }, + "publish": { + "max_pending_cluster_states": "25" + }, + "minimum_master_nodes": "-1", + "unsafe_rolling_upgrades_enabled": "true", + "hosts_provider": [], + "publish_timeout": "30s", + "fd": { + "connect_on_network_disconnect": "false", + "ping_interval": "1s", + "ping_retries": "3", + "register_connection_listener": "true", + "ping_timeout": "30s" + }, + "max_pings_from_another_master": "3" + }, + "initial_state_timeout": "30s", + "cluster_formation_warning_timeout": "10000ms", + "seed_providers": [], + "type": "single-node", + "seed_resolver": { + "max_concurrent_resolvers": "10", + "timeout": "5s" + }, + "find_peers_interval": "1000ms", + "probe": { + "connect_timeout": "30s", + "handshake_timeout": "30s" + } + }, + "http": { + "cors": { + "max-age": "1728000", + "allow-origin": "", + "allow-headers": "X-Requested-With,Content-Type,Content-Length", + "allow-credentials": "false", + "allow-methods": "OPTIONS,HEAD,GET,POST,PUT,DELETE", + "enabled": "false" + }, + "max_chunk_size": "8kb", + "compression_level": "3", + "max_initial_line_length": "4kb", + "type": "security4", + "pipelining": { + "max_events": "10000" + }, + "type.default": "netty4", + "content_type": { + "required": "true" + }, + "host": [], + "publish_port": "-1", + "read_timeout": "0ms", + "max_content_length": "100mb", + "netty": { + "receive_predictor_size": "64kb", + "max_composite_buffer_components": "69905", + "worker_count": "0" + }, + "tcp": { + "reuse_address": "true", + "keep_count": "-1", + "keep_interval": "-1", + "no_delay": "true", + "keep_alive": "true", + "receive_buffer_size": "-1b", + "keep_idle": "-1", + "send_buffer_size": "-1b" + }, + "bind_host": [], + "client_stats": { + "enabled": "true", + "closed_channels": { + "max_age": "5m", + "max_count": "10000" + } + }, + "reset_cookies": "false", + "max_warning_header_count": "-1", + "tracer": { + "include": [], + "exclude": [] + }, + "max_warning_header_size": "-1b", + "detailed_errors": { + "enabled": "true" + }, + "port": "9200-9300", + "max_header_size": "8kb", + "tcp_no_delay": "true", + "compression": "true", + "publish_host": [] + }, + "gateway": { + "recover_after_master_nodes": "0", + "expected_nodes": "-1", + "recover_after_data_nodes": "-1", + "expected_data_nodes": "-1", + "write_dangling_indices_info": "true", + "slow_write_logging_threshold": "10s", + "recover_after_time": "0ms", + "expected_master_nodes": "-1", + "recover_after_nodes": "-1", + "auto_import_dangling_indices": "false" + }, + "snapshot": { + "refresh_repo_uuid_on_restore": "true", + "max_concurrent_operations": "1000" + } + } +} diff --git a/fixtures/shards/7.15.0.json b/fixtures/shards/7.15.0.json new file mode 100644 index 00000000..2e78aa6e --- /dev/null +++ b/fixtures/shards/7.15.0.json @@ -0,0 +1 @@ +[{"index":".geoip_databases","shard":"0","prirep":"p","state":"STARTED","docs":"38","store":"36.4mb","ip":"172.17.0.2","node":"35dfca79831a"},{"index":"otherindex","shard":"0","prirep":"p","state":"STARTED","docs":"0","store":"208b","ip":"172.17.0.2","node":"35dfca79831a"},{"index":"otherindex","shard":"0","prirep":"r","state":"UNASSIGNED","docs":null,"store":null,"ip":null,"node":null},{"index":"testindex","shard":"0","prirep":"p","state":"STARTED","docs":"0","store":"208b","ip":"172.17.0.2","node":"35dfca79831a"},{"index":"testindex","shard":"0","prirep":"r","state":"UNASSIGNED","docs":null,"store":null,"ip":null,"node":null}] \ No newline at end of file diff --git a/fixtures/slm/stats/7.15.0.json b/fixtures/slm/stats/7.15.0.json new file mode 100644 index 00000000..e94f8d7b --- /dev/null +++ b/fixtures/slm/stats/7.15.0.json @@ -0,0 +1,20 @@ +{ + "retention_runs": 9, + "retention_failed": 0, + "retention_timed_out": 0, + "retention_deletion_time": "1.2m", + "retention_deletion_time_millis": 72491, + "total_snapshots_taken": 103, + "total_snapshots_failed": 2, + "total_snapshots_deleted": 20, + "total_snapshot_deletion_failures": 0, + "policy_stats": [ + { + "policy": "everything", + "snapshots_taken": 50, + "snapshots_failed": 2, + "snapshots_deleted": 20, + "snapshot_deletion_failures": 0 + } + ] +} diff --git a/fixtures/slm/status/7.15.0.json b/fixtures/slm/status/7.15.0.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/fixtures/slm/status/7.15.0.json @@ -0,0 +1 @@ +{} diff --git a/fixtures/snapshots/1.7.6.json b/fixtures/snapshots/1.7.6.json new file mode 100644 index 00000000..8df72227 --- /dev/null +++ b/fixtures/snapshots/1.7.6.json @@ -0,0 +1 @@ +{"snapshots":[{"snapshot":"snapshot_1","version_id":1070699,"version":"1.7.6","indices":["foo_1","foo_2"],"state":"SUCCESS","start_time":"2018-09-04T09:09:02.427Z","start_time_in_millis":1536052142427,"end_time":"2018-09-04T09:09:02.755Z","end_time_in_millis":1536052142755,"duration_in_millis":328,"failures":[],"shards":{"total":10,"failed":0,"successful":10}}]} diff --git a/fixtures/snapshots/2.4.5.json b/fixtures/snapshots/2.4.5.json new file mode 100644 index 00000000..a691f425 --- /dev/null +++ b/fixtures/snapshots/2.4.5.json @@ -0,0 +1 @@ +{"snapshots":[{"snapshot":"snapshot_1","version_id":2040599,"version":"2.4.5","indices":["foo_2","foo_1"],"state":"SUCCESS","start_time":"2018-09-04T09:25:25.818Z","start_time_in_millis":1536053125818,"end_time":"2018-09-04T09:25:26.326Z","end_time_in_millis":1536053126326,"duration_in_millis":508,"failures":[],"shards":{"total":10,"failed":0,"successful":10}}]} diff --git a/fixtures/snapshots/5.4.2-failed.json b/fixtures/snapshots/5.4.2-failed.json new file mode 100644 index 00000000..2c8b6f6a --- /dev/null +++ b/fixtures/snapshots/5.4.2-failed.json @@ -0,0 +1 @@ +{"snapshots":[{"snapshot":"snapshot_1","uuid":"VZ_c_kKISAW8rpcqiwSg0w","version_id":5040299,"version":"5.4.2","indices":["foo_2","foo_1"],"state":"SUCCESS","start_time":"2018-09-04T09:29:13.971Z","start_time_in_millis":1536053353971,"end_time":"2018-09-04T09:29:14.477Z","end_time_in_millis":1536053354477,"duration_in_millis":506,"failures":[{"index" : "index_name","index_uuid" : "index_name","shard_id" : 52,"reason" : "IndexShardSnapshotFailedException[error deleting index file [pending-index-5] during cleanup]; nested: NoSuchFileException[Blob [pending-index-5] does not exist]; ","node_id" : "pPm9jafyTjyMk0T5A101xA","status" : "INTERNAL_SERVER_ERROR"}],"shards":{"total":10,"failed":1,"successful":10}}]} diff --git a/fixtures/snapshots/5.4.2.json b/fixtures/snapshots/5.4.2.json new file mode 100644 index 00000000..49690da3 --- /dev/null +++ b/fixtures/snapshots/5.4.2.json @@ -0,0 +1 @@ +{"snapshots":[{"snapshot":"snapshot_1","uuid":"VZ_c_kKISAW8rpcqiwSg0w","version_id":5040299,"version":"5.4.2","indices":["foo_2","foo_1"],"state":"SUCCESS","start_time":"2018-09-04T09:29:13.971Z","start_time_in_millis":1536053353971,"end_time":"2018-09-04T09:29:14.477Z","end_time_in_millis":1536053354477,"duration_in_millis":506,"failures":[],"shards":{"total":10,"failed":0,"successful":10}}]} diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..a8e2eba9 --- /dev/null +++ b/go.mod @@ -0,0 +1,50 @@ +module github.com/prometheus-community/elasticsearch_exporter + +go 1.23.0 + +require ( + github.com/alecthomas/kingpin/v2 v2.4.0 + github.com/aws/aws-sdk-go-v2 v1.32.7 + github.com/aws/aws-sdk-go-v2/config v1.28.7 + github.com/aws/aws-sdk-go-v2/credentials v1.17.48 + github.com/aws/aws-sdk-go-v2/service/sts v1.33.3 + github.com/blang/semver/v4 v4.0.0 + github.com/imdario/mergo v0.3.13 + github.com/prometheus/client_golang v1.20.5 + github.com/prometheus/common v0.60.1 + github.com/prometheus/exporter-toolkit v0.13.1 +) + +require ( + github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 // indirect + github.com/aws/smithy-go v1.22.1 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/jpillora/backoff v1.0.0 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mdlayher/socket v0.4.1 // indirect + github.com/mdlayher/vsock v1.2.1 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + github.com/xhit/go-str2duration/v2 v2.1.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..a79496e1 --- /dev/null +++ b/go.sum @@ -0,0 +1,107 @@ +github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY= +github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/aws/aws-sdk-go-v2 v1.32.7 h1:ky5o35oENWi0JYWUZkB7WYvVPP+bcRF5/Iq7JWSb5Rw= +github.com/aws/aws-sdk-go-v2 v1.32.7/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= +github.com/aws/aws-sdk-go-v2/config v1.28.7 h1:GduUnoTXlhkgnxTD93g1nv4tVPILbdNQOzav+Wpg7AE= +github.com/aws/aws-sdk-go-v2/config v1.28.7/go.mod h1:vZGX6GVkIE8uECSUHB6MWAUsd4ZcG2Yq/dMa4refR3M= +github.com/aws/aws-sdk-go-v2/credentials v1.17.48 h1:IYdLD1qTJ0zanRavulofmqut4afs45mOWEI+MzZtTfQ= +github.com/aws/aws-sdk-go-v2/credentials v1.17.48/go.mod h1:tOscxHN3CGmuX9idQ3+qbkzrjVIx32lqDSU1/0d/qXs= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 h1:kqOrpojG71DxJm/KDPO+Z/y1phm1JlC8/iT+5XRmAn8= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22/go.mod h1:NtSFajXVVL8TA2QNngagVZmUtXciyrHOt7xgz4faS/M= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 h1:I/5wmGMffY4happ8NOCuIUEWGUvvFp5NSeQcXl9RHcI= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26/go.mod h1:FR8f4turZtNy6baO0KJ5FJUmXH/cSkI9fOngs0yl6mA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 h1:zXFLuEuMMUOvEARXFUVJdfqZ4bvvSgdGRq/ATcrQxzM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26/go.mod h1:3o2Wpy0bogG1kyOPrgkXA8pgIfEEv0+m19O9D5+W8y8= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 h1:8eUsivBQzZHqe/3FE+cqwfH+0p5Jo8PFM/QYQSmeZ+M= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7/go.mod h1:kLPQvGUmxn/fqiCrDeohwG33bq2pQpGeY62yRO6Nrh0= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 h1:CvuUmnXI7ebaUAhbJcDy9YQx8wHR69eZ9I7q5hszt/g= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.8/go.mod h1:XDeGv1opzwm8ubxddF0cgqkZWsyOtw4lr6dxwmb6YQg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 h1:F2rBfNAL5UyswqoeWv9zs74N/NanhK16ydHW1pahX6E= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7/go.mod h1:JfyQ0g2JG8+Krq0EuZNnRwX0mU0HrwY/tG6JNfcqh4k= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.3 h1:Xgv/hyNgvLda/M9l9qxXc4UFSgppnRczLxlMs5Ae/QY= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.3/go.mod h1:5Gn+d+VaaRgsjewpMvGazt0WfcFO+Md4wLOuBfGR9Bc= +github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= +github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U= +github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= +github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ= +github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc= +github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= +github.com/prometheus/exporter-toolkit v0.13.1 h1:Evsh0gWQo2bdOHlnz9+0Nm7/OFfIwhE2Ws4A2jIlR04= +github.com/prometheus/exporter-toolkit v0.13.1/go.mod h1:ujdv2YIOxtdFxxqtloLpbqmxd5J0Le6IITUvIRSWjj0= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= +github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/logger.go b/logger.go deleted file mode 100644 index f57a0bd7..00000000 --- a/logger.go +++ /dev/null @@ -1,55 +0,0 @@ -package main - -import ( - "os" - - "github.com/go-kit/kit/log" - "github.com/go-kit/kit/log/level" - "io" - "strings" -) - -func getLogger(loglevel, logoutput, logfmt string) log.Logger { - var out *os.File - switch strings.ToLower(logoutput) { - case "stderr": - out = os.Stderr - case "stdout": - out = os.Stdout - default: - out = os.Stdout - } - var logCreator func(io.Writer) log.Logger - switch strings.ToLower(logfmt) { - case "json": - logCreator = log.NewJSONLogger - case "logfmt": - logCreator = log.NewLogfmtLogger - default: - logCreator = log.NewLogfmtLogger - } - - // create a logger - logger := logCreator(log.NewSyncWriter(out)) - - // set loglevel - var loglevelFilterOpt level.Option - switch strings.ToLower(loglevel) { - case "debug": - loglevelFilterOpt = level.AllowDebug() - case "info": - loglevelFilterOpt = level.AllowInfo() - case "warn": - loglevelFilterOpt = level.AllowWarn() - case "error": - loglevelFilterOpt = level.AllowError() - default: - loglevelFilterOpt = level.AllowInfo() - } - logger = level.NewFilter(logger, loglevelFilterOpt) - logger = log.With(logger, - "ts", log.DefaultTimestampUTC, - "caller", log.DefaultCaller, - ) - return logger -} diff --git a/main.go b/main.go index 9e39eedc..663fb772 100644 --- a/main.go +++ b/main.go @@ -1,114 +1,201 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( + "fmt" + "io" "net/http" "net/url" "os" "os/signal" + "strings" "time" "context" - "github.com/go-kit/kit/log/level" - "github.com/justwatchcom/elasticsearch_exporter/collector" - "github.com/justwatchcom/elasticsearch_exporter/pkg/clusterinfo" + "github.com/alecthomas/kingpin/v2" + "github.com/prometheus-community/elasticsearch_exporter/collector" + "github.com/prometheus-community/elasticsearch_exporter/pkg/clusterinfo" + "github.com/prometheus-community/elasticsearch_exporter/pkg/roundtripper" "github.com/prometheus/client_golang/prometheus" + versioncollector "github.com/prometheus/client_golang/prometheus/collectors/version" + "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/prometheus/common/promslog" + "github.com/prometheus/common/promslog/flag" "github.com/prometheus/common/version" - "gopkg.in/alecthomas/kingpin.v2" + "github.com/prometheus/exporter-toolkit/web" + webflag "github.com/prometheus/exporter-toolkit/web/kingpinflag" ) +const name = "elasticsearch_exporter" + +type transportWithAPIKey struct { + underlyingTransport http.RoundTripper + apiKey string +} + +func (t *transportWithAPIKey) RoundTrip(req *http.Request) (*http.Response, error) { + req.Header.Add("Authorization", fmt.Sprintf("ApiKey %s", t.apiKey)) + return t.underlyingTransport.RoundTrip(req) +} + func main() { var ( - Name = "elasticsearch_exporter" - listenAddress = kingpin.Flag("web.listen-address", - "Address to listen on for web interface and telemetry."). - Default(":9114").Envar("WEB_LISTEN_ADDRESS").String() metricsPath = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics."). - Default("/metrics").Envar("WEB_TELEMETRY_PATH").String() - esURI = kingpin.Flag("es.uri", + Default("/metrics").String() + toolkitFlags = webflag.AddFlags(kingpin.CommandLine, ":9114") + esURI = kingpin.Flag("es.uri", "HTTP API address of an Elasticsearch node."). - Default("http://localhost:9200").Envar("ES_URI").String() + Default("http://localhost:9200").String() esTimeout = kingpin.Flag("es.timeout", "Timeout for trying to get stats from Elasticsearch."). - Default("5s").Envar("ES_TIMEOUT").Duration() + Default("5s").Duration() esAllNodes = kingpin.Flag("es.all", "Export stats for all nodes in the cluster. If used, this flag will override the flag es.node."). - Default("false").Envar("ES_ALL").Bool() + Default("false").Bool() esNode = kingpin.Flag("es.node", "Node's name of which metrics should be exposed."). - Default("_local").Envar("ES_NODE").String() + Default("_local").String() esExportIndices = kingpin.Flag("es.indices", "Export stats for indices in the cluster."). - Default("false").Envar("ES_INDICES").Bool() + Default("false").Bool() esExportIndicesSettings = kingpin.Flag("es.indices_settings", "Export stats for settings of all indices of the cluster."). - Default("false").Envar("ES_INDICES_SETTINGS").Bool() - esExportClusterSettings = kingpin.Flag("es.cluster_settings", - "Export stats for cluster settings."). - Default("false").Envar("ES_CLUSTER_SETTINGS").Bool() + Default("false").Bool() + esExportIndicesMappings = kingpin.Flag("es.indices_mappings", + "Export stats for mappings of all indices of the cluster."). + Default("false").Bool() + esExportIndexAliases = kingpin.Flag("es.aliases", + "Export informational alias metrics."). + Default("true").Bool() + esExportILM = kingpin.Flag("es.ilm", + "Export index lifecycle politics for indices in the cluster."). + Default("false").Bool() esExportShards = kingpin.Flag("es.shards", "Export stats for shards in the cluster (implies --es.indices)."). - Default("false").Envar("ES_SHARDS").Bool() - esExportSnapshots = kingpin.Flag("es.snapshots", - "Export stats for the cluster snapshots."). - Default("false").Envar("ES_SNAPSHOTS").Bool() + Default("false").Bool() + esExportDataStream = kingpin.Flag("es.data_stream", + "Export stas for Data Streams."). + Default("false").Bool() esClusterInfoInterval = kingpin.Flag("es.clusterinfo.interval", "Cluster info update interval for the cluster label"). - Default("5m").Envar("ES_CLUSTERINFO_INTERVAL").Duration() + Default("5m").Duration() esCA = kingpin.Flag("es.ca", "Path to PEM file that contains trusted Certificate Authorities for the Elasticsearch connection."). - Default("").Envar("ES_CA").String() + Default("").String() esClientPrivateKey = kingpin.Flag("es.client-private-key", "Path to PEM file that contains the private key for client auth when connecting to Elasticsearch."). - Default("").Envar("ES_CLIENT_PRIVATE_KEY").String() + Default("").String() esClientCert = kingpin.Flag("es.client-cert", "Path to PEM file that contains the corresponding cert for the private key to connect to Elasticsearch."). - Default("").Envar("ES_CLIENT_CERT").String() + Default("").String() esInsecureSkipVerify = kingpin.Flag("es.ssl-skip-verify", "Skip SSL verification when connecting to Elasticsearch."). - Default("false").Envar("ES_SSL_SKIP_VERIFY").Bool() - logLevel = kingpin.Flag("log.level", - "Sets the loglevel. Valid levels are debug, info, warn, error"). - Default("info").Envar("LOG_LEVEL").String() - logFormat = kingpin.Flag("log.format", - "Sets the log format. Valid formats are json and logfmt"). - Default("logfmt").Envar("LOG_FMT").String() + Default("false").Bool() logOutput = kingpin.Flag("log.output", "Sets the log output. Valid outputs are stdout and stderr"). - Default("stdout").Envar("LOG_OUTPUT").String() + Default("stdout").String() + awsRegion = kingpin.Flag("aws.region", + "Region for AWS elasticsearch"). + Default("").String() + awsRoleArn = kingpin.Flag("aws.role-arn", + "Role ARN of an IAM role to assume."). + Default("").String() ) - kingpin.Version(version.Print(Name)) + promslogConfig := &promslog.Config{} + flag.AddFlags(kingpin.CommandLine, promslogConfig) + kingpin.Version(version.Print(name)) kingpin.CommandLine.HelpFlag.Short('h') kingpin.Parse() - logger := getLogger(*logLevel, *logOutput, *logFormat) + var w io.Writer + switch strings.ToLower(*logOutput) { + case "stderr": + w = os.Stderr + case "stdout": + w = os.Stdout + default: + w = os.Stdout + } + promslogConfig.Writer = w + logger := promslog.New(promslogConfig) esURL, err := url.Parse(*esURI) if err != nil { - _ = level.Error(logger).Log( - "msg", "failed to parse es.uri", - "err", err, - ) + logger.Error("failed to parse es.uri", "err", err) os.Exit(1) } + esUsername := os.Getenv("ES_USERNAME") + esPassword := os.Getenv("ES_PASSWORD") + + if esUsername != "" && esPassword != "" { + esURL.User = url.UserPassword(esUsername, esPassword) + } + // returns nil if not provided and falls back to simple TCP. tlsConfig := createTLSConfig(*esCA, *esClientCert, *esClientPrivateKey, *esInsecureSkipVerify) + var httpTransport http.RoundTripper + + httpTransport = &http.Transport{ + TLSClientConfig: tlsConfig, + Proxy: http.ProxyFromEnvironment, + } + + esAPIKey := os.Getenv("ES_API_KEY") + + if esAPIKey != "" { + httpTransport = &transportWithAPIKey{ + underlyingTransport: httpTransport, + apiKey: esAPIKey, + } + } + httpClient := &http.Client{ - Timeout: *esTimeout, - Transport: &http.Transport{ - TLSClientConfig: tlsConfig, - Proxy: http.ProxyFromEnvironment, - }, + Timeout: *esTimeout, + Transport: httpTransport, + } + + if *awsRegion != "" { + httpClient.Transport, err = roundtripper.NewAWSSigningTransport(httpTransport, *awsRegion, *awsRoleArn, logger) + if err != nil { + logger.Error("failed to create AWS transport", "err", err) + os.Exit(1) + } } // version metric - versionMetric := version.NewCollector(Name) - prometheus.MustRegister(versionMetric) + prometheus.MustRegister(versioncollector.NewCollector(name)) + // create the exporter + exporter, err := collector.NewElasticsearchCollector( + logger, + []string{}, + collector.WithElasticsearchURL(esURL), + collector.WithHTTPClient(httpClient), + ) + if err != nil { + logger.Error("failed to create Elasticsearch collector", "err", err) + os.Exit(1) + } + prometheus.MustRegister(exporter) + + // TODO(@sysadmind): Remove this when we have a better way to get the cluster name to down stream collectors. // cluster info retriever clusterInfoRetriever := clusterinfo.New(logger, httpClient, esURL, *esClusterInfoInterval) @@ -116,93 +203,93 @@ func main() { prometheus.MustRegister(collector.NewNodes(logger, httpClient, esURL, *esAllNodes, *esNode)) if *esExportIndices || *esExportShards { - iC := collector.NewIndices(logger, httpClient, esURL, *esExportShards) + sC := collector.NewShards(logger, httpClient, esURL) + prometheus.MustRegister(sC) + iC := collector.NewIndices(logger, httpClient, esURL, *esExportShards, *esExportIndexAliases) prometheus.MustRegister(iC) if registerErr := clusterInfoRetriever.RegisterConsumer(iC); registerErr != nil { - _ = level.Error(logger).Log("msg", "failed to register indices collector in cluster info") + logger.Error("failed to register indices collector in cluster info") + os.Exit(1) + } + if registerErr := clusterInfoRetriever.RegisterConsumer(sC); registerErr != nil { + logger.Error("failed to register shards collector in cluster info") os.Exit(1) } } - if *esExportSnapshots { - prometheus.MustRegister(collector.NewSnapshots(logger, httpClient, esURL)) - } - - if *esExportClusterSettings { - prometheus.MustRegister(collector.NewClusterSettings(logger, httpClient, esURL)) + if *esExportDataStream { + prometheus.MustRegister(collector.NewDataStream(logger, httpClient, esURL)) } if *esExportIndicesSettings { prometheus.MustRegister(collector.NewIndicesSettings(logger, httpClient, esURL)) } - // create a http server - server := &http.Server{} + if *esExportIndicesMappings { + prometheus.MustRegister(collector.NewIndicesMappings(logger, httpClient, esURL)) + } - // create a context that is cancelled on SIGKILL - ctx, cancel := context.WithCancel(context.Background()) + if *esExportILM { + prometheus.MustRegister(collector.NewIlmStatus(logger, httpClient, esURL)) + prometheus.MustRegister(collector.NewIlmIndicies(logger, httpClient, esURL)) + } + + // Create a context that is cancelled on SIGKILL or SIGINT. + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill) + defer cancel() // start the cluster info retriever switch runErr := clusterInfoRetriever.Run(ctx); runErr { case nil: - _ = level.Info(logger).Log( - "msg", "started cluster info retriever", - "interval", (*esClusterInfoInterval).String(), - ) + logger.Info("started cluster info retriever", "interval", (*esClusterInfoInterval).String()) case clusterinfo.ErrInitialCallTimeout: - _ = level.Info(logger).Log("msg", "initial cluster info call timed out") + logger.Info("initial cluster info call timed out") default: - _ = level.Error(logger).Log("msg", "failed to run cluster info retriever", "err", err) + logger.Error("failed to run cluster info retriever", "err", err) os.Exit(1) } // register cluster info retriever as prometheus collector prometheus.MustRegister(clusterInfoRetriever) - mux := http.DefaultServeMux - mux.Handle(*metricsPath, prometheus.Handler()) - mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - _, err = w.Write([]byte(` - Elasticsearch Exporter - -

Elasticsearch Exporter

-

Metrics

- - `)) + http.Handle(*metricsPath, promhttp.Handler()) + if *metricsPath != "/" && *metricsPath != "" { + landingConfig := web.LandingConfig{ + Name: "Elasticsearch Exporter", + Description: "Prometheus Exporter for Elasticsearch servers", + Version: version.Info(), + Links: []web.LandingLinks{ + { + Address: *metricsPath, + Text: "Metrics", + }, + }, + } + landingPage, err := web.NewLandingPage(landingConfig) if err != nil { - _ = level.Error(logger).Log( - "msg", "failed handling writer", - "err", err, - ) + logger.Error("error creating landing page", "err", err) + os.Exit(1) } - }) - - server.Handler = mux - server.Addr = *listenAddress + http.Handle("/", landingPage) + } - _ = level.Info(logger).Log( - "msg", "starting elasticsearch_exporter", - "addr", *listenAddress, - ) + // health endpoint + http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { + http.Error(w, http.StatusText(http.StatusOK), http.StatusOK) + }) + server := &http.Server{} go func() { - if err := server.ListenAndServe(); err != nil { - _ = level.Error(logger).Log( - "msg", "http server quit", - "err", err, - ) + if err = web.ListenAndServe(server, toolkitFlags, logger); err != nil { + logger.Error("http server quit", "err", err) os.Exit(1) } }() - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - + <-ctx.Done() + logger.Info("shutting down") // create a context for graceful http server shutdown srvCtx, srvCancel := context.WithTimeout(context.Background(), 5*time.Second) defer srvCancel() - <-c - _ = level.Info(logger).Log("msg", "shutting down") _ = server.Shutdown(srvCtx) - cancel() } diff --git a/pkg/clusterinfo/clusterinfo.go b/pkg/clusterinfo/clusterinfo.go index 8ad9d15e..f47659c3 100644 --- a/pkg/clusterinfo/clusterinfo.go +++ b/pkg/clusterinfo/clusterinfo.go @@ -1,3 +1,16 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package clusterinfo import ( @@ -5,13 +18,13 @@ import ( "encoding/json" "errors" "fmt" + "io" + "log/slog" "net/http" "net/url" "path" "time" - "github.com/go-kit/kit/log" - "github.com/go-kit/kit/log/level" "github.com/prometheus/client_golang/prometheus" ) @@ -35,11 +48,11 @@ type consumer interface { String() string } -// Retriever periodically gets the cluster info from the / endpoint end +// Retriever periodically gets the cluster info from the / endpoint and // sends it to all registered consumer channels type Retriever struct { consumerChannels map[string]*chan *Response - logger log.Logger + logger *slog.Logger client *http.Client url *url.URL interval time.Duration @@ -51,7 +64,7 @@ type Retriever struct { } // New creates a new Retriever -func New(logger log.Logger, client *http.Client, u *url.URL, interval time.Duration) *Retriever { +func New(logger *slog.Logger, client *http.Client, u *url.URL, interval time.Duration) *Retriever { return &Retriever{ consumerChannels: make(map[string]*chan *Response), logger: logger, @@ -114,14 +127,17 @@ func (r *Retriever) Collect(ch chan<- prometheus.Metric) { } func (r *Retriever) updateMetrics(res *Response) { - _ = level.Debug(r.logger).Log("msg", "updating cluster info metrics") + u := *r.url + u.User = nil + url := u.String() + r.logger.Debug("updating cluster info metrics") // scrape failed, response is nil if res == nil { - r.up.WithLabelValues(r.url.String()).Set(0.0) - r.lastUpstreamErrorTs.WithLabelValues(r.url.String()).Set(float64(time.Now().Unix())) + r.up.WithLabelValues(url).Set(0.0) + r.lastUpstreamErrorTs.WithLabelValues(url).Set(float64(time.Now().Unix())) return } - r.up.WithLabelValues(r.url.String()).Set(1.0) + r.up.WithLabelValues(url).Set(1.0) r.versionMetric.WithLabelValues( res.ClusterName, res.ClusterUUID, @@ -129,8 +145,8 @@ func (r *Retriever) updateMetrics(res *Response) { res.Version.BuildHash, res.Version.Number.String(), res.Version.LuceneVersion.String(), - ) - r.lastUpstreamSuccessTs.WithLabelValues(r.url.String()).Set(float64(time.Now().Unix())) + ).Set(1.0) + r.lastUpstreamSuccessTs.WithLabelValues(url).Set(float64(time.Now().Unix())) } // Update triggers an external cluster info label update @@ -157,19 +173,17 @@ func (r *Retriever) Run(ctx context.Context) error { for { select { case <-ctx.Done(): - _ = level.Info(r.logger).Log( - "msg", "context cancelled, exiting cluster info update loop", + r.logger.Info( + "context cancelled, exiting cluster info update loop", "err", ctx.Err(), ) return case <-r.sync: - _ = level.Info(r.logger).Log( - "msg", "providing consumers with updated cluster info label", - ) + r.logger.Info("providing consumers with updated cluster info label") res, err := r.fetchAndDecodeClusterInfo() if err != nil { - _ = level.Error(r.logger).Log( - "msg", "failed to retrieve cluster info from ES", + r.logger.Error( + "failed to retrieve cluster info from ES", "err", err, ) r.updateMetrics(nil) @@ -177,8 +191,8 @@ func (r *Retriever) Run(ctx context.Context) error { } r.updateMetrics(res) for name, consumerCh := range r.consumerChannels { - _ = level.Debug(r.logger).Log( - "msg", "sending update", + r.logger.Debug( + "sending update", "consumer", name, "res", fmt.Sprintf("%+v", res), ) @@ -194,32 +208,26 @@ func (r *Retriever) Run(ctx context.Context) error { } }(ctx) // trigger initial cluster info call - _ = level.Info(r.logger).Log( - "msg", "triggering initial cluster info call", - ) + r.logger.Info("triggering initial cluster info call") r.sync <- struct{}{} // start a ticker routine go func(ctx context.Context) { if r.interval <= 0 { - _ = level.Info(r.logger).Log( - "msg", "no periodic cluster info label update requested", - ) + r.logger.Info("no periodic cluster info label update requested") return } ticker := time.NewTicker(r.interval) for { select { case <-ctx.Done(): - _ = level.Info(r.logger).Log( - "msg", "context cancelled, exiting cluster info trigger loop", + r.logger.Info( + "context cancelled, exiting cluster info trigger loop", "err", ctx.Err(), ) return case <-ticker.C: - _ = level.Debug(r.logger).Log( - "msg", "triggering periodic update", - ) + r.logger.Debug("triggering periodic update") r.sync <- struct{}{} } } @@ -229,7 +237,7 @@ func (r *Retriever) Run(ctx context.Context) error { select { case <-startupComplete: // first sync has been successful - _ = level.Debug(r.logger).Log("msg", "initial clusterinfo sync succeeded") + r.logger.Debug("initial clusterinfo sync succeeded") return nil case <-time.After(initialTimeout): // initial call timed out @@ -247,8 +255,8 @@ func (r *Retriever) fetchAndDecodeClusterInfo() (*Response, error) { res, err := r.client.Get(u.String()) if err != nil { - _ = level.Error(r.logger).Log( - "msg", "failed to get cluster info", + r.logger.Error( + "failed to get cluster info", "err", err, ) return nil, err @@ -257,8 +265,8 @@ func (r *Retriever) fetchAndDecodeClusterInfo() (*Response, error) { defer func() { err = res.Body.Close() if err != nil { - _ = level.Warn(r.logger).Log( - "msg", "failed to close http.Client", + r.logger.Warn( + "failed to close http.Client", "err", err, ) } @@ -268,7 +276,12 @@ func (r *Retriever) fetchAndDecodeClusterInfo() (*Response, error) { return nil, fmt.Errorf("HTTP Request failed with code %d", res.StatusCode) } - if err := json.NewDecoder(res.Body).Decode(&response); err != nil { + bts, err := io.ReadAll(res.Body) + if err != nil { + return nil, err + } + + if err := json.Unmarshal(bts, &response); err != nil { return nil, err } diff --git a/pkg/clusterinfo/clusterinfo_response.go b/pkg/clusterinfo/clusterinfo_response.go index f484d16d..5e384f0c 100644 --- a/pkg/clusterinfo/clusterinfo_response.go +++ b/pkg/clusterinfo/clusterinfo_response.go @@ -1,7 +1,20 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package clusterinfo import ( - "github.com/blang/semver" + "github.com/blang/semver/v4" ) // Response is the cluster info retrievable from the / endpoint diff --git a/pkg/clusterinfo/clusterinfo_test.go b/pkg/clusterinfo/clusterinfo_test.go index 5956b276..c1803cca 100644 --- a/pkg/clusterinfo/clusterinfo_test.go +++ b/pkg/clusterinfo/clusterinfo_test.go @@ -1,3 +1,16 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package clusterinfo import ( @@ -8,12 +21,13 @@ import ( "net/url" "os" "reflect" + "sync" "testing" "time" - "github.com/go-kit/kit/log" + "github.com/prometheus/common/promslog" - "github.com/blang/semver" + "github.com/blang/semver/v4" ) const ( @@ -30,7 +44,7 @@ const ( type mockES struct{} -func (mockES) ServeHTTP(w http.ResponseWriter, r *http.Request) { +func (mockES) ServeHTTP(w http.ResponseWriter, _ *http.Request) { fmt.Fprintf(w, `{ "name" : "%s", @@ -59,8 +73,11 @@ func (mockES) ServeHTTP(w http.ResponseWriter, r *http.Request) { type mockConsumer struct { name string + + mu sync.RWMutex data *Response - ch chan *Response + + ch chan *Response } func newMockConsumer(ctx context.Context, name string, t *testing.T) *mockConsumer { @@ -72,10 +89,11 @@ func newMockConsumer(ctx context.Context, name string, t *testing.T) *mockConsum for { select { case d := <-mc.ch: + mc.mu.Lock() mc.data = d t.Logf("consumer %s received data from channel: %+v\n", mc, mc.data) + mc.mu.Unlock() case <-ctx.Done(): - t.Logf("shutting down consumer %s", mc) return } } @@ -83,6 +101,12 @@ func newMockConsumer(ctx context.Context, name string, t *testing.T) *mockConsum return mc } +func (mc *mockConsumer) getData() Response { + mc.mu.RLock() + defer mc.mu.RUnlock() + return *mc.data +} + func (mc *mockConsumer) String() string { return mc.name } @@ -96,7 +120,7 @@ func TestNew(t *testing.T) { if err != nil { t.Skipf("internal test error: %s", err) } - r := New(log.NewNopLogger(), http.DefaultClient, u, 0) + r := New(promslog.NewNopLogger(), http.DefaultClient, u, 0) if r.url != u { t.Errorf("new Retriever mal-constructed") } @@ -108,7 +132,7 @@ func TestRetriever_RegisterConsumer(t *testing.T) { if err != nil { t.Fatalf("internal test error: %s", err) } - retriever := New(log.NewNopLogger(), mockES.Client(), u, 0) + retriever := New(promslog.NewNopLogger(), mockES.Client(), u, 0) ctx, cancel := context.WithCancel(context.Background()) defer cancel() consumerNames := []string{"consumer-1", "consumer-2"} @@ -147,7 +171,7 @@ func TestRetriever_fetchAndDecodeClusterInfo(t *testing.T) { if err != nil { t.Skipf("internal test error: %s", err) } - retriever := New(log.NewNopLogger(), mockES.Client(), u, 0) + retriever := New(promslog.NewNopLogger(), mockES.Client(), u, 0) ci, err := retriever.fetchAndDecodeClusterInfo() if err != nil { t.Fatalf("failed to retrieve cluster info: %s", err) @@ -167,7 +191,7 @@ func TestRetriever_Run(t *testing.T) { } // setup cluster info retriever - retriever := New(log.NewLogfmtLogger(os.Stdout), mockES.Client(), u, 0) + retriever := New(promslog.New(&promslog.Config{Writer: os.Stdout}), mockES.Client(), u, 0) // setup mock consumer ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) @@ -184,7 +208,7 @@ func TestRetriever_Run(t *testing.T) { retriever.Update() time.Sleep(20 * time.Millisecond) // ToDo: check mockConsumers received data - t.Logf("%+v\n", mc.data) + t.Logf("%+v\n", mc.getData()) // check for deadlocks select { diff --git a/pkg/roundtripper/roundtripper.go b/pkg/roundtripper/roundtripper.go new file mode 100644 index 00000000..97e33672 --- /dev/null +++ b/pkg/roundtripper/roundtripper.go @@ -0,0 +1,109 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package roundtripper + +import ( + "bytes" + "context" + "crypto/sha256" + "encoding/hex" + "io" + "log/slog" + "net/http" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/credentials/stscreds" + "github.com/aws/aws-sdk-go-v2/service/sts" +) + +const ( + service = "es" +) + +type AWSSigningTransport struct { + t http.RoundTripper + creds aws.CredentialsProvider + region string + log *slog.Logger +} + +func NewAWSSigningTransport(transport http.RoundTripper, region string, roleArn string, log *slog.Logger) (*AWSSigningTransport, error) { + cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRegion(region)) + if err != nil { + log.Error("failed to load aws default config", "err", err) + return nil, err + } + + if roleArn != "" { + cfg.Credentials = stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), roleArn) + } + + creds := aws.NewCredentialsCache(cfg.Credentials) + // Run a single fetch credentials operation to ensure that the credentials + // are valid before returning the transport. + _, err = cfg.Credentials.Retrieve(context.Background()) + if err != nil { + log.Error("failed to retrive aws credentials", "err", err) + return nil, err + } + + return &AWSSigningTransport{ + t: transport, + region: region, + creds: creds, + log: log, + }, err +} + +func (a *AWSSigningTransport) RoundTrip(req *http.Request) (*http.Response, error) { + signer := v4.NewSigner() + payloadHash, newReader, err := hashPayload(req.Body) + if err != nil { + a.log.Error("failed to hash request body", "err", err) + return nil, err + } + req.Body = newReader + + creds, err := a.creds.Retrieve(context.Background()) + if err != nil { + a.log.Error("failed to retrieve aws credentials", "err", err) + return nil, err + } + + err = signer.SignHTTP(context.Background(), creds, req, payloadHash, service, a.region, time.Now()) + if err != nil { + a.log.Error("failed to sign request body", "err", err) + return nil, err + } + return a.t.RoundTrip(req) +} + +func hashPayload(r io.ReadCloser) (string, io.ReadCloser, error) { + var newReader io.ReadCloser + payload := []byte("") + if r != nil { + defer r.Close() + payload, err := io.ReadAll(r) + if err != nil { + return "", newReader, err + } + newReader = io.NopCloser(bytes.NewReader(payload)) + } + hash := sha256.Sum256(payload) + payloadHash := hex.EncodeToString(hash[:]) + return payloadHash, newReader, nil +} diff --git a/scripts/compile-mixin.sh b/scripts/compile-mixin.sh new file mode 100755 index 00000000..1cd1f849 --- /dev/null +++ b/scripts/compile-mixin.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +MIXIN_PATH=./elasticsearch-mixin +MIXIN_OUT_PATH=./elasticsearch-mixin/compiled + +rm -rf ${MIXIN_OUT_PATH} && mkdir ${MIXIN_OUT_PATH} +pushd ${MIXIN_PATH} && jb install && popd +mixtool generate all --output-alerts ${MIXIN_OUT_PATH}/alerts.yaml --output-rules ${MIXIN_OUT_PATH}/rules.yaml --directory ${MIXIN_OUT_PATH}/dashboards ${MIXIN_PATH}/mixin.libsonnet diff --git a/scripts/errcheck_excludes.txt b/scripts/errcheck_excludes.txt new file mode 100644 index 00000000..2cadaa53 --- /dev/null +++ b/scripts/errcheck_excludes.txt @@ -0,0 +1,2 @@ +// Used in HTTP handlers, any error is handled by the server itself. +(net/http.ResponseWriter).Write diff --git a/scripts/lint-jsonnet.sh b/scripts/lint-jsonnet.sh new file mode 100755 index 00000000..74348bf5 --- /dev/null +++ b/scripts/lint-jsonnet.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Run lint on all jsonnet files in the repository +RESULT=0; +for f in $(find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print); do + # jsonnet fmt -i "$$f" + echo "Linting ${f}" + jsonnetfmt -- "${f}" | diff -u "${f}" - + RESULT=$((RESULT+$?)) +done + +echo "Linting complete" +exit $RESULT diff --git a/tls.go b/tls.go index fcbbc508..0631a409 100644 --- a/tls.go +++ b/tls.go @@ -1,10 +1,23 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( "crypto/tls" "crypto/x509" - "io/ioutil" "log" + "os" ) func createTLSConfig(pemFile, pemCertFile, pemPrivateKeyFile string, insecureSkipVerify bool) *tls.Config { @@ -22,18 +35,23 @@ func createTLSConfig(pemFile, pemCertFile, pemPrivateKeyFile string, insecureSki tlsConfig.RootCAs = rootCerts } if len(pemCertFile) > 0 && len(pemPrivateKeyFile) > 0 { - clientPrivateKey, err := loadPrivateKeyFrom(pemCertFile, pemPrivateKeyFile) + // Load files once to catch configuration error early. + _, err := loadPrivateKeyFrom(pemCertFile, pemPrivateKeyFile) if err != nil { log.Fatalf("Couldn't setup client authentication. Got %s.", err) return nil } - tlsConfig.Certificates = []tls.Certificate{*clientPrivateKey} + // Define a function to load certificate and key lazily at TLS handshake to + // ensure that the latest files are used in case they have been rotated. + tlsConfig.GetClientCertificate = func(*tls.CertificateRequestInfo) (*tls.Certificate, error) { + return loadPrivateKeyFrom(pemCertFile, pemPrivateKeyFile) + } } return &tlsConfig } func loadCertificatesFrom(pemFile string) (*x509.CertPool, error) { - caCert, err := ioutil.ReadFile(pemFile) + caCert, err := os.ReadFile(pemFile) if err != nil { return nil, err } diff --git a/vendor/github.com/alecthomas/template/LICENSE b/vendor/github.com/alecthomas/template/LICENSE deleted file mode 100644 index 74487567..00000000 --- a/vendor/github.com/alecthomas/template/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/alecthomas/template/README.md b/vendor/github.com/alecthomas/template/README.md deleted file mode 100644 index ef6a8ee3..00000000 --- a/vendor/github.com/alecthomas/template/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Go's `text/template` package with newline elision - -This is a fork of Go 1.4's [text/template](http://golang.org/pkg/text/template/) package with one addition: a backslash immediately after a closing delimiter will delete all subsequent newlines until a non-newline. - -eg. - -``` -{{if true}}\ -hello -{{end}}\ -``` - -Will result in: - -``` -hello\n -``` - -Rather than: - -``` -\n -hello\n -\n -``` diff --git a/vendor/github.com/alecthomas/template/doc.go b/vendor/github.com/alecthomas/template/doc.go deleted file mode 100644 index 223c595c..00000000 --- a/vendor/github.com/alecthomas/template/doc.go +++ /dev/null @@ -1,406 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package template implements data-driven templates for generating textual output. - -To generate HTML output, see package html/template, which has the same interface -as this package but automatically secures HTML output against certain attacks. - -Templates are executed by applying them to a data structure. Annotations in the -template refer to elements of the data structure (typically a field of a struct -or a key in a map) to control execution and derive values to be displayed. -Execution of the template walks the structure and sets the cursor, represented -by a period '.' and called "dot", to the value at the current location in the -structure as execution proceeds. - -The input text for a template is UTF-8-encoded text in any format. -"Actions"--data evaluations or control structures--are delimited by -"{{" and "}}"; all text outside actions is copied to the output unchanged. -Actions may not span newlines, although comments can. - -Once parsed, a template may be executed safely in parallel. - -Here is a trivial example that prints "17 items are made of wool". - - type Inventory struct { - Material string - Count uint - } - sweaters := Inventory{"wool", 17} - tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}}") - if err != nil { panic(err) } - err = tmpl.Execute(os.Stdout, sweaters) - if err != nil { panic(err) } - -More intricate examples appear below. - -Actions - -Here is the list of actions. "Arguments" and "pipelines" are evaluations of -data, defined in detail below. - -*/ -// {{/* a comment */}} -// A comment; discarded. May contain newlines. -// Comments do not nest and must start and end at the -// delimiters, as shown here. -/* - - {{pipeline}} - The default textual representation of the value of the pipeline - is copied to the output. - - {{if pipeline}} T1 {{end}} - If the value of the pipeline is empty, no output is generated; - otherwise, T1 is executed. The empty values are false, 0, any - nil pointer or interface value, and any array, slice, map, or - string of length zero. - Dot is unaffected. - - {{if pipeline}} T1 {{else}} T0 {{end}} - If the value of the pipeline is empty, T0 is executed; - otherwise, T1 is executed. Dot is unaffected. - - {{if pipeline}} T1 {{else if pipeline}} T0 {{end}} - To simplify the appearance of if-else chains, the else action - of an if may include another if directly; the effect is exactly - the same as writing - {{if pipeline}} T1 {{else}}{{if pipeline}} T0 {{end}}{{end}} - - {{range pipeline}} T1 {{end}} - The value of the pipeline must be an array, slice, map, or channel. - If the value of the pipeline has length zero, nothing is output; - otherwise, dot is set to the successive elements of the array, - slice, or map and T1 is executed. If the value is a map and the - keys are of basic type with a defined order ("comparable"), the - elements will be visited in sorted key order. - - {{range pipeline}} T1 {{else}} T0 {{end}} - The value of the pipeline must be an array, slice, map, or channel. - If the value of the pipeline has length zero, dot is unaffected and - T0 is executed; otherwise, dot is set to the successive elements - of the array, slice, or map and T1 is executed. - - {{template "name"}} - The template with the specified name is executed with nil data. - - {{template "name" pipeline}} - The template with the specified name is executed with dot set - to the value of the pipeline. - - {{with pipeline}} T1 {{end}} - If the value of the pipeline is empty, no output is generated; - otherwise, dot is set to the value of the pipeline and T1 is - executed. - - {{with pipeline}} T1 {{else}} T0 {{end}} - If the value of the pipeline is empty, dot is unaffected and T0 - is executed; otherwise, dot is set to the value of the pipeline - and T1 is executed. - -Arguments - -An argument is a simple value, denoted by one of the following. - - - A boolean, string, character, integer, floating-point, imaginary - or complex constant in Go syntax. These behave like Go's untyped - constants, although raw strings may not span newlines. - - The keyword nil, representing an untyped Go nil. - - The character '.' (period): - . - The result is the value of dot. - - A variable name, which is a (possibly empty) alphanumeric string - preceded by a dollar sign, such as - $piOver2 - or - $ - The result is the value of the variable. - Variables are described below. - - The name of a field of the data, which must be a struct, preceded - by a period, such as - .Field - The result is the value of the field. Field invocations may be - chained: - .Field1.Field2 - Fields can also be evaluated on variables, including chaining: - $x.Field1.Field2 - - The name of a key of the data, which must be a map, preceded - by a period, such as - .Key - The result is the map element value indexed by the key. - Key invocations may be chained and combined with fields to any - depth: - .Field1.Key1.Field2.Key2 - Although the key must be an alphanumeric identifier, unlike with - field names they do not need to start with an upper case letter. - Keys can also be evaluated on variables, including chaining: - $x.key1.key2 - - The name of a niladic method of the data, preceded by a period, - such as - .Method - The result is the value of invoking the method with dot as the - receiver, dot.Method(). Such a method must have one return value (of - any type) or two return values, the second of which is an error. - If it has two and the returned error is non-nil, execution terminates - and an error is returned to the caller as the value of Execute. - Method invocations may be chained and combined with fields and keys - to any depth: - .Field1.Key1.Method1.Field2.Key2.Method2 - Methods can also be evaluated on variables, including chaining: - $x.Method1.Field - - The name of a niladic function, such as - fun - The result is the value of invoking the function, fun(). The return - types and values behave as in methods. Functions and function - names are described below. - - A parenthesized instance of one the above, for grouping. The result - may be accessed by a field or map key invocation. - print (.F1 arg1) (.F2 arg2) - (.StructValuedMethod "arg").Field - -Arguments may evaluate to any type; if they are pointers the implementation -automatically indirects to the base type when required. -If an evaluation yields a function value, such as a function-valued -field of a struct, the function is not invoked automatically, but it -can be used as a truth value for an if action and the like. To invoke -it, use the call function, defined below. - -A pipeline is a possibly chained sequence of "commands". A command is a simple -value (argument) or a function or method call, possibly with multiple arguments: - - Argument - The result is the value of evaluating the argument. - .Method [Argument...] - The method can be alone or the last element of a chain but, - unlike methods in the middle of a chain, it can take arguments. - The result is the value of calling the method with the - arguments: - dot.Method(Argument1, etc.) - functionName [Argument...] - The result is the value of calling the function associated - with the name: - function(Argument1, etc.) - Functions and function names are described below. - -Pipelines - -A pipeline may be "chained" by separating a sequence of commands with pipeline -characters '|'. In a chained pipeline, the result of the each command is -passed as the last argument of the following command. The output of the final -command in the pipeline is the value of the pipeline. - -The output of a command will be either one value or two values, the second of -which has type error. If that second value is present and evaluates to -non-nil, execution terminates and the error is returned to the caller of -Execute. - -Variables - -A pipeline inside an action may initialize a variable to capture the result. -The initialization has syntax - - $variable := pipeline - -where $variable is the name of the variable. An action that declares a -variable produces no output. - -If a "range" action initializes a variable, the variable is set to the -successive elements of the iteration. Also, a "range" may declare two -variables, separated by a comma: - - range $index, $element := pipeline - -in which case $index and $element are set to the successive values of the -array/slice index or map key and element, respectively. Note that if there is -only one variable, it is assigned the element; this is opposite to the -convention in Go range clauses. - -A variable's scope extends to the "end" action of the control structure ("if", -"with", or "range") in which it is declared, or to the end of the template if -there is no such control structure. A template invocation does not inherit -variables from the point of its invocation. - -When execution begins, $ is set to the data argument passed to Execute, that is, -to the starting value of dot. - -Examples - -Here are some example one-line templates demonstrating pipelines and variables. -All produce the quoted word "output": - - {{"\"output\""}} - A string constant. - {{`"output"`}} - A raw string constant. - {{printf "%q" "output"}} - A function call. - {{"output" | printf "%q"}} - A function call whose final argument comes from the previous - command. - {{printf "%q" (print "out" "put")}} - A parenthesized argument. - {{"put" | printf "%s%s" "out" | printf "%q"}} - A more elaborate call. - {{"output" | printf "%s" | printf "%q"}} - A longer chain. - {{with "output"}}{{printf "%q" .}}{{end}} - A with action using dot. - {{with $x := "output" | printf "%q"}}{{$x}}{{end}} - A with action that creates and uses a variable. - {{with $x := "output"}}{{printf "%q" $x}}{{end}} - A with action that uses the variable in another action. - {{with $x := "output"}}{{$x | printf "%q"}}{{end}} - The same, but pipelined. - -Functions - -During execution functions are found in two function maps: first in the -template, then in the global function map. By default, no functions are defined -in the template but the Funcs method can be used to add them. - -Predefined global functions are named as follows. - - and - Returns the boolean AND of its arguments by returning the - first empty argument or the last argument, that is, - "and x y" behaves as "if x then y else x". All the - arguments are evaluated. - call - Returns the result of calling the first argument, which - must be a function, with the remaining arguments as parameters. - Thus "call .X.Y 1 2" is, in Go notation, dot.X.Y(1, 2) where - Y is a func-valued field, map entry, or the like. - The first argument must be the result of an evaluation - that yields a value of function type (as distinct from - a predefined function such as print). The function must - return either one or two result values, the second of which - is of type error. If the arguments don't match the function - or the returned error value is non-nil, execution stops. - html - Returns the escaped HTML equivalent of the textual - representation of its arguments. - index - Returns the result of indexing its first argument by the - following arguments. Thus "index x 1 2 3" is, in Go syntax, - x[1][2][3]. Each indexed item must be a map, slice, or array. - js - Returns the escaped JavaScript equivalent of the textual - representation of its arguments. - len - Returns the integer length of its argument. - not - Returns the boolean negation of its single argument. - or - Returns the boolean OR of its arguments by returning the - first non-empty argument or the last argument, that is, - "or x y" behaves as "if x then x else y". All the - arguments are evaluated. - print - An alias for fmt.Sprint - printf - An alias for fmt.Sprintf - println - An alias for fmt.Sprintln - urlquery - Returns the escaped value of the textual representation of - its arguments in a form suitable for embedding in a URL query. - -The boolean functions take any zero value to be false and a non-zero -value to be true. - -There is also a set of binary comparison operators defined as -functions: - - eq - Returns the boolean truth of arg1 == arg2 - ne - Returns the boolean truth of arg1 != arg2 - lt - Returns the boolean truth of arg1 < arg2 - le - Returns the boolean truth of arg1 <= arg2 - gt - Returns the boolean truth of arg1 > arg2 - ge - Returns the boolean truth of arg1 >= arg2 - -For simpler multi-way equality tests, eq (only) accepts two or more -arguments and compares the second and subsequent to the first, -returning in effect - - arg1==arg2 || arg1==arg3 || arg1==arg4 ... - -(Unlike with || in Go, however, eq is a function call and all the -arguments will be evaluated.) - -The comparison functions work on basic types only (or named basic -types, such as "type Celsius float32"). They implement the Go rules -for comparison of values, except that size and exact type are -ignored, so any integer value, signed or unsigned, may be compared -with any other integer value. (The arithmetic value is compared, -not the bit pattern, so all negative integers are less than all -unsigned integers.) However, as usual, one may not compare an int -with a float32 and so on. - -Associated templates - -Each template is named by a string specified when it is created. Also, each -template is associated with zero or more other templates that it may invoke by -name; such associations are transitive and form a name space of templates. - -A template may use a template invocation to instantiate another associated -template; see the explanation of the "template" action above. The name must be -that of a template associated with the template that contains the invocation. - -Nested template definitions - -When parsing a template, another template may be defined and associated with the -template being parsed. Template definitions must appear at the top level of the -template, much like global variables in a Go program. - -The syntax of such definitions is to surround each template declaration with a -"define" and "end" action. - -The define action names the template being created by providing a string -constant. Here is a simple example: - - `{{define "T1"}}ONE{{end}} - {{define "T2"}}TWO{{end}} - {{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}} - {{template "T3"}}` - -This defines two templates, T1 and T2, and a third T3 that invokes the other two -when it is executed. Finally it invokes T3. If executed this template will -produce the text - - ONE TWO - -By construction, a template may reside in only one association. If it's -necessary to have a template addressable from multiple associations, the -template definition must be parsed multiple times to create distinct *Template -values, or must be copied with the Clone or AddParseTree method. - -Parse may be called multiple times to assemble the various associated templates; -see the ParseFiles and ParseGlob functions and methods for simple ways to parse -related templates stored in files. - -A template may be executed directly or through ExecuteTemplate, which executes -an associated template identified by name. To invoke our example above, we -might write, - - err := tmpl.Execute(os.Stdout, "no data needed") - if err != nil { - log.Fatalf("execution failed: %s", err) - } - -or to invoke a particular template explicitly by name, - - err := tmpl.ExecuteTemplate(os.Stdout, "T2", "no data needed") - if err != nil { - log.Fatalf("execution failed: %s", err) - } - -*/ -package template diff --git a/vendor/github.com/alecthomas/template/exec.go b/vendor/github.com/alecthomas/template/exec.go deleted file mode 100644 index c3078e5d..00000000 --- a/vendor/github.com/alecthomas/template/exec.go +++ /dev/null @@ -1,845 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package template - -import ( - "bytes" - "fmt" - "io" - "reflect" - "runtime" - "sort" - "strings" - - "github.com/alecthomas/template/parse" -) - -// state represents the state of an execution. It's not part of the -// template so that multiple executions of the same template -// can execute in parallel. -type state struct { - tmpl *Template - wr io.Writer - node parse.Node // current node, for errors - vars []variable // push-down stack of variable values. -} - -// variable holds the dynamic value of a variable such as $, $x etc. -type variable struct { - name string - value reflect.Value -} - -// push pushes a new variable on the stack. -func (s *state) push(name string, value reflect.Value) { - s.vars = append(s.vars, variable{name, value}) -} - -// mark returns the length of the variable stack. -func (s *state) mark() int { - return len(s.vars) -} - -// pop pops the variable stack up to the mark. -func (s *state) pop(mark int) { - s.vars = s.vars[0:mark] -} - -// setVar overwrites the top-nth variable on the stack. Used by range iterations. -func (s *state) setVar(n int, value reflect.Value) { - s.vars[len(s.vars)-n].value = value -} - -// varValue returns the value of the named variable. -func (s *state) varValue(name string) reflect.Value { - for i := s.mark() - 1; i >= 0; i-- { - if s.vars[i].name == name { - return s.vars[i].value - } - } - s.errorf("undefined variable: %s", name) - return zero -} - -var zero reflect.Value - -// at marks the state to be on node n, for error reporting. -func (s *state) at(node parse.Node) { - s.node = node -} - -// doublePercent returns the string with %'s replaced by %%, if necessary, -// so it can be used safely inside a Printf format string. -func doublePercent(str string) string { - if strings.Contains(str, "%") { - str = strings.Replace(str, "%", "%%", -1) - } - return str -} - -// errorf formats the error and terminates processing. -func (s *state) errorf(format string, args ...interface{}) { - name := doublePercent(s.tmpl.Name()) - if s.node == nil { - format = fmt.Sprintf("template: %s: %s", name, format) - } else { - location, context := s.tmpl.ErrorContext(s.node) - format = fmt.Sprintf("template: %s: executing %q at <%s>: %s", location, name, doublePercent(context), format) - } - panic(fmt.Errorf(format, args...)) -} - -// errRecover is the handler that turns panics into returns from the top -// level of Parse. -func errRecover(errp *error) { - e := recover() - if e != nil { - switch err := e.(type) { - case runtime.Error: - panic(e) - case error: - *errp = err - default: - panic(e) - } - } -} - -// ExecuteTemplate applies the template associated with t that has the given name -// to the specified data object and writes the output to wr. -// If an error occurs executing the template or writing its output, -// execution stops, but partial results may already have been written to -// the output writer. -// A template may be executed safely in parallel. -func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error { - tmpl := t.tmpl[name] - if tmpl == nil { - return fmt.Errorf("template: no template %q associated with template %q", name, t.name) - } - return tmpl.Execute(wr, data) -} - -// Execute applies a parsed template to the specified data object, -// and writes the output to wr. -// If an error occurs executing the template or writing its output, -// execution stops, but partial results may already have been written to -// the output writer. -// A template may be executed safely in parallel. -func (t *Template) Execute(wr io.Writer, data interface{}) (err error) { - defer errRecover(&err) - value := reflect.ValueOf(data) - state := &state{ - tmpl: t, - wr: wr, - vars: []variable{{"$", value}}, - } - t.init() - if t.Tree == nil || t.Root == nil { - var b bytes.Buffer - for name, tmpl := range t.tmpl { - if tmpl.Tree == nil || tmpl.Root == nil { - continue - } - if b.Len() > 0 { - b.WriteString(", ") - } - fmt.Fprintf(&b, "%q", name) - } - var s string - if b.Len() > 0 { - s = "; defined templates are: " + b.String() - } - state.errorf("%q is an incomplete or empty template%s", t.Name(), s) - } - state.walk(value, t.Root) - return -} - -// Walk functions step through the major pieces of the template structure, -// generating output as they go. -func (s *state) walk(dot reflect.Value, node parse.Node) { - s.at(node) - switch node := node.(type) { - case *parse.ActionNode: - // Do not pop variables so they persist until next end. - // Also, if the action declares variables, don't print the result. - val := s.evalPipeline(dot, node.Pipe) - if len(node.Pipe.Decl) == 0 { - s.printValue(node, val) - } - case *parse.IfNode: - s.walkIfOrWith(parse.NodeIf, dot, node.Pipe, node.List, node.ElseList) - case *parse.ListNode: - for _, node := range node.Nodes { - s.walk(dot, node) - } - case *parse.RangeNode: - s.walkRange(dot, node) - case *parse.TemplateNode: - s.walkTemplate(dot, node) - case *parse.TextNode: - if _, err := s.wr.Write(node.Text); err != nil { - s.errorf("%s", err) - } - case *parse.WithNode: - s.walkIfOrWith(parse.NodeWith, dot, node.Pipe, node.List, node.ElseList) - default: - s.errorf("unknown node: %s", node) - } -} - -// walkIfOrWith walks an 'if' or 'with' node. The two control structures -// are identical in behavior except that 'with' sets dot. -func (s *state) walkIfOrWith(typ parse.NodeType, dot reflect.Value, pipe *parse.PipeNode, list, elseList *parse.ListNode) { - defer s.pop(s.mark()) - val := s.evalPipeline(dot, pipe) - truth, ok := isTrue(val) - if !ok { - s.errorf("if/with can't use %v", val) - } - if truth { - if typ == parse.NodeWith { - s.walk(val, list) - } else { - s.walk(dot, list) - } - } else if elseList != nil { - s.walk(dot, elseList) - } -} - -// isTrue reports whether the value is 'true', in the sense of not the zero of its type, -// and whether the value has a meaningful truth value. -func isTrue(val reflect.Value) (truth, ok bool) { - if !val.IsValid() { - // Something like var x interface{}, never set. It's a form of nil. - return false, true - } - switch val.Kind() { - case reflect.Array, reflect.Map, reflect.Slice, reflect.String: - truth = val.Len() > 0 - case reflect.Bool: - truth = val.Bool() - case reflect.Complex64, reflect.Complex128: - truth = val.Complex() != 0 - case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface: - truth = !val.IsNil() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - truth = val.Int() != 0 - case reflect.Float32, reflect.Float64: - truth = val.Float() != 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - truth = val.Uint() != 0 - case reflect.Struct: - truth = true // Struct values are always true. - default: - return - } - return truth, true -} - -func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) { - s.at(r) - defer s.pop(s.mark()) - val, _ := indirect(s.evalPipeline(dot, r.Pipe)) - // mark top of stack before any variables in the body are pushed. - mark := s.mark() - oneIteration := func(index, elem reflect.Value) { - // Set top var (lexically the second if there are two) to the element. - if len(r.Pipe.Decl) > 0 { - s.setVar(1, elem) - } - // Set next var (lexically the first if there are two) to the index. - if len(r.Pipe.Decl) > 1 { - s.setVar(2, index) - } - s.walk(elem, r.List) - s.pop(mark) - } - switch val.Kind() { - case reflect.Array, reflect.Slice: - if val.Len() == 0 { - break - } - for i := 0; i < val.Len(); i++ { - oneIteration(reflect.ValueOf(i), val.Index(i)) - } - return - case reflect.Map: - if val.Len() == 0 { - break - } - for _, key := range sortKeys(val.MapKeys()) { - oneIteration(key, val.MapIndex(key)) - } - return - case reflect.Chan: - if val.IsNil() { - break - } - i := 0 - for ; ; i++ { - elem, ok := val.Recv() - if !ok { - break - } - oneIteration(reflect.ValueOf(i), elem) - } - if i == 0 { - break - } - return - case reflect.Invalid: - break // An invalid value is likely a nil map, etc. and acts like an empty map. - default: - s.errorf("range can't iterate over %v", val) - } - if r.ElseList != nil { - s.walk(dot, r.ElseList) - } -} - -func (s *state) walkTemplate(dot reflect.Value, t *parse.TemplateNode) { - s.at(t) - tmpl := s.tmpl.tmpl[t.Name] - if tmpl == nil { - s.errorf("template %q not defined", t.Name) - } - // Variables declared by the pipeline persist. - dot = s.evalPipeline(dot, t.Pipe) - newState := *s - newState.tmpl = tmpl - // No dynamic scoping: template invocations inherit no variables. - newState.vars = []variable{{"$", dot}} - newState.walk(dot, tmpl.Root) -} - -// Eval functions evaluate pipelines, commands, and their elements and extract -// values from the data structure by examining fields, calling methods, and so on. -// The printing of those values happens only through walk functions. - -// evalPipeline returns the value acquired by evaluating a pipeline. If the -// pipeline has a variable declaration, the variable will be pushed on the -// stack. Callers should therefore pop the stack after they are finished -// executing commands depending on the pipeline value. -func (s *state) evalPipeline(dot reflect.Value, pipe *parse.PipeNode) (value reflect.Value) { - if pipe == nil { - return - } - s.at(pipe) - for _, cmd := range pipe.Cmds { - value = s.evalCommand(dot, cmd, value) // previous value is this one's final arg. - // If the object has type interface{}, dig down one level to the thing inside. - if value.Kind() == reflect.Interface && value.Type().NumMethod() == 0 { - value = reflect.ValueOf(value.Interface()) // lovely! - } - } - for _, variable := range pipe.Decl { - s.push(variable.Ident[0], value) - } - return value -} - -func (s *state) notAFunction(args []parse.Node, final reflect.Value) { - if len(args) > 1 || final.IsValid() { - s.errorf("can't give argument to non-function %s", args[0]) - } -} - -func (s *state) evalCommand(dot reflect.Value, cmd *parse.CommandNode, final reflect.Value) reflect.Value { - firstWord := cmd.Args[0] - switch n := firstWord.(type) { - case *parse.FieldNode: - return s.evalFieldNode(dot, n, cmd.Args, final) - case *parse.ChainNode: - return s.evalChainNode(dot, n, cmd.Args, final) - case *parse.IdentifierNode: - // Must be a function. - return s.evalFunction(dot, n, cmd, cmd.Args, final) - case *parse.PipeNode: - // Parenthesized pipeline. The arguments are all inside the pipeline; final is ignored. - return s.evalPipeline(dot, n) - case *parse.VariableNode: - return s.evalVariableNode(dot, n, cmd.Args, final) - } - s.at(firstWord) - s.notAFunction(cmd.Args, final) - switch word := firstWord.(type) { - case *parse.BoolNode: - return reflect.ValueOf(word.True) - case *parse.DotNode: - return dot - case *parse.NilNode: - s.errorf("nil is not a command") - case *parse.NumberNode: - return s.idealConstant(word) - case *parse.StringNode: - return reflect.ValueOf(word.Text) - } - s.errorf("can't evaluate command %q", firstWord) - panic("not reached") -} - -// idealConstant is called to return the value of a number in a context where -// we don't know the type. In that case, the syntax of the number tells us -// its type, and we use Go rules to resolve. Note there is no such thing as -// a uint ideal constant in this situation - the value must be of int type. -func (s *state) idealConstant(constant *parse.NumberNode) reflect.Value { - // These are ideal constants but we don't know the type - // and we have no context. (If it was a method argument, - // we'd know what we need.) The syntax guides us to some extent. - s.at(constant) - switch { - case constant.IsComplex: - return reflect.ValueOf(constant.Complex128) // incontrovertible. - case constant.IsFloat && !isHexConstant(constant.Text) && strings.IndexAny(constant.Text, ".eE") >= 0: - return reflect.ValueOf(constant.Float64) - case constant.IsInt: - n := int(constant.Int64) - if int64(n) != constant.Int64 { - s.errorf("%s overflows int", constant.Text) - } - return reflect.ValueOf(n) - case constant.IsUint: - s.errorf("%s overflows int", constant.Text) - } - return zero -} - -func isHexConstant(s string) bool { - return len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') -} - -func (s *state) evalFieldNode(dot reflect.Value, field *parse.FieldNode, args []parse.Node, final reflect.Value) reflect.Value { - s.at(field) - return s.evalFieldChain(dot, dot, field, field.Ident, args, final) -} - -func (s *state) evalChainNode(dot reflect.Value, chain *parse.ChainNode, args []parse.Node, final reflect.Value) reflect.Value { - s.at(chain) - // (pipe).Field1.Field2 has pipe as .Node, fields as .Field. Eval the pipeline, then the fields. - pipe := s.evalArg(dot, nil, chain.Node) - if len(chain.Field) == 0 { - s.errorf("internal error: no fields in evalChainNode") - } - return s.evalFieldChain(dot, pipe, chain, chain.Field, args, final) -} - -func (s *state) evalVariableNode(dot reflect.Value, variable *parse.VariableNode, args []parse.Node, final reflect.Value) reflect.Value { - // $x.Field has $x as the first ident, Field as the second. Eval the var, then the fields. - s.at(variable) - value := s.varValue(variable.Ident[0]) - if len(variable.Ident) == 1 { - s.notAFunction(args, final) - return value - } - return s.evalFieldChain(dot, value, variable, variable.Ident[1:], args, final) -} - -// evalFieldChain evaluates .X.Y.Z possibly followed by arguments. -// dot is the environment in which to evaluate arguments, while -// receiver is the value being walked along the chain. -func (s *state) evalFieldChain(dot, receiver reflect.Value, node parse.Node, ident []string, args []parse.Node, final reflect.Value) reflect.Value { - n := len(ident) - for i := 0; i < n-1; i++ { - receiver = s.evalField(dot, ident[i], node, nil, zero, receiver) - } - // Now if it's a method, it gets the arguments. - return s.evalField(dot, ident[n-1], node, args, final, receiver) -} - -func (s *state) evalFunction(dot reflect.Value, node *parse.IdentifierNode, cmd parse.Node, args []parse.Node, final reflect.Value) reflect.Value { - s.at(node) - name := node.Ident - function, ok := findFunction(name, s.tmpl) - if !ok { - s.errorf("%q is not a defined function", name) - } - return s.evalCall(dot, function, cmd, name, args, final) -} - -// evalField evaluates an expression like (.Field) or (.Field arg1 arg2). -// The 'final' argument represents the return value from the preceding -// value of the pipeline, if any. -func (s *state) evalField(dot reflect.Value, fieldName string, node parse.Node, args []parse.Node, final, receiver reflect.Value) reflect.Value { - if !receiver.IsValid() { - return zero - } - typ := receiver.Type() - receiver, _ = indirect(receiver) - // Unless it's an interface, need to get to a value of type *T to guarantee - // we see all methods of T and *T. - ptr := receiver - if ptr.Kind() != reflect.Interface && ptr.CanAddr() { - ptr = ptr.Addr() - } - if method := ptr.MethodByName(fieldName); method.IsValid() { - return s.evalCall(dot, method, node, fieldName, args, final) - } - hasArgs := len(args) > 1 || final.IsValid() - // It's not a method; must be a field of a struct or an element of a map. The receiver must not be nil. - receiver, isNil := indirect(receiver) - if isNil { - s.errorf("nil pointer evaluating %s.%s", typ, fieldName) - } - switch receiver.Kind() { - case reflect.Struct: - tField, ok := receiver.Type().FieldByName(fieldName) - if ok { - field := receiver.FieldByIndex(tField.Index) - if tField.PkgPath != "" { // field is unexported - s.errorf("%s is an unexported field of struct type %s", fieldName, typ) - } - // If it's a function, we must call it. - if hasArgs { - s.errorf("%s has arguments but cannot be invoked as function", fieldName) - } - return field - } - s.errorf("%s is not a field of struct type %s", fieldName, typ) - case reflect.Map: - // If it's a map, attempt to use the field name as a key. - nameVal := reflect.ValueOf(fieldName) - if nameVal.Type().AssignableTo(receiver.Type().Key()) { - if hasArgs { - s.errorf("%s is not a method but has arguments", fieldName) - } - return receiver.MapIndex(nameVal) - } - } - s.errorf("can't evaluate field %s in type %s", fieldName, typ) - panic("not reached") -} - -var ( - errorType = reflect.TypeOf((*error)(nil)).Elem() - fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() -) - -// evalCall executes a function or method call. If it's a method, fun already has the receiver bound, so -// it looks just like a function call. The arg list, if non-nil, includes (in the manner of the shell), arg[0] -// as the function itself. -func (s *state) evalCall(dot, fun reflect.Value, node parse.Node, name string, args []parse.Node, final reflect.Value) reflect.Value { - if args != nil { - args = args[1:] // Zeroth arg is function name/node; not passed to function. - } - typ := fun.Type() - numIn := len(args) - if final.IsValid() { - numIn++ - } - numFixed := len(args) - if typ.IsVariadic() { - numFixed = typ.NumIn() - 1 // last arg is the variadic one. - if numIn < numFixed { - s.errorf("wrong number of args for %s: want at least %d got %d", name, typ.NumIn()-1, len(args)) - } - } else if numIn < typ.NumIn()-1 || !typ.IsVariadic() && numIn != typ.NumIn() { - s.errorf("wrong number of args for %s: want %d got %d", name, typ.NumIn(), len(args)) - } - if !goodFunc(typ) { - // TODO: This could still be a confusing error; maybe goodFunc should provide info. - s.errorf("can't call method/function %q with %d results", name, typ.NumOut()) - } - // Build the arg list. - argv := make([]reflect.Value, numIn) - // Args must be evaluated. Fixed args first. - i := 0 - for ; i < numFixed && i < len(args); i++ { - argv[i] = s.evalArg(dot, typ.In(i), args[i]) - } - // Now the ... args. - if typ.IsVariadic() { - argType := typ.In(typ.NumIn() - 1).Elem() // Argument is a slice. - for ; i < len(args); i++ { - argv[i] = s.evalArg(dot, argType, args[i]) - } - } - // Add final value if necessary. - if final.IsValid() { - t := typ.In(typ.NumIn() - 1) - if typ.IsVariadic() { - t = t.Elem() - } - argv[i] = s.validateType(final, t) - } - result := fun.Call(argv) - // If we have an error that is not nil, stop execution and return that error to the caller. - if len(result) == 2 && !result[1].IsNil() { - s.at(node) - s.errorf("error calling %s: %s", name, result[1].Interface().(error)) - } - return result[0] -} - -// canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero. -func canBeNil(typ reflect.Type) bool { - switch typ.Kind() { - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return true - } - return false -} - -// validateType guarantees that the value is valid and assignable to the type. -func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Value { - if !value.IsValid() { - if typ == nil || canBeNil(typ) { - // An untyped nil interface{}. Accept as a proper nil value. - return reflect.Zero(typ) - } - s.errorf("invalid value; expected %s", typ) - } - if typ != nil && !value.Type().AssignableTo(typ) { - if value.Kind() == reflect.Interface && !value.IsNil() { - value = value.Elem() - if value.Type().AssignableTo(typ) { - return value - } - // fallthrough - } - // Does one dereference or indirection work? We could do more, as we - // do with method receivers, but that gets messy and method receivers - // are much more constrained, so it makes more sense there than here. - // Besides, one is almost always all you need. - switch { - case value.Kind() == reflect.Ptr && value.Type().Elem().AssignableTo(typ): - value = value.Elem() - if !value.IsValid() { - s.errorf("dereference of nil pointer of type %s", typ) - } - case reflect.PtrTo(value.Type()).AssignableTo(typ) && value.CanAddr(): - value = value.Addr() - default: - s.errorf("wrong type for value; expected %s; got %s", typ, value.Type()) - } - } - return value -} - -func (s *state) evalArg(dot reflect.Value, typ reflect.Type, n parse.Node) reflect.Value { - s.at(n) - switch arg := n.(type) { - case *parse.DotNode: - return s.validateType(dot, typ) - case *parse.NilNode: - if canBeNil(typ) { - return reflect.Zero(typ) - } - s.errorf("cannot assign nil to %s", typ) - case *parse.FieldNode: - return s.validateType(s.evalFieldNode(dot, arg, []parse.Node{n}, zero), typ) - case *parse.VariableNode: - return s.validateType(s.evalVariableNode(dot, arg, nil, zero), typ) - case *parse.PipeNode: - return s.validateType(s.evalPipeline(dot, arg), typ) - case *parse.IdentifierNode: - return s.evalFunction(dot, arg, arg, nil, zero) - case *parse.ChainNode: - return s.validateType(s.evalChainNode(dot, arg, nil, zero), typ) - } - switch typ.Kind() { - case reflect.Bool: - return s.evalBool(typ, n) - case reflect.Complex64, reflect.Complex128: - return s.evalComplex(typ, n) - case reflect.Float32, reflect.Float64: - return s.evalFloat(typ, n) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return s.evalInteger(typ, n) - case reflect.Interface: - if typ.NumMethod() == 0 { - return s.evalEmptyInterface(dot, n) - } - case reflect.String: - return s.evalString(typ, n) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return s.evalUnsignedInteger(typ, n) - } - s.errorf("can't handle %s for arg of type %s", n, typ) - panic("not reached") -} - -func (s *state) evalBool(typ reflect.Type, n parse.Node) reflect.Value { - s.at(n) - if n, ok := n.(*parse.BoolNode); ok { - value := reflect.New(typ).Elem() - value.SetBool(n.True) - return value - } - s.errorf("expected bool; found %s", n) - panic("not reached") -} - -func (s *state) evalString(typ reflect.Type, n parse.Node) reflect.Value { - s.at(n) - if n, ok := n.(*parse.StringNode); ok { - value := reflect.New(typ).Elem() - value.SetString(n.Text) - return value - } - s.errorf("expected string; found %s", n) - panic("not reached") -} - -func (s *state) evalInteger(typ reflect.Type, n parse.Node) reflect.Value { - s.at(n) - if n, ok := n.(*parse.NumberNode); ok && n.IsInt { - value := reflect.New(typ).Elem() - value.SetInt(n.Int64) - return value - } - s.errorf("expected integer; found %s", n) - panic("not reached") -} - -func (s *state) evalUnsignedInteger(typ reflect.Type, n parse.Node) reflect.Value { - s.at(n) - if n, ok := n.(*parse.NumberNode); ok && n.IsUint { - value := reflect.New(typ).Elem() - value.SetUint(n.Uint64) - return value - } - s.errorf("expected unsigned integer; found %s", n) - panic("not reached") -} - -func (s *state) evalFloat(typ reflect.Type, n parse.Node) reflect.Value { - s.at(n) - if n, ok := n.(*parse.NumberNode); ok && n.IsFloat { - value := reflect.New(typ).Elem() - value.SetFloat(n.Float64) - return value - } - s.errorf("expected float; found %s", n) - panic("not reached") -} - -func (s *state) evalComplex(typ reflect.Type, n parse.Node) reflect.Value { - if n, ok := n.(*parse.NumberNode); ok && n.IsComplex { - value := reflect.New(typ).Elem() - value.SetComplex(n.Complex128) - return value - } - s.errorf("expected complex; found %s", n) - panic("not reached") -} - -func (s *state) evalEmptyInterface(dot reflect.Value, n parse.Node) reflect.Value { - s.at(n) - switch n := n.(type) { - case *parse.BoolNode: - return reflect.ValueOf(n.True) - case *parse.DotNode: - return dot - case *parse.FieldNode: - return s.evalFieldNode(dot, n, nil, zero) - case *parse.IdentifierNode: - return s.evalFunction(dot, n, n, nil, zero) - case *parse.NilNode: - // NilNode is handled in evalArg, the only place that calls here. - s.errorf("evalEmptyInterface: nil (can't happen)") - case *parse.NumberNode: - return s.idealConstant(n) - case *parse.StringNode: - return reflect.ValueOf(n.Text) - case *parse.VariableNode: - return s.evalVariableNode(dot, n, nil, zero) - case *parse.PipeNode: - return s.evalPipeline(dot, n) - } - s.errorf("can't handle assignment of %s to empty interface argument", n) - panic("not reached") -} - -// indirect returns the item at the end of indirection, and a bool to indicate if it's nil. -// We indirect through pointers and empty interfaces (only) because -// non-empty interfaces have methods we might need. -func indirect(v reflect.Value) (rv reflect.Value, isNil bool) { - for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() { - if v.IsNil() { - return v, true - } - if v.Kind() == reflect.Interface && v.NumMethod() > 0 { - break - } - } - return v, false -} - -// printValue writes the textual representation of the value to the output of -// the template. -func (s *state) printValue(n parse.Node, v reflect.Value) { - s.at(n) - iface, ok := printableValue(v) - if !ok { - s.errorf("can't print %s of type %s", n, v.Type()) - } - fmt.Fprint(s.wr, iface) -} - -// printableValue returns the, possibly indirected, interface value inside v that -// is best for a call to formatted printer. -func printableValue(v reflect.Value) (interface{}, bool) { - if v.Kind() == reflect.Ptr { - v, _ = indirect(v) // fmt.Fprint handles nil. - } - if !v.IsValid() { - return "", true - } - - if !v.Type().Implements(errorType) && !v.Type().Implements(fmtStringerType) { - if v.CanAddr() && (reflect.PtrTo(v.Type()).Implements(errorType) || reflect.PtrTo(v.Type()).Implements(fmtStringerType)) { - v = v.Addr() - } else { - switch v.Kind() { - case reflect.Chan, reflect.Func: - return nil, false - } - } - } - return v.Interface(), true -} - -// Types to help sort the keys in a map for reproducible output. - -type rvs []reflect.Value - -func (x rvs) Len() int { return len(x) } -func (x rvs) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -type rvInts struct{ rvs } - -func (x rvInts) Less(i, j int) bool { return x.rvs[i].Int() < x.rvs[j].Int() } - -type rvUints struct{ rvs } - -func (x rvUints) Less(i, j int) bool { return x.rvs[i].Uint() < x.rvs[j].Uint() } - -type rvFloats struct{ rvs } - -func (x rvFloats) Less(i, j int) bool { return x.rvs[i].Float() < x.rvs[j].Float() } - -type rvStrings struct{ rvs } - -func (x rvStrings) Less(i, j int) bool { return x.rvs[i].String() < x.rvs[j].String() } - -// sortKeys sorts (if it can) the slice of reflect.Values, which is a slice of map keys. -func sortKeys(v []reflect.Value) []reflect.Value { - if len(v) <= 1 { - return v - } - switch v[0].Kind() { - case reflect.Float32, reflect.Float64: - sort.Sort(rvFloats{v}) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - sort.Sort(rvInts{v}) - case reflect.String: - sort.Sort(rvStrings{v}) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - sort.Sort(rvUints{v}) - } - return v -} diff --git a/vendor/github.com/alecthomas/template/funcs.go b/vendor/github.com/alecthomas/template/funcs.go deleted file mode 100644 index 39ee5ed6..00000000 --- a/vendor/github.com/alecthomas/template/funcs.go +++ /dev/null @@ -1,598 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package template - -import ( - "bytes" - "errors" - "fmt" - "io" - "net/url" - "reflect" - "strings" - "unicode" - "unicode/utf8" -) - -// FuncMap is the type of the map defining the mapping from names to functions. -// Each function must have either a single return value, or two return values of -// which the second has type error. In that case, if the second (error) -// return value evaluates to non-nil during execution, execution terminates and -// Execute returns that error. -type FuncMap map[string]interface{} - -var builtins = FuncMap{ - "and": and, - "call": call, - "html": HTMLEscaper, - "index": index, - "js": JSEscaper, - "len": length, - "not": not, - "or": or, - "print": fmt.Sprint, - "printf": fmt.Sprintf, - "println": fmt.Sprintln, - "urlquery": URLQueryEscaper, - - // Comparisons - "eq": eq, // == - "ge": ge, // >= - "gt": gt, // > - "le": le, // <= - "lt": lt, // < - "ne": ne, // != -} - -var builtinFuncs = createValueFuncs(builtins) - -// createValueFuncs turns a FuncMap into a map[string]reflect.Value -func createValueFuncs(funcMap FuncMap) map[string]reflect.Value { - m := make(map[string]reflect.Value) - addValueFuncs(m, funcMap) - return m -} - -// addValueFuncs adds to values the functions in funcs, converting them to reflect.Values. -func addValueFuncs(out map[string]reflect.Value, in FuncMap) { - for name, fn := range in { - v := reflect.ValueOf(fn) - if v.Kind() != reflect.Func { - panic("value for " + name + " not a function") - } - if !goodFunc(v.Type()) { - panic(fmt.Errorf("can't install method/function %q with %d results", name, v.Type().NumOut())) - } - out[name] = v - } -} - -// addFuncs adds to values the functions in funcs. It does no checking of the input - -// call addValueFuncs first. -func addFuncs(out, in FuncMap) { - for name, fn := range in { - out[name] = fn - } -} - -// goodFunc checks that the function or method has the right result signature. -func goodFunc(typ reflect.Type) bool { - // We allow functions with 1 result or 2 results where the second is an error. - switch { - case typ.NumOut() == 1: - return true - case typ.NumOut() == 2 && typ.Out(1) == errorType: - return true - } - return false -} - -// findFunction looks for a function in the template, and global map. -func findFunction(name string, tmpl *Template) (reflect.Value, bool) { - if tmpl != nil && tmpl.common != nil { - if fn := tmpl.execFuncs[name]; fn.IsValid() { - return fn, true - } - } - if fn := builtinFuncs[name]; fn.IsValid() { - return fn, true - } - return reflect.Value{}, false -} - -// Indexing. - -// index returns the result of indexing its first argument by the following -// arguments. Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each -// indexed item must be a map, slice, or array. -func index(item interface{}, indices ...interface{}) (interface{}, error) { - v := reflect.ValueOf(item) - for _, i := range indices { - index := reflect.ValueOf(i) - var isNil bool - if v, isNil = indirect(v); isNil { - return nil, fmt.Errorf("index of nil pointer") - } - switch v.Kind() { - case reflect.Array, reflect.Slice, reflect.String: - var x int64 - switch index.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - x = index.Int() - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - x = int64(index.Uint()) - default: - return nil, fmt.Errorf("cannot index slice/array with type %s", index.Type()) - } - if x < 0 || x >= int64(v.Len()) { - return nil, fmt.Errorf("index out of range: %d", x) - } - v = v.Index(int(x)) - case reflect.Map: - if !index.IsValid() { - index = reflect.Zero(v.Type().Key()) - } - if !index.Type().AssignableTo(v.Type().Key()) { - return nil, fmt.Errorf("%s is not index type for %s", index.Type(), v.Type()) - } - if x := v.MapIndex(index); x.IsValid() { - v = x - } else { - v = reflect.Zero(v.Type().Elem()) - } - default: - return nil, fmt.Errorf("can't index item of type %s", v.Type()) - } - } - return v.Interface(), nil -} - -// Length - -// length returns the length of the item, with an error if it has no defined length. -func length(item interface{}) (int, error) { - v, isNil := indirect(reflect.ValueOf(item)) - if isNil { - return 0, fmt.Errorf("len of nil pointer") - } - switch v.Kind() { - case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String: - return v.Len(), nil - } - return 0, fmt.Errorf("len of type %s", v.Type()) -} - -// Function invocation - -// call returns the result of evaluating the first argument as a function. -// The function must return 1 result, or 2 results, the second of which is an error. -func call(fn interface{}, args ...interface{}) (interface{}, error) { - v := reflect.ValueOf(fn) - typ := v.Type() - if typ.Kind() != reflect.Func { - return nil, fmt.Errorf("non-function of type %s", typ) - } - if !goodFunc(typ) { - return nil, fmt.Errorf("function called with %d args; should be 1 or 2", typ.NumOut()) - } - numIn := typ.NumIn() - var dddType reflect.Type - if typ.IsVariadic() { - if len(args) < numIn-1 { - return nil, fmt.Errorf("wrong number of args: got %d want at least %d", len(args), numIn-1) - } - dddType = typ.In(numIn - 1).Elem() - } else { - if len(args) != numIn { - return nil, fmt.Errorf("wrong number of args: got %d want %d", len(args), numIn) - } - } - argv := make([]reflect.Value, len(args)) - for i, arg := range args { - value := reflect.ValueOf(arg) - // Compute the expected type. Clumsy because of variadics. - var argType reflect.Type - if !typ.IsVariadic() || i < numIn-1 { - argType = typ.In(i) - } else { - argType = dddType - } - if !value.IsValid() && canBeNil(argType) { - value = reflect.Zero(argType) - } - if !value.Type().AssignableTo(argType) { - return nil, fmt.Errorf("arg %d has type %s; should be %s", i, value.Type(), argType) - } - argv[i] = value - } - result := v.Call(argv) - if len(result) == 2 && !result[1].IsNil() { - return result[0].Interface(), result[1].Interface().(error) - } - return result[0].Interface(), nil -} - -// Boolean logic. - -func truth(a interface{}) bool { - t, _ := isTrue(reflect.ValueOf(a)) - return t -} - -// and computes the Boolean AND of its arguments, returning -// the first false argument it encounters, or the last argument. -func and(arg0 interface{}, args ...interface{}) interface{} { - if !truth(arg0) { - return arg0 - } - for i := range args { - arg0 = args[i] - if !truth(arg0) { - break - } - } - return arg0 -} - -// or computes the Boolean OR of its arguments, returning -// the first true argument it encounters, or the last argument. -func or(arg0 interface{}, args ...interface{}) interface{} { - if truth(arg0) { - return arg0 - } - for i := range args { - arg0 = args[i] - if truth(arg0) { - break - } - } - return arg0 -} - -// not returns the Boolean negation of its argument. -func not(arg interface{}) (truth bool) { - truth, _ = isTrue(reflect.ValueOf(arg)) - return !truth -} - -// Comparison. - -// TODO: Perhaps allow comparison between signed and unsigned integers. - -var ( - errBadComparisonType = errors.New("invalid type for comparison") - errBadComparison = errors.New("incompatible types for comparison") - errNoComparison = errors.New("missing argument for comparison") -) - -type kind int - -const ( - invalidKind kind = iota - boolKind - complexKind - intKind - floatKind - integerKind - stringKind - uintKind -) - -func basicKind(v reflect.Value) (kind, error) { - switch v.Kind() { - case reflect.Bool: - return boolKind, nil - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return intKind, nil - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return uintKind, nil - case reflect.Float32, reflect.Float64: - return floatKind, nil - case reflect.Complex64, reflect.Complex128: - return complexKind, nil - case reflect.String: - return stringKind, nil - } - return invalidKind, errBadComparisonType -} - -// eq evaluates the comparison a == b || a == c || ... -func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) { - v1 := reflect.ValueOf(arg1) - k1, err := basicKind(v1) - if err != nil { - return false, err - } - if len(arg2) == 0 { - return false, errNoComparison - } - for _, arg := range arg2 { - v2 := reflect.ValueOf(arg) - k2, err := basicKind(v2) - if err != nil { - return false, err - } - truth := false - if k1 != k2 { - // Special case: Can compare integer values regardless of type's sign. - switch { - case k1 == intKind && k2 == uintKind: - truth = v1.Int() >= 0 && uint64(v1.Int()) == v2.Uint() - case k1 == uintKind && k2 == intKind: - truth = v2.Int() >= 0 && v1.Uint() == uint64(v2.Int()) - default: - return false, errBadComparison - } - } else { - switch k1 { - case boolKind: - truth = v1.Bool() == v2.Bool() - case complexKind: - truth = v1.Complex() == v2.Complex() - case floatKind: - truth = v1.Float() == v2.Float() - case intKind: - truth = v1.Int() == v2.Int() - case stringKind: - truth = v1.String() == v2.String() - case uintKind: - truth = v1.Uint() == v2.Uint() - default: - panic("invalid kind") - } - } - if truth { - return true, nil - } - } - return false, nil -} - -// ne evaluates the comparison a != b. -func ne(arg1, arg2 interface{}) (bool, error) { - // != is the inverse of ==. - equal, err := eq(arg1, arg2) - return !equal, err -} - -// lt evaluates the comparison a < b. -func lt(arg1, arg2 interface{}) (bool, error) { - v1 := reflect.ValueOf(arg1) - k1, err := basicKind(v1) - if err != nil { - return false, err - } - v2 := reflect.ValueOf(arg2) - k2, err := basicKind(v2) - if err != nil { - return false, err - } - truth := false - if k1 != k2 { - // Special case: Can compare integer values regardless of type's sign. - switch { - case k1 == intKind && k2 == uintKind: - truth = v1.Int() < 0 || uint64(v1.Int()) < v2.Uint() - case k1 == uintKind && k2 == intKind: - truth = v2.Int() >= 0 && v1.Uint() < uint64(v2.Int()) - default: - return false, errBadComparison - } - } else { - switch k1 { - case boolKind, complexKind: - return false, errBadComparisonType - case floatKind: - truth = v1.Float() < v2.Float() - case intKind: - truth = v1.Int() < v2.Int() - case stringKind: - truth = v1.String() < v2.String() - case uintKind: - truth = v1.Uint() < v2.Uint() - default: - panic("invalid kind") - } - } - return truth, nil -} - -// le evaluates the comparison <= b. -func le(arg1, arg2 interface{}) (bool, error) { - // <= is < or ==. - lessThan, err := lt(arg1, arg2) - if lessThan || err != nil { - return lessThan, err - } - return eq(arg1, arg2) -} - -// gt evaluates the comparison a > b. -func gt(arg1, arg2 interface{}) (bool, error) { - // > is the inverse of <=. - lessOrEqual, err := le(arg1, arg2) - if err != nil { - return false, err - } - return !lessOrEqual, nil -} - -// ge evaluates the comparison a >= b. -func ge(arg1, arg2 interface{}) (bool, error) { - // >= is the inverse of <. - lessThan, err := lt(arg1, arg2) - if err != nil { - return false, err - } - return !lessThan, nil -} - -// HTML escaping. - -var ( - htmlQuot = []byte(""") // shorter than """ - htmlApos = []byte("'") // shorter than "'" and apos was not in HTML until HTML5 - htmlAmp = []byte("&") - htmlLt = []byte("<") - htmlGt = []byte(">") -) - -// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b. -func HTMLEscape(w io.Writer, b []byte) { - last := 0 - for i, c := range b { - var html []byte - switch c { - case '"': - html = htmlQuot - case '\'': - html = htmlApos - case '&': - html = htmlAmp - case '<': - html = htmlLt - case '>': - html = htmlGt - default: - continue - } - w.Write(b[last:i]) - w.Write(html) - last = i + 1 - } - w.Write(b[last:]) -} - -// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s. -func HTMLEscapeString(s string) string { - // Avoid allocation if we can. - if strings.IndexAny(s, `'"&<>`) < 0 { - return s - } - var b bytes.Buffer - HTMLEscape(&b, []byte(s)) - return b.String() -} - -// HTMLEscaper returns the escaped HTML equivalent of the textual -// representation of its arguments. -func HTMLEscaper(args ...interface{}) string { - return HTMLEscapeString(evalArgs(args)) -} - -// JavaScript escaping. - -var ( - jsLowUni = []byte(`\u00`) - hex = []byte("0123456789ABCDEF") - - jsBackslash = []byte(`\\`) - jsApos = []byte(`\'`) - jsQuot = []byte(`\"`) - jsLt = []byte(`\x3C`) - jsGt = []byte(`\x3E`) -) - -// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b. -func JSEscape(w io.Writer, b []byte) { - last := 0 - for i := 0; i < len(b); i++ { - c := b[i] - - if !jsIsSpecial(rune(c)) { - // fast path: nothing to do - continue - } - w.Write(b[last:i]) - - if c < utf8.RuneSelf { - // Quotes, slashes and angle brackets get quoted. - // Control characters get written as \u00XX. - switch c { - case '\\': - w.Write(jsBackslash) - case '\'': - w.Write(jsApos) - case '"': - w.Write(jsQuot) - case '<': - w.Write(jsLt) - case '>': - w.Write(jsGt) - default: - w.Write(jsLowUni) - t, b := c>>4, c&0x0f - w.Write(hex[t : t+1]) - w.Write(hex[b : b+1]) - } - } else { - // Unicode rune. - r, size := utf8.DecodeRune(b[i:]) - if unicode.IsPrint(r) { - w.Write(b[i : i+size]) - } else { - fmt.Fprintf(w, "\\u%04X", r) - } - i += size - 1 - } - last = i + 1 - } - w.Write(b[last:]) -} - -// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s. -func JSEscapeString(s string) string { - // Avoid allocation if we can. - if strings.IndexFunc(s, jsIsSpecial) < 0 { - return s - } - var b bytes.Buffer - JSEscape(&b, []byte(s)) - return b.String() -} - -func jsIsSpecial(r rune) bool { - switch r { - case '\\', '\'', '"', '<', '>': - return true - } - return r < ' ' || utf8.RuneSelf <= r -} - -// JSEscaper returns the escaped JavaScript equivalent of the textual -// representation of its arguments. -func JSEscaper(args ...interface{}) string { - return JSEscapeString(evalArgs(args)) -} - -// URLQueryEscaper returns the escaped value of the textual representation of -// its arguments in a form suitable for embedding in a URL query. -func URLQueryEscaper(args ...interface{}) string { - return url.QueryEscape(evalArgs(args)) -} - -// evalArgs formats the list of arguments into a string. It is therefore equivalent to -// fmt.Sprint(args...) -// except that each argument is indirected (if a pointer), as required, -// using the same rules as the default string evaluation during template -// execution. -func evalArgs(args []interface{}) string { - ok := false - var s string - // Fast path for simple common case. - if len(args) == 1 { - s, ok = args[0].(string) - } - if !ok { - for i, arg := range args { - a, ok := printableValue(reflect.ValueOf(arg)) - if ok { - args[i] = a - } // else left fmt do its thing - } - s = fmt.Sprint(args...) - } - return s -} diff --git a/vendor/github.com/alecthomas/template/helper.go b/vendor/github.com/alecthomas/template/helper.go deleted file mode 100644 index 3636fb54..00000000 --- a/vendor/github.com/alecthomas/template/helper.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Helper functions to make constructing templates easier. - -package template - -import ( - "fmt" - "io/ioutil" - "path/filepath" -) - -// Functions and methods to parse templates. - -// Must is a helper that wraps a call to a function returning (*Template, error) -// and panics if the error is non-nil. It is intended for use in variable -// initializations such as -// var t = template.Must(template.New("name").Parse("text")) -func Must(t *Template, err error) *Template { - if err != nil { - panic(err) - } - return t -} - -// ParseFiles creates a new Template and parses the template definitions from -// the named files. The returned template's name will have the (base) name and -// (parsed) contents of the first file. There must be at least one file. -// If an error occurs, parsing stops and the returned *Template is nil. -func ParseFiles(filenames ...string) (*Template, error) { - return parseFiles(nil, filenames...) -} - -// ParseFiles parses the named files and associates the resulting templates with -// t. If an error occurs, parsing stops and the returned template is nil; -// otherwise it is t. There must be at least one file. -func (t *Template) ParseFiles(filenames ...string) (*Template, error) { - return parseFiles(t, filenames...) -} - -// parseFiles is the helper for the method and function. If the argument -// template is nil, it is created from the first file. -func parseFiles(t *Template, filenames ...string) (*Template, error) { - if len(filenames) == 0 { - // Not really a problem, but be consistent. - return nil, fmt.Errorf("template: no files named in call to ParseFiles") - } - for _, filename := range filenames { - b, err := ioutil.ReadFile(filename) - if err != nil { - return nil, err - } - s := string(b) - name := filepath.Base(filename) - // First template becomes return value if not already defined, - // and we use that one for subsequent New calls to associate - // all the templates together. Also, if this file has the same name - // as t, this file becomes the contents of t, so - // t, err := New(name).Funcs(xxx).ParseFiles(name) - // works. Otherwise we create a new template associated with t. - var tmpl *Template - if t == nil { - t = New(name) - } - if name == t.Name() { - tmpl = t - } else { - tmpl = t.New(name) - } - _, err = tmpl.Parse(s) - if err != nil { - return nil, err - } - } - return t, nil -} - -// ParseGlob creates a new Template and parses the template definitions from the -// files identified by the pattern, which must match at least one file. The -// returned template will have the (base) name and (parsed) contents of the -// first file matched by the pattern. ParseGlob is equivalent to calling -// ParseFiles with the list of files matched by the pattern. -func ParseGlob(pattern string) (*Template, error) { - return parseGlob(nil, pattern) -} - -// ParseGlob parses the template definitions in the files identified by the -// pattern and associates the resulting templates with t. The pattern is -// processed by filepath.Glob and must match at least one file. ParseGlob is -// equivalent to calling t.ParseFiles with the list of files matched by the -// pattern. -func (t *Template) ParseGlob(pattern string) (*Template, error) { - return parseGlob(t, pattern) -} - -// parseGlob is the implementation of the function and method ParseGlob. -func parseGlob(t *Template, pattern string) (*Template, error) { - filenames, err := filepath.Glob(pattern) - if err != nil { - return nil, err - } - if len(filenames) == 0 { - return nil, fmt.Errorf("template: pattern matches no files: %#q", pattern) - } - return parseFiles(t, filenames...) -} diff --git a/vendor/github.com/alecthomas/template/parse/lex.go b/vendor/github.com/alecthomas/template/parse/lex.go deleted file mode 100644 index 55f1c051..00000000 --- a/vendor/github.com/alecthomas/template/parse/lex.go +++ /dev/null @@ -1,556 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package parse - -import ( - "fmt" - "strings" - "unicode" - "unicode/utf8" -) - -// item represents a token or text string returned from the scanner. -type item struct { - typ itemType // The type of this item. - pos Pos // The starting position, in bytes, of this item in the input string. - val string // The value of this item. -} - -func (i item) String() string { - switch { - case i.typ == itemEOF: - return "EOF" - case i.typ == itemError: - return i.val - case i.typ > itemKeyword: - return fmt.Sprintf("<%s>", i.val) - case len(i.val) > 10: - return fmt.Sprintf("%.10q...", i.val) - } - return fmt.Sprintf("%q", i.val) -} - -// itemType identifies the type of lex items. -type itemType int - -const ( - itemError itemType = iota // error occurred; value is text of error - itemBool // boolean constant - itemChar // printable ASCII character; grab bag for comma etc. - itemCharConstant // character constant - itemComplex // complex constant (1+2i); imaginary is just a number - itemColonEquals // colon-equals (':=') introducing a declaration - itemEOF - itemField // alphanumeric identifier starting with '.' - itemIdentifier // alphanumeric identifier not starting with '.' - itemLeftDelim // left action delimiter - itemLeftParen // '(' inside action - itemNumber // simple number, including imaginary - itemPipe // pipe symbol - itemRawString // raw quoted string (includes quotes) - itemRightDelim // right action delimiter - itemElideNewline // elide newline after right delim - itemRightParen // ')' inside action - itemSpace // run of spaces separating arguments - itemString // quoted string (includes quotes) - itemText // plain text - itemVariable // variable starting with '$', such as '$' or '$1' or '$hello' - // Keywords appear after all the rest. - itemKeyword // used only to delimit the keywords - itemDot // the cursor, spelled '.' - itemDefine // define keyword - itemElse // else keyword - itemEnd // end keyword - itemIf // if keyword - itemNil // the untyped nil constant, easiest to treat as a keyword - itemRange // range keyword - itemTemplate // template keyword - itemWith // with keyword -) - -var key = map[string]itemType{ - ".": itemDot, - "define": itemDefine, - "else": itemElse, - "end": itemEnd, - "if": itemIf, - "range": itemRange, - "nil": itemNil, - "template": itemTemplate, - "with": itemWith, -} - -const eof = -1 - -// stateFn represents the state of the scanner as a function that returns the next state. -type stateFn func(*lexer) stateFn - -// lexer holds the state of the scanner. -type lexer struct { - name string // the name of the input; used only for error reports - input string // the string being scanned - leftDelim string // start of action - rightDelim string // end of action - state stateFn // the next lexing function to enter - pos Pos // current position in the input - start Pos // start position of this item - width Pos // width of last rune read from input - lastPos Pos // position of most recent item returned by nextItem - items chan item // channel of scanned items - parenDepth int // nesting depth of ( ) exprs -} - -// next returns the next rune in the input. -func (l *lexer) next() rune { - if int(l.pos) >= len(l.input) { - l.width = 0 - return eof - } - r, w := utf8.DecodeRuneInString(l.input[l.pos:]) - l.width = Pos(w) - l.pos += l.width - return r -} - -// peek returns but does not consume the next rune in the input. -func (l *lexer) peek() rune { - r := l.next() - l.backup() - return r -} - -// backup steps back one rune. Can only be called once per call of next. -func (l *lexer) backup() { - l.pos -= l.width -} - -// emit passes an item back to the client. -func (l *lexer) emit(t itemType) { - l.items <- item{t, l.start, l.input[l.start:l.pos]} - l.start = l.pos -} - -// ignore skips over the pending input before this point. -func (l *lexer) ignore() { - l.start = l.pos -} - -// accept consumes the next rune if it's from the valid set. -func (l *lexer) accept(valid string) bool { - if strings.IndexRune(valid, l.next()) >= 0 { - return true - } - l.backup() - return false -} - -// acceptRun consumes a run of runes from the valid set. -func (l *lexer) acceptRun(valid string) { - for strings.IndexRune(valid, l.next()) >= 0 { - } - l.backup() -} - -// lineNumber reports which line we're on, based on the position of -// the previous item returned by nextItem. Doing it this way -// means we don't have to worry about peek double counting. -func (l *lexer) lineNumber() int { - return 1 + strings.Count(l.input[:l.lastPos], "\n") -} - -// errorf returns an error token and terminates the scan by passing -// back a nil pointer that will be the next state, terminating l.nextItem. -func (l *lexer) errorf(format string, args ...interface{}) stateFn { - l.items <- item{itemError, l.start, fmt.Sprintf(format, args...)} - return nil -} - -// nextItem returns the next item from the input. -func (l *lexer) nextItem() item { - item := <-l.items - l.lastPos = item.pos - return item -} - -// lex creates a new scanner for the input string. -func lex(name, input, left, right string) *lexer { - if left == "" { - left = leftDelim - } - if right == "" { - right = rightDelim - } - l := &lexer{ - name: name, - input: input, - leftDelim: left, - rightDelim: right, - items: make(chan item), - } - go l.run() - return l -} - -// run runs the state machine for the lexer. -func (l *lexer) run() { - for l.state = lexText; l.state != nil; { - l.state = l.state(l) - } -} - -// state functions - -const ( - leftDelim = "{{" - rightDelim = "}}" - leftComment = "/*" - rightComment = "*/" -) - -// lexText scans until an opening action delimiter, "{{". -func lexText(l *lexer) stateFn { - for { - if strings.HasPrefix(l.input[l.pos:], l.leftDelim) { - if l.pos > l.start { - l.emit(itemText) - } - return lexLeftDelim - } - if l.next() == eof { - break - } - } - // Correctly reached EOF. - if l.pos > l.start { - l.emit(itemText) - } - l.emit(itemEOF) - return nil -} - -// lexLeftDelim scans the left delimiter, which is known to be present. -func lexLeftDelim(l *lexer) stateFn { - l.pos += Pos(len(l.leftDelim)) - if strings.HasPrefix(l.input[l.pos:], leftComment) { - return lexComment - } - l.emit(itemLeftDelim) - l.parenDepth = 0 - return lexInsideAction -} - -// lexComment scans a comment. The left comment marker is known to be present. -func lexComment(l *lexer) stateFn { - l.pos += Pos(len(leftComment)) - i := strings.Index(l.input[l.pos:], rightComment) - if i < 0 { - return l.errorf("unclosed comment") - } - l.pos += Pos(i + len(rightComment)) - if !strings.HasPrefix(l.input[l.pos:], l.rightDelim) { - return l.errorf("comment ends before closing delimiter") - - } - l.pos += Pos(len(l.rightDelim)) - l.ignore() - return lexText -} - -// lexRightDelim scans the right delimiter, which is known to be present. -func lexRightDelim(l *lexer) stateFn { - l.pos += Pos(len(l.rightDelim)) - l.emit(itemRightDelim) - if l.peek() == '\\' { - l.pos++ - l.emit(itemElideNewline) - } - return lexText -} - -// lexInsideAction scans the elements inside action delimiters. -func lexInsideAction(l *lexer) stateFn { - // Either number, quoted string, or identifier. - // Spaces separate arguments; runs of spaces turn into itemSpace. - // Pipe symbols separate and are emitted. - if strings.HasPrefix(l.input[l.pos:], l.rightDelim+"\\") || strings.HasPrefix(l.input[l.pos:], l.rightDelim) { - if l.parenDepth == 0 { - return lexRightDelim - } - return l.errorf("unclosed left paren") - } - switch r := l.next(); { - case r == eof || isEndOfLine(r): - return l.errorf("unclosed action") - case isSpace(r): - return lexSpace - case r == ':': - if l.next() != '=' { - return l.errorf("expected :=") - } - l.emit(itemColonEquals) - case r == '|': - l.emit(itemPipe) - case r == '"': - return lexQuote - case r == '`': - return lexRawQuote - case r == '$': - return lexVariable - case r == '\'': - return lexChar - case r == '.': - // special look-ahead for ".field" so we don't break l.backup(). - if l.pos < Pos(len(l.input)) { - r := l.input[l.pos] - if r < '0' || '9' < r { - return lexField - } - } - fallthrough // '.' can start a number. - case r == '+' || r == '-' || ('0' <= r && r <= '9'): - l.backup() - return lexNumber - case isAlphaNumeric(r): - l.backup() - return lexIdentifier - case r == '(': - l.emit(itemLeftParen) - l.parenDepth++ - return lexInsideAction - case r == ')': - l.emit(itemRightParen) - l.parenDepth-- - if l.parenDepth < 0 { - return l.errorf("unexpected right paren %#U", r) - } - return lexInsideAction - case r <= unicode.MaxASCII && unicode.IsPrint(r): - l.emit(itemChar) - return lexInsideAction - default: - return l.errorf("unrecognized character in action: %#U", r) - } - return lexInsideAction -} - -// lexSpace scans a run of space characters. -// One space has already been seen. -func lexSpace(l *lexer) stateFn { - for isSpace(l.peek()) { - l.next() - } - l.emit(itemSpace) - return lexInsideAction -} - -// lexIdentifier scans an alphanumeric. -func lexIdentifier(l *lexer) stateFn { -Loop: - for { - switch r := l.next(); { - case isAlphaNumeric(r): - // absorb. - default: - l.backup() - word := l.input[l.start:l.pos] - if !l.atTerminator() { - return l.errorf("bad character %#U", r) - } - switch { - case key[word] > itemKeyword: - l.emit(key[word]) - case word[0] == '.': - l.emit(itemField) - case word == "true", word == "false": - l.emit(itemBool) - default: - l.emit(itemIdentifier) - } - break Loop - } - } - return lexInsideAction -} - -// lexField scans a field: .Alphanumeric. -// The . has been scanned. -func lexField(l *lexer) stateFn { - return lexFieldOrVariable(l, itemField) -} - -// lexVariable scans a Variable: $Alphanumeric. -// The $ has been scanned. -func lexVariable(l *lexer) stateFn { - if l.atTerminator() { // Nothing interesting follows -> "$". - l.emit(itemVariable) - return lexInsideAction - } - return lexFieldOrVariable(l, itemVariable) -} - -// lexVariable scans a field or variable: [.$]Alphanumeric. -// The . or $ has been scanned. -func lexFieldOrVariable(l *lexer, typ itemType) stateFn { - if l.atTerminator() { // Nothing interesting follows -> "." or "$". - if typ == itemVariable { - l.emit(itemVariable) - } else { - l.emit(itemDot) - } - return lexInsideAction - } - var r rune - for { - r = l.next() - if !isAlphaNumeric(r) { - l.backup() - break - } - } - if !l.atTerminator() { - return l.errorf("bad character %#U", r) - } - l.emit(typ) - return lexInsideAction -} - -// atTerminator reports whether the input is at valid termination character to -// appear after an identifier. Breaks .X.Y into two pieces. Also catches cases -// like "$x+2" not being acceptable without a space, in case we decide one -// day to implement arithmetic. -func (l *lexer) atTerminator() bool { - r := l.peek() - if isSpace(r) || isEndOfLine(r) { - return true - } - switch r { - case eof, '.', ',', '|', ':', ')', '(': - return true - } - // Does r start the delimiter? This can be ambiguous (with delim=="//", $x/2 will - // succeed but should fail) but only in extremely rare cases caused by willfully - // bad choice of delimiter. - if rd, _ := utf8.DecodeRuneInString(l.rightDelim); rd == r { - return true - } - return false -} - -// lexChar scans a character constant. The initial quote is already -// scanned. Syntax checking is done by the parser. -func lexChar(l *lexer) stateFn { -Loop: - for { - switch l.next() { - case '\\': - if r := l.next(); r != eof && r != '\n' { - break - } - fallthrough - case eof, '\n': - return l.errorf("unterminated character constant") - case '\'': - break Loop - } - } - l.emit(itemCharConstant) - return lexInsideAction -} - -// lexNumber scans a number: decimal, octal, hex, float, or imaginary. This -// isn't a perfect number scanner - for instance it accepts "." and "0x0.2" -// and "089" - but when it's wrong the input is invalid and the parser (via -// strconv) will notice. -func lexNumber(l *lexer) stateFn { - if !l.scanNumber() { - return l.errorf("bad number syntax: %q", l.input[l.start:l.pos]) - } - if sign := l.peek(); sign == '+' || sign == '-' { - // Complex: 1+2i. No spaces, must end in 'i'. - if !l.scanNumber() || l.input[l.pos-1] != 'i' { - return l.errorf("bad number syntax: %q", l.input[l.start:l.pos]) - } - l.emit(itemComplex) - } else { - l.emit(itemNumber) - } - return lexInsideAction -} - -func (l *lexer) scanNumber() bool { - // Optional leading sign. - l.accept("+-") - // Is it hex? - digits := "0123456789" - if l.accept("0") && l.accept("xX") { - digits = "0123456789abcdefABCDEF" - } - l.acceptRun(digits) - if l.accept(".") { - l.acceptRun(digits) - } - if l.accept("eE") { - l.accept("+-") - l.acceptRun("0123456789") - } - // Is it imaginary? - l.accept("i") - // Next thing mustn't be alphanumeric. - if isAlphaNumeric(l.peek()) { - l.next() - return false - } - return true -} - -// lexQuote scans a quoted string. -func lexQuote(l *lexer) stateFn { -Loop: - for { - switch l.next() { - case '\\': - if r := l.next(); r != eof && r != '\n' { - break - } - fallthrough - case eof, '\n': - return l.errorf("unterminated quoted string") - case '"': - break Loop - } - } - l.emit(itemString) - return lexInsideAction -} - -// lexRawQuote scans a raw quoted string. -func lexRawQuote(l *lexer) stateFn { -Loop: - for { - switch l.next() { - case eof, '\n': - return l.errorf("unterminated raw quoted string") - case '`': - break Loop - } - } - l.emit(itemRawString) - return lexInsideAction -} - -// isSpace reports whether r is a space character. -func isSpace(r rune) bool { - return r == ' ' || r == '\t' -} - -// isEndOfLine reports whether r is an end-of-line character. -func isEndOfLine(r rune) bool { - return r == '\r' || r == '\n' -} - -// isAlphaNumeric reports whether r is an alphabetic, digit, or underscore. -func isAlphaNumeric(r rune) bool { - return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r) -} diff --git a/vendor/github.com/alecthomas/template/parse/node.go b/vendor/github.com/alecthomas/template/parse/node.go deleted file mode 100644 index 55c37f6d..00000000 --- a/vendor/github.com/alecthomas/template/parse/node.go +++ /dev/null @@ -1,834 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Parse nodes. - -package parse - -import ( - "bytes" - "fmt" - "strconv" - "strings" -) - -var textFormat = "%s" // Changed to "%q" in tests for better error messages. - -// A Node is an element in the parse tree. The interface is trivial. -// The interface contains an unexported method so that only -// types local to this package can satisfy it. -type Node interface { - Type() NodeType - String() string - // Copy does a deep copy of the Node and all its components. - // To avoid type assertions, some XxxNodes also have specialized - // CopyXxx methods that return *XxxNode. - Copy() Node - Position() Pos // byte position of start of node in full original input string - // tree returns the containing *Tree. - // It is unexported so all implementations of Node are in this package. - tree() *Tree -} - -// NodeType identifies the type of a parse tree node. -type NodeType int - -// Pos represents a byte position in the original input text from which -// this template was parsed. -type Pos int - -func (p Pos) Position() Pos { - return p -} - -// Type returns itself and provides an easy default implementation -// for embedding in a Node. Embedded in all non-trivial Nodes. -func (t NodeType) Type() NodeType { - return t -} - -const ( - NodeText NodeType = iota // Plain text. - NodeAction // A non-control action such as a field evaluation. - NodeBool // A boolean constant. - NodeChain // A sequence of field accesses. - NodeCommand // An element of a pipeline. - NodeDot // The cursor, dot. - nodeElse // An else action. Not added to tree. - nodeEnd // An end action. Not added to tree. - NodeField // A field or method name. - NodeIdentifier // An identifier; always a function name. - NodeIf // An if action. - NodeList // A list of Nodes. - NodeNil // An untyped nil constant. - NodeNumber // A numerical constant. - NodePipe // A pipeline of commands. - NodeRange // A range action. - NodeString // A string constant. - NodeTemplate // A template invocation action. - NodeVariable // A $ variable. - NodeWith // A with action. -) - -// Nodes. - -// ListNode holds a sequence of nodes. -type ListNode struct { - NodeType - Pos - tr *Tree - Nodes []Node // The element nodes in lexical order. -} - -func (t *Tree) newList(pos Pos) *ListNode { - return &ListNode{tr: t, NodeType: NodeList, Pos: pos} -} - -func (l *ListNode) append(n Node) { - l.Nodes = append(l.Nodes, n) -} - -func (l *ListNode) tree() *Tree { - return l.tr -} - -func (l *ListNode) String() string { - b := new(bytes.Buffer) - for _, n := range l.Nodes { - fmt.Fprint(b, n) - } - return b.String() -} - -func (l *ListNode) CopyList() *ListNode { - if l == nil { - return l - } - n := l.tr.newList(l.Pos) - for _, elem := range l.Nodes { - n.append(elem.Copy()) - } - return n -} - -func (l *ListNode) Copy() Node { - return l.CopyList() -} - -// TextNode holds plain text. -type TextNode struct { - NodeType - Pos - tr *Tree - Text []byte // The text; may span newlines. -} - -func (t *Tree) newText(pos Pos, text string) *TextNode { - return &TextNode{tr: t, NodeType: NodeText, Pos: pos, Text: []byte(text)} -} - -func (t *TextNode) String() string { - return fmt.Sprintf(textFormat, t.Text) -} - -func (t *TextNode) tree() *Tree { - return t.tr -} - -func (t *TextNode) Copy() Node { - return &TextNode{tr: t.tr, NodeType: NodeText, Pos: t.Pos, Text: append([]byte{}, t.Text...)} -} - -// PipeNode holds a pipeline with optional declaration -type PipeNode struct { - NodeType - Pos - tr *Tree - Line int // The line number in the input (deprecated; kept for compatibility) - Decl []*VariableNode // Variable declarations in lexical order. - Cmds []*CommandNode // The commands in lexical order. -} - -func (t *Tree) newPipeline(pos Pos, line int, decl []*VariableNode) *PipeNode { - return &PipeNode{tr: t, NodeType: NodePipe, Pos: pos, Line: line, Decl: decl} -} - -func (p *PipeNode) append(command *CommandNode) { - p.Cmds = append(p.Cmds, command) -} - -func (p *PipeNode) String() string { - s := "" - if len(p.Decl) > 0 { - for i, v := range p.Decl { - if i > 0 { - s += ", " - } - s += v.String() - } - s += " := " - } - for i, c := range p.Cmds { - if i > 0 { - s += " | " - } - s += c.String() - } - return s -} - -func (p *PipeNode) tree() *Tree { - return p.tr -} - -func (p *PipeNode) CopyPipe() *PipeNode { - if p == nil { - return p - } - var decl []*VariableNode - for _, d := range p.Decl { - decl = append(decl, d.Copy().(*VariableNode)) - } - n := p.tr.newPipeline(p.Pos, p.Line, decl) - for _, c := range p.Cmds { - n.append(c.Copy().(*CommandNode)) - } - return n -} - -func (p *PipeNode) Copy() Node { - return p.CopyPipe() -} - -// ActionNode holds an action (something bounded by delimiters). -// Control actions have their own nodes; ActionNode represents simple -// ones such as field evaluations and parenthesized pipelines. -type ActionNode struct { - NodeType - Pos - tr *Tree - Line int // The line number in the input (deprecated; kept for compatibility) - Pipe *PipeNode // The pipeline in the action. -} - -func (t *Tree) newAction(pos Pos, line int, pipe *PipeNode) *ActionNode { - return &ActionNode{tr: t, NodeType: NodeAction, Pos: pos, Line: line, Pipe: pipe} -} - -func (a *ActionNode) String() string { - return fmt.Sprintf("{{%s}}", a.Pipe) - -} - -func (a *ActionNode) tree() *Tree { - return a.tr -} - -func (a *ActionNode) Copy() Node { - return a.tr.newAction(a.Pos, a.Line, a.Pipe.CopyPipe()) - -} - -// CommandNode holds a command (a pipeline inside an evaluating action). -type CommandNode struct { - NodeType - Pos - tr *Tree - Args []Node // Arguments in lexical order: Identifier, field, or constant. -} - -func (t *Tree) newCommand(pos Pos) *CommandNode { - return &CommandNode{tr: t, NodeType: NodeCommand, Pos: pos} -} - -func (c *CommandNode) append(arg Node) { - c.Args = append(c.Args, arg) -} - -func (c *CommandNode) String() string { - s := "" - for i, arg := range c.Args { - if i > 0 { - s += " " - } - if arg, ok := arg.(*PipeNode); ok { - s += "(" + arg.String() + ")" - continue - } - s += arg.String() - } - return s -} - -func (c *CommandNode) tree() *Tree { - return c.tr -} - -func (c *CommandNode) Copy() Node { - if c == nil { - return c - } - n := c.tr.newCommand(c.Pos) - for _, c := range c.Args { - n.append(c.Copy()) - } - return n -} - -// IdentifierNode holds an identifier. -type IdentifierNode struct { - NodeType - Pos - tr *Tree - Ident string // The identifier's name. -} - -// NewIdentifier returns a new IdentifierNode with the given identifier name. -func NewIdentifier(ident string) *IdentifierNode { - return &IdentifierNode{NodeType: NodeIdentifier, Ident: ident} -} - -// SetPos sets the position. NewIdentifier is a public method so we can't modify its signature. -// Chained for convenience. -// TODO: fix one day? -func (i *IdentifierNode) SetPos(pos Pos) *IdentifierNode { - i.Pos = pos - return i -} - -// SetTree sets the parent tree for the node. NewIdentifier is a public method so we can't modify its signature. -// Chained for convenience. -// TODO: fix one day? -func (i *IdentifierNode) SetTree(t *Tree) *IdentifierNode { - i.tr = t - return i -} - -func (i *IdentifierNode) String() string { - return i.Ident -} - -func (i *IdentifierNode) tree() *Tree { - return i.tr -} - -func (i *IdentifierNode) Copy() Node { - return NewIdentifier(i.Ident).SetTree(i.tr).SetPos(i.Pos) -} - -// VariableNode holds a list of variable names, possibly with chained field -// accesses. The dollar sign is part of the (first) name. -type VariableNode struct { - NodeType - Pos - tr *Tree - Ident []string // Variable name and fields in lexical order. -} - -func (t *Tree) newVariable(pos Pos, ident string) *VariableNode { - return &VariableNode{tr: t, NodeType: NodeVariable, Pos: pos, Ident: strings.Split(ident, ".")} -} - -func (v *VariableNode) String() string { - s := "" - for i, id := range v.Ident { - if i > 0 { - s += "." - } - s += id - } - return s -} - -func (v *VariableNode) tree() *Tree { - return v.tr -} - -func (v *VariableNode) Copy() Node { - return &VariableNode{tr: v.tr, NodeType: NodeVariable, Pos: v.Pos, Ident: append([]string{}, v.Ident...)} -} - -// DotNode holds the special identifier '.'. -type DotNode struct { - NodeType - Pos - tr *Tree -} - -func (t *Tree) newDot(pos Pos) *DotNode { - return &DotNode{tr: t, NodeType: NodeDot, Pos: pos} -} - -func (d *DotNode) Type() NodeType { - // Override method on embedded NodeType for API compatibility. - // TODO: Not really a problem; could change API without effect but - // api tool complains. - return NodeDot -} - -func (d *DotNode) String() string { - return "." -} - -func (d *DotNode) tree() *Tree { - return d.tr -} - -func (d *DotNode) Copy() Node { - return d.tr.newDot(d.Pos) -} - -// NilNode holds the special identifier 'nil' representing an untyped nil constant. -type NilNode struct { - NodeType - Pos - tr *Tree -} - -func (t *Tree) newNil(pos Pos) *NilNode { - return &NilNode{tr: t, NodeType: NodeNil, Pos: pos} -} - -func (n *NilNode) Type() NodeType { - // Override method on embedded NodeType for API compatibility. - // TODO: Not really a problem; could change API without effect but - // api tool complains. - return NodeNil -} - -func (n *NilNode) String() string { - return "nil" -} - -func (n *NilNode) tree() *Tree { - return n.tr -} - -func (n *NilNode) Copy() Node { - return n.tr.newNil(n.Pos) -} - -// FieldNode holds a field (identifier starting with '.'). -// The names may be chained ('.x.y'). -// The period is dropped from each ident. -type FieldNode struct { - NodeType - Pos - tr *Tree - Ident []string // The identifiers in lexical order. -} - -func (t *Tree) newField(pos Pos, ident string) *FieldNode { - return &FieldNode{tr: t, NodeType: NodeField, Pos: pos, Ident: strings.Split(ident[1:], ".")} // [1:] to drop leading period -} - -func (f *FieldNode) String() string { - s := "" - for _, id := range f.Ident { - s += "." + id - } - return s -} - -func (f *FieldNode) tree() *Tree { - return f.tr -} - -func (f *FieldNode) Copy() Node { - return &FieldNode{tr: f.tr, NodeType: NodeField, Pos: f.Pos, Ident: append([]string{}, f.Ident...)} -} - -// ChainNode holds a term followed by a chain of field accesses (identifier starting with '.'). -// The names may be chained ('.x.y'). -// The periods are dropped from each ident. -type ChainNode struct { - NodeType - Pos - tr *Tree - Node Node - Field []string // The identifiers in lexical order. -} - -func (t *Tree) newChain(pos Pos, node Node) *ChainNode { - return &ChainNode{tr: t, NodeType: NodeChain, Pos: pos, Node: node} -} - -// Add adds the named field (which should start with a period) to the end of the chain. -func (c *ChainNode) Add(field string) { - if len(field) == 0 || field[0] != '.' { - panic("no dot in field") - } - field = field[1:] // Remove leading dot. - if field == "" { - panic("empty field") - } - c.Field = append(c.Field, field) -} - -func (c *ChainNode) String() string { - s := c.Node.String() - if _, ok := c.Node.(*PipeNode); ok { - s = "(" + s + ")" - } - for _, field := range c.Field { - s += "." + field - } - return s -} - -func (c *ChainNode) tree() *Tree { - return c.tr -} - -func (c *ChainNode) Copy() Node { - return &ChainNode{tr: c.tr, NodeType: NodeChain, Pos: c.Pos, Node: c.Node, Field: append([]string{}, c.Field...)} -} - -// BoolNode holds a boolean constant. -type BoolNode struct { - NodeType - Pos - tr *Tree - True bool // The value of the boolean constant. -} - -func (t *Tree) newBool(pos Pos, true bool) *BoolNode { - return &BoolNode{tr: t, NodeType: NodeBool, Pos: pos, True: true} -} - -func (b *BoolNode) String() string { - if b.True { - return "true" - } - return "false" -} - -func (b *BoolNode) tree() *Tree { - return b.tr -} - -func (b *BoolNode) Copy() Node { - return b.tr.newBool(b.Pos, b.True) -} - -// NumberNode holds a number: signed or unsigned integer, float, or complex. -// The value is parsed and stored under all the types that can represent the value. -// This simulates in a small amount of code the behavior of Go's ideal constants. -type NumberNode struct { - NodeType - Pos - tr *Tree - IsInt bool // Number has an integral value. - IsUint bool // Number has an unsigned integral value. - IsFloat bool // Number has a floating-point value. - IsComplex bool // Number is complex. - Int64 int64 // The signed integer value. - Uint64 uint64 // The unsigned integer value. - Float64 float64 // The floating-point value. - Complex128 complex128 // The complex value. - Text string // The original textual representation from the input. -} - -func (t *Tree) newNumber(pos Pos, text string, typ itemType) (*NumberNode, error) { - n := &NumberNode{tr: t, NodeType: NodeNumber, Pos: pos, Text: text} - switch typ { - case itemCharConstant: - rune, _, tail, err := strconv.UnquoteChar(text[1:], text[0]) - if err != nil { - return nil, err - } - if tail != "'" { - return nil, fmt.Errorf("malformed character constant: %s", text) - } - n.Int64 = int64(rune) - n.IsInt = true - n.Uint64 = uint64(rune) - n.IsUint = true - n.Float64 = float64(rune) // odd but those are the rules. - n.IsFloat = true - return n, nil - case itemComplex: - // fmt.Sscan can parse the pair, so let it do the work. - if _, err := fmt.Sscan(text, &n.Complex128); err != nil { - return nil, err - } - n.IsComplex = true - n.simplifyComplex() - return n, nil - } - // Imaginary constants can only be complex unless they are zero. - if len(text) > 0 && text[len(text)-1] == 'i' { - f, err := strconv.ParseFloat(text[:len(text)-1], 64) - if err == nil { - n.IsComplex = true - n.Complex128 = complex(0, f) - n.simplifyComplex() - return n, nil - } - } - // Do integer test first so we get 0x123 etc. - u, err := strconv.ParseUint(text, 0, 64) // will fail for -0; fixed below. - if err == nil { - n.IsUint = true - n.Uint64 = u - } - i, err := strconv.ParseInt(text, 0, 64) - if err == nil { - n.IsInt = true - n.Int64 = i - if i == 0 { - n.IsUint = true // in case of -0. - n.Uint64 = u - } - } - // If an integer extraction succeeded, promote the float. - if n.IsInt { - n.IsFloat = true - n.Float64 = float64(n.Int64) - } else if n.IsUint { - n.IsFloat = true - n.Float64 = float64(n.Uint64) - } else { - f, err := strconv.ParseFloat(text, 64) - if err == nil { - n.IsFloat = true - n.Float64 = f - // If a floating-point extraction succeeded, extract the int if needed. - if !n.IsInt && float64(int64(f)) == f { - n.IsInt = true - n.Int64 = int64(f) - } - if !n.IsUint && float64(uint64(f)) == f { - n.IsUint = true - n.Uint64 = uint64(f) - } - } - } - if !n.IsInt && !n.IsUint && !n.IsFloat { - return nil, fmt.Errorf("illegal number syntax: %q", text) - } - return n, nil -} - -// simplifyComplex pulls out any other types that are represented by the complex number. -// These all require that the imaginary part be zero. -func (n *NumberNode) simplifyComplex() { - n.IsFloat = imag(n.Complex128) == 0 - if n.IsFloat { - n.Float64 = real(n.Complex128) - n.IsInt = float64(int64(n.Float64)) == n.Float64 - if n.IsInt { - n.Int64 = int64(n.Float64) - } - n.IsUint = float64(uint64(n.Float64)) == n.Float64 - if n.IsUint { - n.Uint64 = uint64(n.Float64) - } - } -} - -func (n *NumberNode) String() string { - return n.Text -} - -func (n *NumberNode) tree() *Tree { - return n.tr -} - -func (n *NumberNode) Copy() Node { - nn := new(NumberNode) - *nn = *n // Easy, fast, correct. - return nn -} - -// StringNode holds a string constant. The value has been "unquoted". -type StringNode struct { - NodeType - Pos - tr *Tree - Quoted string // The original text of the string, with quotes. - Text string // The string, after quote processing. -} - -func (t *Tree) newString(pos Pos, orig, text string) *StringNode { - return &StringNode{tr: t, NodeType: NodeString, Pos: pos, Quoted: orig, Text: text} -} - -func (s *StringNode) String() string { - return s.Quoted -} - -func (s *StringNode) tree() *Tree { - return s.tr -} - -func (s *StringNode) Copy() Node { - return s.tr.newString(s.Pos, s.Quoted, s.Text) -} - -// endNode represents an {{end}} action. -// It does not appear in the final parse tree. -type endNode struct { - NodeType - Pos - tr *Tree -} - -func (t *Tree) newEnd(pos Pos) *endNode { - return &endNode{tr: t, NodeType: nodeEnd, Pos: pos} -} - -func (e *endNode) String() string { - return "{{end}}" -} - -func (e *endNode) tree() *Tree { - return e.tr -} - -func (e *endNode) Copy() Node { - return e.tr.newEnd(e.Pos) -} - -// elseNode represents an {{else}} action. Does not appear in the final tree. -type elseNode struct { - NodeType - Pos - tr *Tree - Line int // The line number in the input (deprecated; kept for compatibility) -} - -func (t *Tree) newElse(pos Pos, line int) *elseNode { - return &elseNode{tr: t, NodeType: nodeElse, Pos: pos, Line: line} -} - -func (e *elseNode) Type() NodeType { - return nodeElse -} - -func (e *elseNode) String() string { - return "{{else}}" -} - -func (e *elseNode) tree() *Tree { - return e.tr -} - -func (e *elseNode) Copy() Node { - return e.tr.newElse(e.Pos, e.Line) -} - -// BranchNode is the common representation of if, range, and with. -type BranchNode struct { - NodeType - Pos - tr *Tree - Line int // The line number in the input (deprecated; kept for compatibility) - Pipe *PipeNode // The pipeline to be evaluated. - List *ListNode // What to execute if the value is non-empty. - ElseList *ListNode // What to execute if the value is empty (nil if absent). -} - -func (b *BranchNode) String() string { - name := "" - switch b.NodeType { - case NodeIf: - name = "if" - case NodeRange: - name = "range" - case NodeWith: - name = "with" - default: - panic("unknown branch type") - } - if b.ElseList != nil { - return fmt.Sprintf("{{%s %s}}%s{{else}}%s{{end}}", name, b.Pipe, b.List, b.ElseList) - } - return fmt.Sprintf("{{%s %s}}%s{{end}}", name, b.Pipe, b.List) -} - -func (b *BranchNode) tree() *Tree { - return b.tr -} - -func (b *BranchNode) Copy() Node { - switch b.NodeType { - case NodeIf: - return b.tr.newIf(b.Pos, b.Line, b.Pipe, b.List, b.ElseList) - case NodeRange: - return b.tr.newRange(b.Pos, b.Line, b.Pipe, b.List, b.ElseList) - case NodeWith: - return b.tr.newWith(b.Pos, b.Line, b.Pipe, b.List, b.ElseList) - default: - panic("unknown branch type") - } -} - -// IfNode represents an {{if}} action and its commands. -type IfNode struct { - BranchNode -} - -func (t *Tree) newIf(pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) *IfNode { - return &IfNode{BranchNode{tr: t, NodeType: NodeIf, Pos: pos, Line: line, Pipe: pipe, List: list, ElseList: elseList}} -} - -func (i *IfNode) Copy() Node { - return i.tr.newIf(i.Pos, i.Line, i.Pipe.CopyPipe(), i.List.CopyList(), i.ElseList.CopyList()) -} - -// RangeNode represents a {{range}} action and its commands. -type RangeNode struct { - BranchNode -} - -func (t *Tree) newRange(pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) *RangeNode { - return &RangeNode{BranchNode{tr: t, NodeType: NodeRange, Pos: pos, Line: line, Pipe: pipe, List: list, ElseList: elseList}} -} - -func (r *RangeNode) Copy() Node { - return r.tr.newRange(r.Pos, r.Line, r.Pipe.CopyPipe(), r.List.CopyList(), r.ElseList.CopyList()) -} - -// WithNode represents a {{with}} action and its commands. -type WithNode struct { - BranchNode -} - -func (t *Tree) newWith(pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) *WithNode { - return &WithNode{BranchNode{tr: t, NodeType: NodeWith, Pos: pos, Line: line, Pipe: pipe, List: list, ElseList: elseList}} -} - -func (w *WithNode) Copy() Node { - return w.tr.newWith(w.Pos, w.Line, w.Pipe.CopyPipe(), w.List.CopyList(), w.ElseList.CopyList()) -} - -// TemplateNode represents a {{template}} action. -type TemplateNode struct { - NodeType - Pos - tr *Tree - Line int // The line number in the input (deprecated; kept for compatibility) - Name string // The name of the template (unquoted). - Pipe *PipeNode // The command to evaluate as dot for the template. -} - -func (t *Tree) newTemplate(pos Pos, line int, name string, pipe *PipeNode) *TemplateNode { - return &TemplateNode{tr: t, NodeType: NodeTemplate, Pos: pos, Line: line, Name: name, Pipe: pipe} -} - -func (t *TemplateNode) String() string { - if t.Pipe == nil { - return fmt.Sprintf("{{template %q}}", t.Name) - } - return fmt.Sprintf("{{template %q %s}}", t.Name, t.Pipe) -} - -func (t *TemplateNode) tree() *Tree { - return t.tr -} - -func (t *TemplateNode) Copy() Node { - return t.tr.newTemplate(t.Pos, t.Line, t.Name, t.Pipe.CopyPipe()) -} diff --git a/vendor/github.com/alecthomas/template/parse/parse.go b/vendor/github.com/alecthomas/template/parse/parse.go deleted file mode 100644 index 0d77ade8..00000000 --- a/vendor/github.com/alecthomas/template/parse/parse.go +++ /dev/null @@ -1,700 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package parse builds parse trees for templates as defined by text/template -// and html/template. Clients should use those packages to construct templates -// rather than this one, which provides shared internal data structures not -// intended for general use. -package parse - -import ( - "bytes" - "fmt" - "runtime" - "strconv" - "strings" -) - -// Tree is the representation of a single parsed template. -type Tree struct { - Name string // name of the template represented by the tree. - ParseName string // name of the top-level template during parsing, for error messages. - Root *ListNode // top-level root of the tree. - text string // text parsed to create the template (or its parent) - // Parsing only; cleared after parse. - funcs []map[string]interface{} - lex *lexer - token [3]item // three-token lookahead for parser. - peekCount int - vars []string // variables defined at the moment. -} - -// Copy returns a copy of the Tree. Any parsing state is discarded. -func (t *Tree) Copy() *Tree { - if t == nil { - return nil - } - return &Tree{ - Name: t.Name, - ParseName: t.ParseName, - Root: t.Root.CopyList(), - text: t.text, - } -} - -// Parse returns a map from template name to parse.Tree, created by parsing the -// templates described in the argument string. The top-level template will be -// given the specified name. If an error is encountered, parsing stops and an -// empty map is returned with the error. -func Parse(name, text, leftDelim, rightDelim string, funcs ...map[string]interface{}) (treeSet map[string]*Tree, err error) { - treeSet = make(map[string]*Tree) - t := New(name) - t.text = text - _, err = t.Parse(text, leftDelim, rightDelim, treeSet, funcs...) - return -} - -// next returns the next token. -func (t *Tree) next() item { - if t.peekCount > 0 { - t.peekCount-- - } else { - t.token[0] = t.lex.nextItem() - } - return t.token[t.peekCount] -} - -// backup backs the input stream up one token. -func (t *Tree) backup() { - t.peekCount++ -} - -// backup2 backs the input stream up two tokens. -// The zeroth token is already there. -func (t *Tree) backup2(t1 item) { - t.token[1] = t1 - t.peekCount = 2 -} - -// backup3 backs the input stream up three tokens -// The zeroth token is already there. -func (t *Tree) backup3(t2, t1 item) { // Reverse order: we're pushing back. - t.token[1] = t1 - t.token[2] = t2 - t.peekCount = 3 -} - -// peek returns but does not consume the next token. -func (t *Tree) peek() item { - if t.peekCount > 0 { - return t.token[t.peekCount-1] - } - t.peekCount = 1 - t.token[0] = t.lex.nextItem() - return t.token[0] -} - -// nextNonSpace returns the next non-space token. -func (t *Tree) nextNonSpace() (token item) { - for { - token = t.next() - if token.typ != itemSpace { - break - } - } - return token -} - -// peekNonSpace returns but does not consume the next non-space token. -func (t *Tree) peekNonSpace() (token item) { - for { - token = t.next() - if token.typ != itemSpace { - break - } - } - t.backup() - return token -} - -// Parsing. - -// New allocates a new parse tree with the given name. -func New(name string, funcs ...map[string]interface{}) *Tree { - return &Tree{ - Name: name, - funcs: funcs, - } -} - -// ErrorContext returns a textual representation of the location of the node in the input text. -// The receiver is only used when the node does not have a pointer to the tree inside, -// which can occur in old code. -func (t *Tree) ErrorContext(n Node) (location, context string) { - pos := int(n.Position()) - tree := n.tree() - if tree == nil { - tree = t - } - text := tree.text[:pos] - byteNum := strings.LastIndex(text, "\n") - if byteNum == -1 { - byteNum = pos // On first line. - } else { - byteNum++ // After the newline. - byteNum = pos - byteNum - } - lineNum := 1 + strings.Count(text, "\n") - context = n.String() - if len(context) > 20 { - context = fmt.Sprintf("%.20s...", context) - } - return fmt.Sprintf("%s:%d:%d", tree.ParseName, lineNum, byteNum), context -} - -// errorf formats the error and terminates processing. -func (t *Tree) errorf(format string, args ...interface{}) { - t.Root = nil - format = fmt.Sprintf("template: %s:%d: %s", t.ParseName, t.lex.lineNumber(), format) - panic(fmt.Errorf(format, args...)) -} - -// error terminates processing. -func (t *Tree) error(err error) { - t.errorf("%s", err) -} - -// expect consumes the next token and guarantees it has the required type. -func (t *Tree) expect(expected itemType, context string) item { - token := t.nextNonSpace() - if token.typ != expected { - t.unexpected(token, context) - } - return token -} - -// expectOneOf consumes the next token and guarantees it has one of the required types. -func (t *Tree) expectOneOf(expected1, expected2 itemType, context string) item { - token := t.nextNonSpace() - if token.typ != expected1 && token.typ != expected2 { - t.unexpected(token, context) - } - return token -} - -// unexpected complains about the token and terminates processing. -func (t *Tree) unexpected(token item, context string) { - t.errorf("unexpected %s in %s", token, context) -} - -// recover is the handler that turns panics into returns from the top level of Parse. -func (t *Tree) recover(errp *error) { - e := recover() - if e != nil { - if _, ok := e.(runtime.Error); ok { - panic(e) - } - if t != nil { - t.stopParse() - } - *errp = e.(error) - } - return -} - -// startParse initializes the parser, using the lexer. -func (t *Tree) startParse(funcs []map[string]interface{}, lex *lexer) { - t.Root = nil - t.lex = lex - t.vars = []string{"$"} - t.funcs = funcs -} - -// stopParse terminates parsing. -func (t *Tree) stopParse() { - t.lex = nil - t.vars = nil - t.funcs = nil -} - -// Parse parses the template definition string to construct a representation of -// the template for execution. If either action delimiter string is empty, the -// default ("{{" or "}}") is used. Embedded template definitions are added to -// the treeSet map. -func (t *Tree) Parse(text, leftDelim, rightDelim string, treeSet map[string]*Tree, funcs ...map[string]interface{}) (tree *Tree, err error) { - defer t.recover(&err) - t.ParseName = t.Name - t.startParse(funcs, lex(t.Name, text, leftDelim, rightDelim)) - t.text = text - t.parse(treeSet) - t.add(treeSet) - t.stopParse() - return t, nil -} - -// add adds tree to the treeSet. -func (t *Tree) add(treeSet map[string]*Tree) { - tree := treeSet[t.Name] - if tree == nil || IsEmptyTree(tree.Root) { - treeSet[t.Name] = t - return - } - if !IsEmptyTree(t.Root) { - t.errorf("template: multiple definition of template %q", t.Name) - } -} - -// IsEmptyTree reports whether this tree (node) is empty of everything but space. -func IsEmptyTree(n Node) bool { - switch n := n.(type) { - case nil: - return true - case *ActionNode: - case *IfNode: - case *ListNode: - for _, node := range n.Nodes { - if !IsEmptyTree(node) { - return false - } - } - return true - case *RangeNode: - case *TemplateNode: - case *TextNode: - return len(bytes.TrimSpace(n.Text)) == 0 - case *WithNode: - default: - panic("unknown node: " + n.String()) - } - return false -} - -// parse is the top-level parser for a template, essentially the same -// as itemList except it also parses {{define}} actions. -// It runs to EOF. -func (t *Tree) parse(treeSet map[string]*Tree) (next Node) { - t.Root = t.newList(t.peek().pos) - for t.peek().typ != itemEOF { - if t.peek().typ == itemLeftDelim { - delim := t.next() - if t.nextNonSpace().typ == itemDefine { - newT := New("definition") // name will be updated once we know it. - newT.text = t.text - newT.ParseName = t.ParseName - newT.startParse(t.funcs, t.lex) - newT.parseDefinition(treeSet) - continue - } - t.backup2(delim) - } - n := t.textOrAction() - if n.Type() == nodeEnd { - t.errorf("unexpected %s", n) - } - t.Root.append(n) - } - return nil -} - -// parseDefinition parses a {{define}} ... {{end}} template definition and -// installs the definition in the treeSet map. The "define" keyword has already -// been scanned. -func (t *Tree) parseDefinition(treeSet map[string]*Tree) { - const context = "define clause" - name := t.expectOneOf(itemString, itemRawString, context) - var err error - t.Name, err = strconv.Unquote(name.val) - if err != nil { - t.error(err) - } - t.expect(itemRightDelim, context) - var end Node - t.Root, end = t.itemList() - if end.Type() != nodeEnd { - t.errorf("unexpected %s in %s", end, context) - } - t.add(treeSet) - t.stopParse() -} - -// itemList: -// textOrAction* -// Terminates at {{end}} or {{else}}, returned separately. -func (t *Tree) itemList() (list *ListNode, next Node) { - list = t.newList(t.peekNonSpace().pos) - for t.peekNonSpace().typ != itemEOF { - n := t.textOrAction() - switch n.Type() { - case nodeEnd, nodeElse: - return list, n - } - list.append(n) - } - t.errorf("unexpected EOF") - return -} - -// textOrAction: -// text | action -func (t *Tree) textOrAction() Node { - switch token := t.nextNonSpace(); token.typ { - case itemElideNewline: - return t.elideNewline() - case itemText: - return t.newText(token.pos, token.val) - case itemLeftDelim: - return t.action() - default: - t.unexpected(token, "input") - } - return nil -} - -// elideNewline: -// Remove newlines trailing rightDelim if \\ is present. -func (t *Tree) elideNewline() Node { - token := t.peek() - if token.typ != itemText { - t.unexpected(token, "input") - return nil - } - - t.next() - stripped := strings.TrimLeft(token.val, "\n\r") - diff := len(token.val) - len(stripped) - if diff > 0 { - // This is a bit nasty. We mutate the token in-place to remove - // preceding newlines. - token.pos += Pos(diff) - token.val = stripped - } - return t.newText(token.pos, token.val) -} - -// Action: -// control -// command ("|" command)* -// Left delim is past. Now get actions. -// First word could be a keyword such as range. -func (t *Tree) action() (n Node) { - switch token := t.nextNonSpace(); token.typ { - case itemElse: - return t.elseControl() - case itemEnd: - return t.endControl() - case itemIf: - return t.ifControl() - case itemRange: - return t.rangeControl() - case itemTemplate: - return t.templateControl() - case itemWith: - return t.withControl() - } - t.backup() - // Do not pop variables; they persist until "end". - return t.newAction(t.peek().pos, t.lex.lineNumber(), t.pipeline("command")) -} - -// Pipeline: -// declarations? command ('|' command)* -func (t *Tree) pipeline(context string) (pipe *PipeNode) { - var decl []*VariableNode - pos := t.peekNonSpace().pos - // Are there declarations? - for { - if v := t.peekNonSpace(); v.typ == itemVariable { - t.next() - // Since space is a token, we need 3-token look-ahead here in the worst case: - // in "$x foo" we need to read "foo" (as opposed to ":=") to know that $x is an - // argument variable rather than a declaration. So remember the token - // adjacent to the variable so we can push it back if necessary. - tokenAfterVariable := t.peek() - if next := t.peekNonSpace(); next.typ == itemColonEquals || (next.typ == itemChar && next.val == ",") { - t.nextNonSpace() - variable := t.newVariable(v.pos, v.val) - decl = append(decl, variable) - t.vars = append(t.vars, v.val) - if next.typ == itemChar && next.val == "," { - if context == "range" && len(decl) < 2 { - continue - } - t.errorf("too many declarations in %s", context) - } - } else if tokenAfterVariable.typ == itemSpace { - t.backup3(v, tokenAfterVariable) - } else { - t.backup2(v) - } - } - break - } - pipe = t.newPipeline(pos, t.lex.lineNumber(), decl) - for { - switch token := t.nextNonSpace(); token.typ { - case itemRightDelim, itemRightParen: - if len(pipe.Cmds) == 0 { - t.errorf("missing value for %s", context) - } - if token.typ == itemRightParen { - t.backup() - } - return - case itemBool, itemCharConstant, itemComplex, itemDot, itemField, itemIdentifier, - itemNumber, itemNil, itemRawString, itemString, itemVariable, itemLeftParen: - t.backup() - pipe.append(t.command()) - default: - t.unexpected(token, context) - } - } -} - -func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) { - defer t.popVars(len(t.vars)) - line = t.lex.lineNumber() - pipe = t.pipeline(context) - var next Node - list, next = t.itemList() - switch next.Type() { - case nodeEnd: //done - case nodeElse: - if allowElseIf { - // Special case for "else if". If the "else" is followed immediately by an "if", - // the elseControl will have left the "if" token pending. Treat - // {{if a}}_{{else if b}}_{{end}} - // as - // {{if a}}_{{else}}{{if b}}_{{end}}{{end}}. - // To do this, parse the if as usual and stop at it {{end}}; the subsequent{{end}} - // is assumed. This technique works even for long if-else-if chains. - // TODO: Should we allow else-if in with and range? - if t.peek().typ == itemIf { - t.next() // Consume the "if" token. - elseList = t.newList(next.Position()) - elseList.append(t.ifControl()) - // Do not consume the next item - only one {{end}} required. - break - } - } - elseList, next = t.itemList() - if next.Type() != nodeEnd { - t.errorf("expected end; found %s", next) - } - } - return pipe.Position(), line, pipe, list, elseList -} - -// If: -// {{if pipeline}} itemList {{end}} -// {{if pipeline}} itemList {{else}} itemList {{end}} -// If keyword is past. -func (t *Tree) ifControl() Node { - return t.newIf(t.parseControl(true, "if")) -} - -// Range: -// {{range pipeline}} itemList {{end}} -// {{range pipeline}} itemList {{else}} itemList {{end}} -// Range keyword is past. -func (t *Tree) rangeControl() Node { - return t.newRange(t.parseControl(false, "range")) -} - -// With: -// {{with pipeline}} itemList {{end}} -// {{with pipeline}} itemList {{else}} itemList {{end}} -// If keyword is past. -func (t *Tree) withControl() Node { - return t.newWith(t.parseControl(false, "with")) -} - -// End: -// {{end}} -// End keyword is past. -func (t *Tree) endControl() Node { - return t.newEnd(t.expect(itemRightDelim, "end").pos) -} - -// Else: -// {{else}} -// Else keyword is past. -func (t *Tree) elseControl() Node { - // Special case for "else if". - peek := t.peekNonSpace() - if peek.typ == itemIf { - // We see "{{else if ... " but in effect rewrite it to {{else}}{{if ... ". - return t.newElse(peek.pos, t.lex.lineNumber()) - } - return t.newElse(t.expect(itemRightDelim, "else").pos, t.lex.lineNumber()) -} - -// Template: -// {{template stringValue pipeline}} -// Template keyword is past. The name must be something that can evaluate -// to a string. -func (t *Tree) templateControl() Node { - var name string - token := t.nextNonSpace() - switch token.typ { - case itemString, itemRawString: - s, err := strconv.Unquote(token.val) - if err != nil { - t.error(err) - } - name = s - default: - t.unexpected(token, "template invocation") - } - var pipe *PipeNode - if t.nextNonSpace().typ != itemRightDelim { - t.backup() - // Do not pop variables; they persist until "end". - pipe = t.pipeline("template") - } - return t.newTemplate(token.pos, t.lex.lineNumber(), name, pipe) -} - -// command: -// operand (space operand)* -// space-separated arguments up to a pipeline character or right delimiter. -// we consume the pipe character but leave the right delim to terminate the action. -func (t *Tree) command() *CommandNode { - cmd := t.newCommand(t.peekNonSpace().pos) - for { - t.peekNonSpace() // skip leading spaces. - operand := t.operand() - if operand != nil { - cmd.append(operand) - } - switch token := t.next(); token.typ { - case itemSpace: - continue - case itemError: - t.errorf("%s", token.val) - case itemRightDelim, itemRightParen: - t.backup() - case itemPipe: - default: - t.errorf("unexpected %s in operand; missing space?", token) - } - break - } - if len(cmd.Args) == 0 { - t.errorf("empty command") - } - return cmd -} - -// operand: -// term .Field* -// An operand is a space-separated component of a command, -// a term possibly followed by field accesses. -// A nil return means the next item is not an operand. -func (t *Tree) operand() Node { - node := t.term() - if node == nil { - return nil - } - if t.peek().typ == itemField { - chain := t.newChain(t.peek().pos, node) - for t.peek().typ == itemField { - chain.Add(t.next().val) - } - // Compatibility with original API: If the term is of type NodeField - // or NodeVariable, just put more fields on the original. - // Otherwise, keep the Chain node. - // TODO: Switch to Chains always when we can. - switch node.Type() { - case NodeField: - node = t.newField(chain.Position(), chain.String()) - case NodeVariable: - node = t.newVariable(chain.Position(), chain.String()) - default: - node = chain - } - } - return node -} - -// term: -// literal (number, string, nil, boolean) -// function (identifier) -// . -// .Field -// $ -// '(' pipeline ')' -// A term is a simple "expression". -// A nil return means the next item is not a term. -func (t *Tree) term() Node { - switch token := t.nextNonSpace(); token.typ { - case itemError: - t.errorf("%s", token.val) - case itemIdentifier: - if !t.hasFunction(token.val) { - t.errorf("function %q not defined", token.val) - } - return NewIdentifier(token.val).SetTree(t).SetPos(token.pos) - case itemDot: - return t.newDot(token.pos) - case itemNil: - return t.newNil(token.pos) - case itemVariable: - return t.useVar(token.pos, token.val) - case itemField: - return t.newField(token.pos, token.val) - case itemBool: - return t.newBool(token.pos, token.val == "true") - case itemCharConstant, itemComplex, itemNumber: - number, err := t.newNumber(token.pos, token.val, token.typ) - if err != nil { - t.error(err) - } - return number - case itemLeftParen: - pipe := t.pipeline("parenthesized pipeline") - if token := t.next(); token.typ != itemRightParen { - t.errorf("unclosed right paren: unexpected %s", token) - } - return pipe - case itemString, itemRawString: - s, err := strconv.Unquote(token.val) - if err != nil { - t.error(err) - } - return t.newString(token.pos, token.val, s) - } - t.backup() - return nil -} - -// hasFunction reports if a function name exists in the Tree's maps. -func (t *Tree) hasFunction(name string) bool { - for _, funcMap := range t.funcs { - if funcMap == nil { - continue - } - if funcMap[name] != nil { - return true - } - } - return false -} - -// popVars trims the variable list to the specified length -func (t *Tree) popVars(n int) { - t.vars = t.vars[:n] -} - -// useVar returns a node for a variable reference. It errors if the -// variable is not defined. -func (t *Tree) useVar(pos Pos, name string) Node { - v := t.newVariable(pos, name) - for _, varName := range t.vars { - if varName == v.Ident[0] { - return v - } - } - t.errorf("undefined variable %q", v.Ident[0]) - return nil -} diff --git a/vendor/github.com/alecthomas/template/template.go b/vendor/github.com/alecthomas/template/template.go deleted file mode 100644 index 447ed2ab..00000000 --- a/vendor/github.com/alecthomas/template/template.go +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package template - -import ( - "fmt" - "reflect" - - "github.com/alecthomas/template/parse" -) - -// common holds the information shared by related templates. -type common struct { - tmpl map[string]*Template - // We use two maps, one for parsing and one for execution. - // This separation makes the API cleaner since it doesn't - // expose reflection to the client. - parseFuncs FuncMap - execFuncs map[string]reflect.Value -} - -// Template is the representation of a parsed template. The *parse.Tree -// field is exported only for use by html/template and should be treated -// as unexported by all other clients. -type Template struct { - name string - *parse.Tree - *common - leftDelim string - rightDelim string -} - -// New allocates a new template with the given name. -func New(name string) *Template { - return &Template{ - name: name, - } -} - -// Name returns the name of the template. -func (t *Template) Name() string { - return t.name -} - -// New allocates a new template associated with the given one and with the same -// delimiters. The association, which is transitive, allows one template to -// invoke another with a {{template}} action. -func (t *Template) New(name string) *Template { - t.init() - return &Template{ - name: name, - common: t.common, - leftDelim: t.leftDelim, - rightDelim: t.rightDelim, - } -} - -func (t *Template) init() { - if t.common == nil { - t.common = new(common) - t.tmpl = make(map[string]*Template) - t.parseFuncs = make(FuncMap) - t.execFuncs = make(map[string]reflect.Value) - } -} - -// Clone returns a duplicate of the template, including all associated -// templates. The actual representation is not copied, but the name space of -// associated templates is, so further calls to Parse in the copy will add -// templates to the copy but not to the original. Clone can be used to prepare -// common templates and use them with variant definitions for other templates -// by adding the variants after the clone is made. -func (t *Template) Clone() (*Template, error) { - nt := t.copy(nil) - nt.init() - nt.tmpl[t.name] = nt - for k, v := range t.tmpl { - if k == t.name { // Already installed. - continue - } - // The associated templates share nt's common structure. - tmpl := v.copy(nt.common) - nt.tmpl[k] = tmpl - } - for k, v := range t.parseFuncs { - nt.parseFuncs[k] = v - } - for k, v := range t.execFuncs { - nt.execFuncs[k] = v - } - return nt, nil -} - -// copy returns a shallow copy of t, with common set to the argument. -func (t *Template) copy(c *common) *Template { - nt := New(t.name) - nt.Tree = t.Tree - nt.common = c - nt.leftDelim = t.leftDelim - nt.rightDelim = t.rightDelim - return nt -} - -// AddParseTree creates a new template with the name and parse tree -// and associates it with t. -func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error) { - if t.common != nil && t.tmpl[name] != nil { - return nil, fmt.Errorf("template: redefinition of template %q", name) - } - nt := t.New(name) - nt.Tree = tree - t.tmpl[name] = nt - return nt, nil -} - -// Templates returns a slice of the templates associated with t, including t -// itself. -func (t *Template) Templates() []*Template { - if t.common == nil { - return nil - } - // Return a slice so we don't expose the map. - m := make([]*Template, 0, len(t.tmpl)) - for _, v := range t.tmpl { - m = append(m, v) - } - return m -} - -// Delims sets the action delimiters to the specified strings, to be used in -// subsequent calls to Parse, ParseFiles, or ParseGlob. Nested template -// definitions will inherit the settings. An empty delimiter stands for the -// corresponding default: {{ or }}. -// The return value is the template, so calls can be chained. -func (t *Template) Delims(left, right string) *Template { - t.leftDelim = left - t.rightDelim = right - return t -} - -// Funcs adds the elements of the argument map to the template's function map. -// It panics if a value in the map is not a function with appropriate return -// type. However, it is legal to overwrite elements of the map. The return -// value is the template, so calls can be chained. -func (t *Template) Funcs(funcMap FuncMap) *Template { - t.init() - addValueFuncs(t.execFuncs, funcMap) - addFuncs(t.parseFuncs, funcMap) - return t -} - -// Lookup returns the template with the given name that is associated with t, -// or nil if there is no such template. -func (t *Template) Lookup(name string) *Template { - if t.common == nil { - return nil - } - return t.tmpl[name] -} - -// Parse parses a string into a template. Nested template definitions will be -// associated with the top-level template t. Parse may be called multiple times -// to parse definitions of templates to associate with t. It is an error if a -// resulting template is non-empty (contains content other than template -// definitions) and would replace a non-empty template with the same name. -// (In multiple calls to Parse with the same receiver template, only one call -// can contain text other than space, comments, and template definitions.) -func (t *Template) Parse(text string) (*Template, error) { - t.init() - trees, err := parse.Parse(t.name, text, t.leftDelim, t.rightDelim, t.parseFuncs, builtins) - if err != nil { - return nil, err - } - // Add the newly parsed trees, including the one for t, into our common structure. - for name, tree := range trees { - // If the name we parsed is the name of this template, overwrite this template. - // The associate method checks it's not a redefinition. - tmpl := t - if name != t.name { - tmpl = t.New(name) - } - // Even if t == tmpl, we need to install it in the common.tmpl map. - if replace, err := t.associate(tmpl, tree); err != nil { - return nil, err - } else if replace { - tmpl.Tree = tree - } - tmpl.leftDelim = t.leftDelim - tmpl.rightDelim = t.rightDelim - } - return t, nil -} - -// associate installs the new template into the group of templates associated -// with t. It is an error to reuse a name except to overwrite an empty -// template. The two are already known to share the common structure. -// The boolean return value reports wither to store this tree as t.Tree. -func (t *Template) associate(new *Template, tree *parse.Tree) (bool, error) { - if new.common != t.common { - panic("internal error: associate not common") - } - name := new.name - if old := t.tmpl[name]; old != nil { - oldIsEmpty := parse.IsEmptyTree(old.Root) - newIsEmpty := parse.IsEmptyTree(tree.Root) - if newIsEmpty { - // Whether old is empty or not, new is empty; no reason to replace old. - return false, nil - } - if !oldIsEmpty { - return false, fmt.Errorf("template: redefinition of template %q", name) - } - } - t.tmpl[name] = new - return true, nil -} diff --git a/vendor/github.com/alecthomas/units/COPYING b/vendor/github.com/alecthomas/units/COPYING deleted file mode 100644 index 2993ec08..00000000 --- a/vendor/github.com/alecthomas/units/COPYING +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2014 Alec Thomas - -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. diff --git a/vendor/github.com/alecthomas/units/README.md b/vendor/github.com/alecthomas/units/README.md deleted file mode 100644 index bee884e3..00000000 --- a/vendor/github.com/alecthomas/units/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Units - Helpful unit multipliers and functions for Go - -The goal of this package is to have functionality similar to the [time](http://golang.org/pkg/time/) package. - -It allows for code like this: - -```go -n, err := ParseBase2Bytes("1KB") -// n == 1024 -n = units.Mebibyte * 512 -``` diff --git a/vendor/github.com/alecthomas/units/bytes.go b/vendor/github.com/alecthomas/units/bytes.go deleted file mode 100644 index eaadeb80..00000000 --- a/vendor/github.com/alecthomas/units/bytes.go +++ /dev/null @@ -1,83 +0,0 @@ -package units - -// Base2Bytes is the old non-SI power-of-2 byte scale (1024 bytes in a kilobyte, -// etc.). -type Base2Bytes int64 - -// Base-2 byte units. -const ( - Kibibyte Base2Bytes = 1024 - KiB = Kibibyte - Mebibyte = Kibibyte * 1024 - MiB = Mebibyte - Gibibyte = Mebibyte * 1024 - GiB = Gibibyte - Tebibyte = Gibibyte * 1024 - TiB = Tebibyte - Pebibyte = Tebibyte * 1024 - PiB = Pebibyte - Exbibyte = Pebibyte * 1024 - EiB = Exbibyte -) - -var ( - bytesUnitMap = MakeUnitMap("iB", "B", 1024) - oldBytesUnitMap = MakeUnitMap("B", "B", 1024) -) - -// ParseBase2Bytes supports both iB and B in base-2 multipliers. That is, KB -// and KiB are both 1024. -func ParseBase2Bytes(s string) (Base2Bytes, error) { - n, err := ParseUnit(s, bytesUnitMap) - if err != nil { - n, err = ParseUnit(s, oldBytesUnitMap) - } - return Base2Bytes(n), err -} - -func (b Base2Bytes) String() string { - return ToString(int64(b), 1024, "iB", "B") -} - -var ( - metricBytesUnitMap = MakeUnitMap("B", "B", 1000) -) - -// MetricBytes are SI byte units (1000 bytes in a kilobyte). -type MetricBytes SI - -// SI base-10 byte units. -const ( - Kilobyte MetricBytes = 1000 - KB = Kilobyte - Megabyte = Kilobyte * 1000 - MB = Megabyte - Gigabyte = Megabyte * 1000 - GB = Gigabyte - Terabyte = Gigabyte * 1000 - TB = Terabyte - Petabyte = Terabyte * 1000 - PB = Petabyte - Exabyte = Petabyte * 1000 - EB = Exabyte -) - -// ParseMetricBytes parses base-10 metric byte units. That is, KB is 1000 bytes. -func ParseMetricBytes(s string) (MetricBytes, error) { - n, err := ParseUnit(s, metricBytesUnitMap) - return MetricBytes(n), err -} - -func (m MetricBytes) String() string { - return ToString(int64(m), 1000, "B", "B") -} - -// ParseStrictBytes supports both iB and B suffixes for base 2 and metric, -// respectively. That is, KiB represents 1024 and KB represents 1000. -func ParseStrictBytes(s string) (int64, error) { - n, err := ParseUnit(s, bytesUnitMap) - if err != nil { - n, err = ParseUnit(s, metricBytesUnitMap) - } - return int64(n), err -} diff --git a/vendor/github.com/alecthomas/units/doc.go b/vendor/github.com/alecthomas/units/doc.go deleted file mode 100644 index 156ae386..00000000 --- a/vendor/github.com/alecthomas/units/doc.go +++ /dev/null @@ -1,13 +0,0 @@ -// Package units provides helpful unit multipliers and functions for Go. -// -// The goal of this package is to have functionality similar to the time [1] package. -// -// -// [1] http://golang.org/pkg/time/ -// -// It allows for code like this: -// -// n, err := ParseBase2Bytes("1KB") -// // n == 1024 -// n = units.Mebibyte * 512 -package units diff --git a/vendor/github.com/alecthomas/units/si.go b/vendor/github.com/alecthomas/units/si.go deleted file mode 100644 index 8234a9d5..00000000 --- a/vendor/github.com/alecthomas/units/si.go +++ /dev/null @@ -1,26 +0,0 @@ -package units - -// SI units. -type SI int64 - -// SI unit multiples. -const ( - Kilo SI = 1000 - Mega = Kilo * 1000 - Giga = Mega * 1000 - Tera = Giga * 1000 - Peta = Tera * 1000 - Exa = Peta * 1000 -) - -func MakeUnitMap(suffix, shortSuffix string, scale int64) map[string]float64 { - return map[string]float64{ - shortSuffix: 1, - "K" + suffix: float64(scale), - "M" + suffix: float64(scale * scale), - "G" + suffix: float64(scale * scale * scale), - "T" + suffix: float64(scale * scale * scale * scale), - "P" + suffix: float64(scale * scale * scale * scale * scale), - "E" + suffix: float64(scale * scale * scale * scale * scale * scale), - } -} diff --git a/vendor/github.com/alecthomas/units/util.go b/vendor/github.com/alecthomas/units/util.go deleted file mode 100644 index 6527e92d..00000000 --- a/vendor/github.com/alecthomas/units/util.go +++ /dev/null @@ -1,138 +0,0 @@ -package units - -import ( - "errors" - "fmt" - "strings" -) - -var ( - siUnits = []string{"", "K", "M", "G", "T", "P", "E"} -) - -func ToString(n int64, scale int64, suffix, baseSuffix string) string { - mn := len(siUnits) - out := make([]string, mn) - for i, m := range siUnits { - if n%scale != 0 || i == 0 && n == 0 { - s := suffix - if i == 0 { - s = baseSuffix - } - out[mn-1-i] = fmt.Sprintf("%d%s%s", n%scale, m, s) - } - n /= scale - if n == 0 { - break - } - } - return strings.Join(out, "") -} - -// Below code ripped straight from http://golang.org/src/pkg/time/format.go?s=33392:33438#L1123 -var errLeadingInt = errors.New("units: bad [0-9]*") // never printed - -// leadingInt consumes the leading [0-9]* from s. -func leadingInt(s string) (x int64, rem string, err error) { - i := 0 - for ; i < len(s); i++ { - c := s[i] - if c < '0' || c > '9' { - break - } - if x >= (1<<63-10)/10 { - // overflow - return 0, "", errLeadingInt - } - x = x*10 + int64(c) - '0' - } - return x, s[i:], nil -} - -func ParseUnit(s string, unitMap map[string]float64) (int64, error) { - // [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+ - orig := s - f := float64(0) - neg := false - - // Consume [-+]? - if s != "" { - c := s[0] - if c == '-' || c == '+' { - neg = c == '-' - s = s[1:] - } - } - // Special case: if all that is left is "0", this is zero. - if s == "0" { - return 0, nil - } - if s == "" { - return 0, errors.New("units: invalid " + orig) - } - for s != "" { - g := float64(0) // this element of the sequence - - var x int64 - var err error - - // The next character must be [0-9.] - if !(s[0] == '.' || ('0' <= s[0] && s[0] <= '9')) { - return 0, errors.New("units: invalid " + orig) - } - // Consume [0-9]* - pl := len(s) - x, s, err = leadingInt(s) - if err != nil { - return 0, errors.New("units: invalid " + orig) - } - g = float64(x) - pre := pl != len(s) // whether we consumed anything before a period - - // Consume (\.[0-9]*)? - post := false - if s != "" && s[0] == '.' { - s = s[1:] - pl := len(s) - x, s, err = leadingInt(s) - if err != nil { - return 0, errors.New("units: invalid " + orig) - } - scale := 1.0 - for n := pl - len(s); n > 0; n-- { - scale *= 10 - } - g += float64(x) / scale - post = pl != len(s) - } - if !pre && !post { - // no digits (e.g. ".s" or "-.s") - return 0, errors.New("units: invalid " + orig) - } - - // Consume unit. - i := 0 - for ; i < len(s); i++ { - c := s[i] - if c == '.' || ('0' <= c && c <= '9') { - break - } - } - u := s[:i] - s = s[i:] - unit, ok := unitMap[u] - if !ok { - return 0, errors.New("units: unknown unit " + u + " in " + orig) - } - - f += g * unit - } - - if neg { - f = -f - } - if f < float64(-1<<63) || f > float64(1<<63-1) { - return 0, errors.New("units: overflow parsing unit") - } - return int64(f), nil -} diff --git a/vendor/github.com/beorn7/perks/LICENSE b/vendor/github.com/beorn7/perks/LICENSE deleted file mode 100644 index 339177be..00000000 --- a/vendor/github.com/beorn7/perks/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (C) 2013 Blake Mizerany - -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. diff --git a/vendor/github.com/beorn7/perks/quantile/exampledata.txt b/vendor/github.com/beorn7/perks/quantile/exampledata.txt deleted file mode 100644 index 1602287d..00000000 --- a/vendor/github.com/beorn7/perks/quantile/exampledata.txt +++ /dev/null @@ -1,2388 +0,0 @@ -8 -5 -26 -12 -5 -235 -13 -6 -28 -30 -3 -3 -3 -3 -5 -2 -33 -7 -2 -4 -7 -12 -14 -5 -8 -3 -10 -4 -5 -3 -6 -6 -209 -20 -3 -10 -14 -3 -4 -6 -8 -5 -11 -7 -3 -2 -3 -3 -212 -5 -222 -4 -10 -10 -5 -6 -3 -8 -3 -10 -254 -220 -2 -3 -5 -24 -5 -4 -222 -7 -3 -3 -223 -8 -15 -12 -14 -14 -3 -2 -2 -3 -13 -3 -11 -4 -4 -6 -5 -7 -13 -5 -3 -5 -2 -5 -3 -5 -2 -7 -15 -17 -14 -3 -6 -6 -3 -17 -5 -4 -7 -6 -4 -4 -8 -6 -8 -3 -9 -3 -6 -3 -4 -5 -3 -3 -660 -4 -6 -10 -3 -6 -3 -2 -5 -13 -2 -4 -4 -10 -4 -8 -4 -3 -7 -9 -9 -3 -10 -37 -3 -13 -4 -12 -3 -6 -10 -8 -5 -21 -2 -3 -8 -3 -2 -3 -3 -4 -12 -2 -4 -8 -8 -4 -3 -2 -20 -1 -6 -32 -2 -11 -6 -18 -3 -8 -11 -3 -212 -3 -4 -2 -6 -7 -12 -11 -3 -2 -16 -10 -6 -4 -6 -3 -2 -7 -3 -2 -2 -2 -2 -5 -6 -4 -3 -10 -3 -4 -6 -5 -3 -4 -4 -5 -6 -4 -3 -4 -4 -5 -7 -5 -5 -3 -2 -7 -2 -4 -12 -4 -5 -6 -2 -4 -4 -8 -4 -15 -13 -7 -16 -5 -3 -23 -5 -5 -7 -3 -2 -9 -8 -7 -5 -8 -11 -4 -10 -76 -4 -47 -4 -3 -2 -7 -4 -2 -3 -37 -10 -4 -2 -20 -5 -4 -4 -10 -10 -4 -3 -7 -23 -240 -7 -13 -5 -5 -3 -3 -2 -5 -4 -2 -8 -7 -19 -2 -23 -8 -7 -2 -5 -3 -8 -3 -8 -13 -5 -5 -5 -2 -3 -23 -4 -9 -8 -4 -3 -3 -5 -220 -2 -3 -4 -6 -14 -3 -53 -6 -2 -5 -18 -6 -3 -219 -6 -5 -2 -5 -3 -6 -5 -15 -4 -3 -17 -3 -2 -4 -7 -2 -3 -3 -4 -4 -3 -2 -664 -6 -3 -23 -5 -5 -16 -5 -8 -2 -4 -2 -24 -12 -3 -2 -3 -5 -8 -3 -5 -4 -3 -14 -3 -5 -8 -2 -3 -7 -9 -4 -2 -3 -6 -8 -4 -3 -4 -6 -5 -3 -3 -6 -3 -19 -4 -4 -6 -3 -6 -3 -5 -22 -5 -4 -4 -3 -8 -11 -4 -9 -7 -6 -13 -4 -4 -4 -6 -17 -9 -3 -3 -3 -4 -3 -221 -5 -11 -3 -4 -2 -12 -6 -3 -5 -7 -5 -7 -4 -9 -7 -14 -37 -19 -217 -16 -3 -5 -2 -2 -7 -19 -7 -6 -7 -4 -24 -5 -11 -4 -7 -7 -9 -13 -3 -4 -3 -6 -28 -4 -4 -5 -5 -2 -5 -6 -4 -4 -6 -10 -5 -4 -3 -2 -3 -3 -6 -5 -5 -4 -3 -2 -3 -7 -4 -6 -18 -16 -8 -16 -4 -5 -8 -6 -9 -13 -1545 -6 -215 -6 -5 -6 -3 -45 -31 -5 -2 -2 -4 -3 -3 -2 -5 -4 -3 -5 -7 -7 -4 -5 -8 -5 -4 -749 -2 -31 -9 -11 -2 -11 -5 -4 -4 -7 -9 -11 -4 -5 -4 -7 -3 -4 -6 -2 -15 -3 -4 -3 -4 -3 -5 -2 -13 -5 -5 -3 -3 -23 -4 -4 -5 -7 -4 -13 -2 -4 -3 -4 -2 -6 -2 -7 -3 -5 -5 -3 -29 -5 -4 -4 -3 -10 -2 -3 -79 -16 -6 -6 -7 -7 -3 -5 -5 -7 -4 -3 -7 -9 -5 -6 -5 -9 -6 -3 -6 -4 -17 -2 -10 -9 -3 -6 -2 -3 -21 -22 -5 -11 -4 -2 -17 -2 -224 -2 -14 -3 -4 -4 -2 -4 -4 -4 -4 -5 -3 -4 -4 -10 -2 -6 -3 -3 -5 -7 -2 -7 -5 -6 -3 -218 -2 -2 -5 -2 -6 -3 -5 -222 -14 -6 -33 -3 -2 -5 -3 -3 -3 -9 -5 -3 -3 -2 -7 -4 -3 -4 -3 -5 -6 -5 -26 -4 -13 -9 -7 -3 -221 -3 -3 -4 -4 -4 -4 -2 -18 -5 -3 -7 -9 -6 -8 -3 -10 -3 -11 -9 -5 -4 -17 -5 -5 -6 -6 -3 -2 -4 -12 -17 -6 -7 -218 -4 -2 -4 -10 -3 -5 -15 -3 -9 -4 -3 -3 -6 -29 -3 -3 -4 -5 -5 -3 -8 -5 -6 -6 -7 -5 -3 -5 -3 -29 -2 -31 -5 -15 -24 -16 -5 -207 -4 -3 -3 -2 -15 -4 -4 -13 -5 -5 -4 -6 -10 -2 -7 -8 -4 -6 -20 -5 -3 -4 -3 -12 -12 -5 -17 -7 -3 -3 -3 -6 -10 -3 -5 -25 -80 -4 -9 -3 -2 -11 -3 -3 -2 -3 -8 -7 -5 -5 -19 -5 -3 -3 -12 -11 -2 -6 -5 -5 -5 -3 -3 -3 -4 -209 -14 -3 -2 -5 -19 -4 -4 -3 -4 -14 -5 -6 -4 -13 -9 -7 -4 -7 -10 -2 -9 -5 -7 -2 -8 -4 -6 -5 -5 -222 -8 -7 -12 -5 -216 -3 -4 -4 -6 -3 -14 -8 -7 -13 -4 -3 -3 -3 -3 -17 -5 -4 -3 -33 -6 -6 -33 -7 -5 -3 -8 -7 -5 -2 -9 -4 -2 -233 -24 -7 -4 -8 -10 -3 -4 -15 -2 -16 -3 -3 -13 -12 -7 -5 -4 -207 -4 -2 -4 -27 -15 -2 -5 -2 -25 -6 -5 -5 -6 -13 -6 -18 -6 -4 -12 -225 -10 -7 -5 -2 -2 -11 -4 -14 -21 -8 -10 -3 -5 -4 -232 -2 -5 -5 -3 -7 -17 -11 -6 -6 -23 -4 -6 -3 -5 -4 -2 -17 -3 -6 -5 -8 -3 -2 -2 -14 -9 -4 -4 -2 -5 -5 -3 -7 -6 -12 -6 -10 -3 -6 -2 -2 -19 -5 -4 -4 -9 -2 -4 -13 -3 -5 -6 -3 -6 -5 -4 -9 -6 -3 -5 -7 -3 -6 -6 -4 -3 -10 -6 -3 -221 -3 -5 -3 -6 -4 -8 -5 -3 -6 -4 -4 -2 -54 -5 -6 -11 -3 -3 -4 -4 -4 -3 -7 -3 -11 -11 -7 -10 -6 -13 -223 -213 -15 -231 -7 -3 -7 -228 -2 -3 -4 -4 -5 -6 -7 -4 -13 -3 -4 -5 -3 -6 -4 -6 -7 -2 -4 -3 -4 -3 -3 -6 -3 -7 -3 -5 -18 -5 -6 -8 -10 -3 -3 -3 -2 -4 -2 -4 -4 -5 -6 -6 -4 -10 -13 -3 -12 -5 -12 -16 -8 -4 -19 -11 -2 -4 -5 -6 -8 -5 -6 -4 -18 -10 -4 -2 -216 -6 -6 -6 -2 -4 -12 -8 -3 -11 -5 -6 -14 -5 -3 -13 -4 -5 -4 -5 -3 -28 -6 -3 -7 -219 -3 -9 -7 -3 -10 -6 -3 -4 -19 -5 -7 -11 -6 -15 -19 -4 -13 -11 -3 -7 -5 -10 -2 -8 -11 -2 -6 -4 -6 -24 -6 -3 -3 -3 -3 -6 -18 -4 -11 -4 -2 -5 -10 -8 -3 -9 -5 -3 -4 -5 -6 -2 -5 -7 -4 -4 -14 -6 -4 -4 -5 -5 -7 -2 -4 -3 -7 -3 -3 -6 -4 -5 -4 -4 -4 -3 -3 -3 -3 -8 -14 -2 -3 -5 -3 -2 -4 -5 -3 -7 -3 -3 -18 -3 -4 -4 -5 -7 -3 -3 -3 -13 -5 -4 -8 -211 -5 -5 -3 -5 -2 -5 -4 -2 -655 -6 -3 -5 -11 -2 -5 -3 -12 -9 -15 -11 -5 -12 -217 -2 -6 -17 -3 -3 -207 -5 -5 -4 -5 -9 -3 -2 -8 -5 -4 -3 -2 -5 -12 -4 -14 -5 -4 -2 -13 -5 -8 -4 -225 -4 -3 -4 -5 -4 -3 -3 -6 -23 -9 -2 -6 -7 -233 -4 -4 -6 -18 -3 -4 -6 -3 -4 -4 -2 -3 -7 -4 -13 -227 -4 -3 -5 -4 -2 -12 -9 -17 -3 -7 -14 -6 -4 -5 -21 -4 -8 -9 -2 -9 -25 -16 -3 -6 -4 -7 -8 -5 -2 -3 -5 -4 -3 -3 -5 -3 -3 -3 -2 -3 -19 -2 -4 -3 -4 -2 -3 -4 -4 -2 -4 -3 -3 -3 -2 -6 -3 -17 -5 -6 -4 -3 -13 -5 -3 -3 -3 -4 -9 -4 -2 -14 -12 -4 -5 -24 -4 -3 -37 -12 -11 -21 -3 -4 -3 -13 -4 -2 -3 -15 -4 -11 -4 -4 -3 -8 -3 -4 -4 -12 -8 -5 -3 -3 -4 -2 -220 -3 -5 -223 -3 -3 -3 -10 -3 -15 -4 -241 -9 -7 -3 -6 -6 -23 -4 -13 -7 -3 -4 -7 -4 -9 -3 -3 -4 -10 -5 -5 -1 -5 -24 -2 -4 -5 -5 -6 -14 -3 -8 -2 -3 -5 -13 -13 -3 -5 -2 -3 -15 -3 -4 -2 -10 -4 -4 -4 -5 -5 -3 -5 -3 -4 -7 -4 -27 -3 -6 -4 -15 -3 -5 -6 -6 -5 -4 -8 -3 -9 -2 -6 -3 -4 -3 -7 -4 -18 -3 -11 -3 -3 -8 -9 -7 -24 -3 -219 -7 -10 -4 -5 -9 -12 -2 -5 -4 -4 -4 -3 -3 -19 -5 -8 -16 -8 -6 -22 -3 -23 -3 -242 -9 -4 -3 -3 -5 -7 -3 -3 -5 -8 -3 -7 -5 -14 -8 -10 -3 -4 -3 -7 -4 -6 -7 -4 -10 -4 -3 -11 -3 -7 -10 -3 -13 -6 -8 -12 -10 -5 -7 -9 -3 -4 -7 -7 -10 -8 -30 -9 -19 -4 -3 -19 -15 -4 -13 -3 -215 -223 -4 -7 -4 -8 -17 -16 -3 -7 -6 -5 -5 -4 -12 -3 -7 -4 -4 -13 -4 -5 -2 -5 -6 -5 -6 -6 -7 -10 -18 -23 -9 -3 -3 -6 -5 -2 -4 -2 -7 -3 -3 -2 -5 -5 -14 -10 -224 -6 -3 -4 -3 -7 -5 -9 -3 -6 -4 -2 -5 -11 -4 -3 -3 -2 -8 -4 -7 -4 -10 -7 -3 -3 -18 -18 -17 -3 -3 -3 -4 -5 -3 -3 -4 -12 -7 -3 -11 -13 -5 -4 -7 -13 -5 -4 -11 -3 -12 -3 -6 -4 -4 -21 -4 -6 -9 -5 -3 -10 -8 -4 -6 -4 -4 -6 -5 -4 -8 -6 -4 -6 -4 -4 -5 -9 -6 -3 -4 -2 -9 -3 -18 -2 -4 -3 -13 -3 -6 -6 -8 -7 -9 -3 -2 -16 -3 -4 -6 -3 -2 -33 -22 -14 -4 -9 -12 -4 -5 -6 -3 -23 -9 -4 -3 -5 -5 -3 -4 -5 -3 -5 -3 -10 -4 -5 -5 -8 -4 -4 -6 -8 -5 -4 -3 -4 -6 -3 -3 -3 -5 -9 -12 -6 -5 -9 -3 -5 -3 -2 -2 -2 -18 -3 -2 -21 -2 -5 -4 -6 -4 -5 -10 -3 -9 -3 -2 -10 -7 -3 -6 -6 -4 -4 -8 -12 -7 -3 -7 -3 -3 -9 -3 -4 -5 -4 -4 -5 -5 -10 -15 -4 -4 -14 -6 -227 -3 -14 -5 -216 -22 -5 -4 -2 -2 -6 -3 -4 -2 -9 -9 -4 -3 -28 -13 -11 -4 -5 -3 -3 -2 -3 -3 -5 -3 -4 -3 -5 -23 -26 -3 -4 -5 -6 -4 -6 -3 -5 -5 -3 -4 -3 -2 -2 -2 -7 -14 -3 -6 -7 -17 -2 -2 -15 -14 -16 -4 -6 -7 -13 -6 -4 -5 -6 -16 -3 -3 -28 -3 -6 -15 -3 -9 -2 -4 -6 -3 -3 -22 -4 -12 -6 -7 -2 -5 -4 -10 -3 -16 -6 -9 -2 -5 -12 -7 -5 -5 -5 -5 -2 -11 -9 -17 -4 -3 -11 -7 -3 -5 -15 -4 -3 -4 -211 -8 -7 -5 -4 -7 -6 -7 -6 -3 -6 -5 -6 -5 -3 -4 -4 -26 -4 -6 -10 -4 -4 -3 -2 -3 -3 -4 -5 -9 -3 -9 -4 -4 -5 -5 -8 -2 -4 -2 -3 -8 -4 -11 -19 -5 -8 -6 -3 -5 -6 -12 -3 -2 -4 -16 -12 -3 -4 -4 -8 -6 -5 -6 -6 -219 -8 -222 -6 -16 -3 -13 -19 -5 -4 -3 -11 -6 -10 -4 -7 -7 -12 -5 -3 -3 -5 -6 -10 -3 -8 -2 -5 -4 -7 -2 -4 -4 -2 -12 -9 -6 -4 -2 -40 -2 -4 -10 -4 -223 -4 -2 -20 -6 -7 -24 -5 -4 -5 -2 -20 -16 -6 -5 -13 -2 -3 -3 -19 -3 -2 -4 -5 -6 -7 -11 -12 -5 -6 -7 -7 -3 -5 -3 -5 -3 -14 -3 -4 -4 -2 -11 -1 -7 -3 -9 -6 -11 -12 -5 -8 -6 -221 -4 -2 -12 -4 -3 -15 -4 -5 -226 -7 -218 -7 -5 -4 -5 -18 -4 -5 -9 -4 -4 -2 -9 -18 -18 -9 -5 -6 -6 -3 -3 -7 -3 -5 -4 -4 -4 -12 -3 -6 -31 -5 -4 -7 -3 -6 -5 -6 -5 -11 -2 -2 -11 -11 -6 -7 -5 -8 -7 -10 -5 -23 -7 -4 -3 -5 -34 -2 -5 -23 -7 -3 -6 -8 -4 -4 -4 -2 -5 -3 -8 -5 -4 -8 -25 -2 -3 -17 -8 -3 -4 -8 -7 -3 -15 -6 -5 -7 -21 -9 -5 -6 -6 -5 -3 -2 -3 -10 -3 -6 -3 -14 -7 -4 -4 -8 -7 -8 -2 -6 -12 -4 -213 -6 -5 -21 -8 -2 -5 -23 -3 -11 -2 -3 -6 -25 -2 -3 -6 -7 -6 -6 -4 -4 -6 -3 -17 -9 -7 -6 -4 -3 -10 -7 -2 -3 -3 -3 -11 -8 -3 -7 -6 -4 -14 -36 -3 -4 -3 -3 -22 -13 -21 -4 -2 -7 -4 -4 -17 -15 -3 -7 -11 -2 -4 -7 -6 -209 -6 -3 -2 -2 -24 -4 -9 -4 -3 -3 -3 -29 -2 -2 -4 -3 -3 -5 -4 -6 -3 -3 -2 -4 diff --git a/vendor/github.com/beorn7/perks/quantile/stream.go b/vendor/github.com/beorn7/perks/quantile/stream.go deleted file mode 100644 index 587b1fc5..00000000 --- a/vendor/github.com/beorn7/perks/quantile/stream.go +++ /dev/null @@ -1,292 +0,0 @@ -// Package quantile computes approximate quantiles over an unbounded data -// stream within low memory and CPU bounds. -// -// A small amount of accuracy is traded to achieve the above properties. -// -// Multiple streams can be merged before calling Query to generate a single set -// of results. This is meaningful when the streams represent the same type of -// data. See Merge and Samples. -// -// For more detailed information about the algorithm used, see: -// -// Effective Computation of Biased Quantiles over Data Streams -// -// http://www.cs.rutgers.edu/~muthu/bquant.pdf -package quantile - -import ( - "math" - "sort" -) - -// Sample holds an observed value and meta information for compression. JSON -// tags have been added for convenience. -type Sample struct { - Value float64 `json:",string"` - Width float64 `json:",string"` - Delta float64 `json:",string"` -} - -// Samples represents a slice of samples. It implements sort.Interface. -type Samples []Sample - -func (a Samples) Len() int { return len(a) } -func (a Samples) Less(i, j int) bool { return a[i].Value < a[j].Value } -func (a Samples) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - -type invariant func(s *stream, r float64) float64 - -// NewLowBiased returns an initialized Stream for low-biased quantiles -// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but -// error guarantees can still be given even for the lower ranks of the data -// distribution. -// -// The provided epsilon is a relative error, i.e. the true quantile of a value -// returned by a query is guaranteed to be within (1±Epsilon)*Quantile. -// -// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error -// properties. -func NewLowBiased(epsilon float64) *Stream { - ƒ := func(s *stream, r float64) float64 { - return 2 * epsilon * r - } - return newStream(ƒ) -} - -// NewHighBiased returns an initialized Stream for high-biased quantiles -// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but -// error guarantees can still be given even for the higher ranks of the data -// distribution. -// -// The provided epsilon is a relative error, i.e. the true quantile of a value -// returned by a query is guaranteed to be within 1-(1±Epsilon)*(1-Quantile). -// -// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error -// properties. -func NewHighBiased(epsilon float64) *Stream { - ƒ := func(s *stream, r float64) float64 { - return 2 * epsilon * (s.n - r) - } - return newStream(ƒ) -} - -// NewTargeted returns an initialized Stream concerned with a particular set of -// quantile values that are supplied a priori. Knowing these a priori reduces -// space and computation time. The targets map maps the desired quantiles to -// their absolute errors, i.e. the true quantile of a value returned by a query -// is guaranteed to be within (Quantile±Epsilon). -// -// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error properties. -func NewTargeted(targets map[float64]float64) *Stream { - ƒ := func(s *stream, r float64) float64 { - var m = math.MaxFloat64 - var f float64 - for quantile, epsilon := range targets { - if quantile*s.n <= r { - f = (2 * epsilon * r) / quantile - } else { - f = (2 * epsilon * (s.n - r)) / (1 - quantile) - } - if f < m { - m = f - } - } - return m - } - return newStream(ƒ) -} - -// Stream computes quantiles for a stream of float64s. It is not thread-safe by -// design. Take care when using across multiple goroutines. -type Stream struct { - *stream - b Samples - sorted bool -} - -func newStream(ƒ invariant) *Stream { - x := &stream{ƒ: ƒ} - return &Stream{x, make(Samples, 0, 500), true} -} - -// Insert inserts v into the stream. -func (s *Stream) Insert(v float64) { - s.insert(Sample{Value: v, Width: 1}) -} - -func (s *Stream) insert(sample Sample) { - s.b = append(s.b, sample) - s.sorted = false - if len(s.b) == cap(s.b) { - s.flush() - } -} - -// Query returns the computed qth percentiles value. If s was created with -// NewTargeted, and q is not in the set of quantiles provided a priori, Query -// will return an unspecified result. -func (s *Stream) Query(q float64) float64 { - if !s.flushed() { - // Fast path when there hasn't been enough data for a flush; - // this also yields better accuracy for small sets of data. - l := len(s.b) - if l == 0 { - return 0 - } - i := int(float64(l) * q) - if i > 0 { - i -= 1 - } - s.maybeSort() - return s.b[i].Value - } - s.flush() - return s.stream.query(q) -} - -// Merge merges samples into the underlying streams samples. This is handy when -// merging multiple streams from separate threads, database shards, etc. -// -// ATTENTION: This method is broken and does not yield correct results. The -// underlying algorithm is not capable of merging streams correctly. -func (s *Stream) Merge(samples Samples) { - sort.Sort(samples) - s.stream.merge(samples) -} - -// Reset reinitializes and clears the list reusing the samples buffer memory. -func (s *Stream) Reset() { - s.stream.reset() - s.b = s.b[:0] -} - -// Samples returns stream samples held by s. -func (s *Stream) Samples() Samples { - if !s.flushed() { - return s.b - } - s.flush() - return s.stream.samples() -} - -// Count returns the total number of samples observed in the stream -// since initialization. -func (s *Stream) Count() int { - return len(s.b) + s.stream.count() -} - -func (s *Stream) flush() { - s.maybeSort() - s.stream.merge(s.b) - s.b = s.b[:0] -} - -func (s *Stream) maybeSort() { - if !s.sorted { - s.sorted = true - sort.Sort(s.b) - } -} - -func (s *Stream) flushed() bool { - return len(s.stream.l) > 0 -} - -type stream struct { - n float64 - l []Sample - ƒ invariant -} - -func (s *stream) reset() { - s.l = s.l[:0] - s.n = 0 -} - -func (s *stream) insert(v float64) { - s.merge(Samples{{v, 1, 0}}) -} - -func (s *stream) merge(samples Samples) { - // TODO(beorn7): This tries to merge not only individual samples, but - // whole summaries. The paper doesn't mention merging summaries at - // all. Unittests show that the merging is inaccurate. Find out how to - // do merges properly. - var r float64 - i := 0 - for _, sample := range samples { - for ; i < len(s.l); i++ { - c := s.l[i] - if c.Value > sample.Value { - // Insert at position i. - s.l = append(s.l, Sample{}) - copy(s.l[i+1:], s.l[i:]) - s.l[i] = Sample{ - sample.Value, - sample.Width, - math.Max(sample.Delta, math.Floor(s.ƒ(s, r))-1), - // TODO(beorn7): How to calculate delta correctly? - } - i++ - goto inserted - } - r += c.Width - } - s.l = append(s.l, Sample{sample.Value, sample.Width, 0}) - i++ - inserted: - s.n += sample.Width - r += sample.Width - } - s.compress() -} - -func (s *stream) count() int { - return int(s.n) -} - -func (s *stream) query(q float64) float64 { - t := math.Ceil(q * s.n) - t += math.Ceil(s.ƒ(s, t) / 2) - p := s.l[0] - var r float64 - for _, c := range s.l[1:] { - r += p.Width - if r+c.Width+c.Delta > t { - return p.Value - } - p = c - } - return p.Value -} - -func (s *stream) compress() { - if len(s.l) < 2 { - return - } - x := s.l[len(s.l)-1] - xi := len(s.l) - 1 - r := s.n - 1 - x.Width - - for i := len(s.l) - 2; i >= 0; i-- { - c := s.l[i] - if c.Width+x.Width+x.Delta <= s.ƒ(s, r) { - x.Width += c.Width - s.l[xi] = x - // Remove element at i. - copy(s.l[i:], s.l[i+1:]) - s.l = s.l[:len(s.l)-1] - xi -= 1 - } else { - x = c - xi = i - } - r -= c.Width - } -} - -func (s *stream) samples() Samples { - samples := make(Samples, len(s.l)) - copy(samples, s.l) - return samples -} diff --git a/vendor/github.com/blang/semver/LICENSE b/vendor/github.com/blang/semver/LICENSE deleted file mode 100644 index 5ba5c86f..00000000 --- a/vendor/github.com/blang/semver/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License - -Copyright (c) 2014 Benedikt Lang - -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. - diff --git a/vendor/github.com/blang/semver/README.md b/vendor/github.com/blang/semver/README.md deleted file mode 100644 index 6af4dde7..00000000 --- a/vendor/github.com/blang/semver/README.md +++ /dev/null @@ -1,194 +0,0 @@ -semver for golang [![Build Status](https://travis-ci.org/blang/semver.svg?branch=master)](https://travis-ci.org/blang/semver) [![GoDoc](https://godoc.org/github.com/blang/semver?status.svg)](https://godoc.org/github.com/blang/semver) [![Coverage Status](https://img.shields.io/coveralls/blang/semver.svg)](https://coveralls.io/r/blang/semver?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/blang/semver)](https://goreportcard.com/report/github.com/blang/semver) -====== - -semver is a [Semantic Versioning](http://semver.org/) library written in golang. It fully covers spec version `2.0.0`. - -Usage ------ -```bash -$ go get github.com/blang/semver -``` -Note: Always vendor your dependencies or fix on a specific version tag. - -```go -import github.com/blang/semver -v1, err := semver.Make("1.0.0-beta") -v2, err := semver.Make("2.0.0-beta") -v1.Compare(v2) -``` - -Also check the [GoDocs](http://godoc.org/github.com/blang/semver). - -Why should I use this lib? ------ - -- Fully spec compatible -- No reflection -- No regex -- Fully tested (Coverage >99%) -- Readable parsing/validation errors -- Fast (See [Benchmarks](#benchmarks)) -- Only Stdlib -- Uses values instead of pointers -- Many features, see below - - -Features ------ - -- Parsing and validation at all levels -- Comparator-like comparisons -- Compare Helper Methods -- InPlace manipulation -- Ranges `>=1.0.0 <2.0.0 || >=3.0.0 !3.0.1-beta.1` -- Wildcards `>=1.x`, `<=2.5.x` -- Sortable (implements sort.Interface) -- database/sql compatible (sql.Scanner/Valuer) -- encoding/json compatible (json.Marshaler/Unmarshaler) - -Ranges ------- - -A `Range` is a set of conditions which specify which versions satisfy the range. - -A condition is composed of an operator and a version. The supported operators are: - -- `<1.0.0` Less than `1.0.0` -- `<=1.0.0` Less than or equal to `1.0.0` -- `>1.0.0` Greater than `1.0.0` -- `>=1.0.0` Greater than or equal to `1.0.0` -- `1.0.0`, `=1.0.0`, `==1.0.0` Equal to `1.0.0` -- `!1.0.0`, `!=1.0.0` Not equal to `1.0.0`. Excludes version `1.0.0`. - -Note that spaces between the operator and the version will be gracefully tolerated. - -A `Range` can link multiple `Ranges` separated by space: - -Ranges can be linked by logical AND: - - - `>1.0.0 <2.0.0` would match between both ranges, so `1.1.1` and `1.8.7` but not `1.0.0` or `2.0.0` - - `>1.0.0 <3.0.0 !2.0.3-beta.2` would match every version between `1.0.0` and `3.0.0` except `2.0.3-beta.2` - -Ranges can also be linked by logical OR: - - - `<2.0.0 || >=3.0.0` would match `1.x.x` and `3.x.x` but not `2.x.x` - -AND has a higher precedence than OR. It's not possible to use brackets. - -Ranges can be combined by both AND and OR - - - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1` - -Range usage: - -``` -v, err := semver.Parse("1.2.3") -range, err := semver.ParseRange(">1.0.0 <2.0.0 || >=3.0.0") -if range(v) { - //valid -} - -``` - -Example ------ - -Have a look at full examples in [examples/main.go](examples/main.go) - -```go -import github.com/blang/semver - -v, err := semver.Make("0.0.1-alpha.preview+123.github") -fmt.Printf("Major: %d\n", v.Major) -fmt.Printf("Minor: %d\n", v.Minor) -fmt.Printf("Patch: %d\n", v.Patch) -fmt.Printf("Pre: %s\n", v.Pre) -fmt.Printf("Build: %s\n", v.Build) - -// Prerelease versions array -if len(v.Pre) > 0 { - fmt.Println("Prerelease versions:") - for i, pre := range v.Pre { - fmt.Printf("%d: %q\n", i, pre) - } -} - -// Build meta data array -if len(v.Build) > 0 { - fmt.Println("Build meta data:") - for i, build := range v.Build { - fmt.Printf("%d: %q\n", i, build) - } -} - -v001, err := semver.Make("0.0.1") -// Compare using helpers: v.GT(v2), v.LT, v.GTE, v.LTE -v001.GT(v) == true -v.LT(v001) == true -v.GTE(v) == true -v.LTE(v) == true - -// Or use v.Compare(v2) for comparisons (-1, 0, 1): -v001.Compare(v) == 1 -v.Compare(v001) == -1 -v.Compare(v) == 0 - -// Manipulate Version in place: -v.Pre[0], err = semver.NewPRVersion("beta") -if err != nil { - fmt.Printf("Error parsing pre release version: %q", err) -} - -fmt.Println("\nValidate versions:") -v.Build[0] = "?" - -err = v.Validate() -if err != nil { - fmt.Printf("Validation failed: %s\n", err) -} -``` - - -Benchmarks ------ - - BenchmarkParseSimple-4 5000000 390 ns/op 48 B/op 1 allocs/op - BenchmarkParseComplex-4 1000000 1813 ns/op 256 B/op 7 allocs/op - BenchmarkParseAverage-4 1000000 1171 ns/op 163 B/op 4 allocs/op - BenchmarkStringSimple-4 20000000 119 ns/op 16 B/op 1 allocs/op - BenchmarkStringLarger-4 10000000 206 ns/op 32 B/op 2 allocs/op - BenchmarkStringComplex-4 5000000 324 ns/op 80 B/op 3 allocs/op - BenchmarkStringAverage-4 5000000 273 ns/op 53 B/op 2 allocs/op - BenchmarkValidateSimple-4 200000000 9.33 ns/op 0 B/op 0 allocs/op - BenchmarkValidateComplex-4 3000000 469 ns/op 0 B/op 0 allocs/op - BenchmarkValidateAverage-4 5000000 256 ns/op 0 B/op 0 allocs/op - BenchmarkCompareSimple-4 100000000 11.8 ns/op 0 B/op 0 allocs/op - BenchmarkCompareComplex-4 50000000 30.8 ns/op 0 B/op 0 allocs/op - BenchmarkCompareAverage-4 30000000 41.5 ns/op 0 B/op 0 allocs/op - BenchmarkSort-4 3000000 419 ns/op 256 B/op 2 allocs/op - BenchmarkRangeParseSimple-4 2000000 850 ns/op 192 B/op 5 allocs/op - BenchmarkRangeParseAverage-4 1000000 1677 ns/op 400 B/op 10 allocs/op - BenchmarkRangeParseComplex-4 300000 5214 ns/op 1440 B/op 30 allocs/op - BenchmarkRangeMatchSimple-4 50000000 25.6 ns/op 0 B/op 0 allocs/op - BenchmarkRangeMatchAverage-4 30000000 56.4 ns/op 0 B/op 0 allocs/op - BenchmarkRangeMatchComplex-4 10000000 153 ns/op 0 B/op 0 allocs/op - -See benchmark cases at [semver_test.go](semver_test.go) - - -Motivation ------ - -I simply couldn't find any lib supporting the full spec. Others were just wrong or used reflection and regex which i don't like. - - -Contribution ------ - -Feel free to make a pull request. For bigger changes create a issue first to discuss about it. - - -License ------ - -See [LICENSE](LICENSE) file. diff --git a/vendor/github.com/blang/semver/json.go b/vendor/github.com/blang/semver/json.go deleted file mode 100644 index a74bf7c4..00000000 --- a/vendor/github.com/blang/semver/json.go +++ /dev/null @@ -1,23 +0,0 @@ -package semver - -import ( - "encoding/json" -) - -// MarshalJSON implements the encoding/json.Marshaler interface. -func (v Version) MarshalJSON() ([]byte, error) { - return json.Marshal(v.String()) -} - -// UnmarshalJSON implements the encoding/json.Unmarshaler interface. -func (v *Version) UnmarshalJSON(data []byte) (err error) { - var versionString string - - if err = json.Unmarshal(data, &versionString); err != nil { - return - } - - *v, err = Parse(versionString) - - return -} diff --git a/vendor/github.com/blang/semver/package.json b/vendor/github.com/blang/semver/package.json deleted file mode 100644 index 1cf8ebdd..00000000 --- a/vendor/github.com/blang/semver/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "author": "blang", - "bugs": { - "URL": "https://github.com/blang/semver/issues", - "url": "https://github.com/blang/semver/issues" - }, - "gx": { - "dvcsimport": "github.com/blang/semver" - }, - "gxVersion": "0.10.0", - "language": "go", - "license": "MIT", - "name": "semver", - "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", - "version": "3.5.1" -} - diff --git a/vendor/github.com/blang/semver/range.go b/vendor/github.com/blang/semver/range.go deleted file mode 100644 index fca406d4..00000000 --- a/vendor/github.com/blang/semver/range.go +++ /dev/null @@ -1,416 +0,0 @@ -package semver - -import ( - "fmt" - "strconv" - "strings" - "unicode" -) - -type wildcardType int - -const ( - noneWildcard wildcardType = iota - majorWildcard wildcardType = 1 - minorWildcard wildcardType = 2 - patchWildcard wildcardType = 3 -) - -func wildcardTypefromInt(i int) wildcardType { - switch i { - case 1: - return majorWildcard - case 2: - return minorWildcard - case 3: - return patchWildcard - default: - return noneWildcard - } -} - -type comparator func(Version, Version) bool - -var ( - compEQ comparator = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) == 0 - } - compNE = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) != 0 - } - compGT = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) == 1 - } - compGE = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) >= 0 - } - compLT = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) == -1 - } - compLE = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) <= 0 - } -) - -type versionRange struct { - v Version - c comparator -} - -// rangeFunc creates a Range from the given versionRange. -func (vr *versionRange) rangeFunc() Range { - return Range(func(v Version) bool { - return vr.c(v, vr.v) - }) -} - -// Range represents a range of versions. -// A Range can be used to check if a Version satisfies it: -// -// range, err := semver.ParseRange(">1.0.0 <2.0.0") -// range(semver.MustParse("1.1.1") // returns true -type Range func(Version) bool - -// OR combines the existing Range with another Range using logical OR. -func (rf Range) OR(f Range) Range { - return Range(func(v Version) bool { - return rf(v) || f(v) - }) -} - -// AND combines the existing Range with another Range using logical AND. -func (rf Range) AND(f Range) Range { - return Range(func(v Version) bool { - return rf(v) && f(v) - }) -} - -// ParseRange parses a range and returns a Range. -// If the range could not be parsed an error is returned. -// -// Valid ranges are: -// - "<1.0.0" -// - "<=1.0.0" -// - ">1.0.0" -// - ">=1.0.0" -// - "1.0.0", "=1.0.0", "==1.0.0" -// - "!1.0.0", "!=1.0.0" -// -// A Range can consist of multiple ranges separated by space: -// Ranges can be linked by logical AND: -// - ">1.0.0 <2.0.0" would match between both ranges, so "1.1.1" and "1.8.7" but not "1.0.0" or "2.0.0" -// - ">1.0.0 <3.0.0 !2.0.3-beta.2" would match every version between 1.0.0 and 3.0.0 except 2.0.3-beta.2 -// -// Ranges can also be linked by logical OR: -// - "<2.0.0 || >=3.0.0" would match "1.x.x" and "3.x.x" but not "2.x.x" -// -// AND has a higher precedence than OR. It's not possible to use brackets. -// -// Ranges can be combined by both AND and OR -// -// - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1` -func ParseRange(s string) (Range, error) { - parts := splitAndTrim(s) - orParts, err := splitORParts(parts) - if err != nil { - return nil, err - } - expandedParts, err := expandWildcardVersion(orParts) - if err != nil { - return nil, err - } - var orFn Range - for _, p := range expandedParts { - var andFn Range - for _, ap := range p { - opStr, vStr, err := splitComparatorVersion(ap) - if err != nil { - return nil, err - } - vr, err := buildVersionRange(opStr, vStr) - if err != nil { - return nil, fmt.Errorf("Could not parse Range %q: %s", ap, err) - } - rf := vr.rangeFunc() - - // Set function - if andFn == nil { - andFn = rf - } else { // Combine with existing function - andFn = andFn.AND(rf) - } - } - if orFn == nil { - orFn = andFn - } else { - orFn = orFn.OR(andFn) - } - - } - return orFn, nil -} - -// splitORParts splits the already cleaned parts by '||'. -// Checks for invalid positions of the operator and returns an -// error if found. -func splitORParts(parts []string) ([][]string, error) { - var ORparts [][]string - last := 0 - for i, p := range parts { - if p == "||" { - if i == 0 { - return nil, fmt.Errorf("First element in range is '||'") - } - ORparts = append(ORparts, parts[last:i]) - last = i + 1 - } - } - if last == len(parts) { - return nil, fmt.Errorf("Last element in range is '||'") - } - ORparts = append(ORparts, parts[last:]) - return ORparts, nil -} - -// buildVersionRange takes a slice of 2: operator and version -// and builds a versionRange, otherwise an error. -func buildVersionRange(opStr, vStr string) (*versionRange, error) { - c := parseComparator(opStr) - if c == nil { - return nil, fmt.Errorf("Could not parse comparator %q in %q", opStr, strings.Join([]string{opStr, vStr}, "")) - } - v, err := Parse(vStr) - if err != nil { - return nil, fmt.Errorf("Could not parse version %q in %q: %s", vStr, strings.Join([]string{opStr, vStr}, ""), err) - } - - return &versionRange{ - v: v, - c: c, - }, nil - -} - -// inArray checks if a byte is contained in an array of bytes -func inArray(s byte, list []byte) bool { - for _, el := range list { - if el == s { - return true - } - } - return false -} - -// splitAndTrim splits a range string by spaces and cleans whitespaces -func splitAndTrim(s string) (result []string) { - last := 0 - var lastChar byte - excludeFromSplit := []byte{'>', '<', '='} - for i := 0; i < len(s); i++ { - if s[i] == ' ' && !inArray(lastChar, excludeFromSplit) { - if last < i-1 { - result = append(result, s[last:i]) - } - last = i + 1 - } else if s[i] != ' ' { - lastChar = s[i] - } - } - if last < len(s)-1 { - result = append(result, s[last:]) - } - - for i, v := range result { - result[i] = strings.Replace(v, " ", "", -1) - } - - // parts := strings.Split(s, " ") - // for _, x := range parts { - // if s := strings.TrimSpace(x); len(s) != 0 { - // result = append(result, s) - // } - // } - return -} - -// splitComparatorVersion splits the comparator from the version. -// Input must be free of leading or trailing spaces. -func splitComparatorVersion(s string) (string, string, error) { - i := strings.IndexFunc(s, unicode.IsDigit) - if i == -1 { - return "", "", fmt.Errorf("Could not get version from string: %q", s) - } - return strings.TrimSpace(s[0:i]), s[i:], nil -} - -// getWildcardType will return the type of wildcard that the -// passed version contains -func getWildcardType(vStr string) wildcardType { - parts := strings.Split(vStr, ".") - nparts := len(parts) - wildcard := parts[nparts-1] - - possibleWildcardType := wildcardTypefromInt(nparts) - if wildcard == "x" { - return possibleWildcardType - } - - return noneWildcard -} - -// createVersionFromWildcard will convert a wildcard version -// into a regular version, replacing 'x's with '0's, handling -// special cases like '1.x.x' and '1.x' -func createVersionFromWildcard(vStr string) string { - // handle 1.x.x - vStr2 := strings.Replace(vStr, ".x.x", ".x", 1) - vStr2 = strings.Replace(vStr2, ".x", ".0", 1) - parts := strings.Split(vStr2, ".") - - // handle 1.x - if len(parts) == 2 { - return vStr2 + ".0" - } - - return vStr2 -} - -// incrementMajorVersion will increment the major version -// of the passed version -func incrementMajorVersion(vStr string) (string, error) { - parts := strings.Split(vStr, ".") - i, err := strconv.Atoi(parts[0]) - if err != nil { - return "", err - } - parts[0] = strconv.Itoa(i + 1) - - return strings.Join(parts, "."), nil -} - -// incrementMajorVersion will increment the minor version -// of the passed version -func incrementMinorVersion(vStr string) (string, error) { - parts := strings.Split(vStr, ".") - i, err := strconv.Atoi(parts[1]) - if err != nil { - return "", err - } - parts[1] = strconv.Itoa(i + 1) - - return strings.Join(parts, "."), nil -} - -// expandWildcardVersion will expand wildcards inside versions -// following these rules: -// -// * when dealing with patch wildcards: -// >= 1.2.x will become >= 1.2.0 -// <= 1.2.x will become < 1.3.0 -// > 1.2.x will become >= 1.3.0 -// < 1.2.x will become < 1.2.0 -// != 1.2.x will become < 1.2.0 >= 1.3.0 -// -// * when dealing with minor wildcards: -// >= 1.x will become >= 1.0.0 -// <= 1.x will become < 2.0.0 -// > 1.x will become >= 2.0.0 -// < 1.0 will become < 1.0.0 -// != 1.x will become < 1.0.0 >= 2.0.0 -// -// * when dealing with wildcards without -// version operator: -// 1.2.x will become >= 1.2.0 < 1.3.0 -// 1.x will become >= 1.0.0 < 2.0.0 -func expandWildcardVersion(parts [][]string) ([][]string, error) { - var expandedParts [][]string - for _, p := range parts { - var newParts []string - for _, ap := range p { - if strings.Index(ap, "x") != -1 { - opStr, vStr, err := splitComparatorVersion(ap) - if err != nil { - return nil, err - } - - versionWildcardType := getWildcardType(vStr) - flatVersion := createVersionFromWildcard(vStr) - - var resultOperator string - var shouldIncrementVersion bool - switch opStr { - case ">": - resultOperator = ">=" - shouldIncrementVersion = true - case ">=": - resultOperator = ">=" - case "<": - resultOperator = "<" - case "<=": - resultOperator = "<" - shouldIncrementVersion = true - case "", "=", "==": - newParts = append(newParts, ">="+flatVersion) - resultOperator = "<" - shouldIncrementVersion = true - case "!=", "!": - newParts = append(newParts, "<"+flatVersion) - resultOperator = ">=" - shouldIncrementVersion = true - } - - var resultVersion string - if shouldIncrementVersion { - switch versionWildcardType { - case patchWildcard: - resultVersion, _ = incrementMinorVersion(flatVersion) - case minorWildcard: - resultVersion, _ = incrementMajorVersion(flatVersion) - } - } else { - resultVersion = flatVersion - } - - ap = resultOperator + resultVersion - } - newParts = append(newParts, ap) - } - expandedParts = append(expandedParts, newParts) - } - - return expandedParts, nil -} - -func parseComparator(s string) comparator { - switch s { - case "==": - fallthrough - case "": - fallthrough - case "=": - return compEQ - case ">": - return compGT - case ">=": - return compGE - case "<": - return compLT - case "<=": - return compLE - case "!": - fallthrough - case "!=": - return compNE - } - - return nil -} - -// MustParseRange is like ParseRange but panics if the range cannot be parsed. -func MustParseRange(s string) Range { - r, err := ParseRange(s) - if err != nil { - panic(`semver: ParseRange(` + s + `): ` + err.Error()) - } - return r -} diff --git a/vendor/github.com/blang/semver/semver.go b/vendor/github.com/blang/semver/semver.go deleted file mode 100644 index ec26aa03..00000000 --- a/vendor/github.com/blang/semver/semver.go +++ /dev/null @@ -1,418 +0,0 @@ -package semver - -import ( - "errors" - "fmt" - "strconv" - "strings" -) - -const ( - numbers string = "0123456789" - alphas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" - alphanum = alphas + numbers -) - -// SpecVersion is the latest fully supported spec version of semver -var SpecVersion = Version{ - Major: 2, - Minor: 0, - Patch: 0, -} - -// Version represents a semver compatible version -type Version struct { - Major uint64 - Minor uint64 - Patch uint64 - Pre []PRVersion - Build []string //No Precedence -} - -// Version to string -func (v Version) String() string { - b := make([]byte, 0, 5) - b = strconv.AppendUint(b, v.Major, 10) - b = append(b, '.') - b = strconv.AppendUint(b, v.Minor, 10) - b = append(b, '.') - b = strconv.AppendUint(b, v.Patch, 10) - - if len(v.Pre) > 0 { - b = append(b, '-') - b = append(b, v.Pre[0].String()...) - - for _, pre := range v.Pre[1:] { - b = append(b, '.') - b = append(b, pre.String()...) - } - } - - if len(v.Build) > 0 { - b = append(b, '+') - b = append(b, v.Build[0]...) - - for _, build := range v.Build[1:] { - b = append(b, '.') - b = append(b, build...) - } - } - - return string(b) -} - -// Equals checks if v is equal to o. -func (v Version) Equals(o Version) bool { - return (v.Compare(o) == 0) -} - -// EQ checks if v is equal to o. -func (v Version) EQ(o Version) bool { - return (v.Compare(o) == 0) -} - -// NE checks if v is not equal to o. -func (v Version) NE(o Version) bool { - return (v.Compare(o) != 0) -} - -// GT checks if v is greater than o. -func (v Version) GT(o Version) bool { - return (v.Compare(o) == 1) -} - -// GTE checks if v is greater than or equal to o. -func (v Version) GTE(o Version) bool { - return (v.Compare(o) >= 0) -} - -// GE checks if v is greater than or equal to o. -func (v Version) GE(o Version) bool { - return (v.Compare(o) >= 0) -} - -// LT checks if v is less than o. -func (v Version) LT(o Version) bool { - return (v.Compare(o) == -1) -} - -// LTE checks if v is less than or equal to o. -func (v Version) LTE(o Version) bool { - return (v.Compare(o) <= 0) -} - -// LE checks if v is less than or equal to o. -func (v Version) LE(o Version) bool { - return (v.Compare(o) <= 0) -} - -// Compare compares Versions v to o: -// -1 == v is less than o -// 0 == v is equal to o -// 1 == v is greater than o -func (v Version) Compare(o Version) int { - if v.Major != o.Major { - if v.Major > o.Major { - return 1 - } - return -1 - } - if v.Minor != o.Minor { - if v.Minor > o.Minor { - return 1 - } - return -1 - } - if v.Patch != o.Patch { - if v.Patch > o.Patch { - return 1 - } - return -1 - } - - // Quick comparison if a version has no prerelease versions - if len(v.Pre) == 0 && len(o.Pre) == 0 { - return 0 - } else if len(v.Pre) == 0 && len(o.Pre) > 0 { - return 1 - } else if len(v.Pre) > 0 && len(o.Pre) == 0 { - return -1 - } - - i := 0 - for ; i < len(v.Pre) && i < len(o.Pre); i++ { - if comp := v.Pre[i].Compare(o.Pre[i]); comp == 0 { - continue - } else if comp == 1 { - return 1 - } else { - return -1 - } - } - - // If all pr versions are the equal but one has further prversion, this one greater - if i == len(v.Pre) && i == len(o.Pre) { - return 0 - } else if i == len(v.Pre) && i < len(o.Pre) { - return -1 - } else { - return 1 - } - -} - -// Validate validates v and returns error in case -func (v Version) Validate() error { - // Major, Minor, Patch already validated using uint64 - - for _, pre := range v.Pre { - if !pre.IsNum { //Numeric prerelease versions already uint64 - if len(pre.VersionStr) == 0 { - return fmt.Errorf("Prerelease can not be empty %q", pre.VersionStr) - } - if !containsOnly(pre.VersionStr, alphanum) { - return fmt.Errorf("Invalid character(s) found in prerelease %q", pre.VersionStr) - } - } - } - - for _, build := range v.Build { - if len(build) == 0 { - return fmt.Errorf("Build meta data can not be empty %q", build) - } - if !containsOnly(build, alphanum) { - return fmt.Errorf("Invalid character(s) found in build meta data %q", build) - } - } - - return nil -} - -// New is an alias for Parse and returns a pointer, parses version string and returns a validated Version or error -func New(s string) (vp *Version, err error) { - v, err := Parse(s) - vp = &v - return -} - -// Make is an alias for Parse, parses version string and returns a validated Version or error -func Make(s string) (Version, error) { - return Parse(s) -} - -// ParseTolerant allows for certain version specifications that do not strictly adhere to semver -// specs to be parsed by this library. It does so by normalizing versions before passing them to -// Parse(). It currently trims spaces, removes a "v" prefix, and adds a 0 patch number to versions -// with only major and minor components specified -func ParseTolerant(s string) (Version, error) { - s = strings.TrimSpace(s) - s = strings.TrimPrefix(s, "v") - - // Split into major.minor.(patch+pr+meta) - parts := strings.SplitN(s, ".", 3) - if len(parts) < 3 { - if strings.ContainsAny(parts[len(parts)-1], "+-") { - return Version{}, errors.New("Short version cannot contain PreRelease/Build meta data") - } - for len(parts) < 3 { - parts = append(parts, "0") - } - s = strings.Join(parts, ".") - } - - return Parse(s) -} - -// Parse parses version string and returns a validated Version or error -func Parse(s string) (Version, error) { - if len(s) == 0 { - return Version{}, errors.New("Version string empty") - } - - // Split into major.minor.(patch+pr+meta) - parts := strings.SplitN(s, ".", 3) - if len(parts) != 3 { - return Version{}, errors.New("No Major.Minor.Patch elements found") - } - - // Major - if !containsOnly(parts[0], numbers) { - return Version{}, fmt.Errorf("Invalid character(s) found in major number %q", parts[0]) - } - if hasLeadingZeroes(parts[0]) { - return Version{}, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0]) - } - major, err := strconv.ParseUint(parts[0], 10, 64) - if err != nil { - return Version{}, err - } - - // Minor - if !containsOnly(parts[1], numbers) { - return Version{}, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1]) - } - if hasLeadingZeroes(parts[1]) { - return Version{}, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1]) - } - minor, err := strconv.ParseUint(parts[1], 10, 64) - if err != nil { - return Version{}, err - } - - v := Version{} - v.Major = major - v.Minor = minor - - var build, prerelease []string - patchStr := parts[2] - - if buildIndex := strings.IndexRune(patchStr, '+'); buildIndex != -1 { - build = strings.Split(patchStr[buildIndex+1:], ".") - patchStr = patchStr[:buildIndex] - } - - if preIndex := strings.IndexRune(patchStr, '-'); preIndex != -1 { - prerelease = strings.Split(patchStr[preIndex+1:], ".") - patchStr = patchStr[:preIndex] - } - - if !containsOnly(patchStr, numbers) { - return Version{}, fmt.Errorf("Invalid character(s) found in patch number %q", patchStr) - } - if hasLeadingZeroes(patchStr) { - return Version{}, fmt.Errorf("Patch number must not contain leading zeroes %q", patchStr) - } - patch, err := strconv.ParseUint(patchStr, 10, 64) - if err != nil { - return Version{}, err - } - - v.Patch = patch - - // Prerelease - for _, prstr := range prerelease { - parsedPR, err := NewPRVersion(prstr) - if err != nil { - return Version{}, err - } - v.Pre = append(v.Pre, parsedPR) - } - - // Build meta data - for _, str := range build { - if len(str) == 0 { - return Version{}, errors.New("Build meta data is empty") - } - if !containsOnly(str, alphanum) { - return Version{}, fmt.Errorf("Invalid character(s) found in build meta data %q", str) - } - v.Build = append(v.Build, str) - } - - return v, nil -} - -// MustParse is like Parse but panics if the version cannot be parsed. -func MustParse(s string) Version { - v, err := Parse(s) - if err != nil { - panic(`semver: Parse(` + s + `): ` + err.Error()) - } - return v -} - -// PRVersion represents a PreRelease Version -type PRVersion struct { - VersionStr string - VersionNum uint64 - IsNum bool -} - -// NewPRVersion creates a new valid prerelease version -func NewPRVersion(s string) (PRVersion, error) { - if len(s) == 0 { - return PRVersion{}, errors.New("Prerelease is empty") - } - v := PRVersion{} - if containsOnly(s, numbers) { - if hasLeadingZeroes(s) { - return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s) - } - num, err := strconv.ParseUint(s, 10, 64) - - // Might never be hit, but just in case - if err != nil { - return PRVersion{}, err - } - v.VersionNum = num - v.IsNum = true - } else if containsOnly(s, alphanum) { - v.VersionStr = s - v.IsNum = false - } else { - return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s) - } - return v, nil -} - -// IsNumeric checks if prerelease-version is numeric -func (v PRVersion) IsNumeric() bool { - return v.IsNum -} - -// Compare compares two PreRelease Versions v and o: -// -1 == v is less than o -// 0 == v is equal to o -// 1 == v is greater than o -func (v PRVersion) Compare(o PRVersion) int { - if v.IsNum && !o.IsNum { - return -1 - } else if !v.IsNum && o.IsNum { - return 1 - } else if v.IsNum && o.IsNum { - if v.VersionNum == o.VersionNum { - return 0 - } else if v.VersionNum > o.VersionNum { - return 1 - } else { - return -1 - } - } else { // both are Alphas - if v.VersionStr == o.VersionStr { - return 0 - } else if v.VersionStr > o.VersionStr { - return 1 - } else { - return -1 - } - } -} - -// PreRelease version to string -func (v PRVersion) String() string { - if v.IsNum { - return strconv.FormatUint(v.VersionNum, 10) - } - return v.VersionStr -} - -func containsOnly(s string, set string) bool { - return strings.IndexFunc(s, func(r rune) bool { - return !strings.ContainsRune(set, r) - }) == -1 -} - -func hasLeadingZeroes(s string) bool { - return len(s) > 1 && s[0] == '0' -} - -// NewBuildVersion creates a new valid build version -func NewBuildVersion(s string) (string, error) { - if len(s) == 0 { - return "", errors.New("Buildversion is empty") - } - if !containsOnly(s, alphanum) { - return "", fmt.Errorf("Invalid character(s) found in build meta data %q", s) - } - return s, nil -} diff --git a/vendor/github.com/blang/semver/sort.go b/vendor/github.com/blang/semver/sort.go deleted file mode 100644 index e18f8808..00000000 --- a/vendor/github.com/blang/semver/sort.go +++ /dev/null @@ -1,28 +0,0 @@ -package semver - -import ( - "sort" -) - -// Versions represents multiple versions. -type Versions []Version - -// Len returns length of version collection -func (s Versions) Len() int { - return len(s) -} - -// Swap swaps two versions inside the collection by its indices -func (s Versions) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -// Less checks if version at index i is less than version at index j -func (s Versions) Less(i, j int) bool { - return s[i].LT(s[j]) -} - -// Sort sorts a slice of versions -func Sort(versions []Version) { - sort.Sort(Versions(versions)) -} diff --git a/vendor/github.com/blang/semver/sql.go b/vendor/github.com/blang/semver/sql.go deleted file mode 100644 index eb4d8026..00000000 --- a/vendor/github.com/blang/semver/sql.go +++ /dev/null @@ -1,30 +0,0 @@ -package semver - -import ( - "database/sql/driver" - "fmt" -) - -// Scan implements the database/sql.Scanner interface. -func (v *Version) Scan(src interface{}) (err error) { - var str string - switch src := src.(type) { - case string: - str = src - case []byte: - str = string(src) - default: - return fmt.Errorf("Version.Scan: cannot convert %T to string.", src) - } - - if t, err := Parse(str); err == nil { - *v = t - } - - return -} - -// Value implements the database/sql/driver.Valuer interface. -func (v Version) Value() (driver.Value, error) { - return v.String(), nil -} diff --git a/vendor/github.com/go-kit/kit/LICENSE b/vendor/github.com/go-kit/kit/LICENSE deleted file mode 100644 index 9d83342a..00000000 --- a/vendor/github.com/go-kit/kit/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Peter Bourgon - -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. - diff --git a/vendor/github.com/go-kit/kit/log/README.md b/vendor/github.com/go-kit/kit/log/README.md deleted file mode 100644 index 7222f800..00000000 --- a/vendor/github.com/go-kit/kit/log/README.md +++ /dev/null @@ -1,147 +0,0 @@ -# package log - -`package log` provides a minimal interface for structured logging in services. -It may be wrapped to encode conventions, enforce type-safety, provide leveled -logging, and so on. It can be used for both typical application log events, -and log-structured data streams. - -## Structured logging - -Structured logging is, basically, conceding to the reality that logs are -_data_, and warrant some level of schematic rigor. Using a stricter, -key/value-oriented message format for our logs, containing contextual and -semantic information, makes it much easier to get insight into the -operational activity of the systems we build. Consequently, `package log` is -of the strong belief that "[the benefits of structured logging outweigh the -minimal effort involved](https://www.thoughtworks.com/radar/techniques/structured-logging)". - -Migrating from unstructured to structured logging is probably a lot easier -than you'd expect. - -```go -// Unstructured -log.Printf("HTTP server listening on %s", addr) - -// Structured -logger.Log("transport", "HTTP", "addr", addr, "msg", "listening") -``` - -## Usage - -### Typical application logging - -```go -w := log.NewSyncWriter(os.Stderr) -logger := log.NewLogfmtLogger(w) -logger.Log("question", "what is the meaning of life?", "answer", 42) - -// Output: -// question="what is the meaning of life?" answer=42 -``` - -### Contextual Loggers - -```go -func main() { - var logger log.Logger - logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) - logger = log.With(logger, "instance_id", 123) - - logger.Log("msg", "starting") - NewWorker(log.With(logger, "component", "worker")).Run() - NewSlacker(log.With(logger, "component", "slacker")).Run() -} - -// Output: -// instance_id=123 msg=starting -// instance_id=123 component=worker msg=running -// instance_id=123 component=slacker msg=running -``` - -### Interact with stdlib logger - -Redirect stdlib logger to Go kit logger. - -```go -import ( - "os" - stdlog "log" - kitlog "github.com/go-kit/kit/log" -) - -func main() { - logger := kitlog.NewJSONLogger(kitlog.NewSyncWriter(os.Stdout)) - stdlog.SetOutput(kitlog.NewStdlibAdapter(logger)) - stdlog.Print("I sure like pie") -} - -// Output: -// {"msg":"I sure like pie","ts":"2016/01/01 12:34:56"} -``` - -Or, if, for legacy reasons, you need to pipe all of your logging through the -stdlib log package, you can redirect Go kit logger to the stdlib logger. - -```go -logger := kitlog.NewLogfmtLogger(kitlog.StdlibWriter{}) -logger.Log("legacy", true, "msg", "at least it's something") - -// Output: -// 2016/01/01 12:34:56 legacy=true msg="at least it's something" -``` - -### Timestamps and callers - -```go -var logger log.Logger -logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) -logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) - -logger.Log("msg", "hello") - -// Output: -// ts=2016-01-01T12:34:56Z caller=main.go:15 msg=hello -``` - -## Supported output formats - -- [Logfmt](https://brandur.org/logfmt) ([see also](https://blog.codeship.com/logfmt-a-log-format-thats-easy-to-read-and-write)) -- JSON - -## Enhancements - -`package log` is centered on the one-method Logger interface. - -```go -type Logger interface { - Log(keyvals ...interface{}) error -} -``` - -This interface, and its supporting code like is the product of much iteration -and evaluation. For more details on the evolution of the Logger interface, -see [The Hunt for a Logger Interface](http://go-talks.appspot.com/github.com/ChrisHines/talks/structured-logging/structured-logging.slide#1), -a talk by [Chris Hines](https://github.com/ChrisHines). -Also, please see -[#63](https://github.com/go-kit/kit/issues/63), -[#76](https://github.com/go-kit/kit/pull/76), -[#131](https://github.com/go-kit/kit/issues/131), -[#157](https://github.com/go-kit/kit/pull/157), -[#164](https://github.com/go-kit/kit/issues/164), and -[#252](https://github.com/go-kit/kit/pull/252) -to review historical conversations about package log and the Logger interface. - -Value-add packages and suggestions, -like improvements to [the leveled logger](https://godoc.org/github.com/go-kit/kit/log/level), -are of course welcome. Good proposals should - -- Be composable with [contextual loggers](https://godoc.org/github.com/go-kit/kit/log#With), -- Not break the behavior of [log.Caller](https://godoc.org/github.com/go-kit/kit/log#Caller) in any wrapped contextual loggers, and -- Be friendly to packages that accept only an unadorned log.Logger. - -## Benchmarks & comparisons - -There are a few Go logging benchmarks and comparisons that include Go kit's package log. - -- [imkira/go-loggers-bench](https://github.com/imkira/go-loggers-bench) includes kit/log -- [uber-common/zap](https://github.com/uber-common/zap), a zero-alloc logging library, includes a comparison with kit/log diff --git a/vendor/github.com/go-kit/kit/log/doc.go b/vendor/github.com/go-kit/kit/log/doc.go deleted file mode 100644 index 918c0af4..00000000 --- a/vendor/github.com/go-kit/kit/log/doc.go +++ /dev/null @@ -1,116 +0,0 @@ -// Package log provides a structured logger. -// -// Structured logging produces logs easily consumed later by humans or -// machines. Humans might be interested in debugging errors, or tracing -// specific requests. Machines might be interested in counting interesting -// events, or aggregating information for off-line processing. In both cases, -// it is important that the log messages are structured and actionable. -// Package log is designed to encourage both of these best practices. -// -// Basic Usage -// -// The fundamental interface is Logger. Loggers create log events from -// key/value data. The Logger interface has a single method, Log, which -// accepts a sequence of alternating key/value pairs, which this package names -// keyvals. -// -// type Logger interface { -// Log(keyvals ...interface{}) error -// } -// -// Here is an example of a function using a Logger to create log events. -// -// func RunTask(task Task, logger log.Logger) string { -// logger.Log("taskID", task.ID, "event", "starting task") -// ... -// logger.Log("taskID", task.ID, "event", "task complete") -// } -// -// The keys in the above example are "taskID" and "event". The values are -// task.ID, "starting task", and "task complete". Every key is followed -// immediately by its value. -// -// Keys are usually plain strings. Values may be any type that has a sensible -// encoding in the chosen log format. With structured logging it is a good -// idea to log simple values without formatting them. This practice allows -// the chosen logger to encode values in the most appropriate way. -// -// Contextual Loggers -// -// A contextual logger stores keyvals that it includes in all log events. -// Building appropriate contextual loggers reduces repetition and aids -// consistency in the resulting log output. With and WithPrefix add context to -// a logger. We can use With to improve the RunTask example. -// -// func RunTask(task Task, logger log.Logger) string { -// logger = log.With(logger, "taskID", task.ID) -// logger.Log("event", "starting task") -// ... -// taskHelper(task.Cmd, logger) -// ... -// logger.Log("event", "task complete") -// } -// -// The improved version emits the same log events as the original for the -// first and last calls to Log. Passing the contextual logger to taskHelper -// enables each log event created by taskHelper to include the task.ID even -// though taskHelper does not have access to that value. Using contextual -// loggers this way simplifies producing log output that enables tracing the -// life cycle of individual tasks. (See the Contextual example for the full -// code of the above snippet.) -// -// Dynamic Contextual Values -// -// A Valuer function stored in a contextual logger generates a new value each -// time an event is logged. The Valuer example demonstrates how this feature -// works. -// -// Valuers provide the basis for consistently logging timestamps and source -// code location. The log package defines several valuers for that purpose. -// See Timestamp, DefaultTimestamp, DefaultTimestampUTC, Caller, and -// DefaultCaller. A common logger initialization sequence that ensures all log -// entries contain a timestamp and source location looks like this: -// -// logger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout)) -// logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) -// -// Concurrent Safety -// -// Applications with multiple goroutines want each log event written to the -// same logger to remain separate from other log events. Package log provides -// two simple solutions for concurrent safe logging. -// -// NewSyncWriter wraps an io.Writer and serializes each call to its Write -// method. Using a SyncWriter has the benefit that the smallest practical -// portion of the logging logic is performed within a mutex, but it requires -// the formatting Logger to make only one call to Write per log event. -// -// NewSyncLogger wraps any Logger and serializes each call to its Log method. -// Using a SyncLogger has the benefit that it guarantees each log event is -// handled atomically within the wrapped logger, but it typically serializes -// both the formatting and output logic. Use a SyncLogger if the formatting -// logger may perform multiple writes per log event. -// -// Error Handling -// -// This package relies on the practice of wrapping or decorating loggers with -// other loggers to provide composable pieces of functionality. It also means -// that Logger.Log must return an error because some -// implementations—especially those that output log data to an io.Writer—may -// encounter errors that cannot be handled locally. This in turn means that -// Loggers that wrap other loggers should return errors from the wrapped -// logger up the stack. -// -// Fortunately, the decorator pattern also provides a way to avoid the -// necessity to check for errors every time an application calls Logger.Log. -// An application required to panic whenever its Logger encounters -// an error could initialize its logger as follows. -// -// fmtlogger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout)) -// logger := log.LoggerFunc(func(keyvals ...interface{}) error { -// if err := fmtlogger.Log(keyvals...); err != nil { -// panic(err) -// } -// return nil -// }) -package log diff --git a/vendor/github.com/go-kit/kit/log/json_logger.go b/vendor/github.com/go-kit/kit/log/json_logger.go deleted file mode 100644 index 231e0995..00000000 --- a/vendor/github.com/go-kit/kit/log/json_logger.go +++ /dev/null @@ -1,92 +0,0 @@ -package log - -import ( - "encoding" - "encoding/json" - "fmt" - "io" - "reflect" -) - -type jsonLogger struct { - io.Writer -} - -// NewJSONLogger returns a Logger that encodes keyvals to the Writer as a -// single JSON object. Each log event produces no more than one call to -// w.Write. The passed Writer must be safe for concurrent use by multiple -// goroutines if the returned Logger will be used concurrently. -func NewJSONLogger(w io.Writer) Logger { - return &jsonLogger{w} -} - -func (l *jsonLogger) Log(keyvals ...interface{}) error { - n := (len(keyvals) + 1) / 2 // +1 to handle case when len is odd - m := make(map[string]interface{}, n) - for i := 0; i < len(keyvals); i += 2 { - k := keyvals[i] - var v interface{} = ErrMissingValue - if i+1 < len(keyvals) { - v = keyvals[i+1] - } - merge(m, k, v) - } - return json.NewEncoder(l.Writer).Encode(m) -} - -func merge(dst map[string]interface{}, k, v interface{}) { - var key string - switch x := k.(type) { - case string: - key = x - case fmt.Stringer: - key = safeString(x) - default: - key = fmt.Sprint(x) - } - if x, ok := v.(error); ok { - v = safeError(x) - } - - // We want json.Marshaler and encoding.TextMarshaller to take priority over - // err.Error() and v.String(). But json.Marshall (called later) does that by - // default so we force a no-op if it's one of those 2 case. - switch x := v.(type) { - case json.Marshaler: - case encoding.TextMarshaler: - case error: - v = safeError(x) - case fmt.Stringer: - v = safeString(x) - } - - dst[key] = v -} - -func safeString(str fmt.Stringer) (s string) { - defer func() { - if panicVal := recover(); panicVal != nil { - if v := reflect.ValueOf(str); v.Kind() == reflect.Ptr && v.IsNil() { - s = "NULL" - } else { - panic(panicVal) - } - } - }() - s = str.String() - return -} - -func safeError(err error) (s interface{}) { - defer func() { - if panicVal := recover(); panicVal != nil { - if v := reflect.ValueOf(err); v.Kind() == reflect.Ptr && v.IsNil() { - s = nil - } else { - panic(panicVal) - } - } - }() - s = err.Error() - return -} diff --git a/vendor/github.com/go-kit/kit/log/level/doc.go b/vendor/github.com/go-kit/kit/log/level/doc.go deleted file mode 100644 index 5e9df7fa..00000000 --- a/vendor/github.com/go-kit/kit/log/level/doc.go +++ /dev/null @@ -1,22 +0,0 @@ -// Package level implements leveled logging on top of package log. To use the -// level package, create a logger as per normal in your func main, and wrap it -// with level.NewFilter. -// -// var logger log.Logger -// logger = log.NewLogfmtLogger(os.Stderr) -// logger = level.NewFilter(logger, level.AllowInfoAndAbove()) // <-- -// logger = log.With(logger, "ts", log.DefaultTimestampUTC) -// -// Then, at the callsites, use one of the level.Debug, Info, Warn, or Error -// helper methods to emit leveled log events. -// -// logger.Log("foo", "bar") // as normal, no level -// level.Debug(logger).Log("request_id", reqID, "trace_data", trace.Get()) -// if value > 100 { -// level.Error(logger).Log("value", value) -// } -// -// NewFilter allows precise control over what happens when a log event is -// emitted without a level key, or if a squelched level is used. Check the -// Option functions for details. -package level diff --git a/vendor/github.com/go-kit/kit/log/level/level.go b/vendor/github.com/go-kit/kit/log/level/level.go deleted file mode 100644 index 6833b0dc..00000000 --- a/vendor/github.com/go-kit/kit/log/level/level.go +++ /dev/null @@ -1,205 +0,0 @@ -package level - -import "github.com/go-kit/kit/log" - -// Error returns a logger that includes a Key/ErrorValue pair. -func Error(logger log.Logger) log.Logger { - return log.WithPrefix(logger, Key(), ErrorValue()) -} - -// Warn returns a logger that includes a Key/WarnValue pair. -func Warn(logger log.Logger) log.Logger { - return log.WithPrefix(logger, Key(), WarnValue()) -} - -// Info returns a logger that includes a Key/InfoValue pair. -func Info(logger log.Logger) log.Logger { - return log.WithPrefix(logger, Key(), InfoValue()) -} - -// Debug returns a logger that includes a Key/DebugValue pair. -func Debug(logger log.Logger) log.Logger { - return log.WithPrefix(logger, Key(), DebugValue()) -} - -// NewFilter wraps next and implements level filtering. See the commentary on -// the Option functions for a detailed description of how to configure levels. -// If no options are provided, all leveled log events created with Debug, -// Info, Warn or Error helper methods are squelched and non-leveled log -// events are passed to next unmodified. -func NewFilter(next log.Logger, options ...Option) log.Logger { - l := &logger{ - next: next, - } - for _, option := range options { - option(l) - } - return l -} - -type logger struct { - next log.Logger - allowed level - squelchNoLevel bool - errNotAllowed error - errNoLevel error -} - -func (l *logger) Log(keyvals ...interface{}) error { - var hasLevel, levelAllowed bool - for i := 1; i < len(keyvals); i += 2 { - if v, ok := keyvals[i].(*levelValue); ok { - hasLevel = true - levelAllowed = l.allowed&v.level != 0 - break - } - } - if !hasLevel && l.squelchNoLevel { - return l.errNoLevel - } - if hasLevel && !levelAllowed { - return l.errNotAllowed - } - return l.next.Log(keyvals...) -} - -// Option sets a parameter for the leveled logger. -type Option func(*logger) - -// AllowAll is an alias for AllowDebug. -func AllowAll() Option { - return AllowDebug() -} - -// AllowDebug allows error, warn, info and debug level log events to pass. -func AllowDebug() Option { - return allowed(levelError | levelWarn | levelInfo | levelDebug) -} - -// AllowInfo allows error, warn and info level log events to pass. -func AllowInfo() Option { - return allowed(levelError | levelWarn | levelInfo) -} - -// AllowWarn allows error and warn level log events to pass. -func AllowWarn() Option { - return allowed(levelError | levelWarn) -} - -// AllowError allows only error level log events to pass. -func AllowError() Option { - return allowed(levelError) -} - -// AllowNone allows no leveled log events to pass. -func AllowNone() Option { - return allowed(0) -} - -func allowed(allowed level) Option { - return func(l *logger) { l.allowed = allowed } -} - -// ErrNotAllowed sets the error to return from Log when it squelches a log -// event disallowed by the configured Allow[Level] option. By default, -// ErrNotAllowed is nil; in this case the log event is squelched with no -// error. -func ErrNotAllowed(err error) Option { - return func(l *logger) { l.errNotAllowed = err } -} - -// SquelchNoLevel instructs Log to squelch log events with no level, so that -// they don't proceed through to the wrapped logger. If SquelchNoLevel is set -// to true and a log event is squelched in this way, the error value -// configured with ErrNoLevel is returned to the caller. -func SquelchNoLevel(squelch bool) Option { - return func(l *logger) { l.squelchNoLevel = squelch } -} - -// ErrNoLevel sets the error to return from Log when it squelches a log event -// with no level. By default, ErrNoLevel is nil; in this case the log event is -// squelched with no error. -func ErrNoLevel(err error) Option { - return func(l *logger) { l.errNoLevel = err } -} - -// NewInjector wraps next and returns a logger that adds a Key/level pair to -// the beginning of log events that don't already contain a level. In effect, -// this gives a default level to logs without a level. -func NewInjector(next log.Logger, level Value) log.Logger { - return &injector{ - next: next, - level: level, - } -} - -type injector struct { - next log.Logger - level interface{} -} - -func (l *injector) Log(keyvals ...interface{}) error { - for i := 1; i < len(keyvals); i += 2 { - if _, ok := keyvals[i].(*levelValue); ok { - return l.next.Log(keyvals...) - } - } - kvs := make([]interface{}, len(keyvals)+2) - kvs[0], kvs[1] = key, l.level - copy(kvs[2:], keyvals) - return l.next.Log(kvs...) -} - -// Value is the interface that each of the canonical level values implement. -// It contains unexported methods that prevent types from other packages from -// implementing it and guaranteeing that NewFilter can distinguish the levels -// defined in this package from all other values. -type Value interface { - String() string - levelVal() -} - -// Key returns the unique key added to log events by the loggers in this -// package. -func Key() interface{} { return key } - -// ErrorValue returns the unique value added to log events by Error. -func ErrorValue() Value { return errorValue } - -// WarnValue returns the unique value added to log events by Warn. -func WarnValue() Value { return warnValue } - -// InfoValue returns the unique value added to log events by Info. -func InfoValue() Value { return infoValue } - -// DebugValue returns the unique value added to log events by Warn. -func DebugValue() Value { return debugValue } - -var ( - // key is of type interfae{} so that it allocates once during package - // initialization and avoids allocating every type the value is added to a - // []interface{} later. - key interface{} = "level" - - errorValue = &levelValue{level: levelError, name: "error"} - warnValue = &levelValue{level: levelWarn, name: "warn"} - infoValue = &levelValue{level: levelInfo, name: "info"} - debugValue = &levelValue{level: levelDebug, name: "debug"} -) - -type level byte - -const ( - levelDebug level = 1 << iota - levelInfo - levelWarn - levelError -) - -type levelValue struct { - name string - level -} - -func (v *levelValue) String() string { return v.name } -func (v *levelValue) levelVal() {} diff --git a/vendor/github.com/go-kit/kit/log/log.go b/vendor/github.com/go-kit/kit/log/log.go deleted file mode 100644 index 66a9e2fd..00000000 --- a/vendor/github.com/go-kit/kit/log/log.go +++ /dev/null @@ -1,135 +0,0 @@ -package log - -import "errors" - -// Logger is the fundamental interface for all log operations. Log creates a -// log event from keyvals, a variadic sequence of alternating keys and values. -// Implementations must be safe for concurrent use by multiple goroutines. In -// particular, any implementation of Logger that appends to keyvals or -// modifies or retains any of its elements must make a copy first. -type Logger interface { - Log(keyvals ...interface{}) error -} - -// ErrMissingValue is appended to keyvals slices with odd length to substitute -// the missing value. -var ErrMissingValue = errors.New("(MISSING)") - -// With returns a new contextual logger with keyvals prepended to those passed -// to calls to Log. If logger is also a contextual logger created by With or -// WithPrefix, keyvals is appended to the existing context. -// -// The returned Logger replaces all value elements (odd indexes) containing a -// Valuer with their generated value for each call to its Log method. -func With(logger Logger, keyvals ...interface{}) Logger { - if len(keyvals) == 0 { - return logger - } - l := newContext(logger) - kvs := append(l.keyvals, keyvals...) - if len(kvs)%2 != 0 { - kvs = append(kvs, ErrMissingValue) - } - return &context{ - logger: l.logger, - // Limiting the capacity of the stored keyvals ensures that a new - // backing array is created if the slice must grow in Log or With. - // Using the extra capacity without copying risks a data race that - // would violate the Logger interface contract. - keyvals: kvs[:len(kvs):len(kvs)], - hasValuer: l.hasValuer || containsValuer(keyvals), - } -} - -// WithPrefix returns a new contextual logger with keyvals prepended to those -// passed to calls to Log. If logger is also a contextual logger created by -// With or WithPrefix, keyvals is prepended to the existing context. -// -// The returned Logger replaces all value elements (odd indexes) containing a -// Valuer with their generated value for each call to its Log method. -func WithPrefix(logger Logger, keyvals ...interface{}) Logger { - if len(keyvals) == 0 { - return logger - } - l := newContext(logger) - // Limiting the capacity of the stored keyvals ensures that a new - // backing array is created if the slice must grow in Log or With. - // Using the extra capacity without copying risks a data race that - // would violate the Logger interface contract. - n := len(l.keyvals) + len(keyvals) - if len(keyvals)%2 != 0 { - n++ - } - kvs := make([]interface{}, 0, n) - kvs = append(kvs, keyvals...) - if len(kvs)%2 != 0 { - kvs = append(kvs, ErrMissingValue) - } - kvs = append(kvs, l.keyvals...) - return &context{ - logger: l.logger, - keyvals: kvs, - hasValuer: l.hasValuer || containsValuer(keyvals), - } -} - -// context is the Logger implementation returned by With and WithPrefix. It -// wraps a Logger and holds keyvals that it includes in all log events. Its -// Log method calls bindValues to generate values for each Valuer in the -// context keyvals. -// -// A context must always have the same number of stack frames between calls to -// its Log method and the eventual binding of Valuers to their value. This -// requirement comes from the functional requirement to allow a context to -// resolve application call site information for a Caller stored in the -// context. To do this we must be able to predict the number of logging -// functions on the stack when bindValues is called. -// -// Two implementation details provide the needed stack depth consistency. -// -// 1. newContext avoids introducing an additional layer when asked to -// wrap another context. -// 2. With and WithPrefix avoid introducing an additional layer by -// returning a newly constructed context with a merged keyvals rather -// than simply wrapping the existing context. -type context struct { - logger Logger - keyvals []interface{} - hasValuer bool -} - -func newContext(logger Logger) *context { - if c, ok := logger.(*context); ok { - return c - } - return &context{logger: logger} -} - -// Log replaces all value elements (odd indexes) containing a Valuer in the -// stored context with their generated value, appends keyvals, and passes the -// result to the wrapped Logger. -func (l *context) Log(keyvals ...interface{}) error { - kvs := append(l.keyvals, keyvals...) - if len(kvs)%2 != 0 { - kvs = append(kvs, ErrMissingValue) - } - if l.hasValuer { - // If no keyvals were appended above then we must copy l.keyvals so - // that future log events will reevaluate the stored Valuers. - if len(keyvals) == 0 { - kvs = append([]interface{}{}, l.keyvals...) - } - bindValues(kvs[:len(l.keyvals)]) - } - return l.logger.Log(kvs...) -} - -// LoggerFunc is an adapter to allow use of ordinary functions as Loggers. If -// f is a function with the appropriate signature, LoggerFunc(f) is a Logger -// object that calls f. -type LoggerFunc func(...interface{}) error - -// Log implements Logger by calling f(keyvals...). -func (f LoggerFunc) Log(keyvals ...interface{}) error { - return f(keyvals...) -} diff --git a/vendor/github.com/go-kit/kit/log/logfmt_logger.go b/vendor/github.com/go-kit/kit/log/logfmt_logger.go deleted file mode 100644 index a0030529..00000000 --- a/vendor/github.com/go-kit/kit/log/logfmt_logger.go +++ /dev/null @@ -1,62 +0,0 @@ -package log - -import ( - "bytes" - "io" - "sync" - - "github.com/go-logfmt/logfmt" -) - -type logfmtEncoder struct { - *logfmt.Encoder - buf bytes.Buffer -} - -func (l *logfmtEncoder) Reset() { - l.Encoder.Reset() - l.buf.Reset() -} - -var logfmtEncoderPool = sync.Pool{ - New: func() interface{} { - var enc logfmtEncoder - enc.Encoder = logfmt.NewEncoder(&enc.buf) - return &enc - }, -} - -type logfmtLogger struct { - w io.Writer -} - -// NewLogfmtLogger returns a logger that encodes keyvals to the Writer in -// logfmt format. Each log event produces no more than one call to w.Write. -// The passed Writer must be safe for concurrent use by multiple goroutines if -// the returned Logger will be used concurrently. -func NewLogfmtLogger(w io.Writer) Logger { - return &logfmtLogger{w} -} - -func (l logfmtLogger) Log(keyvals ...interface{}) error { - enc := logfmtEncoderPool.Get().(*logfmtEncoder) - enc.Reset() - defer logfmtEncoderPool.Put(enc) - - if err := enc.EncodeKeyvals(keyvals...); err != nil { - return err - } - - // Add newline to the end of the buffer - if err := enc.EndRecord(); err != nil { - return err - } - - // The Logger interface requires implementations to be safe for concurrent - // use by multiple goroutines. For this implementation that means making - // only one call to l.w.Write() for each call to Log. - if _, err := l.w.Write(enc.buf.Bytes()); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/go-kit/kit/log/nop_logger.go b/vendor/github.com/go-kit/kit/log/nop_logger.go deleted file mode 100644 index 1047d626..00000000 --- a/vendor/github.com/go-kit/kit/log/nop_logger.go +++ /dev/null @@ -1,8 +0,0 @@ -package log - -type nopLogger struct{} - -// NewNopLogger returns a logger that doesn't do anything. -func NewNopLogger() Logger { return nopLogger{} } - -func (nopLogger) Log(...interface{}) error { return nil } diff --git a/vendor/github.com/go-kit/kit/log/stdlib.go b/vendor/github.com/go-kit/kit/log/stdlib.go deleted file mode 100644 index ff96b5de..00000000 --- a/vendor/github.com/go-kit/kit/log/stdlib.go +++ /dev/null @@ -1,116 +0,0 @@ -package log - -import ( - "io" - "log" - "regexp" - "strings" -) - -// StdlibWriter implements io.Writer by invoking the stdlib log.Print. It's -// designed to be passed to a Go kit logger as the writer, for cases where -// it's necessary to redirect all Go kit log output to the stdlib logger. -// -// If you have any choice in the matter, you shouldn't use this. Prefer to -// redirect the stdlib log to the Go kit logger via NewStdlibAdapter. -type StdlibWriter struct{} - -// Write implements io.Writer. -func (w StdlibWriter) Write(p []byte) (int, error) { - log.Print(strings.TrimSpace(string(p))) - return len(p), nil -} - -// StdlibAdapter wraps a Logger and allows it to be passed to the stdlib -// logger's SetOutput. It will extract date/timestamps, filenames, and -// messages, and place them under relevant keys. -type StdlibAdapter struct { - Logger - timestampKey string - fileKey string - messageKey string -} - -// StdlibAdapterOption sets a parameter for the StdlibAdapter. -type StdlibAdapterOption func(*StdlibAdapter) - -// TimestampKey sets the key for the timestamp field. By default, it's "ts". -func TimestampKey(key string) StdlibAdapterOption { - return func(a *StdlibAdapter) { a.timestampKey = key } -} - -// FileKey sets the key for the file and line field. By default, it's "caller". -func FileKey(key string) StdlibAdapterOption { - return func(a *StdlibAdapter) { a.fileKey = key } -} - -// MessageKey sets the key for the actual log message. By default, it's "msg". -func MessageKey(key string) StdlibAdapterOption { - return func(a *StdlibAdapter) { a.messageKey = key } -} - -// NewStdlibAdapter returns a new StdlibAdapter wrapper around the passed -// logger. It's designed to be passed to log.SetOutput. -func NewStdlibAdapter(logger Logger, options ...StdlibAdapterOption) io.Writer { - a := StdlibAdapter{ - Logger: logger, - timestampKey: "ts", - fileKey: "caller", - messageKey: "msg", - } - for _, option := range options { - option(&a) - } - return a -} - -func (a StdlibAdapter) Write(p []byte) (int, error) { - result := subexps(p) - keyvals := []interface{}{} - var timestamp string - if date, ok := result["date"]; ok && date != "" { - timestamp = date - } - if time, ok := result["time"]; ok && time != "" { - if timestamp != "" { - timestamp += " " - } - timestamp += time - } - if timestamp != "" { - keyvals = append(keyvals, a.timestampKey, timestamp) - } - if file, ok := result["file"]; ok && file != "" { - keyvals = append(keyvals, a.fileKey, file) - } - if msg, ok := result["msg"]; ok { - keyvals = append(keyvals, a.messageKey, msg) - } - if err := a.Logger.Log(keyvals...); err != nil { - return 0, err - } - return len(p), nil -} - -const ( - logRegexpDate = `(?P[0-9]{4}/[0-9]{2}/[0-9]{2})?[ ]?` - logRegexpTime = `(?P