├── .dockerignore ├── .gitignore ├── .travis.yml ├── Dockerfile ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── app ├── controllers │ ├── application_controller.rb │ ├── concerns │ │ └── .keep │ └── stats_controller.rb └── models │ ├── concerns │ └── .keep │ ├── exporter │ ├── collector │ │ └── op_log.rb │ ├── dsl │ │ ├── context.rb │ │ ├── helper.rb │ │ ├── nested_proxy.rb │ │ └── proxy.rb │ ├── point.rb │ ├── point │ │ ├── counter.rb │ │ └── gauge.rb │ ├── server.rb │ ├── server │ │ ├── configuration.rb │ │ ├── mongos.rb │ │ └── shard.rb │ ├── settings.rb │ ├── settings │ │ ├── mongodb.rb │ │ └── reader.rb │ ├── source.rb │ └── source │ │ ├── collection.rb │ │ ├── helpers │ │ ├── wired_tiger_collection.rb │ │ └── wired_tiger_database.rb │ │ ├── index.rb │ │ ├── mongod.rb │ │ ├── mongos.rb │ │ └── replica_set.rb │ └── prometheus.rb ├── bin ├── bundle ├── rails ├── rake ├── setup └── update ├── config.ru ├── config ├── application.rb ├── boot.rb ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── application_controller_renderer.rb │ ├── backport_rails.rb │ ├── backtrace_silencers.rb │ ├── cors.rb │ ├── filter_parameter_logging.rb │ ├── inflections.rb │ ├── mime_types.rb │ ├── new_framework_defaults.rb │ ├── session_store.rb │ └── wrap_parameters.rb ├── locales │ └── en.yml ├── routes.rb ├── secrets.yml ├── settings.yml └── warble.rb ├── db └── seeds.rb ├── lib └── tasks │ └── .keep ├── public └── robots.txt └── vendor ├── grafana ├── mongo_cloud.json └── mongo_collection.json └── prometheus └── prometheus.yml /.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | vendor/* 3 | tmp/* 4 | spec/* 5 | src/* 6 | logs/* 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | log/**/* 3 | tmp/**/* 4 | vendor/mongo/data/* 5 | vendor/prometheus/data/* 6 | vendor/gems/* 7 | !vendor/gems/cache/ 8 | .sass-cache/* 9 | db/*.db 10 | .*.sw* 11 | *.jar 12 | *.war 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: ruby 4 | rvm: 5 | - jruby-9.1.12.0 6 | 7 | jdk: 8 | - oraclejdk8 9 | 10 | script: 11 | - 'gem install rake -v 12.0.0' 12 | - 'gem install warbler' 13 | - 'warble' 14 | 15 | deploy: 16 | provider: releases 17 | skip_cleanup: true 18 | file: mongo_collection_exporter.war 19 | file_glob: true 20 | on: 21 | repo: y8/mongo_collection_exporter 22 | tags: true 23 | api_key: 24 | secure: dz0C08/FnnCjRn6fcx5jcsIQU/Ozot0aCKvMPSjGupDTUocWJLjudRmn7j6Yn+TlJ5IyGbrUQH65Cmpe9rtiohI5rZVrwexoSwBLUMpFrpG8b8Ywmsl+nqosRfYtRDEgSR5ud+SVjNrB2X21yZ+ZBs4sheHoCcYk7Rlw6GfaCQhXEcod8F9x83FAjdpHGkHWvBMIB6I9+rJWAAIwT4oJ/zGM9qvqCrCkJIh0uvJAj+MfDd3s/Mzhot2pyreZqlIhGbp2W7RIUrENDvWpoTpZlwzYtYc+ei8PGrhwbYNqx3ZIJBfdO5M9lcKS8/y3eNgJ1tmtwg2IcAlwDDwRdeEt0QSo/fcaBPw5BSBVRr2piNbe05XHVnzX9rPE888dWkM3Hm4RXgCj8Wiu07jhov9g+QgE9fg5LKFvdnyq6b7Xvujvl1dtnLiwMycTgdyVRZfpQdcnkXZfkW0JFx4ssJ3kbR+BXDiRXkX1DhZs3BPg/YHpDtXnHnck/PmXAdRoOZw86JUjr44iuhjqS4UyFoBcJaz3uihQmml9I6EA734rYnQIVaGqz+w4MvuFscPzMtN5UyDLvqmm5dWJC6JkhAhB94U0DhYNouZerZ1mz+IOeTzZqmEv17RmZ3WXWGk73SjXjfpRHTdD2eblBczO5Z+LF9Q9hl5V3KX2N2Q1TUXEJS4= 25 | 26 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jruby:9.1-jre-alpine 2 | 3 | ADD . /exporter 4 | WORKDIR /exporter 5 | RUN bundler install --deployment --jobs=4 6 | 7 | EXPOSE 8080 8 | 9 | ENV RAILS_ENV=production 10 | 11 | CMD bundle exec rails server -b 0.0.0.0 12 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 4 | gem 'rails', '~> 5.0.0', '>= 5.0.0.1' 5 | 6 | # Mongo Driver 7 | gem 'mongo', '~> 2.4' 8 | 9 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 10 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 11 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actioncable (5.0.4) 5 | actionpack (= 5.0.4) 6 | nio4r (>= 1.2, < 3.0) 7 | websocket-driver (~> 0.6.1) 8 | actionmailer (5.0.4) 9 | actionpack (= 5.0.4) 10 | actionview (= 5.0.4) 11 | activejob (= 5.0.4) 12 | mail (~> 2.5, >= 2.5.4) 13 | rails-dom-testing (~> 2.0) 14 | actionpack (5.0.4) 15 | actionview (= 5.0.4) 16 | activesupport (= 5.0.4) 17 | rack (~> 2.0) 18 | rack-test (~> 0.6.3) 19 | rails-dom-testing (~> 2.0) 20 | rails-html-sanitizer (~> 1.0, >= 1.0.2) 21 | actionview (5.0.4) 22 | activesupport (= 5.0.4) 23 | builder (~> 3.1) 24 | erubis (~> 2.7.0) 25 | rails-dom-testing (~> 2.0) 26 | rails-html-sanitizer (~> 1.0, >= 1.0.3) 27 | activejob (5.0.4) 28 | activesupport (= 5.0.4) 29 | globalid (>= 0.3.6) 30 | activemodel (5.0.4) 31 | activesupport (= 5.0.4) 32 | activerecord (5.0.4) 33 | activemodel (= 5.0.4) 34 | activesupport (= 5.0.4) 35 | arel (~> 7.0) 36 | activesupport (5.0.4) 37 | concurrent-ruby (~> 1.0, >= 1.0.2) 38 | i18n (~> 0.7) 39 | minitest (~> 5.1) 40 | tzinfo (~> 1.1) 41 | arel (7.1.4) 42 | bson (4.2.2-java) 43 | builder (3.2.3) 44 | concurrent-ruby (1.0.5-java) 45 | erubis (2.7.0) 46 | globalid (0.4.0) 47 | activesupport (>= 4.2.0) 48 | i18n (0.8.6) 49 | loofah (2.0.3) 50 | nokogiri (>= 1.5.9) 51 | mail (2.6.6) 52 | mime-types (>= 1.16, < 4) 53 | method_source (0.8.2) 54 | mime-types (3.1) 55 | mime-types-data (~> 3.2015) 56 | mime-types-data (3.2016.0521) 57 | minitest (5.10.2) 58 | mongo (2.4.2) 59 | bson (>= 4.2.1, < 5.0.0) 60 | nio4r (2.1.0-java) 61 | nokogiri (1.8.0-java) 62 | rack (2.0.3) 63 | rack-test (0.6.3) 64 | rack (>= 1.0) 65 | rails (5.0.4) 66 | actioncable (= 5.0.4) 67 | actionmailer (= 5.0.4) 68 | actionpack (= 5.0.4) 69 | actionview (= 5.0.4) 70 | activejob (= 5.0.4) 71 | activemodel (= 5.0.4) 72 | activerecord (= 5.0.4) 73 | activesupport (= 5.0.4) 74 | bundler (>= 1.3.0, < 2.0) 75 | railties (= 5.0.4) 76 | sprockets-rails (>= 2.0.0) 77 | rails-dom-testing (2.0.3) 78 | activesupport (>= 4.2.0) 79 | nokogiri (>= 1.6) 80 | rails-html-sanitizer (1.0.3) 81 | loofah (~> 2.0) 82 | railties (5.0.4) 83 | actionpack (= 5.0.4) 84 | activesupport (= 5.0.4) 85 | method_source 86 | rake (>= 0.8.7) 87 | thor (>= 0.18.1, < 2.0) 88 | rake (12.0.0) 89 | sprockets (3.7.1) 90 | concurrent-ruby (~> 1.0) 91 | rack (> 1, < 3) 92 | sprockets-rails (3.2.0) 93 | actionpack (>= 4.0) 94 | activesupport (>= 4.0) 95 | sprockets (>= 3.0.0) 96 | thor (0.19.4) 97 | thread_safe (0.3.6-java) 98 | tzinfo (1.2.3) 99 | thread_safe (~> 0.1) 100 | tzinfo-data (1.2017.2) 101 | tzinfo (>= 1.0.0) 102 | websocket-driver (0.6.5-java) 103 | websocket-extensions (>= 0.1.0) 104 | websocket-extensions (0.1.2) 105 | 106 | PLATFORMS 107 | java 108 | 109 | DEPENDENCIES 110 | mongo (~> 2.4) 111 | rails (~> 5.0.0, >= 5.0.0.1) 112 | tzinfo-data 113 | 114 | BUNDLED WITH 115 | 1.15.2 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # No longer supported 2 | 3 | This project is no longer supported 4 | 5 | # Mongo Collection Exporter 6 | 7 | [![Build Status](https://travis-ci.org/y8/mongo_collection_exporter.svg?branch=master)](https://travis-ci.org/y8/mongo_collection_exporter) [![](https://images.microbadger.com/badges/image/yopp/mongo_collection_exporter.svg)](https://hub.docker.com/r/yopp/mongo_collection_exporter) 8 | 9 | Exports all metrics from MongoDB collections (including indexes) to Prometheus 10 | for in-depth analysis and monitoring. 11 | 12 | ## Requirements 13 | 14 | 1. Docker 1.7+ or Java 8+ 15 | 16 | ## Start with docker 17 | 18 | 1. Get a copy of `settings.yml` and adjust it to your topology 19 | 2. Make sure that hostnames or IP addresses are accessible from docker container 20 | 3. `docker run -tdi --restart=always yopp/mongo_collection_exporter:latest -e MONGO_EXPORT_CONF=/path/to/config.yml` 21 | 22 | ## Start with java 23 | 24 | 1. Get a copy of `settings.yml` and adjust it to your topology 25 | 2. Download [latest build](https://github.com/y8/mongo_collection_exporter/releases) 26 | 3. Start exporter: `MONGO_EXPORT_CONF=/path/to/config.yml java -jar mongo_collection_exporter.war` 27 | 4. It will start exporter on port `8080`. 28 | 5. Add new prometheus target. 29 | 6. Import sample Grafana Dashboards from `vendor/grafana` 30 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::API 2 | end 3 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/db-ai/mongo_collection_exporter/2666c8309adda5ddb7272cd12f3fc41a61f6d187/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /app/controllers/stats_controller.rb: -------------------------------------------------------------------------------- 1 | class StatsController < ApplicationController 2 | def index 3 | render plain: "OKAY" 4 | end 5 | 6 | def metrics 7 | render plain: Prometheus.new.to_s 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/db-ai/mongo_collection_exporter/2666c8309adda5ddb7272cd12f3fc41a61f6d187/app/models/concerns/.keep -------------------------------------------------------------------------------- /app/models/exporter/collector/op_log.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | module Collector 3 | # Collects informaton about Operation Log collection in the `local` 4 | # database. 5 | class OpLog 6 | OPLOG_COLL = 'oplog.rs'.freeze 7 | 8 | attr_reader :node, :db, :rs 9 | def initialize(node) 10 | @node = node 11 | 12 | @db = client.use(:local).database 13 | @coll = @db[OPLOG_COLL] 14 | @stats = stats 15 | end 16 | 17 | # TODO: Use delegators instead 18 | def server 19 | node.server 20 | end 21 | 22 | def client 23 | node.client 24 | end 25 | 26 | def stats 27 | node.run(selector: { collStats: OPLOG_COLL }, db_name: 'local') 28 | end 29 | 30 | def to_h 31 | { 32 | 'oplog_used_bytes' => used, 33 | 'oplog_max_bytes' => max_size, 34 | 'oplog_window_seconds' => window, 35 | 'oplog_count' => count 36 | } 37 | end 38 | 39 | def count 40 | @coll.count 41 | end 42 | 43 | def window 44 | first_block = { 'ts' => BSON::Timestamp.new(0, 0) } 45 | 46 | first = ordered_first(1) || first_block 47 | last = ordered_first(-1) || first 48 | 49 | last['ts'].seconds - first['ts'].seconds 50 | end 51 | 52 | def used 53 | @stats['size'] 54 | end 55 | 56 | def max_size 57 | @stats['maxSize'] 58 | end 59 | 60 | def ordered_first(order) 61 | @coll.find({}, 'sort' => { '$natural' => order }).limit(1).first 62 | end 63 | end 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /app/models/exporter/dsl/context.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | module DSL 3 | # Despite the fact it called Context, it's something like namespace, that 4 | # can be nested, and names can be inherited. 5 | # 6 | # This class is used by `inside` DSL method to keep the nesting of the 7 | # names. 8 | class Context 9 | attr_reader :scope, :name, :nickname, :parent 10 | 11 | def initialize(name, nickname, parent) 12 | @name = name 13 | @nickname = nickname || name 14 | @parent = parent 15 | end 16 | 17 | def root? 18 | !parent.respond_to? :parent_context 19 | end 20 | 21 | def parent_context 22 | parent.parent_context 23 | end 24 | 25 | def metric_name 26 | if root? 27 | [nickname] 28 | else 29 | parent_context.metric_name + [nickname] 30 | end 31 | end 32 | 33 | def context_name 34 | if root? 35 | [name] 36 | else 37 | parent_context.context_name + [name] 38 | end 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /app/models/exporter/dsl/helper.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | module DSL 3 | # Tiny class that used by `use` DSL method to implement reusable parts of 4 | # DSL logic. 5 | class Helper 6 | class << self 7 | attr_reader :proxy 8 | 9 | def metrics(&blk) 10 | @proxy = blk 11 | end 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /app/models/exporter/dsl/nested_proxy.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | module DSL 3 | # This class overrides some parts of DSL::Proxy to make proxies nestable, so 4 | # we can implement things like `inside` and `namespace`. 5 | class NestedProxy < DSL::Proxy 6 | attr_reader :parent_context 7 | 8 | def initialize(context, labels, parent_context) 9 | @parent_context = parent_context 10 | 11 | super context, labels 12 | end 13 | 14 | # Just forward everything to parent 15 | 16 | def register(point) 17 | parent.register point 18 | end 19 | 20 | def not_found(name) 21 | parent.not_found context_name(name) 22 | end 23 | 24 | def key_left(name, value) 25 | parent.key_left context_name(name), value 26 | end 27 | 28 | private 29 | 30 | def metric_name(key_name) 31 | [parent_context.metric_name, key_name].flatten 32 | end 33 | 34 | def context_name(key_name) 35 | [parent_context.context_name, key_name].flatten 36 | end 37 | 38 | def parent 39 | parent_context.parent 40 | end 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /app/models/exporter/dsl/proxy.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | module DSL 3 | # Here goes the DSL logic. This class is the context where `metrics` block 4 | # is evaluated, so keep an eye on the methods. 5 | class Proxy 6 | attr_reader :all, :keys_not_found, :keys_left, :value_missing 7 | attr_reader :rules, :context, :labels 8 | 9 | def initialize(context, labels = {}, &rules) 10 | @rules = rules.freeze 11 | @context = context 12 | @labels = labels.freeze 13 | 14 | @all = [] 15 | @keys_not_found = [] 16 | @keys_left = {} 17 | @value_missing = [] 18 | 19 | evaluate_rules 20 | 21 | leftover_the_rest_of context 22 | end 23 | 24 | def evaluate_rules 25 | instance_eval(&rules) 26 | end 27 | 28 | # Registry 29 | 30 | def register(point) 31 | if point.registrable? 32 | @all << point 33 | else 34 | @value_missing << point 35 | end 36 | end 37 | 38 | def not_found(name) 39 | @keys_not_found << name 40 | end 41 | 42 | def key_left(name, value) 43 | @keys_left[name] = value 44 | end 45 | 46 | def leftover_the_rest_of(object) 47 | return unless object 48 | 49 | object.each do |key, value| 50 | key_left key, value 51 | end 52 | end 53 | 54 | # Points created from root context 55 | 56 | def counter(key_name, labels = {}, as: nil) 57 | as ||= key_name 58 | register Point::Counter.new metric_name(as), 59 | extract(key_name), 60 | all_labels(labels) 61 | end 62 | 63 | def gauge(key_name, labels = {}, as: nil) 64 | as ||= key_name 65 | register Point::Gauge.new metric_name(as), 66 | extract(key_name), 67 | all_labels(labels) 68 | end 69 | 70 | # Manual Points 71 | 72 | def counter!(key_name, value, labels = {}) 73 | register Point::Counter.new key_name, 74 | value, 75 | all_labels(labels) 76 | end 77 | 78 | def gauge!(key_name, value, labels = {}) 79 | register Point::Gauge.new key_name, 80 | value, 81 | all_labels(labels) 82 | end 83 | 84 | # Nesting 85 | 86 | def inside(key_name, as: nil, &block) 87 | scope = extract(key_name) 88 | nested_context = DSL::Context.new(key_name, as, self) 89 | 90 | DSL::NestedProxy.new(scope, labels, nested_context, &block) 91 | end 92 | 93 | def namespace(key_name, &block) 94 | nested_context = DSL::Context.new(key_name, nil, self) 95 | 96 | DSL::NestedProxy.new(context, labels, nested_context, &block) 97 | end 98 | 99 | # Extraction and transformaton 100 | 101 | def extract(key_name, fallback = nil) 102 | current_context = context || {} 103 | 104 | current_context.delete(key_name) do 105 | not_found(key_name) 106 | break fallback 107 | end 108 | end 109 | 110 | def key?(key_name) 111 | current_context = context || {} 112 | 113 | current_context.key? key_name 114 | end 115 | 116 | def value(key_name, fallback = nil) 117 | current_context = context || {} 118 | 119 | current_context[key_name] || fallback 120 | end 121 | 122 | def ignore(*key_names) 123 | key_names.flatten.each do |key_name| 124 | extract key_name 125 | end 126 | end 127 | 128 | def iterate 129 | context.each_key do |key_name| 130 | value = extract(key_name) 131 | yield key_name, value 132 | end 133 | end 134 | 135 | # Helpers 136 | 137 | def use(mod) 138 | nested_rules = mod.proxy 139 | instance_eval(&nested_rules) 140 | end 141 | 142 | # Utility methods 143 | def keys 144 | context.keys 145 | end 146 | 147 | private 148 | 149 | def metric_name(key_name) 150 | key_name 151 | end 152 | 153 | def all_labels(extra_labels) 154 | labels.merge extra_labels 155 | end 156 | 157 | def log 158 | Padrino.logger 159 | end 160 | end 161 | end 162 | end 163 | -------------------------------------------------------------------------------- /app/models/exporter/point.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | # Abstract Metric data Point. Represents the metric value of Counter or Gauge 3 | # types. It can hold 1 value attached to a name with some labels. Take a look 4 | # at Prometheus metrics to make sense of the difference between name and 5 | # label. 6 | class Point 7 | attr_reader :name, :value, :labels 8 | attr_reader :help_text 9 | 10 | def initialize(name, value, labels = {}) 11 | unless labels.is_a? Hash 12 | raise ArgumentError, "Label should be a hash, but got a '#{labels}'" 13 | end 14 | 15 | @name = name 16 | @value = value 17 | @labels = labels 18 | end 19 | 20 | def to_prom(prefix) 21 | with(prefix) { metric } 22 | end 23 | 24 | def to_prom_banner(prefix) 25 | with(prefix) { banner } 26 | end 27 | 28 | def metric 29 | [full_value].compact.join("\n") 30 | end 31 | 32 | def banner 33 | [help, type].compact.join("\n") 34 | end 35 | 36 | def full_name 37 | [@prefix, name].compact.join('_') 38 | end 39 | 40 | def full_name_with_labels 41 | "#{full_name}#{full_labels}" 42 | end 43 | 44 | def registrable? 45 | value != nil 46 | end 47 | 48 | private 49 | 50 | def with(prefix) 51 | original_prefix = @prefix 52 | @prefix = prefix 53 | 54 | result = yield 55 | 56 | @prefix = original_prefix 57 | 58 | result 59 | end 60 | 61 | def help 62 | "# HELP #{help_text}" if help_text 63 | end 64 | 65 | def type 66 | "# TYPE #{full_name} #{type_name}" 67 | end 68 | 69 | def type_name 70 | 'UNTYPED' 71 | end 72 | 73 | def full_labels 74 | return '' if labels.empty? 75 | text = labels.map do |key, value| 76 | %(#{key}=#{value.to_s.dump}) 77 | end.join(',') 78 | 79 | "{#{text}}" 80 | end 81 | 82 | def full_value 83 | "#{full_name_with_labels} #{value}" 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /app/models/exporter/point/counter.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | class Point 3 | # Metric point that is changes only upwards with possible resets to zero. 4 | # Like number of requests processed or count of logins. 5 | class Counter < Point 6 | COUNTER_TYPE = 'COUNTER'.freeze 7 | 8 | def type_name 9 | COUNTER_TYPE 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/models/exporter/point/gauge.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | class Point 3 | # Metric point that is changes upwards and backwards, like amount of RAM 4 | # used, or number of available cash desks in the store. 5 | class Gauge < Point 6 | GAUGE_TYPE = 'COUNTER'.freeze 7 | 8 | def type_name 9 | GAUGE_TYPE 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/models/exporter/server.rb: -------------------------------------------------------------------------------- 1 | # Implements base class for diffirent node roles in the mongo cluster. Currently 2 | # only Mongos, Config and Shard roles are implemented. 3 | # 4 | # TODO: Labeling stuff should be moved somewhere else, as it not server 5 | # specific. 6 | module Exporter 7 | class Server 8 | attr_reader :address 9 | attr_reader :client 10 | 11 | def initialize(address, opts = {}) 12 | @address = backward_compatible(address) 13 | @client = Mongo::Client.new @address, client_options(opts) 14 | end 15 | 16 | def connect_type 17 | :direct 18 | end 19 | 20 | def default_database 21 | :admin 22 | end 23 | 24 | def default_labels 25 | { 26 | instance: client.cluster.addresses.join(','), 27 | role: self.class.name.split('::').last.downcase 28 | } 29 | end 30 | 31 | def extra_labels 32 | {} 33 | end 34 | 35 | def labels 36 | default_labels.merge extra_labels 37 | end 38 | 39 | def server 40 | client.cluster.servers.first 41 | end 42 | 43 | def run(command) 44 | response = Mongo::Operation::Commands::Command.new(command).execute(server) 45 | response.documents.first 46 | end 47 | 48 | def status 49 | [role, features].flatten.join(' ') 50 | end 51 | 52 | def alive? 53 | false ^ server 54 | end 55 | 56 | def metrics 57 | return [] unless alive? 58 | 59 | fetch_metrics 60 | rescue Mongo::Auth::Unauthorized => auth_error 61 | Rails.logger.warn "Failed to authenticate on #{@address}: #{auth_error}" 62 | return [] 63 | end 64 | 65 | def features 66 | return [] unless alive? 67 | 68 | my_features = [] 69 | my_features << :hidden if server.description.hidden? 70 | my_features << :replica if server.replica_set_name 71 | my_features << :standalone if server.standalone? 72 | my_features 73 | end 74 | 75 | def role 76 | return :down unless alive? 77 | 78 | if server.primary? 79 | :master 80 | elsif server.secondary? 81 | :slave 82 | elsif server.arbiter? 83 | :arbiter 84 | elsif server.description.passive? 85 | :passive 86 | elsif server.description.other? 87 | if server.mongos? 88 | :mongos 89 | else 90 | :other 91 | end 92 | else 93 | :unknown 94 | end 95 | end 96 | 97 | private 98 | 99 | def client_options(extras = {}) 100 | { 101 | connect: connect_type, 102 | database: default_database 103 | }.merge extras 104 | end 105 | 106 | def backward_compatible(address) 107 | return address if address.starts_with? 'mongodb://' 108 | 109 | [address] 110 | end 111 | end 112 | end 113 | -------------------------------------------------------------------------------- /app/models/exporter/server/configuration.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | class Server 3 | # Implements Configuration Server node role 4 | class Configuration < Exporter::Server::Shard 5 | def extra_labels 6 | {} 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/models/exporter/server/mongos.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | class Server 3 | # Implements Shard Router node role 4 | class Mongos < Exporter::Server 5 | def fetch_metrics 6 | [Exporter::Source::Mongos.new(raw_metrics, labels)] 7 | end 8 | 9 | def raw_metrics 10 | run(selector: { serverStatus: 1 }, db_name: 'admin') 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/models/exporter/server/shard.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | class Server 3 | # Implements Shard (mongod) node role. 4 | class Shard < Exporter::Server 5 | def replica_name 6 | server.replica_set_name 7 | end 8 | 9 | def databases 10 | client.database_names - ['local'.freeze] 11 | end 12 | 13 | def fetch_metrics 14 | server_metrics + namespaces_metrics + replica_set_metrics 15 | end 16 | 17 | def server_metrics 18 | [Source::Mongod.new(raw_server_metrics, labels)] 19 | end 20 | 21 | def replica_set_metrics 22 | return [] unless replica? 23 | 24 | oplog_metrics = Collector::OpLog.new(self).to_h.merge! raw_oplog_metrics 25 | 26 | [Source::ReplicaSet.new(oplog_metrics, labels)] 27 | end 28 | 29 | def raw_server_metrics 30 | run(selector: { serverStatus: 1 }, db_name: 'admin') 31 | end 32 | 33 | def raw_oplog_metrics 34 | run(selector: { replSetGetStatus: 1 }, db_name: 'admin') 35 | end 36 | 37 | def namespaces_metrics 38 | databases.map do |database_name| 39 | namespace_metrics(database_name) 40 | end.flatten 41 | end 42 | 43 | def namespace_metrics(database_name) 44 | client.use(database_name).database.collection_names.map do |name| 45 | collections_metrics database_name, name 46 | end 47 | end 48 | 49 | def collections_metrics(database, name) 50 | collection_data = run(selector: { collStats: name }, db_name: database) 51 | index_data = collection_data.delete('indexDetails') { Hash.new } 52 | 53 | [ 54 | indexes_metrics(database, name, index_data), 55 | collection_metric(database, name, collection_data) 56 | ] 57 | end 58 | 59 | def indexes_metrics(database, name, raw_data) 60 | raw_data.map do |index_name, index_raw_data| 61 | index_metric(database, name, index_name, index_raw_data) 62 | end 63 | end 64 | 65 | def collection_metric(database, name, raw_data) 66 | collection_labels = labels.merge db: database, coll: name 67 | 68 | Source::Collection.new(raw_data, collection_labels) 69 | end 70 | 71 | def index_metric(database, name, index_name, index_raw_data) 72 | index_labels = labels.merge db: database, coll: name, idx: index_name 73 | 74 | Source::Index.new(index_raw_data, index_labels) 75 | end 76 | 77 | def extra_labels 78 | { rs: replica_name } 79 | end 80 | 81 | def replica? 82 | features.include? :replica 83 | end 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /app/models/exporter/settings.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | # Represents Exporto configuration 3 | class Settings 4 | DEFAULT_PATH = Rails.root.join('config', 'settings.yml').freeze 5 | 6 | attr_reader :raw 7 | 8 | def self.current 9 | @current ||= new(DEFAULT_PATH) 10 | end 11 | 12 | def initialize(config_path = nil) 13 | reader = ::Exporter::Settings::Reader.new(config_path) 14 | @raw = reader.read 15 | 16 | validate_version 17 | end 18 | 19 | def version 20 | raw['version'.freeze] 21 | end 22 | 23 | def mongo 24 | @mongo ||= ::Exporter::Settings::Mongodb.new(raw['mongo']) 25 | end 26 | 27 | def inspect 28 | "<#Settings: #{file.current_path}, version: #{version}>" 29 | end 30 | 31 | def validate_version 32 | raise "Unsupported config version '#{version}'" if version != 1 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /app/models/exporter/settings/mongodb.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | class Settings 3 | # Uses Settings::File to make a list of Server instances to collect metrics 4 | # from. 5 | class Mongodb 6 | ALLOWED_SSL_KEYS = %i{ssl_verify ssl_cert ssl_ca_cert} 7 | 8 | attr_reader :raw 9 | 10 | attr_reader :mongos, :configs, :shards 11 | 12 | def initialize(raw) 13 | @raw = raw 14 | 15 | validate_mode 16 | validate_ssl 17 | 18 | @mongos = list_mongos.map { |srv| Server::Mongos.new(srv, ssl) } 19 | @configs = list_configs.map { |srv| Server::Configuration.new(srv, ssl) } 20 | @shards = list_shards.map { |srv| Server::Shard.new(srv, ssl) } 21 | end 22 | 23 | def mode 24 | raw['mode'.freeze] 25 | end 26 | 27 | def find(address) 28 | all.find { |srv| srv.address == address } 29 | end 30 | 31 | def all 32 | @mongos + @configs + @shards 33 | end 34 | 35 | def list_all 36 | list_mongos + list_configs + list_shards 37 | end 38 | 39 | private 40 | 41 | def ssl 42 | raw.fetch('ssl') { {} } || {} 43 | end 44 | 45 | def list_mongos 46 | raw.fetch('mongos') { [] } || [] 47 | end 48 | 49 | def list_configs 50 | raw.fetch('configs') { [] } || [] 51 | end 52 | 53 | def list_shards 54 | raw.fetch('shards') { [] } || [] 55 | end 56 | 57 | def validate_mode 58 | raise "Unsupported mongo mode #{mode}" if mode != 'sharded' 59 | end 60 | 61 | def validate_ssl 62 | unknown_keys = ssl.keys.map(&:to_sym) - ALLOWED_SSL_KEYS 63 | 64 | if unknown_keys.any? 65 | raise "Unsupported ssl configuration options: #{unknown_keys}. " \ 66 | "Only #{ALLOWED_SSL_KEYS} are allowed" 67 | end 68 | end 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /app/models/exporter/settings/reader.rb: -------------------------------------------------------------------------------- 1 | require 'yaml' 2 | 3 | module Exporter 4 | # Represents Exporto configuration 5 | class Settings 6 | # Finds readable configuration file candidate and allows to read it's 7 | # contents. 8 | # 9 | # Used in `Exporto::Config` class. 10 | class Reader 11 | ENV_KEY_NAME = 'MONGO_EXPORT_CONF'.freeze 12 | 13 | attr_reader :current_path 14 | 15 | def initialize(override_path = nil) 16 | @override_path = override_path.freeze 17 | @current_path = find_config || not_found 18 | end 19 | 20 | def read 21 | @file_contents ||= YAML.load_file(current_path).freeze 22 | end 23 | 24 | def reset 25 | @file_contents = nil 26 | @current_path = nil 27 | end 28 | 29 | private 30 | 31 | def find_config 32 | paths.find do |path| 33 | next unless path 34 | ::File.file?(path) && ::File.readable?(path) 35 | end 36 | end 37 | 38 | def paths 39 | [ENV[ENV_KEY_NAME], @override_path].compact 40 | end 41 | 42 | def not_found 43 | raise ArgumentError, "Failed to read config file. Tried:\n" \ 44 | "#{paths.join("\n")}" 45 | end 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /app/models/exporter/source.rb: -------------------------------------------------------------------------------- 1 | # Container for metric parsing DSL. It is used to hold `metrics` body and to 2 | # provide basic API to read parsed data. 3 | module Exporter 4 | class Source 5 | class << self 6 | attr_reader :proxy 7 | 8 | def metrics(&blk) 9 | @proxy = blk 10 | end 11 | end 12 | 13 | attr_reader :raw 14 | 15 | def initialize(raw, labels = {}) 16 | @raw = raw 17 | @labels = labels 18 | @proxy = DSL::Proxy.new(raw, labels, &self.class.proxy) 19 | end 20 | 21 | def all 22 | @proxy.all 23 | end 24 | 25 | def keys_not_found 26 | @proxy.keys_not_found 27 | end 28 | 29 | def keys_left 30 | @proxy.keys_left 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /app/models/exporter/source/collection.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | class Source 3 | # Metrics extacted from db.getCollection(name).stats() 4 | class Collection < Exporter::Source 5 | metrics do 6 | ignore 'ns', 'capped', '$gleStats', 'ok' 7 | 8 | counter 'count', as: 'collection_count' 9 | 10 | gauge 'size', as: 'collection_size_bytes' 11 | gauge 'storageSize', as: 'collection_storage_size_bytes' 12 | gauge 'avgObjSize', as: 'collection_avg_size_bytes' 13 | gauge 'nindexes', as: 'collection_indexes_count' 14 | 15 | # Ignore index stats, as we will get them from WT cache info 16 | ignore 'totalIndexSize', 'indexSizes' 17 | 18 | inside 'wiredTiger', as: 'wt' do 19 | use Exporter::Source::Helpers::WiredTigerCollection 20 | end 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /app/models/exporter/source/helpers/wired_tiger_collection.rb: -------------------------------------------------------------------------------- 1 | # WiredTiger rules for collections. 2 | class Exporter::Source::Helpers::WiredTigerCollection < Exporter::DSL::Helper 3 | metrics do 4 | ignore 'uri', 'type', 'creationString' 5 | 6 | inside 'metadata' do 7 | ignore 'infoObj' 8 | gauge 'formatVersion', as: 'format_version' 9 | end 10 | 11 | inside 'LSM', as: 'lsm' do 12 | counter 'bloom filter false positives', 13 | as: 'bloom_filer_false_positives' 14 | counter 'bloom filter hits', 15 | as: 'bloom_filer_hits' 16 | counter 'bloom filter misses', 17 | as: 'bloom_filter_misses' 18 | 19 | counter 'bloom filter pages evicted from cache', 20 | as: 'bloom_filter_cache_evicted_pages' 21 | counter 'bloom filter pages read into cache', 22 | as: 'bloom_filter_cache_read_pages' 23 | 24 | counter 'bloom filters in the LSM tree', 25 | as: 'bloom_filter_count' 26 | counter 'chunks in the LSM tree', 27 | as: 'chunks' 28 | 29 | gauge 'highest merge generation in the LSM tree', 30 | as: 'merge_generation_max' 31 | 32 | counter 'queries that could have benefited from a Bloom filter ' \ 33 | 'that did not exist', as: 'bloom_filter_query_misses' 34 | 35 | gauge 'sleep for LSM checkpoint throttle', { task: 'checkpoint' }, 36 | as: 'throttle_sleep' 37 | 38 | gauge 'sleep for LSM merge throttle', { task: 'merge' }, 39 | as: 'merge_throttle_sleep' 40 | 41 | counter 'total size of bloom filters', 42 | as: 'filter_total_size_bytes' 43 | end 44 | 45 | inside 'block-manager', as: 'block_manager' do 46 | ignore 'file magic number', 47 | 'file major version number', 48 | 'minor version number' 49 | 50 | counter 'allocations requiring file extension', 51 | as: 'allocation_with_extension' 52 | 53 | counter 'blocks allocated', 54 | as: 'allocated_blocks' 55 | 56 | counter 'blocks freed', 57 | as: 'freed_blocks' 58 | 59 | gauge 'checkpoint size', 60 | as: 'checkpoint_size' 61 | 62 | gauge 'file allocation unit size', 63 | as: 'file_allocation_unit_size_bytes' 64 | 65 | gauge 'file bytes available for reuse', 66 | as: 'file_reusable_bytes' 67 | 68 | gauge 'file size in bytes', 69 | as: 'file_size_bytes' 70 | end 71 | 72 | inside 'btree' do 73 | counter 'btree checkpoint generation', 74 | as: 'checkpoint_gen' 75 | 76 | counter 'column-store fixed-size leaf pages', { type: 'fixed_leaf' }, 77 | as: 'column_store_pages' 78 | 79 | counter 'column-store internal pages', { type: 'internal' }, 80 | as: 'column_store_pages' 81 | 82 | counter 'column-store variable-size leaf pages', { type: 'var_leaf' }, 83 | as: 'column_store_pages' 84 | 85 | counter 'column-store variable-size RLE encoded values', 86 | { type: 'var_rle' }, as: 'column_store_values' 87 | 88 | counter 'column-store variable-size deleted values', 89 | { type: 'var_deleted' }, as: 'column_store_values' 90 | 91 | gauge 'fixed-record size', 92 | as: 'fixed_record_size' 93 | 94 | gauge 'maximum internal page key size', 95 | as: 'max_internal_page_key_size' 96 | 97 | gauge 'maximum internal page size', 98 | as: 'max_interal_page_size' 99 | 100 | gauge 'maximum leaf page key size', 101 | as: 'max_leaf_page_key_size' 102 | 103 | gauge 'maximum leaf page size', 104 | as: 'max_leaf_page_size' 105 | 106 | gauge 'maximum leaf page value size', 107 | as: 'max_leaf_page_value_size' 108 | 109 | gauge 'maximum tree depth', 110 | as: 'max_tree_depth' 111 | 112 | gauge 'number of key/value pairs', 113 | as: 'key_value_pairs' 114 | 115 | gauge 'overflow pages', 116 | as: 'overflow_pages' 117 | 118 | gauge 'pages rewritten by compaction', 119 | as: 'rewritten_by_compaction_pages' 120 | 121 | gauge 'row-store internal pages', { type: 'internal' }, 122 | as: 'row_store_pages' 123 | 124 | gauge 'row-store leaf pages', { type: 'leaf' }, 125 | as: 'row_store_pages' 126 | end 127 | 128 | inside 'cache' do 129 | ignore 'overflow pages read into cache', 130 | 'overflow values cached in memory', 131 | 'page split during eviction deepened the tree', 132 | 'page written requiring lookaside records', 133 | 'pages read into cache requiring lookaside entries', 134 | 'pages written requiring in-memory restoration' 135 | 136 | counter 'in-memory page passed criteria to be split', 137 | as: 'can_be_split_inmem_pages' 138 | 139 | counter 'in-memory page splits', 140 | as: 'split_inmem_pages' 141 | 142 | counter 'data source pages selected for eviction unable to be evicted', 143 | as: 'selected_but_cant_be_evicted_pages' 144 | 145 | counter 'checkpoint blocked page eviction', 146 | { cause: 'checkpoint' }, as: 'page_eviction_blocked' 147 | 148 | counter 'hazard pointer blocked page eviction', 149 | { cause: 'hazard_ponter' }, as: 'page_eviction_blocked' 150 | 151 | counter 'internal pages split during eviction', { type: 'internal' }, 152 | as: 'split_during_eviction_pages' 153 | 154 | counter 'leaf pages split during eviction', { type: 'leaf' }, 155 | as: 'split_during_eviction_pages' 156 | 157 | gauge 'bytes currently in the cache', 158 | as: 'used_bytes' 159 | 160 | counter 'bytes read into cache', 161 | as: 'read_into_bytes' 162 | 163 | counter 'bytes written from cache', 164 | as: 'written_from_bytes' 165 | 166 | counter 'pages read into cache', 167 | as: 'read_into_pages' 168 | 169 | counter 'pages requested from the cache', 170 | as: 'read_from_pages' 171 | 172 | counter 'pages written from cache', 173 | as: 'written_from_pages' 174 | 175 | counter 'unmodified pages evicted', { type: 'unmodified' }, 176 | as: 'evicted_pages' 177 | 178 | counter 'modified pages evicted', { type: 'modified' }, 179 | as: 'evicted_pages' 180 | 181 | counter 'internal pages evicted', { type: 'internal' }, 182 | as: 'evicted_pages' 183 | end 184 | 185 | inside 'compression' do 186 | counter 'compressed pages read', 187 | as: 'read_pages' 188 | counter 'compressed pages written', 189 | as: 'written_pages' 190 | counter 'page written failed to compress', 191 | as: 'failed_to_compress_written_pages' 192 | counter 'page written was too small to compress', 193 | as: 'too_small_to_compress_written_pages' 194 | 195 | counter 'raw compression call failed, additional data available', 196 | as: 'raw_failed_with_data_calls' 197 | counter 'raw compression call failed, no additional data available', 198 | as: 'raw_failed_without_data_calls' 199 | counter 'raw compression call succeeded', 200 | as: 'raw_success_calls' 201 | end 202 | 203 | inside 'cursor' do 204 | counter 'cursor-insert key and value bytes inserted', 205 | as: 'insert_key_value_bytes' 206 | counter 'cursor-remove key bytes removed', 207 | as: 'remove_key_bytes' 208 | counter 'cursor-update value bytes updated', 209 | as: 'update_value_bytes' 210 | 211 | counter 'restarted searches', 212 | as: 'restarted_searches' 213 | 214 | # Not sure that this is same event as 'insert calls' 215 | counter 'bulk-loaded cursor-insert calls', { type: 'bulk_load_insert' }, 216 | as: 'calls' 217 | 218 | counter 'create calls', { type: 'create' }, as: 'calls' 219 | counter 'insert calls', { type: 'insert' }, as: 'calls' 220 | counter 'next calls', { type: 'next' }, as: 'calls' 221 | counter 'prev calls', { type: 'prev' }, as: 'calls' 222 | counter 'remove calls', { type: 'remove' }, as: 'calls' 223 | counter 'reset calls', { type: 'reset' }, as: 'calls' 224 | counter 'search calls', { type: 'search' }, as: 'calls' 225 | counter 'search near calls', { type: 'search_near' }, as: 'calls' 226 | counter 'truncate calls', { type: 'truncate' }, as: 'calls' 227 | counter 'update calls', { type: 'update' }, as: 'calls' 228 | end 229 | 230 | inside 'reconciliation' do 231 | ignore 'dictionary matches', 232 | 'fast-path pages deleted', 233 | 'internal page key bytes discarded using suffix compression', 234 | 'internal page multi-block writes', 235 | 'internal-page overflow keys', 236 | 'leaf page key bytes discarded using prefix compression', 237 | 'leaf page multi-block writes', 238 | 'leaf-page overflow keys', 239 | 'maximum blocks required for a page', 240 | 'overflow values written', 241 | 'page checksum matches' 242 | 243 | counter 'page reconciliation calls', 244 | as: 'page_calls' 245 | 246 | counter 'page reconciliation calls for eviction', 247 | as: 'page_eviction_calls' 248 | 249 | counter 'pages deleted', 250 | as: 'page_delete_calls' 251 | end 252 | 253 | inside 'session' do 254 | counter 'object compaction', 255 | as: 'object_compaction' 256 | counter 'open cursor count', 257 | as: 'open_cursor_count' 258 | end 259 | 260 | inside 'transaction' do 261 | counter 'update conflicts', 262 | as: 'update_conflicts' 263 | end 264 | end 265 | end 266 | -------------------------------------------------------------------------------- /app/models/exporter/source/helpers/wired_tiger_database.rb: -------------------------------------------------------------------------------- 1 | # Thats a huge one. We are begin very specific on this metrics, to 2 | # spot the diffirence between server-level and collection level metrics. 3 | class Exporter::Source::Helpers::WiredTigerDatabase < ::Exporter::DSL::Helper 4 | metrics do 5 | ignore 'uri' 6 | 7 | inside 'LSM', as: 'lsm' do 8 | gauge 'application work units currently queued', { type: 'app' }, 9 | as: 'work_units_queued' 10 | 11 | gauge 'merge work units currently queued', { type: 'merge' }, 12 | as: 'work_units_queued' 13 | 14 | gauge 'switch work units currently queued', { type: 'switch' }, 15 | as: 'work_units_queued' 16 | 17 | # Or gauge? 18 | counter 'rows merged in an LSM tree', 19 | as: 'tree_rows_merged' 20 | 21 | gauge 'sleep for LSM checkpoint throttle', { task: 'checkpoint' }, 22 | as: 'throttle_sleep' 23 | 24 | gauge 'sleep for LSM merge throttle', { task: 'merge' }, 25 | as: 'merge_throttle_sleep' 26 | 27 | gauge 'tree maintenance operations discarded', { type: 'discarded' }, 28 | as: 'tree_maintanace_ops' 29 | 30 | gauge 'tree maintenance operations executed', { type: 'executed' }, 31 | as: 'tree_maintanace_ops' 32 | 33 | gauge 'tree maintenance operations scheduled', { type: 'scheduled' }, 34 | as: 'tree_maintanace_ops' 35 | 36 | gauge 'tree queue hit maximum', 37 | as: 'tree_queue_hit_max' 38 | end 39 | 40 | inside 'async' do 41 | gauge 'current work queue length', 42 | as: 'work_queue_length_current' 43 | gauge 'maximum work queue length', 44 | as: 'work_queue_length_max' 45 | 46 | # More likely to be a counter 47 | counter 'number of allocation state races', as: 'allocation_state_races' 48 | counter 'number of flush calls', as: 'flush_calls' 49 | counter 'number of operation slots viewed for allocation', 50 | as: 'slots_viewed_for_allocation' 51 | counter 'number of times operation allocation failed', 52 | as: 'operation_allocation_failed' 53 | counter 'number of times worker found no work', 54 | as: 'worker_work_not_found' 55 | 56 | counter 'total allocations', as: 'allocations_total' 57 | 58 | counter 'total compact calls', { type: 'compact' }, as: 'calls_total' 59 | counter 'total insert calls', { type: 'insert' }, as: 'calls_total' 60 | counter 'total remove calls', { type: 'remove' }, as: 'calls_total' 61 | counter 'total search calls', { type: 'search' }, as: 'calls_total' 62 | counter 'total update calls', { type: 'update' }, as: 'calls_total' 63 | end 64 | 65 | inside 'block-manager', as: 'block_manager' do 66 | counter 'blocks pre-loaded', as: 'preloaded_blocks' 67 | counter 'blocks read', as: 'read_blocks' 68 | counter 'blocks written', as: 'written_blocks' 69 | counter 'bytes read', as: 'read_bytes' 70 | counter 'bytes written', as: 'written_bytes' 71 | counter 'bytes written for checkpoint', as: 'checkpoint_written_bytes' 72 | counter 'mapped blocks read', as: 'read_mapped_blocks' 73 | counter 'mapped bytes read', as: 'read_mapped_bytes' 74 | end 75 | 76 | inside 'connection' do 77 | counter 'auto adjusting condition resets', as: 'adjusting_resets' 78 | counter 'auto adjusting condition wait calls', as: 'adjusting_wait_calls' 79 | counter 'files currently open', as: 'files_open' 80 | counter 'memory allocations', as: 'mem_allocations' 81 | counter 'memory frees', as: 'mem_frees' 82 | counter 'memory re-allocations', as: 'mem_realloc' 83 | 84 | counter 'pthread mutex condition wait calls', 85 | as: 'mutex_condition_wait_calls' 86 | counter 'pthread mutex shared lock read-lock calls', 87 | as: 'mutex_shared_lock_read_calls' 88 | counter 'pthread mutex shared lock write-lock calls', 89 | as: 'mutex_shared_lock_write_calls' 90 | 91 | counter 'total fsync I/Os', as: 'fsync_io_total' 92 | counter 'total read I/Os', as: 'read_io_total' 93 | counter 'total write I/Os', as: 'write_io_total' 94 | end 95 | 96 | inside 'concurrentTransactions', as: 'concurrent_transactions' do 97 | inside 'read' do 98 | gauge 'out' 99 | gauge 'available' 100 | gauge 'totalTickets', as: 'max' 101 | end 102 | 103 | inside 'write' do 104 | gauge 'out' 105 | gauge 'available' 106 | gauge 'totalTickets', as: 'max' 107 | end 108 | end 109 | 110 | inside 'cache' do 111 | ignore 'bytes belonging to page images in the cache', 112 | 'bytes not belonging to page images in the cache', 113 | 'checkpoint blocked page eviction', 114 | 'eviction calls to get a page', 115 | 'eviction calls to get a page found queue empty', 116 | 'eviction calls to get a page found queue empty after locking', 117 | 'eviction currently operating in aggressive mode', 118 | 'eviction empty score', 119 | 'eviction server candidate queue empty when topping up', 120 | 'eviction server candidate queue not empty when topping up', 121 | 'eviction server evicting pages', 122 | 'eviction server slept, because we did not make progress with eviction', 123 | 'eviction server unable to reach eviction goal', 124 | 'eviction state', 125 | 'eviction walks abandoned', 126 | 'eviction worker thread evicting pages', 127 | 'failed eviction of pages that exceeded the in-memory maximum', 128 | 'files with active eviction walks', 129 | 'files with new eviction walks started', 130 | 'hazard pointer blocked page eviction', 131 | 'hazard pointer check calls', 132 | 'hazard pointer check entries walked', 133 | 'hazard pointer maximum array length', 134 | 'in-memory page passed criteria to be split', 135 | 'in-memory page splits', 136 | 'internal pages evicted', 137 | 'internal pages split during eviction', 138 | 'leaf pages split during eviction', 139 | 'lookaside table insert calls', 140 | 'lookaside table remove calls', 141 | 'maximum bytes configured', 142 | 'maximum page size at eviction', 143 | 'modified pages evicted', 144 | 'modified pages evicted by application threads', 145 | 'overflow pages read into cache', 146 | 'overflow values cached in memory', 147 | 'page split during eviction deepened the tree', 148 | 'page written requiring lookaside records', 149 | 'pages currently held in the cache', 150 | 'pages evicted because they exceeded the in-memory maximum', 151 | 'pages evicted because they had chains of deleted items', 152 | 'pages evicted by application threads', 153 | 'pages queued for eviction', 154 | 'pages queued for urgent eviction', 155 | 'pages queued for urgent eviction during walk', 156 | 'pages read into cache', 157 | 'pages read into cache requiring lookaside entries', 158 | 'pages requested from the cache', 159 | 'pages seen by eviction walk', 160 | 'pages selected for eviction unable to be evicted', 161 | 'pages walked for eviction', 162 | 'pages written from cache', 163 | 'pages written requiring in-memory restoration', 164 | 'percentage overhead', 165 | 'tracked bytes belonging to internal pages in the cache', 166 | 'tracked bytes belonging to leaf pages in the cache', 167 | 'tracked dirty bytes in the cache', 168 | 'tracked dirty pages in the cache', 169 | 'unmodified pages evicted' 170 | 171 | gauge 'bytes currently in the cache', as: 'used_bytes' 172 | counter 'bytes read into cache', as: 'read_into_bytes' 173 | counter 'bytes written from cache', as: 'written_from_bytes' 174 | end 175 | 176 | inside 'cursor' do 177 | counter 'cursor create calls', { type: 'create' }, as: 'calls' 178 | counter 'cursor insert calls', { type: 'insert' }, as: 'calls' 179 | counter 'cursor next calls', { type: 'next' }, as: 'calls' 180 | counter 'cursor prev calls', { type: 'prev' }, as: 'calls' 181 | counter 'cursor remove calls', { type: 'remove' }, as: 'calls' 182 | counter 'cursor reset calls', { type: 'reset' }, as: 'calls' 183 | counter 'cursor restarted searches', { type: 'restarted' }, as: 'calls' 184 | counter 'cursor search calls', { type: 'search' }, as: 'calls' 185 | counter 'cursor search near calls', { type: 'search_near' }, as: 'calls' 186 | counter 'cursor update calls', { type: 'update' }, as: 'calls' 187 | counter 'truncate calls', { type: 'truncate' }, as: 'calls' 188 | end 189 | 190 | # TODO: Investigate need of this metrics? 191 | inside 'thread-state' do 192 | ignore 'active filesystem fsync calls', 193 | 'active filesystem read calls', 194 | 'active filesystem write calls' 195 | end 196 | 197 | inside 'thread-yield' do 198 | ignore 'page acquire busy blocked', 199 | 'page acquire eviction blocked', 200 | 'page acquire locked blocked', 201 | 'page acquire read blocked', 202 | 'page acquire time sleeping (usecs)' 203 | end 204 | 205 | inside 'data-handle' do 206 | ignore 'connection data handles currently active', 207 | 'connection sweep candidate became referenced', 208 | 'connection sweep dhandles closed', 209 | 'connection sweep dhandles removed from hash list', 210 | 'connection sweep time-of-death sets', 211 | 'connection sweeps', 212 | 'session dhandles swept', 213 | 'session sweep attempts' 214 | end 215 | 216 | inside 'reconciliation' do 217 | ignore 'fast-path pages deleted', 218 | 'page reconciliation calls', 219 | 'page reconciliation calls for eviction', 220 | 'pages deleted', 221 | 'split bytes currently awaiting free', 222 | 'split objects currently awaiting free' 223 | end 224 | 225 | inside 'transaction' do 226 | ignore 'number of named snapshots created', 227 | 'number of named snapshots dropped', 228 | 'transaction begins', 229 | 'transaction checkpoint currently running', 230 | 'transaction checkpoint generation', 231 | 'transaction checkpoint max time (msecs)', 232 | 'transaction checkpoint min time (msecs)', 233 | 'transaction checkpoint most recent time (msecs)', 234 | 'transaction checkpoint scrub dirty target', 235 | 'transaction checkpoint scrub time (msecs)', 236 | 'transaction checkpoint total time (msecs)', 237 | 'transaction checkpoints', 238 | 'transaction failures due to cache overflow', 239 | 'transaction fsync calls for checkpoint after allocating the transaction ID', 240 | 'transaction fsync duration for checkpoint after allocating the transaction ID (usecs)', 241 | 'transaction range of IDs currently pinned', 242 | 'transaction range of IDs currently pinned by a checkpoint', 243 | 'transaction range of IDs currently pinned by named snapshots', 244 | 'transaction sync calls', 245 | 'transactions committed', 246 | 'transactions rolled back' 247 | end 248 | 249 | inside 'session' do 250 | ignore 'open cursor count', 251 | 'open session count', 252 | 'table compact failed calls', 253 | 'table compact successful calls', 254 | 'table create failed calls', 255 | 'table create successful calls', 256 | 'table drop failed calls', 257 | 'table drop successful calls', 258 | 'table rebalance failed calls', 259 | 'table rebalance successful calls', 260 | 'table rename failed calls', 261 | 'table rename successful calls', 262 | 'table salvage failed calls', 263 | 'table salvage successful calls', 264 | 'table truncate failed calls', 265 | 'table truncate successful calls', 266 | 'table verify failed calls', 267 | 'table verify successful calls' 268 | end 269 | 270 | inside 'log' do 271 | ignore 'busy returns attempting to switch slots', 272 | 'consolidated slot closures', 273 | 'consolidated slot join races', 274 | 'consolidated slot join transitions', 275 | 'consolidated slot joins', 276 | 'consolidated slot unbuffered writes', 277 | 'log bytes of payload data', 278 | 'log bytes written', 279 | 'log files manually zero-filled', 280 | 'log flush operations', 281 | 'log force write operations', 282 | 'log force write operations skipped', 283 | 'log records compressed', 284 | 'log records not compressed', 285 | 'log records too small to compress', 286 | 'log release advances write LSN', 287 | 'log scan operations', 288 | 'log scan records requiring two reads', 289 | 'log server thread advances write LSN', 290 | 'log server thread write LSN walk skipped', 291 | 'log sync operations', 292 | 'log sync time duration (usecs)', 293 | 'log sync_dir operations', 294 | 'log sync_dir time duration (usecs)', 295 | 'log write operations', 296 | 'logging bytes consolidated', 297 | 'maximum log file size', 298 | 'number of pre-allocated log files to create', 299 | 'pre-allocated log files not ready and missed', 300 | 'pre-allocated log files prepared', 301 | 'pre-allocated log files used', 302 | 'records processed by log scan', 303 | 'total in-memory size of compressed records', 304 | 'total log buffer size', 305 | 'total size of compressed records', 306 | 'written slots coalesced', 307 | 'yields waiting for previous log file close' 308 | end 309 | end 310 | end 311 | -------------------------------------------------------------------------------- /app/models/exporter/source/index.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | class Source 3 | # Metrix extracted from db.getCollection(name).stats()[`indexDetails`] key 4 | # in the collection metrics hash. 5 | class Index < Exporter::Source 6 | metrics do 7 | namespace 'wt' do 8 | use Exporter::Source::Helpers::WiredTigerCollection 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/models/exporter/source/mongod.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | class Source 3 | # Metrics extacted from db.serverStatus() on `mongod`\`shard` instances 4 | class Mongod < Exporter::Source 5 | LocksStatsToMetrics = { 6 | 'acquireCount' => 'lock_acquire_count', 7 | 'acquireWaitCount' => 'lock_acquire_wait_count', 8 | 'timeAcquiringMicros' => 'time_acquiring_us' 9 | }.freeze 10 | 11 | LockModesToNames = { 12 | 'R' => 's', 13 | 'W' => 'x', 14 | 'r' => 'is', 15 | 'w' => 'ix' 16 | }.freeze 17 | 18 | metrics do 19 | ignore 'host', 20 | 'advisoryHostFQDNs', 21 | 'version', 22 | 'process', 23 | 'pid', 24 | 'uptimeMillis', 25 | 'uptimeEstimate', 26 | 'localTime', 27 | 'sharding', 28 | 'writeBacksQueued', 29 | 'storageEngine', 30 | '$gleStats' 31 | 32 | gauge 'uptime', as: 'uptime_seconds' 33 | 34 | inside 'extra_info' do 35 | gauge 'heap_usage_bytes' 36 | gauge 'page_faults' 37 | end 38 | 39 | inside 'repl' do 40 | ignore 'rbid', 'setName', 'primary', 'secondary', 'me', 'electionId' 41 | 42 | gauge 'setVersion', as: 'set_version' 43 | 44 | gauge! 'is_master', extract('ismaster') ? 1 : 0 45 | gauge! 'visible_hosts', (extract('hosts') || []).size 46 | end 47 | 48 | inside 'globalLock', as: 'global_lock' do 49 | gauge 'totalTime', as: 'total_time_us' 50 | 51 | inside 'currentQueue' do 52 | ignore 'total' 53 | 54 | iterate do |key, value| 55 | gauge! 'global_lock', value, queue: key 56 | end 57 | end 58 | 59 | inside 'activeClients' do 60 | ignore 'total' 61 | 62 | iterate do |key, value| 63 | gauge! 'global_lock', value, client: key 64 | end 65 | end 66 | end 67 | 68 | inside 'locks' do 69 | # Type: Global | Database | Collection | Metadata | oplog 70 | iterate do |lock_type, lock_data| 71 | # Metric: acquireCount | acquireWaitCount | timeAcquiringMicros 72 | lock_data.each do |metric_name, metric_data| 73 | # Mode: R | r | W | w 74 | metric_data.each do |mode_name, value| 75 | counter! LocksStatsToMetrics[metric_name], value, 76 | type: lock_type, mode: LockModesToNames[mode_name] 77 | end 78 | end 79 | end 80 | end 81 | 82 | inside 'wiredTiger', as: 'wt' do 83 | use Source::Helpers::WiredTigerDatabase 84 | end 85 | 86 | inside 'asserts' do 87 | counter 'rollovers' 88 | 89 | iterate do |key, value| 90 | counter! 'asserts', value, type: key 91 | end 92 | end 93 | 94 | inside 'opcounters' do 95 | iterate do |key, value| 96 | counter! 'opcounters', value, op: key, src: 'self' 97 | end 98 | end 99 | 100 | inside 'opcountersRepl' do 101 | iterate do |key, value| 102 | counter! 'opcounters', value, op: key, src: 'repl' 103 | end 104 | end 105 | 106 | inside 'connections' do 107 | gauge 'current' 108 | gauge 'available' 109 | counter 'totalCreated', as: 'created_total' 110 | end 111 | 112 | inside 'network' do 113 | counter 'bytesIn', as: 'in_bytes' 114 | gauge 'bytesOut', as: 'out_bytes' 115 | counter 'numRequests', as: 'requests_total' 116 | end 117 | 118 | inside 'mem' do 119 | ignore 'bits', 'supported' 120 | ignore 'mapped', 'mappedWithJournal' # MMAPv1 (mem) 121 | 122 | gauge 'resident', as: 'resident_mbytes' 123 | gauge 'virtual', as: 'virtual_mbytes' 124 | end 125 | 126 | inside 'metrics' do 127 | ignore 'getLastError' 128 | ignore 'record' # MMAPv1 (count of on disk moves) 129 | 130 | inside 'document' do 131 | iterate do |key, value| 132 | counter! 'metrics_documents', value, op: key 133 | end 134 | end 135 | 136 | inside 'operation' do 137 | iterate do |key, value| 138 | counter! 'special_operation', value, type: key 139 | end 140 | end 141 | 142 | inside 'queryExecutor' do 143 | counter! 'query_index_scanned_total', extract('scanned') 144 | counter! 'query_documents_scanned_total', extract('scannedObjects') 145 | end 146 | 147 | inside 'ttl' do 148 | counter 'deletedDocuments', as: 'documents_deleted_total' 149 | counter 'passes', as: 'passes_total' 150 | end 151 | 152 | inside 'cursor' do 153 | counter 'timedOut', as: 'timed_out_total' 154 | 155 | inside 'open' do 156 | ignore 'total' 157 | 158 | iterate do |key, value| 159 | gauge! 'metric_cursors_open', value, type: key 160 | end 161 | end 162 | end 163 | 164 | inside 'storage' do 165 | inside 'freelist' do 166 | inside 'search' do 167 | counter 'bucketExhausted', as: 'bucket_exhausted' 168 | counter 'requests' 169 | counter 'scanned' 170 | end 171 | end 172 | end 173 | 174 | ignore 'repl' 175 | 176 | inside 'commands' do 177 | counter '', as: 'unknown' 178 | 179 | iterate do |key, value| 180 | counter! 'command_failed', value['failed'], cmd: key 181 | counter! 'command_total', value['total'], cmd: key 182 | end 183 | end 184 | end 185 | 186 | gauge 'ok', as: 'scrape_ok' 187 | end 188 | end 189 | end 190 | end 191 | -------------------------------------------------------------------------------- /app/models/exporter/source/mongos.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | class Source 3 | # Metrics extacted from db.serverStatus() on `mongos` nodes 4 | class Mongos < ::Exporter::Source 5 | metrics do 6 | ignore 'host', 'advisoryHostFQDNs', 'version', 'process', 'pid', 7 | 'uptimeMillis', 'uptimeEstimate', 'localTime', 8 | 'sharding' 9 | 10 | gauge 'uptime', as: 'uptime_seconds' 11 | 12 | inside 'extra_info' do 13 | ignore 'note' 14 | 15 | gauge 'heap_usage_bytes' 16 | gauge 'page_faults' 17 | end 18 | 19 | inside 'asserts' do 20 | counter 'rollovers' 21 | 22 | iterate do |key, value| 23 | counter! 'asserts', value, type: key 24 | end 25 | end 26 | 27 | inside 'opcounters' do 28 | iterate do |key, value| 29 | counter! 'opcounters', value, op: key, src: 'self' 30 | end 31 | end 32 | 33 | inside 'connections' do 34 | gauge 'current' 35 | gauge 'available' 36 | counter 'totalCreated', as: 'created_total' 37 | end 38 | 39 | inside 'network' do 40 | counter 'bytesIn', as: 'in_bytes' 41 | gauge 'bytesOut', as: 'out_bytes' 42 | counter 'numRequests', as: 'requests_total' 43 | end 44 | 45 | inside 'mem' do 46 | ignore 'bits', 'supported' 47 | 48 | gauge 'resident', as: 'resident_mbytes' 49 | gauge 'virtual', as: 'virtual_mbytes' 50 | end 51 | 52 | inside 'metrics' do 53 | ignore 'getLastError' 54 | 55 | inside 'cursor' do 56 | inside 'open' do 57 | ignore 'total' 58 | 59 | iterate do |key, value| 60 | gauge! 'metric_cursors_open', value, type: key 61 | end 62 | end 63 | end 64 | 65 | inside 'commands' do 66 | counter '', as: 'unknown' 67 | 68 | iterate do |key, value| 69 | counter! 'command_failed', value['failed'], cmd: key 70 | counter! 'command_total', value['total'], cmd: key 71 | end 72 | end 73 | end 74 | 75 | gauge 'ok', as: 'scrape_ok' 76 | end 77 | end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /app/models/exporter/source/replica_set.rb: -------------------------------------------------------------------------------- 1 | module Exporter 2 | class Source 3 | # This metrics are based on implementation of the getReplicationInfo and 4 | # printSlaveReplicationInfo functions of the mongoshell (db.js) 5 | # 6 | # See: https://git.io/vXHSJ 7 | class ReplicaSet < Exporter::Source 8 | metrics do 9 | # This are comming from Collector::ReplicaSet 10 | 11 | gauge 'oplog_used_bytes' 12 | gauge 'oplog_max_bytes' 13 | gauge 'oplog_window_seconds' 14 | gauge 'oplog_count' 15 | 16 | ignore 'set', 'date', 'ok', '$gleStats' 17 | 18 | gauge 'heartbeatIntervalMillis', as: 'rs_heartbit_interval_ms' 19 | gauge 'myState', as: 'rs_state' 20 | gauge 'term', as: 'rs_election_term' 21 | 22 | gauge! 'rs_syncing', 1, to: extract('syncingTo') if key? 'syncingTo' 23 | 24 | members = value('members', []) 25 | primary = members.find { |member| member['state'] == 1 } 26 | me = members.find { |member| member['self'] } 27 | others = members - [me] 28 | 29 | if me 30 | if primary 31 | # If there primary, then replication lag is against it 32 | current_oplog = primary['optimeDate'] 33 | else 34 | # If there no primary, then replication las is against most recent 35 | # oplogDate 36 | current_oplog = members.map { |member| member['optimeDate'] }.max 37 | end 38 | 39 | lag = me['optimeDate'] - current_oplog 40 | gauge! 'rs_lag_seconds', lag 41 | 42 | others.each do |member| 43 | gauge! 'rs_ping_ms', member['pingMs'], to: member['name'] 44 | end 45 | else 46 | gauge! 'rs_no_self', 1 47 | end 48 | end 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /app/models/prometheus.rb: -------------------------------------------------------------------------------- 1 | require 'benchmark' 2 | 3 | # This class aggregates all metrics from all nodes and presents them in the 4 | # Prometheus Text format (>0.0.4) 5 | # 6 | # Additionaly it provides `scrape_duration_ms` metric, that just tells how 7 | # long it took to read all metrics. 8 | class Prometheus 9 | attr_reader :config, :prefix 10 | 11 | METRIC_PREFIX = 'mongo'.freeze 12 | GAUGE = Exporter::Point::Gauge 13 | 14 | def initialize(config = Exporter::Settings.current, prefix = METRIC_PREFIX) 15 | @config = config 16 | @points = [] 17 | @prefix = prefix 18 | 19 | prepare 20 | end 21 | 22 | def to_s 23 | # Trailing new-line is strictly required by Prometheus 24 | @points.join("\n") + "\n" 25 | end 26 | 27 | private 28 | 29 | def scrape_duration 30 | point = GAUGE.new('scrape_duration_ms', (@runtime * 1000.0).to_i) 31 | 32 | [point.to_prom_banner(prefix), point.to_prom(prefix)] 33 | end 34 | 35 | def prepare 36 | runtime do 37 | @points = all_by_name.each_with_object([]) do |(_name, points), memo| 38 | memo.concat [points.first.to_prom_banner(prefix)] 39 | .concat promethize(points) 40 | end 41 | end 42 | 43 | @points.concat scrape_duration 44 | end 45 | 46 | def all_points 47 | all_metrics.map(&:all).flatten 48 | end 49 | 50 | def all_metrics 51 | config.mongo.all.map(&:metrics).flatten 52 | end 53 | 54 | def all_by_name 55 | all_points.each_with_object({}) do |point, memo| 56 | full_name = point.full_name 57 | points = memo[full_name] ||= [] 58 | points.push(point) 59 | end 60 | end 61 | 62 | def promethize(points) 63 | points.map { |point| point.to_prom(prefix) } 64 | end 65 | 66 | def runtime(&body) 67 | @runtime = Benchmark.realtime(&body) 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../config/application', __dir__) 3 | require_relative '../config/boot' 4 | require 'rails/commands' 5 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative '../config/boot' 3 | require 'rake' 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | require 'fileutils' 4 | include FileUtils 5 | 6 | # path to your application root. 7 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 8 | 9 | def system!(*args) 10 | system(*args) || abort("\n== Command #{args} failed ==") 11 | end 12 | 13 | chdir APP_ROOT do 14 | # This script is a starting point to setup your application. 15 | # Add necessary setup steps to this file. 16 | 17 | puts '== Installing dependencies ==' 18 | system! 'gem install bundler --conservative' 19 | system('bundle check') || system!('bundle install') 20 | 21 | # puts "\n== Copying sample files ==" 22 | # unless File.exist?('config/database.yml') 23 | # cp 'config/database.yml.sample', 'config/database.yml' 24 | # end 25 | 26 | puts "\n== Preparing database ==" 27 | system! 'bin/rails db:setup' 28 | 29 | puts "\n== Removing old logs and tempfiles ==" 30 | system! 'bin/rails log:clear tmp:clear' 31 | 32 | puts "\n== Restarting application server ==" 33 | system! 'bin/rails restart' 34 | end 35 | -------------------------------------------------------------------------------- /bin/update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | require 'fileutils' 4 | include FileUtils 5 | 6 | # path to your application root. 7 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 8 | 9 | def system!(*args) 10 | system(*args) || abort("\n== Command #{args} failed ==") 11 | end 12 | 13 | chdir APP_ROOT do 14 | # This script is a way to update your development environment automatically. 15 | # Add necessary update steps to this file. 16 | 17 | puts '== Installing dependencies ==' 18 | system! 'gem install bundler --conservative' 19 | system('bundle check') || system!('bundle install') 20 | 21 | puts "\n== Updating database ==" 22 | system! 'bin/rails db:migrate' 23 | 24 | puts "\n== Removing old logs and tempfiles ==" 25 | system! 'bin/rails log:clear tmp:clear' 26 | 27 | puts "\n== Restarting application server ==" 28 | system! 'bin/rails restart' 29 | end 30 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative 'config/environment' 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative 'boot' 2 | 3 | require "rails" 4 | # Pick the frameworks you want: 5 | require "active_model/railtie" 6 | # require "active_job/railtie" 7 | # require "active_record/railtie" 8 | require "action_controller/railtie" 9 | # require "action_mailer/railtie" 10 | require "action_view/railtie" 11 | # require "action_cable/engine" 12 | # require "sprockets/railtie" 13 | # require "rails/test_unit/railtie" 14 | 15 | # Require the gems listed in Gemfile, including any gems 16 | # you've limited to :test, :development, or :production. 17 | Bundler.require(*Rails.groups) 18 | 19 | module MongoDeepExporter 20 | class Application < Rails::Application 21 | # Settings in config/environments/* take precedence over those specified 22 | # here. 23 | # Application configuration should go into files in config/initializers 24 | # -- all .rb files in that directory are automatically loaded. 25 | 26 | # Only loads a smaller set of middleware suitable for API only apps. 27 | # Middleware like session, flash, cookies can be added back manually. 28 | # Skip views, helpers and assets when generating a new resource. 29 | config.api_only = true 30 | 31 | # Use TorqueBox::Infinispan::Cache for the Rails cache store 32 | if defined? TorqueBox::Infinispan::Cache 33 | config.cache_store = :torquebox_store 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports. 13 | config.consider_all_requests_local = true 14 | 15 | # Enable/disable caching. By default caching is disabled. 16 | if Rails.root.join('tmp/caching-dev.txt').exist? 17 | config.action_controller.perform_caching = true 18 | 19 | config.cache_store = :memory_store 20 | config.public_file_server.headers = { 21 | 'Cache-Control' => 'public, max-age=172800' 22 | } 23 | else 24 | config.action_controller.perform_caching = false 25 | 26 | config.cache_store = :null_store 27 | end 28 | 29 | # Print deprecation notices to the Rails logger. 30 | config.active_support.deprecation = :log 31 | 32 | # Raises error for missing translations 33 | # config.action_view.raise_on_missing_translations = true 34 | 35 | # Use an evented file watcher to asynchronously detect changes in source code, 36 | # routes, locales, etc. This feature depends on the listen gem. 37 | # config.file_watcher = ActiveSupport::EventedFileUpdateChecker 38 | 39 | config.logger = Logger.new($stdout) 40 | end 41 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in 3 | # config/application.rb. 4 | 5 | # Code is not reloaded between requests. 6 | config.cache_classes = true 7 | 8 | # Eager load code on boot. This eager loads most of Rails and 9 | # your application in memory, allowing both threaded web servers 10 | # and those relying on copy on write to perform better. 11 | # Rake tasks automatically ignore this option for performance. 12 | config.eager_load = true 13 | 14 | # Full error reports are disabled and caching is turned on. 15 | config.consider_all_requests_local = false 16 | config.action_controller.perform_caching = true 17 | 18 | # Disable serving static files from the `/public` folder by default since 19 | # Apache or NGINX already handles this. 20 | config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? 21 | 22 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 23 | # config.action_controller.asset_host = 'http://assets.example.com' 24 | 25 | # Specifies the header that your server uses for sending files. 26 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 27 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 28 | 29 | # Mount Action Cable outside main process or domain 30 | # config.action_cable.mount_path = nil 31 | # config.action_cable.url = 'wss://example.com/cable' 32 | # config.action_cable.allowed_request_origins = [ 33 | # 'http://example.com', 34 | # /http:\/\/example.*/ 35 | # ] 36 | 37 | # Force all access to the app over SSL, use Strict-Transport-Security, and 38 | # use secure cookies. 39 | # config.force_ssl = true 40 | 41 | # Use the lowest log level to ensure availability of diagnostic information 42 | # when problems arise. 43 | config.log_level = :debug 44 | 45 | # Prepend all log lines with the following tags. 46 | config.log_tags = [ :request_id ] 47 | 48 | # Use a different cache store in production. 49 | # config.cache_store = :mem_cache_store 50 | 51 | # Use a real queuing backend for Active Job (and separate queues per environment) 52 | # config.active_job.queue_adapter = :resque 53 | # config.active_job.queue_name_prefix = "mongo_deep_exporter_#{Rails.env}" 54 | 55 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 56 | # the I18n.default_locale when a translation cannot be found). 57 | config.i18n.fallbacks = true 58 | 59 | # Send deprecation notices to registered listeners. 60 | config.active_support.deprecation = :notify 61 | 62 | # Use default logging formatter so that PID and timestamp are not suppressed. 63 | config.log_formatter = ::Logger::Formatter.new 64 | 65 | # Use a different logger for distributed setups. 66 | # require 'syslog/logger' 67 | # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') 68 | 69 | if ENV["RAILS_LOG_TO_STDOUT"].present? 70 | logger = TorqueBox::Logger.new 71 | logger.formatter = config.log_formatter 72 | config.logger = ActiveSupport::TaggedLogging.new(logger) 73 | end 74 | end 75 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure public file server for tests with Cache-Control for performance. 16 | config.public_file_server.enabled = true 17 | config.public_file_server.headers = { 18 | 'Cache-Control' => 'public, max-age=3600' 19 | } 20 | 21 | # Show full error reports and disable caching. 22 | config.consider_all_requests_local = true 23 | config.action_controller.perform_caching = false 24 | 25 | # Raise exceptions instead of rendering exception templates. 26 | config.action_dispatch.show_exceptions = false 27 | 28 | # Disable request forgery protection in test environment. 29 | config.action_controller.allow_forgery_protection = false 30 | 31 | # Print deprecation notices to the stderr. 32 | config.active_support.deprecation = :stderr 33 | 34 | # Raises error for missing translations 35 | # config.action_view.raise_on_missing_translations = true 36 | end 37 | -------------------------------------------------------------------------------- /config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ApplicationController.renderer.defaults.merge!( 4 | # http_host: 'example.org', 5 | # https: false 6 | # ) 7 | -------------------------------------------------------------------------------- /config/initializers/backport_rails.rb: -------------------------------------------------------------------------------- 1 | # This file containts backports from rails master. 2 | 3 | # Issue: https://github.com/rails/rails/issues/26912 4 | # Pull Request: https://github.com/rails/rails/pull/27007 5 | # Introduced: 5.0.0.1 6 | module ActionDispatch 7 | module Http 8 | module MimeNegotiation 9 | def has_content_type? # :nodoc: 10 | get_header "CONTENT_TYPE" 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/cors.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Avoid CORS issues when API is called from the frontend app. 4 | # Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests. 5 | 6 | # Read more: https://github.com/cyu/rack-cors 7 | 8 | # Rails.application.config.middleware.insert_before 0, Rack::Cors do 9 | # allow do 10 | # origins 'example.com' 11 | # 12 | # resource '*', 13 | # headers: :any, 14 | # methods: [:get, :post, :put, :patch, :delete, :options, :head] 15 | # end 16 | # end 17 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /config/initializers/new_framework_defaults.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains migration options to ease your Rails 5.0 upgrade. 4 | # 5 | # Read the Rails 5.0 release notes for more info on each option. 6 | 7 | # Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`. 8 | # Previous versions had false. 9 | ActiveSupport.to_time_preserves_timezone = true 10 | 11 | # Do not halt callback chains when a callback returns false. Previous versions had true. 12 | ActiveSupport.halt_callback_chains_on_return_false = false 13 | 14 | # Configure SSL options to enable HSTS with subdomains. Previous versions had false. 15 | Rails.application.config.ssl_options = { hsts: { subdomains: true } } 16 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Configure the TorqueBox Servlet-based session store. 2 | # Provides for server-based, in-memory, cluster-compatible sessions 3 | # if ENV['TORQUEBOX_APP_NAME'] 4 | # # MongoDeepExporter::Application.config.session_store :torquebox_store 5 | # else 6 | # # MongoDeepExporter::Application.config.session_store :cookie_store, :key => '_CHANGEME_session' 7 | # end 8 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | get 'metrics', to: 'stats#metrics' 3 | root to: 'stats#index' 4 | end 5 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rails secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | secret_key_base: unused 15 | 16 | test: 17 | secret_key_base: unused 18 | 19 | # Do not keep production secrets in the repository, 20 | # instead read values from the environment. 21 | production: 22 | secret_key_base: unused 23 | -------------------------------------------------------------------------------- /config/settings.yml: -------------------------------------------------------------------------------- 1 | version: 1 2 | 3 | # To give it a try get `mtools` (https://github.com/rueckstiess/mtools) and 4 | # then launch your small cluster: 5 | # 6 | # mlaunch init --replicaset --sharded hot warm cold --config 3 --mongos 3 \ 7 | # --port 27170 --hostname localhost --auth --csrs 8 | # 9 | # Note: you must specify the nodes in the configuration using the hostnames, 10 | # not the IP address, becuse mongo uses hostnames in nodes names. 11 | 12 | mongo: 13 | # Only `sharded` is currently supported 14 | mode: sharded 15 | 16 | # SSL Configuration, optional 17 | # ssl: 18 | # ssl_verify: true 19 | # ssl_cert: /path/to/cert.pem 20 | # ssl_ca_cert: /path/to/ca.pem 21 | 22 | # List of mongos instanes to connect 23 | mongos: 24 | - mongodb://user:password@localhost:27170 25 | - mongodb://user:password@localhost:27171 26 | - mongodb://user:password@localhost:27172 27 | 28 | # Shard topology 29 | shards: 30 | - mongodb://user:password@localhost:27173 31 | - mongodb://user:password@localhost:27174 32 | - mongodb://user:password@localhost:27175 33 | - mongodb://user:password@localhost:27176 34 | - mongodb://user:password@localhost:27177 35 | - mongodb://user:password@localhost:27178 36 | - mongodb://user:password@localhost:27179 37 | - mongodb://user:password@localhost:27180 38 | - mongodb://user:password@localhost:27181 39 | 40 | # List of config servers 41 | configs: 42 | - mongodb://user:password@localhost:27182 43 | - mongodb://user:password@localhost:27183 44 | - mongodb://user:password@localhost:27184 45 | 46 | # Namespaces to export. 47 | # 48 | # For example, to export metrics only from one collection `foo` from database 49 | # `bar` specify `bar.foo`. To export all collections from `bar` just specify 50 | # `bar.*`. 51 | # 52 | # If no namespace given, all discovered namespaces will be exported. 53 | # namespaces: 54 | # - foo.* 55 | 56 | # Set to true if you want to export index metrics as well. 57 | include_index: true 58 | -------------------------------------------------------------------------------- /config/warble.rb: -------------------------------------------------------------------------------- 1 | # Disable Rake-environment-task framework detection by uncommenting/setting to false 2 | # Warbler.framework_detection = false 3 | 4 | # Warbler web application assembly configuration file 5 | Warbler::Config.new do |config| 6 | # Features: additional options controlling how the jar is built. 7 | # Currently the following features are supported: 8 | # - *gemjar*: package the gem repository in a jar file in WEB-INF/lib 9 | # - *executable*: embed a web server and make the war executable 10 | # - *runnable*: allows to run bin scripts e.g. `java -jar my.war -S rake -T` 11 | # - *compiled*: compile .rb files to .class files 12 | config.features = %w(executable) 13 | 14 | # Application directories to be included in the webapp. 15 | # config.dirs = %w(app config db lib log script vendor tmp) 16 | 17 | # Additional files/directories to include, above those in config.dirs 18 | # config.includes = FileList["db"] 19 | 20 | # Additional files/directories to exclude 21 | # config.excludes = FileList["lib/tasks/*"] 22 | 23 | # Additional Java .jar files to include. Note that if .jar files are placed 24 | # in lib (and not otherwise excluded) then they need not be mentioned here. 25 | # JRuby and JRuby-Rack are pre-loaded in this list. Be sure to include your 26 | # own versions if you directly set the value 27 | # config.java_libs += FileList["lib/java/*.jar"] 28 | 29 | # Loose Java classes and miscellaneous files to be included. 30 | # config.java_classes = FileList["target/classes/**.*"] 31 | 32 | # One or more pathmaps defining how the java classes should be copied into 33 | # the archive. The example pathmap below accompanies the java_classes 34 | # configuration above. See http://rake.rubyforge.org/classes/String.html#M000017 35 | # for details of how to specify a pathmap. 36 | # config.pathmaps.java_classes << "%{target/classes/,}p" 37 | 38 | # Bundler support is built-in. If Warbler finds a Gemfile in the 39 | # project directory, it will be used to collect the gems to bundle 40 | # in your application. If you wish to explicitly disable this 41 | # functionality, uncomment here. 42 | # config.bundler = false 43 | 44 | # An array of Bundler groups to avoid including in the war file. 45 | # Defaults to ["development", "test", "assets"]. 46 | # config.bundle_without = [] 47 | 48 | # Other gems to be included. If you don't use Bundler or a gemspec 49 | # file, you need to tell Warbler which gems your application needs 50 | # so that they can be packaged in the archive. 51 | # For Rails applications, the Rails gems are included by default 52 | # unless the vendor/rails directory is present. 53 | # config.gems += ["activerecord-jdbcmysql-adapter", "jruby-openssl"] 54 | # config.gems << "tzinfo" 55 | 56 | # Uncomment this if you don't want to package rails gem. 57 | # config.gems -= ["rails"] 58 | 59 | # The most recent versions of gems are used. 60 | # You can specify versions of gems by using a hash assignment: 61 | # config.gems["rails"] = "4.2.5" 62 | 63 | # You can also use regexps or Gem::Dependency objects for flexibility or 64 | # finer-grained control. 65 | # config.gems << /^sinatra-/ 66 | # config.gems << Gem::Dependency.new("sinatra", "= 1.4.7") 67 | 68 | # Include gem dependencies not mentioned specifically. Default is 69 | # true, uncomment to turn off. 70 | # config.gem_dependencies = false 71 | 72 | # Array of regular expressions matching relative paths in gems to be 73 | # excluded from the war. Defaults to empty, but you can set it like 74 | # below, which excludes test files. 75 | # config.gem_excludes = [/^(test|spec)\//] 76 | 77 | # Pathmaps for controlling how application files are copied into the archive 78 | # config.pathmaps.application = ["WEB-INF/%p"] 79 | 80 | # Name of the archive (without the extension). Defaults to the basename 81 | # of the project directory. 82 | # config.jar_name = "mywar" 83 | 84 | # File extension for the archive. Defaults to either 'jar' or 'war'. 85 | # config.jar_extension = "jar" 86 | 87 | # Destionation for the created archive. Defaults to project's root directory. 88 | # config.autodeploy_dir = "dist/" 89 | 90 | # Name of the MANIFEST.MF template for the war file. Defaults to a simple 91 | # MANIFEST.MF that contains the version of Warbler used to create the war file. 92 | # config.manifest_file = "config/MANIFEST.MF" 93 | 94 | # When using the 'compiled' feature and specified, only these Ruby 95 | # files will be compiled. Default is to compile all \.rb files in 96 | # the application. 97 | # config.compiled_ruby_files = FileList['app/**/*.rb'] 98 | 99 | # Determines if ruby files in supporting gems will be compiled. 100 | # Ignored unless compile feature is used. 101 | # config.compile_gems = false 102 | 103 | # When set it specify the bytecode version for compiled class files 104 | # config.bytecode_version = "1.6" 105 | 106 | # When set to true, Warbler will override the value of ENV['GEM_HOME'] even it 107 | # has already been set. When set to false it will use any existing value of 108 | # GEM_HOME if it is set. 109 | # config.override_gem_home = true 110 | 111 | # Allows for specifing custom executables 112 | # config.executable = ["rake", "bin/rake"] 113 | 114 | # Sets default (prefixed) parameters for the executables 115 | # config.executable_params = "do:something" 116 | 117 | # If set to true, moves jar files into WEB-INF/lib. Prior to version 1.4.2 of Warbler this was done 118 | # by default. But since 1.4.2 this config defaults to false. It may need to be set to true for 119 | # web servers that do not explode the WAR file. 120 | # Alternatively, this option can be set to a regular expression, which will 121 | # act as a jar selector -- only jar files that match the pattern will be 122 | # included in the archive. 123 | # config.move_jars_to_webinf_lib = false 124 | 125 | # === War files only below here === 126 | 127 | # Embedded webserver to use with the 'executable' feature. Currently supported 128 | # webservers are: 129 | # - *jetty* - Embedded Jetty from Eclipse 130 | # config.webserver = 'jetty' 131 | 132 | # Path to the pre-bundled gem directory inside the war file. Default 133 | # is 'WEB-INF/gems'. Specify path if gems are already bundled 134 | # before running Warbler. This also sets 'gem.path' inside web.xml. 135 | # config.gem_path = "WEB-INF/vendor/bundler_gems" 136 | 137 | # Files for WEB-INF directory (next to web.xml). This contains 138 | # web.xml by default. If there is an .erb-File it will be processed 139 | # with webxml-config. You may want to exclude this file via 140 | # config.excludes. 141 | # config.webinf_files += FileList["jboss-web.xml"] 142 | 143 | # Files to be included in the root of the webapp. Note that files in public 144 | # will have the leading 'public/' part of the path stripped during staging. 145 | # config.public_html = FileList["public/**/*", "doc/**/*"] 146 | 147 | # Pathmaps for controlling how public HTML files are copied into the .war 148 | # config.pathmaps.public_html = ["%{public/,}p"] 149 | 150 | # Value of RAILS_ENV for the webapp -- default as shown below 151 | # config.webxml.rails.env = ENV['RAILS_ENV'] || 'production' 152 | 153 | # Public ROOT mapping, by default assets are copied into .war ROOT directory. 154 | # config.public.root = '' 155 | 156 | # Application booter to use, either :rack or :rails (autodetected by default) 157 | # config.webxml.booter = :rails 158 | 159 | # When using the :rack booter, "Rackup" script to use. 160 | # - For 'rackup.path', the value points to the location of the rackup 161 | # script in the web archive file. You need to make sure this file 162 | # gets included in the war, possibly by adding it to config.includes 163 | # or config.webinf_files above. 164 | # - For 'rackup', the rackup script you provide as an inline string 165 | # is simply embedded in web.xml. 166 | # The script is evaluated in a Rack::Builder to load the application. 167 | # Examples: 168 | # config.webxml.rackup.path = 'WEB-INF/hello.ru' 169 | # config.webxml.rackup = %{require './lib/demo'; run Rack::Adapter::Camping.new(Demo)} 170 | # config.webxml.rackup = require 'cgi' && CGI::escapeHTML(File.read("config.ru")) 171 | 172 | # Control the pool of Rails runtimes. Leaving unspecified means 173 | # the pool will grow as needed to service requests. It is recommended 174 | # that you fix these values when running a production server! 175 | # If you're using threadsafe! mode, you probably don't want to set these values, 176 | # since 1 runtime(default for threadsafe mode) will be enough. 177 | # config.webxml.jruby.min.runtimes = 2 178 | # config.webxml.jruby.max.runtimes = 4 179 | 180 | # JNDI data source name 181 | # config.webxml.jndi = 'jdbc/rails' 182 | end 183 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) 7 | # Character.create(name: 'Luke', movie: movies.first) 8 | -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/db-ai/mongo_collection_exporter/2666c8309adda5ddb7272cd12f3fc41a61f6d187/lib/tasks/.keep -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /vendor/grafana/mongo_cloud.json: -------------------------------------------------------------------------------- 1 | { 2 | "__inputs": [ 3 | { 4 | "name": "DS_PROMETHEUS", 5 | "label": "Prometheus", 6 | "description": "", 7 | "type": "datasource", 8 | "pluginId": "prometheus", 9 | "pluginName": "Prometheus" 10 | }, 11 | { 12 | "name": "VAR_SCOPE", 13 | "type": "constant", 14 | "label": "scope", 15 | "value": "", 16 | "description": "" 17 | } 18 | ], 19 | "__requires": [ 20 | { 21 | "type": "panel", 22 | "id": "graph", 23 | "name": "Graph", 24 | "version": "" 25 | }, 26 | { 27 | "type": "grafana", 28 | "id": "grafana", 29 | "name": "Grafana", 30 | "version": "4.0.2" 31 | }, 32 | { 33 | "type": "datasource", 34 | "id": "prometheus", 35 | "name": "Prometheus", 36 | "version": "1.0.0" 37 | } 38 | ], 39 | "id": null, 40 | "title": "Mongo Cloud", 41 | "description": "", 42 | "tags": [], 43 | "style": "dark", 44 | "timezone": "browser", 45 | "editable": true, 46 | "sharedCrosshair": true, 47 | "hideControls": false, 48 | "time": { 49 | "from": "now-6h", 50 | "to": "now" 51 | }, 52 | "timepicker": { 53 | "refresh_intervals": [ 54 | "5s", 55 | "10s", 56 | "30s", 57 | "1m", 58 | "5m", 59 | "15m", 60 | "30m", 61 | "1h", 62 | "2h", 63 | "1d" 64 | ], 65 | "time_options": [ 66 | "5m", 67 | "15m", 68 | "1h", 69 | "6h", 70 | "12h", 71 | "24h", 72 | "2d", 73 | "7d", 74 | "30d" 75 | ] 76 | }, 77 | "templating": { 78 | "list": [ 79 | { 80 | "allValue": ".*", 81 | "current": {}, 82 | "datasource": "${DS_PROMETHEUS}", 83 | "hide": 0, 84 | "includeAll": true, 85 | "label": "Members", 86 | "multi": false, 87 | "name": "role", 88 | "options": [], 89 | "query": "label_values(mongo_scrape_ok, role)", 90 | "refresh": 1, 91 | "regex": "", 92 | "sort": 0, 93 | "tagValuesQuery": null, 94 | "tagsQuery": null, 95 | "type": "query" 96 | }, 97 | { 98 | "allValue": ".*", 99 | "current": {}, 100 | "datasource": "${DS_PROMETHEUS}", 101 | "hide": 0, 102 | "includeAll": true, 103 | "label": "Cluster", 104 | "multi": false, 105 | "name": "rs", 106 | "options": [], 107 | "query": "label_values(mongo_scrape_ok{role=~\"$role\"}, rs)", 108 | "refresh": 1, 109 | "regex": "", 110 | "sort": 0, 111 | "tagValuesQuery": null, 112 | "tagsQuery": null, 113 | "type": "query" 114 | }, 115 | { 116 | "allValue": ".*", 117 | "current": {}, 118 | "datasource": "${DS_PROMETHEUS}", 119 | "hide": 0, 120 | "includeAll": true, 121 | "label": "Server", 122 | "multi": false, 123 | "name": "instance", 124 | "options": [], 125 | "query": "label_values(mongo_scrape_ok{role=~\"$role\", rs=~\"$rs\"}, instance)", 126 | "refresh": 1, 127 | "regex": "", 128 | "sort": 0, 129 | "tagValuesQuery": null, 130 | "tagsQuery": null, 131 | "type": "query" 132 | }, 133 | { 134 | "auto": false, 135 | "auto_count": 30, 136 | "auto_min": "10s", 137 | "current": { 138 | "text": "5m", 139 | "value": "5m" 140 | }, 141 | "datasource": null, 142 | "hide": 0, 143 | "includeAll": false, 144 | "label": "Scale", 145 | "multi": false, 146 | "name": "scale", 147 | "options": [ 148 | { 149 | "text": "1m", 150 | "value": "1m", 151 | "selected": false 152 | }, 153 | { 154 | "text": "5m", 155 | "value": "5m", 156 | "selected": true 157 | }, 158 | { 159 | "text": "10m", 160 | "value": "10m", 161 | "selected": false 162 | } 163 | ], 164 | "query": "1m,5m,10m", 165 | "refresh": 2, 166 | "type": "interval" 167 | }, 168 | { 169 | "current": { 170 | "value": "${VAR_SCOPE}", 171 | "text": "${VAR_SCOPE}" 172 | }, 173 | "hide": 2, 174 | "label": "", 175 | "name": "scope", 176 | "options": [ 177 | { 178 | "value": "${VAR_SCOPE}", 179 | "text": "${VAR_SCOPE}" 180 | } 181 | ], 182 | "query": "${VAR_SCOPE}", 183 | "type": "constant" 184 | } 185 | ] 186 | }, 187 | "annotations": { 188 | "list": [] 189 | }, 190 | "schemaVersion": 13, 191 | "version": 6, 192 | "links": [], 193 | "gnetId": null, 194 | "rows": [ 195 | { 196 | "title": "Row", 197 | "panels": [ 198 | { 199 | "aliasColors": {}, 200 | "bars": false, 201 | "datasource": "${DS_PROMETHEUS}", 202 | "editable": true, 203 | "error": false, 204 | "fill": 1, 205 | "grid": {}, 206 | "id": 1, 207 | "legend": { 208 | "alignAsTable": true, 209 | "avg": true, 210 | "current": true, 211 | "hideEmpty": true, 212 | "hideZero": true, 213 | "max": true, 214 | "min": true, 215 | "rightSide": true, 216 | "show": true, 217 | "sideWidth": 400, 218 | "total": false, 219 | "values": true 220 | }, 221 | "lines": true, 222 | "linewidth": 2, 223 | "links": [], 224 | "nullPointMode": "connected", 225 | "percentage": false, 226 | "pointradius": 5, 227 | "points": false, 228 | "renderer": "flot", 229 | "seriesOverrides": [], 230 | "span": 12, 231 | "stack": false, 232 | "steppedLine": false, 233 | "targets": [ 234 | { 235 | "expr": "sum(rate(mongo_opcounters{role=~\"$role\",rs=~\"$rs\",instance=~\"$instance\",src=\"self\"}[$scale])) by (op)", 236 | "intervalFactor": 2, 237 | "legendFormat": "{{op}}", 238 | "metric": "mongo_opcounters", 239 | "refId": "A", 240 | "step": 30 241 | } 242 | ], 243 | "thresholds": [], 244 | "timeFrom": null, 245 | "timeShift": null, 246 | "title": "Opcounters", 247 | "tooltip": { 248 | "msResolution": false, 249 | "shared": true, 250 | "sort": 2, 251 | "value_type": "cumulative" 252 | }, 253 | "type": "graph", 254 | "xaxis": { 255 | "mode": "time", 256 | "name": null, 257 | "show": true, 258 | "values": [] 259 | }, 260 | "yaxes": [ 261 | { 262 | "format": "short", 263 | "label": null, 264 | "logBase": 1, 265 | "max": null, 266 | "min": null, 267 | "show": true 268 | }, 269 | { 270 | "format": "short", 271 | "label": null, 272 | "logBase": 1, 273 | "max": null, 274 | "min": null, 275 | "show": true 276 | } 277 | ] 278 | }, 279 | { 280 | "aliasColors": {}, 281 | "bars": false, 282 | "datasource": "${DS_PROMETHEUS}", 283 | "editable": true, 284 | "error": false, 285 | "fill": 1, 286 | "grid": {}, 287 | "id": 2, 288 | "legend": { 289 | "alignAsTable": true, 290 | "avg": true, 291 | "current": true, 292 | "hideEmpty": true, 293 | "hideZero": true, 294 | "max": true, 295 | "min": true, 296 | "rightSide": true, 297 | "show": true, 298 | "sideWidth": 400, 299 | "total": false, 300 | "values": true 301 | }, 302 | "lines": true, 303 | "linewidth": 2, 304 | "links": [], 305 | "nullPointMode": "connected", 306 | "percentage": false, 307 | "pointradius": 5, 308 | "points": false, 309 | "renderer": "flot", 310 | "seriesOverrides": [], 311 | "span": 12, 312 | "stack": false, 313 | "steppedLine": false, 314 | "targets": [ 315 | { 316 | "expr": "sum(mongo_mem_resident_mbytes{role=~\"$role\",rs=~\"$rs\",instance=~\"$instance\"}) by (type)", 317 | "intervalFactor": 2, 318 | "legendFormat": "Resident", 319 | "metric": "mongo_mem_resident_mbytes", 320 | "refId": "A", 321 | "step": 30 322 | }, 323 | { 324 | "expr": "sum(mongo_mem_virtual_mbytes{role=~\"$role\",rs=~\"$rs\",instance=~\"$instance\"}) by (type)", 325 | "intervalFactor": 2, 326 | "legendFormat": "Virtual", 327 | "metric": "mongo_mem_virtual_mbytes", 328 | "refId": "B", 329 | "step": 30 330 | } 331 | ], 332 | "thresholds": [], 333 | "timeFrom": null, 334 | "timeShift": null, 335 | "title": "Memory", 336 | "tooltip": { 337 | "msResolution": false, 338 | "shared": true, 339 | "sort": 0, 340 | "value_type": "cumulative" 341 | }, 342 | "type": "graph", 343 | "xaxis": { 344 | "mode": "time", 345 | "name": null, 346 | "show": true, 347 | "values": [] 348 | }, 349 | "yaxes": [ 350 | { 351 | "format": "mbytes", 352 | "label": "", 353 | "logBase": 1, 354 | "max": null, 355 | "min": null, 356 | "show": true 357 | }, 358 | { 359 | "format": "short", 360 | "label": null, 361 | "logBase": 1, 362 | "max": null, 363 | "min": null, 364 | "show": true 365 | } 366 | ] 367 | } 368 | ], 369 | "showTitle": false, 370 | "titleSize": "h6", 371 | "height": "150px", 372 | "repeat": null, 373 | "repeatRowId": null, 374 | "repeatIteration": null, 375 | "collapse": false 376 | }, 377 | { 378 | "title": "New row", 379 | "panels": [ 380 | { 381 | "aliasColors": {}, 382 | "bars": false, 383 | "datasource": "${DS_PROMETHEUS}", 384 | "editable": true, 385 | "error": false, 386 | "fill": 1, 387 | "grid": {}, 388 | "id": 3, 389 | "legend": { 390 | "alignAsTable": true, 391 | "avg": true, 392 | "current": true, 393 | "hideEmpty": true, 394 | "hideZero": true, 395 | "max": true, 396 | "min": true, 397 | "rightSide": true, 398 | "show": true, 399 | "sideWidth": 400, 400 | "total": false, 401 | "values": true 402 | }, 403 | "lines": true, 404 | "linewidth": 2, 405 | "links": [], 406 | "nullPointMode": "connected", 407 | "percentage": false, 408 | "pointradius": 5, 409 | "points": false, 410 | "renderer": "flot", 411 | "seriesOverrides": [], 412 | "span": 12, 413 | "stack": false, 414 | "steppedLine": false, 415 | "targets": [ 416 | { 417 | "expr": "sum(mongo_metric_cursors_open{role=~\"$role\",rs=~\"$rs\",instance=~\"$instance\"}) by (type)", 418 | "intervalFactor": 2, 419 | "legendFormat": "{{type}}", 420 | "metric": "mongo_metric_cursors_open", 421 | "refId": "A", 422 | "step": 30 423 | } 424 | ], 425 | "thresholds": [], 426 | "timeFrom": null, 427 | "timeShift": null, 428 | "title": "Cursors", 429 | "tooltip": { 430 | "msResolution": false, 431 | "shared": true, 432 | "sort": 0, 433 | "value_type": "cumulative" 434 | }, 435 | "type": "graph", 436 | "xaxis": { 437 | "mode": "time", 438 | "name": null, 439 | "show": true, 440 | "values": [] 441 | }, 442 | "yaxes": [ 443 | { 444 | "format": "short", 445 | "label": null, 446 | "logBase": 1, 447 | "max": null, 448 | "min": null, 449 | "show": true 450 | }, 451 | { 452 | "format": "short", 453 | "label": null, 454 | "logBase": 1, 455 | "max": null, 456 | "min": null, 457 | "show": true 458 | } 459 | ] 460 | } 461 | ], 462 | "showTitle": false, 463 | "titleSize": "h6", 464 | "height": "150px", 465 | "repeat": null, 466 | "repeatRowId": null, 467 | "repeatIteration": null, 468 | "collapse": false 469 | }, 470 | { 471 | "title": "New row", 472 | "panels": [ 473 | { 474 | "aliasColors": { 475 | "Num Requests": "#890F02", 476 | "Out": "#1F78C1" 477 | }, 478 | "bars": false, 479 | "datasource": "${DS_PROMETHEUS}", 480 | "editable": true, 481 | "error": false, 482 | "fill": 1, 483 | "grid": {}, 484 | "id": 4, 485 | "legend": { 486 | "alignAsTable": true, 487 | "avg": true, 488 | "current": true, 489 | "hideEmpty": true, 490 | "hideZero": true, 491 | "max": true, 492 | "min": false, 493 | "rightSide": true, 494 | "show": true, 495 | "total": false, 496 | "values": true 497 | }, 498 | "lines": true, 499 | "linewidth": 2, 500 | "links": [], 501 | "nullPointMode": "connected", 502 | "percentage": false, 503 | "pointradius": 5, 504 | "points": false, 505 | "renderer": "flot", 506 | "seriesOverrides": [ 507 | { 508 | "alias": "Num Requests", 509 | "yaxis": 2 510 | } 511 | ], 512 | "span": 12, 513 | "stack": false, 514 | "steppedLine": false, 515 | "targets": [ 516 | { 517 | "expr": "sum(rate(mongo_network_in_bytes{role=~\"$role\",rs=~\"$rs\",instance=~\"$instance\"}[$scale]))", 518 | "intervalFactor": 2, 519 | "legendFormat": "In", 520 | "metric": "mongo_network_in_bytes", 521 | "refId": "A", 522 | "step": 30 523 | }, 524 | { 525 | "expr": "-sum(rate(mongo_network_out_bytes{role=~\"$role\",rs=~\"$rs\",instance=~\"$instance\"}[$scale]))", 526 | "intervalFactor": 2, 527 | "legendFormat": "Out", 528 | "metric": "mongo_network_out_bytes", 529 | "refId": "B", 530 | "step": 30 531 | }, 532 | { 533 | "expr": "sum(rate(mongo_network_requests_total{role=~\"$role\",rs=~\"$rs\",instance=~\"$instance\"}[$scale]))", 534 | "intervalFactor": 2, 535 | "legendFormat": "Num Requests", 536 | "metric": "mongo_network_requests_total", 537 | "refId": "C", 538 | "step": 30 539 | } 540 | ], 541 | "thresholds": [], 542 | "timeFrom": null, 543 | "timeShift": null, 544 | "title": "Network", 545 | "tooltip": { 546 | "msResolution": false, 547 | "shared": true, 548 | "sort": 0, 549 | "value_type": "cumulative" 550 | }, 551 | "type": "graph", 552 | "xaxis": { 553 | "mode": "time", 554 | "name": null, 555 | "show": true, 556 | "values": [] 557 | }, 558 | "yaxes": [ 559 | { 560 | "format": "bytes", 561 | "label": null, 562 | "logBase": 1, 563 | "max": null, 564 | "min": null, 565 | "show": true 566 | }, 567 | { 568 | "format": "short", 569 | "label": null, 570 | "logBase": 1, 571 | "max": null, 572 | "min": null, 573 | "show": true 574 | } 575 | ] 576 | } 577 | ], 578 | "showTitle": false, 579 | "titleSize": "h6", 580 | "height": "150px", 581 | "repeat": null, 582 | "repeatRowId": null, 583 | "repeatIteration": null, 584 | "collapse": false 585 | }, 586 | { 587 | "title": "New row", 588 | "panels": [ 589 | { 590 | "aliasColors": {}, 591 | "bars": false, 592 | "datasource": "${DS_PROMETHEUS}", 593 | "editable": true, 594 | "error": false, 595 | "fill": 1, 596 | "grid": {}, 597 | "id": 6, 598 | "legend": { 599 | "alignAsTable": true, 600 | "avg": true, 601 | "current": true, 602 | "hideEmpty": true, 603 | "hideZero": true, 604 | "max": true, 605 | "min": true, 606 | "rightSide": true, 607 | "show": true, 608 | "sideWidth": 400, 609 | "total": false, 610 | "values": true 611 | }, 612 | "lines": true, 613 | "linewidth": 2, 614 | "links": [], 615 | "nullPointMode": "connected", 616 | "percentage": false, 617 | "pointradius": 5, 618 | "points": false, 619 | "renderer": "flot", 620 | "seriesOverrides": [], 621 | "span": 12, 622 | "stack": false, 623 | "steppedLine": false, 624 | "targets": [ 625 | { 626 | "expr": "sum(rate(mongo_opcounters{role=~\"$role\",rs=~\"$rs\",instance=~\"$instance\",src=\"repl\"}[$scale])) by (type)", 627 | "intervalFactor": 2, 628 | "legendFormat": "{{type}}", 629 | "metric": "mongo_opcounters", 630 | "refId": "A", 631 | "step": 30 632 | } 633 | ], 634 | "thresholds": [], 635 | "timeFrom": null, 636 | "timeShift": null, 637 | "title": "Opcounters Repliction", 638 | "tooltip": { 639 | "msResolution": false, 640 | "shared": true, 641 | "sort": 0, 642 | "value_type": "cumulative" 643 | }, 644 | "type": "graph", 645 | "xaxis": { 646 | "mode": "time", 647 | "name": null, 648 | "show": true, 649 | "values": [] 650 | }, 651 | "yaxes": [ 652 | { 653 | "format": "short", 654 | "label": null, 655 | "logBase": 1, 656 | "max": null, 657 | "min": null, 658 | "show": true 659 | }, 660 | { 661 | "format": "short", 662 | "label": null, 663 | "logBase": 1, 664 | "max": null, 665 | "min": null, 666 | "show": true 667 | } 668 | ] 669 | } 670 | ], 671 | "showTitle": false, 672 | "titleSize": "h6", 673 | "height": "150px", 674 | "repeat": null, 675 | "repeatRowId": null, 676 | "repeatIteration": null, 677 | "collapse": false 678 | }, 679 | { 680 | "title": "New row", 681 | "panels": [ 682 | { 683 | "aliasColors": {}, 684 | "bars": false, 685 | "datasource": "${DS_PROMETHEUS}", 686 | "editable": true, 687 | "error": false, 688 | "fill": 1, 689 | "grid": {}, 690 | "id": 5, 691 | "legend": { 692 | "alignAsTable": true, 693 | "avg": true, 694 | "current": true, 695 | "hideEmpty": false, 696 | "hideZero": false, 697 | "max": true, 698 | "min": true, 699 | "rightSide": true, 700 | "show": true, 701 | "sideWidth": 400, 702 | "total": false, 703 | "values": true 704 | }, 705 | "lines": true, 706 | "linewidth": 2, 707 | "links": [], 708 | "nullPointMode": "connected", 709 | "percentage": false, 710 | "pointradius": 5, 711 | "points": false, 712 | "renderer": "flot", 713 | "seriesOverrides": [], 714 | "span": 12, 715 | "stack": false, 716 | "steppedLine": false, 717 | "targets": [ 718 | { 719 | "expr": "sum(rate(mongo_global_lock{role=~\"$role\",rs=~\"$rs\",instance=~\"$instance\",queue=~\".+\"}[$scale])) by (queue)", 720 | "intervalFactor": 2, 721 | "legendFormat": "{{queue}}", 722 | "metric": "mongo_global_lock", 723 | "refId": "A", 724 | "step": 30 725 | } 726 | ], 727 | "thresholds": [], 728 | "timeFrom": null, 729 | "timeShift": null, 730 | "title": "Queues", 731 | "tooltip": { 732 | "msResolution": false, 733 | "shared": true, 734 | "sort": 0, 735 | "value_type": "cumulative" 736 | }, 737 | "type": "graph", 738 | "xaxis": { 739 | "mode": "time", 740 | "name": null, 741 | "show": true, 742 | "values": [] 743 | }, 744 | "yaxes": [ 745 | { 746 | "format": "short", 747 | "label": null, 748 | "logBase": 1, 749 | "max": null, 750 | "min": null, 751 | "show": true 752 | }, 753 | { 754 | "format": "short", 755 | "label": null, 756 | "logBase": 1, 757 | "max": null, 758 | "min": null, 759 | "show": true 760 | } 761 | ] 762 | } 763 | ], 764 | "showTitle": false, 765 | "titleSize": "h6", 766 | "height": "150px", 767 | "repeat": null, 768 | "repeatRowId": null, 769 | "repeatIteration": null, 770 | "collapse": false 771 | }, 772 | { 773 | "title": "New row", 774 | "panels": [ 775 | { 776 | "aliasColors": {}, 777 | "bars": false, 778 | "datasource": "${DS_PROMETHEUS}", 779 | "editable": true, 780 | "error": false, 781 | "fill": 1, 782 | "grid": {}, 783 | "id": 7, 784 | "legend": { 785 | "alignAsTable": true, 786 | "avg": true, 787 | "current": true, 788 | "hideEmpty": false, 789 | "hideZero": false, 790 | "max": true, 791 | "min": true, 792 | "rightSide": true, 793 | "show": true, 794 | "sideWidth": 400, 795 | "total": false, 796 | "values": true 797 | }, 798 | "lines": true, 799 | "linewidth": 2, 800 | "links": [], 801 | "nullPointMode": "connected", 802 | "percentage": false, 803 | "pointradius": 5, 804 | "points": false, 805 | "renderer": "flot", 806 | "seriesOverrides": [], 807 | "span": 12, 808 | "stack": false, 809 | "steppedLine": false, 810 | "targets": [ 811 | { 812 | "expr": "mongo_rs_lag_seconds", 813 | "intervalFactor": 2, 814 | "legendFormat": "{{rs}} ({{instance}})", 815 | "metric": "mongo_rs_lag_seconds", 816 | "refId": "A", 817 | "step": 30 818 | } 819 | ], 820 | "thresholds": [], 821 | "timeFrom": null, 822 | "timeShift": null, 823 | "title": "Replication Lag", 824 | "tooltip": { 825 | "msResolution": false, 826 | "shared": true, 827 | "sort": 0, 828 | "value_type": "cumulative" 829 | }, 830 | "type": "graph", 831 | "xaxis": { 832 | "mode": "time", 833 | "name": null, 834 | "show": true, 835 | "values": [] 836 | }, 837 | "yaxes": [ 838 | { 839 | "format": "s", 840 | "label": null, 841 | "logBase": 1, 842 | "max": null, 843 | "min": null, 844 | "show": true 845 | }, 846 | { 847 | "format": "short", 848 | "label": null, 849 | "logBase": 1, 850 | "max": null, 851 | "min": null, 852 | "show": true 853 | } 854 | ] 855 | } 856 | ], 857 | "showTitle": false, 858 | "titleSize": "h6", 859 | "height": "150px", 860 | "repeat": null, 861 | "repeatRowId": null, 862 | "repeatIteration": null, 863 | "collapse": false 864 | }, 865 | { 866 | "title": "New row", 867 | "panels": [ 868 | { 869 | "aliasColors": {}, 870 | "bars": false, 871 | "datasource": "${DS_PROMETHEUS}", 872 | "editable": true, 873 | "error": false, 874 | "fill": 1, 875 | "grid": {}, 876 | "id": 8, 877 | "legend": { 878 | "alignAsTable": true, 879 | "avg": true, 880 | "current": true, 881 | "max": true, 882 | "min": true, 883 | "rightSide": true, 884 | "show": true, 885 | "sideWidth": 400, 886 | "total": false, 887 | "values": true 888 | }, 889 | "lines": true, 890 | "linewidth": 2, 891 | "links": [], 892 | "nullPointMode": "connected", 893 | "percentage": false, 894 | "pointradius": 5, 895 | "points": false, 896 | "renderer": "flot", 897 | "seriesOverrides": [], 898 | "span": 12, 899 | "stack": false, 900 | "steppedLine": false, 901 | "targets": [ 902 | { 903 | "expr": "sum(rate(mongo_extra_info_page_faults{role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"}[$scale]))", 904 | "intervalFactor": 2, 905 | "legendFormat": "Page Faults", 906 | "metric": "mongo_extra_info_page_faults", 907 | "refId": "A", 908 | "step": 30 909 | } 910 | ], 911 | "thresholds": [], 912 | "timeFrom": null, 913 | "timeShift": null, 914 | "title": "Page Faults", 915 | "tooltip": { 916 | "msResolution": false, 917 | "shared": true, 918 | "sort": 0, 919 | "value_type": "cumulative" 920 | }, 921 | "type": "graph", 922 | "xaxis": { 923 | "mode": "time", 924 | "name": null, 925 | "show": true, 926 | "values": [] 927 | }, 928 | "yaxes": [ 929 | { 930 | "format": "short", 931 | "label": null, 932 | "logBase": 1, 933 | "max": null, 934 | "min": null, 935 | "show": true 936 | }, 937 | { 938 | "format": "short", 939 | "label": null, 940 | "logBase": 1, 941 | "max": null, 942 | "min": null, 943 | "show": true 944 | } 945 | ] 946 | } 947 | ], 948 | "showTitle": false, 949 | "titleSize": "h6", 950 | "height": "150px", 951 | "repeat": null, 952 | "repeatRowId": null, 953 | "repeatIteration": null, 954 | "collapse": false 955 | }, 956 | { 957 | "title": "New row", 958 | "panels": [ 959 | { 960 | "aliasColors": {}, 961 | "bars": false, 962 | "datasource": "${DS_PROMETHEUS}", 963 | "editable": true, 964 | "error": false, 965 | "fill": 1, 966 | "grid": {}, 967 | "id": 9, 968 | "legend": { 969 | "alignAsTable": true, 970 | "avg": false, 971 | "current": true, 972 | "max": false, 973 | "min": false, 974 | "rightSide": true, 975 | "show": true, 976 | "sideWidth": 400, 977 | "total": false, 978 | "values": true 979 | }, 980 | "lines": true, 981 | "linewidth": 2, 982 | "links": [], 983 | "nullPointMode": "connected", 984 | "percentage": false, 985 | "pointradius": 5, 986 | "points": false, 987 | "renderer": "flot", 988 | "repeat": null, 989 | "seriesOverrides": [], 990 | "span": 12, 991 | "stack": false, 992 | "steppedLine": false, 993 | "targets": [ 994 | { 995 | "expr": "sum(mongo_collection_storage_size_bytes{role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"})", 996 | "intervalFactor": 2, 997 | "legendFormat": "Storage Size", 998 | "metric": "mongo_collection_storage_size_bytes", 999 | "refId": "A", 1000 | "step": 30 1001 | }, 1002 | { 1003 | "expr": "sum(mongo_collection_size_bytes{role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"})", 1004 | "intervalFactor": 2, 1005 | "legendFormat": "Data Size", 1006 | "metric": "mongo_collection_size_bytes", 1007 | "refId": "B", 1008 | "step": 30 1009 | } 1010 | ], 1011 | "thresholds": [], 1012 | "timeFrom": null, 1013 | "timeShift": null, 1014 | "title": "DB Storage", 1015 | "tooltip": { 1016 | "msResolution": false, 1017 | "shared": true, 1018 | "sort": 0, 1019 | "value_type": "cumulative" 1020 | }, 1021 | "type": "graph", 1022 | "xaxis": { 1023 | "mode": "time", 1024 | "name": null, 1025 | "show": true, 1026 | "values": [] 1027 | }, 1028 | "yaxes": [ 1029 | { 1030 | "format": "bytes", 1031 | "label": null, 1032 | "logBase": 1, 1033 | "max": null, 1034 | "min": null, 1035 | "show": true 1036 | }, 1037 | { 1038 | "format": "short", 1039 | "label": null, 1040 | "logBase": 1, 1041 | "max": null, 1042 | "min": null, 1043 | "show": true 1044 | } 1045 | ] 1046 | }, 1047 | { 1048 | "aliasColors": {}, 1049 | "bars": false, 1050 | "datasource": "${DS_PROMETHEUS}", 1051 | "decimals": 0, 1052 | "editable": true, 1053 | "error": false, 1054 | "fill": 1, 1055 | "grid": {}, 1056 | "id": 10, 1057 | "legend": { 1058 | "alignAsTable": true, 1059 | "avg": false, 1060 | "current": true, 1061 | "max": false, 1062 | "min": false, 1063 | "rightSide": true, 1064 | "show": true, 1065 | "sideWidth": 400, 1066 | "total": false, 1067 | "values": true 1068 | }, 1069 | "lines": true, 1070 | "linewidth": 2, 1071 | "links": [], 1072 | "nullPointMode": "connected", 1073 | "percentage": false, 1074 | "pointradius": 5, 1075 | "points": false, 1076 | "renderer": "flot", 1077 | "seriesOverrides": [], 1078 | "span": 12, 1079 | "stack": false, 1080 | "steppedLine": false, 1081 | "targets": [ 1082 | { 1083 | "expr": "sum(mongo_connections_current{role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"})", 1084 | "intervalFactor": 2, 1085 | "legendFormat": "Current", 1086 | "metric": "mongo_connections_current", 1087 | "refId": "A", 1088 | "step": 30 1089 | } 1090 | ], 1091 | "thresholds": [], 1092 | "timeFrom": null, 1093 | "timeShift": null, 1094 | "title": "Connections", 1095 | "tooltip": { 1096 | "msResolution": false, 1097 | "shared": true, 1098 | "sort": 0, 1099 | "value_type": "cumulative" 1100 | }, 1101 | "type": "graph", 1102 | "xaxis": { 1103 | "mode": "time", 1104 | "name": null, 1105 | "show": true, 1106 | "values": [] 1107 | }, 1108 | "yaxes": [ 1109 | { 1110 | "format": "none", 1111 | "label": null, 1112 | "logBase": 1, 1113 | "max": null, 1114 | "min": null, 1115 | "show": true 1116 | }, 1117 | { 1118 | "format": "short", 1119 | "label": null, 1120 | "logBase": 1, 1121 | "max": null, 1122 | "min": null, 1123 | "show": true 1124 | } 1125 | ] 1126 | }, 1127 | { 1128 | "aliasColors": {}, 1129 | "bars": false, 1130 | "datasource": "${DS_PROMETHEUS}", 1131 | "decimals": 0, 1132 | "editable": true, 1133 | "error": false, 1134 | "fill": 1, 1135 | "grid": {}, 1136 | "id": 11, 1137 | "legend": { 1138 | "alignAsTable": true, 1139 | "avg": false, 1140 | "current": true, 1141 | "max": false, 1142 | "min": false, 1143 | "rightSide": true, 1144 | "show": true, 1145 | "sideWidth": 400, 1146 | "total": false, 1147 | "values": true 1148 | }, 1149 | "lines": true, 1150 | "linewidth": 2, 1151 | "links": [], 1152 | "nullPointMode": "connected", 1153 | "percentage": false, 1154 | "pointradius": 5, 1155 | "points": false, 1156 | "renderer": "flot", 1157 | "seriesOverrides": [], 1158 | "span": 12, 1159 | "stack": false, 1160 | "steppedLine": false, 1161 | "targets": [ 1162 | { 1163 | "expr": "sum(rate(mongo_asserts{role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"}[$scale])) by (type)", 1164 | "intervalFactor": 2, 1165 | "legendFormat": "{{type}}", 1166 | "metric": "mongo_asserts", 1167 | "refId": "A", 1168 | "step": 30 1169 | } 1170 | ], 1171 | "thresholds": [], 1172 | "timeFrom": null, 1173 | "timeShift": null, 1174 | "title": "Asserts", 1175 | "tooltip": { 1176 | "msResolution": false, 1177 | "shared": true, 1178 | "sort": 0, 1179 | "value_type": "cumulative" 1180 | }, 1181 | "type": "graph", 1182 | "xaxis": { 1183 | "mode": "time", 1184 | "name": null, 1185 | "show": true, 1186 | "values": [] 1187 | }, 1188 | "yaxes": [ 1189 | { 1190 | "format": "none", 1191 | "label": null, 1192 | "logBase": 1, 1193 | "max": null, 1194 | "min": null, 1195 | "show": true 1196 | }, 1197 | { 1198 | "format": "short", 1199 | "label": null, 1200 | "logBase": 1, 1201 | "max": null, 1202 | "min": null, 1203 | "show": true 1204 | } 1205 | ] 1206 | }, 1207 | { 1208 | "aliasColors": {}, 1209 | "bars": false, 1210 | "datasource": "${DS_PROMETHEUS}", 1211 | "decimals": 0, 1212 | "editable": true, 1213 | "error": false, 1214 | "fill": 1, 1215 | "grid": {}, 1216 | "id": 12, 1217 | "legend": { 1218 | "alignAsTable": true, 1219 | "avg": true, 1220 | "current": true, 1221 | "max": true, 1222 | "min": true, 1223 | "rightSide": true, 1224 | "show": true, 1225 | "sideWidth": 400, 1226 | "total": false, 1227 | "values": true 1228 | }, 1229 | "lines": true, 1230 | "linewidth": 2, 1231 | "links": [], 1232 | "nullPointMode": "connected", 1233 | "percentage": false, 1234 | "pointradius": 5, 1235 | "points": false, 1236 | "renderer": "flot", 1237 | "seriesOverrides": [], 1238 | "span": 12, 1239 | "stack": false, 1240 | "steppedLine": false, 1241 | "targets": [ 1242 | { 1243 | "expr": "avg(mongo_wt_concurrent_transactions_read_available{role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"})", 1244 | "intervalFactor": 2, 1245 | "legendFormat": "Read Tickets Used", 1246 | "metric": "mongo_wt_concurrent_transactions_read_available", 1247 | "refId": "A", 1248 | "step": 30 1249 | }, 1250 | { 1251 | "expr": "avg(mongo_wt_concurrent_transactions_write_available{role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"})", 1252 | "intervalFactor": 2, 1253 | "legendFormat": "Write Tickets Used", 1254 | "metric": "mongo_wt_concurrent_transactions_write_available", 1255 | "refId": "B", 1256 | "step": 30 1257 | } 1258 | ], 1259 | "thresholds": [], 1260 | "timeFrom": null, 1261 | "timeShift": null, 1262 | "title": "Tickets Available", 1263 | "tooltip": { 1264 | "msResolution": false, 1265 | "shared": true, 1266 | "sort": 0, 1267 | "value_type": "cumulative" 1268 | }, 1269 | "type": "graph", 1270 | "xaxis": { 1271 | "mode": "time", 1272 | "name": null, 1273 | "show": true, 1274 | "values": [] 1275 | }, 1276 | "yaxes": [ 1277 | { 1278 | "format": "none", 1279 | "label": null, 1280 | "logBase": 1, 1281 | "max": null, 1282 | "min": null, 1283 | "show": true 1284 | }, 1285 | { 1286 | "format": "short", 1287 | "label": null, 1288 | "logBase": 1, 1289 | "max": null, 1290 | "min": null, 1291 | "show": true 1292 | } 1293 | ] 1294 | }, 1295 | { 1296 | "aliasColors": {}, 1297 | "bars": false, 1298 | "datasource": "${DS_PROMETHEUS}", 1299 | "decimals": 0, 1300 | "editable": true, 1301 | "error": false, 1302 | "fill": 1, 1303 | "grid": {}, 1304 | "id": 13, 1305 | "legend": { 1306 | "alignAsTable": true, 1307 | "avg": true, 1308 | "current": true, 1309 | "max": true, 1310 | "min": true, 1311 | "rightSide": true, 1312 | "show": true, 1313 | "sideWidth": 400, 1314 | "total": false, 1315 | "values": true 1316 | }, 1317 | "lines": true, 1318 | "linewidth": 2, 1319 | "links": [], 1320 | "nullPointMode": "connected", 1321 | "percentage": false, 1322 | "pointradius": 5, 1323 | "points": false, 1324 | "renderer": "flot", 1325 | "seriesOverrides": [], 1326 | "span": 12, 1327 | "stack": false, 1328 | "steppedLine": false, 1329 | "targets": [ 1330 | { 1331 | "expr": "sum(mongo_wt_cache_used_bytes{coll=\"\", role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"})", 1332 | "intervalFactor": 2, 1333 | "legendFormat": "Cache Usage", 1334 | "metric": "mongo_wt_cache_used_bytes", 1335 | "refId": "A", 1336 | "step": 30 1337 | } 1338 | ], 1339 | "thresholds": [], 1340 | "timeFrom": null, 1341 | "timeShift": null, 1342 | "title": "Cache Usage", 1343 | "tooltip": { 1344 | "msResolution": false, 1345 | "shared": true, 1346 | "sort": 0, 1347 | "value_type": "cumulative" 1348 | }, 1349 | "type": "graph", 1350 | "xaxis": { 1351 | "mode": "time", 1352 | "name": null, 1353 | "show": true, 1354 | "values": [] 1355 | }, 1356 | "yaxes": [ 1357 | { 1358 | "format": "bytes", 1359 | "label": null, 1360 | "logBase": 1, 1361 | "max": null, 1362 | "min": null, 1363 | "show": true 1364 | }, 1365 | { 1366 | "format": "short", 1367 | "label": null, 1368 | "logBase": 1, 1369 | "max": null, 1370 | "min": null, 1371 | "show": true 1372 | } 1373 | ] 1374 | }, 1375 | { 1376 | "aliasColors": {}, 1377 | "bars": false, 1378 | "datasource": "${DS_PROMETHEUS}", 1379 | "decimals": 0, 1380 | "editable": true, 1381 | "error": false, 1382 | "fill": 1, 1383 | "grid": {}, 1384 | "id": 14, 1385 | "legend": { 1386 | "alignAsTable": true, 1387 | "avg": true, 1388 | "current": true, 1389 | "max": true, 1390 | "min": true, 1391 | "rightSide": true, 1392 | "show": true, 1393 | "sideWidth": 400, 1394 | "total": false, 1395 | "values": true 1396 | }, 1397 | "lines": true, 1398 | "linewidth": 2, 1399 | "links": [], 1400 | "nullPointMode": "connected", 1401 | "percentage": false, 1402 | "pointradius": 5, 1403 | "points": false, 1404 | "renderer": "flot", 1405 | "seriesOverrides": [], 1406 | "span": 12, 1407 | "stack": false, 1408 | "steppedLine": false, 1409 | "targets": [ 1410 | { 1411 | "expr": "sum(rate(mongo_wt_cache_read_into_bytes{coll=\"\", role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"}[$scale]))", 1412 | "intervalFactor": 2, 1413 | "legendFormat": "Read Into", 1414 | "metric": "mongo_wt_cache_read_into_bytes", 1415 | "refId": "A", 1416 | "step": 30 1417 | }, 1418 | { 1419 | "expr": "sum(rate(mongo_wt_cache_written_from_bytes{coll=\"\", role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"}[$scale]))", 1420 | "intervalFactor": 2, 1421 | "legendFormat": "Write From", 1422 | "metric": "mongo_wt_cache_written_from_bytes", 1423 | "refId": "B", 1424 | "step": 30 1425 | } 1426 | ], 1427 | "thresholds": [], 1428 | "timeFrom": null, 1429 | "timeShift": null, 1430 | "title": "Cache Activity", 1431 | "tooltip": { 1432 | "msResolution": false, 1433 | "shared": true, 1434 | "sort": 0, 1435 | "value_type": "cumulative" 1436 | }, 1437 | "type": "graph", 1438 | "xaxis": { 1439 | "mode": "time", 1440 | "name": null, 1441 | "show": true, 1442 | "values": [] 1443 | }, 1444 | "yaxes": [ 1445 | { 1446 | "format": "bytes", 1447 | "label": null, 1448 | "logBase": 1, 1449 | "max": null, 1450 | "min": null, 1451 | "show": true 1452 | }, 1453 | { 1454 | "format": "short", 1455 | "label": null, 1456 | "logBase": 1, 1457 | "max": null, 1458 | "min": null, 1459 | "show": true 1460 | } 1461 | ] 1462 | }, 1463 | { 1464 | "aliasColors": {}, 1465 | "bars": false, 1466 | "datasource": "${DS_PROMETHEUS}", 1467 | "decimals": 0, 1468 | "editable": true, 1469 | "error": false, 1470 | "fill": 1, 1471 | "grid": {}, 1472 | "id": 15, 1473 | "legend": { 1474 | "alignAsTable": true, 1475 | "avg": true, 1476 | "current": true, 1477 | "max": true, 1478 | "min": true, 1479 | "rightSide": true, 1480 | "show": true, 1481 | "sideWidth": 400, 1482 | "total": false, 1483 | "values": true 1484 | }, 1485 | "lines": true, 1486 | "linewidth": 2, 1487 | "links": [], 1488 | "nullPointMode": "connected", 1489 | "percentage": false, 1490 | "pointradius": 5, 1491 | "points": false, 1492 | "renderer": "flot", 1493 | "seriesOverrides": [], 1494 | "span": 12, 1495 | "stack": false, 1496 | "steppedLine": false, 1497 | "targets": [ 1498 | { 1499 | "expr": "sum(rate(mongo_metrics_documents{role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"}[$scale])) by (op)", 1500 | "intervalFactor": 2, 1501 | "legendFormat": "{{op}}", 1502 | "metric": "mongo_metrics_documents", 1503 | "refId": "A", 1504 | "step": 30 1505 | } 1506 | ], 1507 | "thresholds": [], 1508 | "timeFrom": null, 1509 | "timeShift": null, 1510 | "title": "Documents Metrics", 1511 | "tooltip": { 1512 | "msResolution": false, 1513 | "shared": true, 1514 | "sort": 0, 1515 | "value_type": "cumulative" 1516 | }, 1517 | "type": "graph", 1518 | "xaxis": { 1519 | "mode": "time", 1520 | "name": null, 1521 | "show": true, 1522 | "values": [] 1523 | }, 1524 | "yaxes": [ 1525 | { 1526 | "format": "bytes", 1527 | "label": null, 1528 | "logBase": 1, 1529 | "max": null, 1530 | "min": null, 1531 | "show": true 1532 | }, 1533 | { 1534 | "format": "short", 1535 | "label": null, 1536 | "logBase": 1, 1537 | "max": null, 1538 | "min": null, 1539 | "show": true 1540 | } 1541 | ] 1542 | }, 1543 | { 1544 | "aliasColors": {}, 1545 | "bars": false, 1546 | "datasource": "${DS_PROMETHEUS}", 1547 | "decimals": 1, 1548 | "editable": true, 1549 | "error": false, 1550 | "fill": 1, 1551 | "grid": {}, 1552 | "id": 16, 1553 | "legend": { 1554 | "alignAsTable": true, 1555 | "avg": true, 1556 | "current": true, 1557 | "max": true, 1558 | "min": true, 1559 | "rightSide": true, 1560 | "show": true, 1561 | "sideWidth": 400, 1562 | "total": false, 1563 | "values": true 1564 | }, 1565 | "lines": true, 1566 | "linewidth": 2, 1567 | "links": [], 1568 | "nullPointMode": "connected", 1569 | "percentage": false, 1570 | "pointradius": 5, 1571 | "points": false, 1572 | "renderer": "flot", 1573 | "seriesOverrides": [], 1574 | "span": 12, 1575 | "stack": false, 1576 | "steppedLine": false, 1577 | "targets": [ 1578 | { 1579 | "expr": "sum(rate(mongo_query_documents_scanned_total{role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"}[$scale]))", 1580 | "intervalFactor": 2, 1581 | "legendFormat": "Documents Scanned", 1582 | "metric": "mongo_query_documents_scanned_total", 1583 | "refId": "A", 1584 | "step": 30 1585 | }, 1586 | { 1587 | "expr": "sum(rate(mongo_query_index_scanned_total{role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"}[$scale]))", 1588 | "intervalFactor": 2, 1589 | "legendFormat": "Index Scanned", 1590 | "metric": "mongo_query_index_scanned_total", 1591 | "refId": "B", 1592 | "step": 30 1593 | } 1594 | ], 1595 | "thresholds": [], 1596 | "timeFrom": null, 1597 | "timeShift": null, 1598 | "title": "Query Executor", 1599 | "tooltip": { 1600 | "msResolution": false, 1601 | "shared": true, 1602 | "sort": 0, 1603 | "value_type": "cumulative" 1604 | }, 1605 | "type": "graph", 1606 | "xaxis": { 1607 | "mode": "time", 1608 | "name": null, 1609 | "show": true, 1610 | "values": [] 1611 | }, 1612 | "yaxes": [ 1613 | { 1614 | "format": "none", 1615 | "label": null, 1616 | "logBase": 1, 1617 | "max": null, 1618 | "min": null, 1619 | "show": true 1620 | }, 1621 | { 1622 | "format": "short", 1623 | "label": null, 1624 | "logBase": 1, 1625 | "max": null, 1626 | "min": null, 1627 | "show": true 1628 | } 1629 | ] 1630 | }, 1631 | { 1632 | "aliasColors": {}, 1633 | "bars": false, 1634 | "datasource": "${DS_PROMETHEUS}", 1635 | "decimals": 1, 1636 | "editable": true, 1637 | "error": false, 1638 | "fill": 1, 1639 | "grid": {}, 1640 | "id": 17, 1641 | "legend": { 1642 | "alignAsTable": true, 1643 | "avg": true, 1644 | "current": true, 1645 | "max": true, 1646 | "min": true, 1647 | "rightSide": true, 1648 | "show": true, 1649 | "sideWidth": 400, 1650 | "total": false, 1651 | "values": true 1652 | }, 1653 | "lines": true, 1654 | "linewidth": 2, 1655 | "links": [], 1656 | "nullPointMode": "connected", 1657 | "percentage": false, 1658 | "pointradius": 5, 1659 | "points": false, 1660 | "renderer": "flot", 1661 | "seriesOverrides": [], 1662 | "span": 12, 1663 | "stack": false, 1664 | "steppedLine": false, 1665 | "targets": [ 1666 | { 1667 | "expr": "sum(rate(mongo_query_documents_scanned_total{role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"}[$scale])) / sum(rate(mongo_metrics_documents{role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\", op=\"returned\"}[$scale]))", 1668 | "intervalFactor": 2, 1669 | "legendFormat": "Documents Scanned / Returned", 1670 | "metric": "mongo_query_documents_scanned_total", 1671 | "refId": "A", 1672 | "step": 30 1673 | }, 1674 | { 1675 | "expr": "sum(rate(mongo_query_index_scanned_total{role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\"}[$scale])) / sum(rate(mongo_metrics_documents{role=~\"$role\", rs=~\"$rs\", instance=~\"$instance\", op=\"returned\"}[$scale]))", 1676 | "intervalFactor": 2, 1677 | "legendFormat": "Index Scanned / Returned", 1678 | "metric": "mongo_query_index_scanned_total", 1679 | "refId": "B", 1680 | "step": 30 1681 | } 1682 | ], 1683 | "thresholds": [], 1684 | "timeFrom": null, 1685 | "timeShift": null, 1686 | "title": "Query Targeting", 1687 | "tooltip": { 1688 | "msResolution": false, 1689 | "shared": true, 1690 | "sort": 0, 1691 | "value_type": "cumulative" 1692 | }, 1693 | "type": "graph", 1694 | "xaxis": { 1695 | "mode": "time", 1696 | "name": null, 1697 | "show": true, 1698 | "values": [] 1699 | }, 1700 | "yaxes": [ 1701 | { 1702 | "format": "none", 1703 | "label": null, 1704 | "logBase": 1, 1705 | "max": null, 1706 | "min": null, 1707 | "show": true 1708 | }, 1709 | { 1710 | "format": "short", 1711 | "label": null, 1712 | "logBase": 1, 1713 | "max": null, 1714 | "min": null, 1715 | "show": true 1716 | } 1717 | ] 1718 | } 1719 | ], 1720 | "showTitle": false, 1721 | "titleSize": "h6", 1722 | "height": "150px", 1723 | "repeat": null, 1724 | "repeatRowId": null, 1725 | "repeatIteration": null, 1726 | "collapse": false 1727 | } 1728 | ] 1729 | } 1730 | -------------------------------------------------------------------------------- /vendor/grafana/mongo_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "__inputs": [ 3 | { 4 | "name": "DS_PROMETHEUS", 5 | "label": "prometheus", 6 | "description": "", 7 | "type": "datasource", 8 | "pluginId": "prometheus", 9 | "pluginName": "Prometheus" 10 | } 11 | ], 12 | "__requires": [ 13 | { 14 | "type": "grafana", 15 | "id": "grafana", 16 | "name": "Grafana", 17 | "version": "4.2.0" 18 | }, 19 | { 20 | "type": "panel", 21 | "id": "graph", 22 | "name": "Graph", 23 | "version": "" 24 | }, 25 | { 26 | "type": "datasource", 27 | "id": "prometheus", 28 | "name": "Prometheus", 29 | "version": "1.0.0" 30 | } 31 | ], 32 | "annotations": { 33 | "list": [] 34 | }, 35 | "editable": true, 36 | "gnetId": null, 37 | "graphTooltip": 1, 38 | "hideControls": false, 39 | "id": null, 40 | "links": [], 41 | "refresh": "1m", 42 | "rows": [ 43 | { 44 | "collapse": false, 45 | "height": 250, 46 | "panels": [ 47 | { 48 | "aliasColors": {}, 49 | "bars": false, 50 | "datasource": "${DS_PROMETHEUS}", 51 | "decimals": 0, 52 | "editable": true, 53 | "error": false, 54 | "fill": 1, 55 | "id": 14, 56 | "legend": { 57 | "alignAsTable": true, 58 | "avg": false, 59 | "current": true, 60 | "hideEmpty": true, 61 | "hideZero": true, 62 | "max": false, 63 | "min": false, 64 | "rightSide": true, 65 | "show": true, 66 | "sort": "current", 67 | "sortDesc": false, 68 | "total": false, 69 | "values": true 70 | }, 71 | "lines": true, 72 | "linewidth": 1, 73 | "links": [], 74 | "nullPointMode": "null", 75 | "percentage": false, 76 | "pointradius": 5, 77 | "points": false, 78 | "renderer": "flot", 79 | "seriesOverrides": [], 80 | "span": 12, 81 | "stack": false, 82 | "steppedLine": true, 83 | "targets": [ 84 | { 85 | "expr": "topk($topk, sum(rate(mongo_wt_cache_read_into_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\", idx=~\"\", coll=~\".+\"}[$scale])) by (db, coll))", 86 | "interval": "", 87 | "intervalFactor": 2, 88 | "legendFormat": "R/I {{db}}.{{coll}}", 89 | "metric": "mongo_wt_cache_read_into_bytes", 90 | "refId": "A", 91 | "step": 20 92 | }, 93 | { 94 | "expr": "-topk($topk, sum(rate(mongo_wt_cache_written_from_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\", idx=~\"\", coll=~\".+\"}[$scale])) by (db, coll))", 95 | "interval": "", 96 | "intervalFactor": 2, 97 | "legendFormat": "W/F {{db}}.{{coll}}", 98 | "metric": "mongo_wt_cache_written_from_bytes", 99 | "refId": "B", 100 | "step": 20 101 | } 102 | ], 103 | "thresholds": [ 104 | { 105 | "colorMode": "critical", 106 | "fill": true, 107 | "line": true, 108 | "op": "gt" 109 | } 110 | ], 111 | "timeFrom": null, 112 | "timeShift": null, 113 | "title": "WT Cache Collection Activity (Bytes/s)", 114 | "tooltip": { 115 | "msResolution": false, 116 | "shared": true, 117 | "sort": 2, 118 | "value_type": "individual" 119 | }, 120 | "type": "graph", 121 | "xaxis": { 122 | "mode": "time", 123 | "name": null, 124 | "show": true, 125 | "values": [ 126 | "total" 127 | ] 128 | }, 129 | "yaxes": [ 130 | { 131 | "format": "Bps", 132 | "label": "", 133 | "logBase": 1, 134 | "max": null, 135 | "min": null, 136 | "show": true 137 | }, 138 | { 139 | "format": "short", 140 | "label": null, 141 | "logBase": 1, 142 | "max": null, 143 | "min": null, 144 | "show": true 145 | } 146 | ] 147 | } 148 | ], 149 | "repeat": null, 150 | "repeatIteration": null, 151 | "repeatRowId": null, 152 | "showTitle": false, 153 | "title": "WT Cache Activity (Coll)", 154 | "titleSize": "h6" 155 | }, 156 | { 157 | "collapse": false, 158 | "height": "600", 159 | "panels": [ 160 | { 161 | "aliasColors": {}, 162 | "bars": false, 163 | "datasource": "${DS_PROMETHEUS}", 164 | "decimals": 0, 165 | "editable": true, 166 | "error": false, 167 | "fill": 1, 168 | "id": 13, 169 | "legend": { 170 | "alignAsTable": true, 171 | "avg": false, 172 | "current": true, 173 | "hideEmpty": true, 174 | "hideZero": true, 175 | "max": false, 176 | "min": false, 177 | "rightSide": false, 178 | "show": true, 179 | "sideWidth": 100, 180 | "sort": "current", 181 | "sortDesc": false, 182 | "total": false, 183 | "values": true 184 | }, 185 | "lines": true, 186 | "linewidth": 1, 187 | "links": [], 188 | "nullPointMode": "null", 189 | "percentage": false, 190 | "pointradius": 5, 191 | "points": false, 192 | "renderer": "flot", 193 | "seriesOverrides": [], 194 | "span": 12, 195 | "stack": false, 196 | "steppedLine": true, 197 | "targets": [ 198 | { 199 | "expr": "topk($topk, sum(rate(mongo_wt_cache_read_into_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\", idx=~\".+\"}[$scale])) by (db, coll, idx))", 200 | "interval": "", 201 | "intervalFactor": 2, 202 | "legendFormat": "In {{db}}.{{coll}} ({{idx}})", 203 | "metric": "mongo_wt_cache_read_into_bytes", 204 | "refId": "A", 205 | "step": 20 206 | }, 207 | { 208 | "expr": "-topk($topk, sum(rate(mongo_wt_cache_written_from_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\", idx=~\".+\"}[$scale])) by (db, coll, idx))", 209 | "interval": "", 210 | "intervalFactor": 2, 211 | "legendFormat": "Out {{db}}.{{coll}} ({{idx}})", 212 | "metric": "mongo_wt_cache_written_from_bytes", 213 | "refId": "B", 214 | "step": 20 215 | } 216 | ], 217 | "thresholds": [], 218 | "timeFrom": null, 219 | "timeShift": null, 220 | "title": "WT Cache Index Activity (Bytes/s)", 221 | "tooltip": { 222 | "msResolution": false, 223 | "shared": true, 224 | "sort": 2, 225 | "value_type": "individual" 226 | }, 227 | "type": "graph", 228 | "xaxis": { 229 | "mode": "time", 230 | "name": null, 231 | "show": true, 232 | "values": [] 233 | }, 234 | "yaxes": [ 235 | { 236 | "format": "Bps", 237 | "label": null, 238 | "logBase": 1, 239 | "max": null, 240 | "min": null, 241 | "show": true 242 | }, 243 | { 244 | "format": "short", 245 | "label": null, 246 | "logBase": 1, 247 | "max": null, 248 | "min": null, 249 | "show": true 250 | } 251 | ] 252 | } 253 | ], 254 | "repeat": null, 255 | "repeatIteration": null, 256 | "repeatRowId": null, 257 | "showTitle": false, 258 | "title": "WT Cache Usage (idx)", 259 | "titleSize": "h6" 260 | }, 261 | { 262 | "collapse": false, 263 | "height": 250, 264 | "panels": [ 265 | { 266 | "aliasColors": {}, 267 | "bars": false, 268 | "datasource": "${DS_PROMETHEUS}", 269 | "decimals": 0, 270 | "editable": true, 271 | "error": false, 272 | "fill": 1, 273 | "id": 15, 274 | "legend": { 275 | "alignAsTable": true, 276 | "avg": false, 277 | "current": true, 278 | "hideEmpty": true, 279 | "hideZero": true, 280 | "max": false, 281 | "min": false, 282 | "rightSide": true, 283 | "show": true, 284 | "sort": null, 285 | "sortDesc": null, 286 | "total": false, 287 | "values": true 288 | }, 289 | "lines": true, 290 | "linewidth": 1, 291 | "links": [], 292 | "nullPointMode": "connected", 293 | "percentage": false, 294 | "pointradius": 5, 295 | "points": false, 296 | "renderer": "flot", 297 | "seriesOverrides": [], 298 | "span": 12, 299 | "stack": true, 300 | "steppedLine": false, 301 | "targets": [ 302 | { 303 | "expr": "topk($topk, sum(delta(mongo_collection_count{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\"}[$scale])) by (db, coll))", 304 | "intervalFactor": 2, 305 | "legendFormat": "{{db}}.{{coll}}", 306 | "metric": "", 307 | "refId": "A", 308 | "step": 20 309 | } 310 | ], 311 | "thresholds": [], 312 | "timeFrom": null, 313 | "timeShift": null, 314 | "title": "Documents Rate ($scale)", 315 | "tooltip": { 316 | "msResolution": false, 317 | "shared": true, 318 | "sort": 2, 319 | "value_type": "individual" 320 | }, 321 | "type": "graph", 322 | "xaxis": { 323 | "mode": "time", 324 | "name": null, 325 | "show": true, 326 | "values": [] 327 | }, 328 | "yaxes": [ 329 | { 330 | "format": "short", 331 | "label": null, 332 | "logBase": 1, 333 | "max": null, 334 | "min": null, 335 | "show": true 336 | }, 337 | { 338 | "format": "short", 339 | "label": null, 340 | "logBase": 1, 341 | "max": null, 342 | "min": null, 343 | "show": true 344 | } 345 | ] 346 | } 347 | ], 348 | "repeat": null, 349 | "repeatIteration": null, 350 | "repeatRowId": null, 351 | "showTitle": false, 352 | "title": "Documents Rate", 353 | "titleSize": "h6" 354 | }, 355 | { 356 | "collapse": false, 357 | "height": 417, 358 | "panels": [ 359 | { 360 | "aliasColors": {}, 361 | "bars": false, 362 | "datasource": "${DS_PROMETHEUS}", 363 | "decimals": 0, 364 | "editable": true, 365 | "error": false, 366 | "fill": 1, 367 | "id": 20, 368 | "legend": { 369 | "alignAsTable": true, 370 | "avg": true, 371 | "current": true, 372 | "hideEmpty": true, 373 | "hideZero": true, 374 | "max": true, 375 | "min": true, 376 | "rightSide": false, 377 | "show": true, 378 | "sort": "current", 379 | "sortDesc": true, 380 | "total": false, 381 | "values": true 382 | }, 383 | "lines": true, 384 | "linewidth": 1, 385 | "links": [], 386 | "nullPointMode": "connected", 387 | "percentage": false, 388 | "pointradius": 5, 389 | "points": false, 390 | "renderer": "flot", 391 | "seriesOverrides": [], 392 | "span": 12, 393 | "stack": true, 394 | "steppedLine": false, 395 | "targets": [ 396 | { 397 | "expr": "sum(delta(mongo_wt_cache_used_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\", idx=~\"\", coll=~\".+\"}[$scale])) by (db, coll)", 398 | "intervalFactor": 2, 399 | "legendFormat": "{{db}}.{{coll}}", 400 | "metric": "mongo_wt_cache_read_into_bytes", 401 | "refId": "A", 402 | "step": 20 403 | } 404 | ], 405 | "thresholds": [], 406 | "timeFrom": null, 407 | "timeShift": null, 408 | "title": "WT Cache Usage Rate by Collections (Bytes/s)", 409 | "tooltip": { 410 | "msResolution": false, 411 | "shared": true, 412 | "sort": 2, 413 | "value_type": "individual" 414 | }, 415 | "type": "graph", 416 | "xaxis": { 417 | "mode": "time", 418 | "name": null, 419 | "show": true, 420 | "values": [] 421 | }, 422 | "yaxes": [ 423 | { 424 | "format": "decbytes", 425 | "label": null, 426 | "logBase": 1, 427 | "max": null, 428 | "min": null, 429 | "show": true 430 | }, 431 | { 432 | "format": "short", 433 | "label": null, 434 | "logBase": 1, 435 | "max": null, 436 | "min": null, 437 | "show": true 438 | } 439 | ] 440 | } 441 | ], 442 | "repeat": null, 443 | "repeatIteration": null, 444 | "repeatRowId": null, 445 | "showTitle": false, 446 | "title": "WT Cache Usage (Coll)", 447 | "titleSize": "h6" 448 | }, 449 | { 450 | "collapse": false, 451 | "height": 452, 452 | "panels": [ 453 | { 454 | "aliasColors": {}, 455 | "bars": false, 456 | "datasource": "${DS_PROMETHEUS}", 457 | "decimals": 0, 458 | "editable": true, 459 | "error": false, 460 | "fill": 1, 461 | "id": 21, 462 | "legend": { 463 | "alignAsTable": true, 464 | "avg": true, 465 | "current": true, 466 | "hideEmpty": true, 467 | "hideZero": true, 468 | "max": true, 469 | "min": true, 470 | "rightSide": false, 471 | "show": true, 472 | "sort": "current", 473 | "sortDesc": true, 474 | "total": false, 475 | "values": true 476 | }, 477 | "lines": true, 478 | "linewidth": 1, 479 | "links": [], 480 | "nullPointMode": "connected", 481 | "percentage": false, 482 | "pointradius": 5, 483 | "points": false, 484 | "renderer": "flot", 485 | "seriesOverrides": [], 486 | "span": 12, 487 | "stack": true, 488 | "steppedLine": false, 489 | "targets": [ 490 | { 491 | "expr": "sum(delta(mongo_wt_cache_used_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\", idx=~\".+\"}[$scale])) by (db, coll, idx)", 492 | "interval": "", 493 | "intervalFactor": 2, 494 | "legendFormat": "{{db}}.{{coll}} ({{idx}})", 495 | "metric": "mongo_wt_cache_read_into_bytes", 496 | "refId": "A", 497 | "step": 20 498 | } 499 | ], 500 | "thresholds": [], 501 | "timeFrom": null, 502 | "timeShift": null, 503 | "title": "WT Cache Usage Rate by Indexes (Bytes/$scale)", 504 | "tooltip": { 505 | "msResolution": false, 506 | "shared": true, 507 | "sort": 2, 508 | "value_type": "individual" 509 | }, 510 | "type": "graph", 511 | "xaxis": { 512 | "mode": "time", 513 | "name": null, 514 | "show": true, 515 | "values": [] 516 | }, 517 | "yaxes": [ 518 | { 519 | "format": "decbytes", 520 | "label": null, 521 | "logBase": 1, 522 | "max": null, 523 | "min": null, 524 | "show": true 525 | }, 526 | { 527 | "format": "short", 528 | "label": null, 529 | "logBase": 1, 530 | "max": null, 531 | "min": null, 532 | "show": true 533 | } 534 | ] 535 | } 536 | ], 537 | "repeat": null, 538 | "repeatIteration": null, 539 | "repeatRowId": null, 540 | "showTitle": false, 541 | "title": "Dashboard Row", 542 | "titleSize": "h6" 543 | }, 544 | { 545 | "collapse": false, 546 | "height": 250, 547 | "panels": [ 548 | { 549 | "aliasColors": {}, 550 | "bars": false, 551 | "datasource": "${DS_PROMETHEUS}", 552 | "decimals": 0, 553 | "editable": true, 554 | "error": false, 555 | "fill": 1, 556 | "id": 6, 557 | "legend": { 558 | "alignAsTable": true, 559 | "avg": false, 560 | "current": true, 561 | "max": false, 562 | "min": false, 563 | "rightSide": true, 564 | "show": true, 565 | "sort": "current", 566 | "sortDesc": true, 567 | "total": false, 568 | "values": true 569 | }, 570 | "lines": true, 571 | "linewidth": 1, 572 | "links": [], 573 | "nullPointMode": "connected", 574 | "percentage": false, 575 | "pointradius": 5, 576 | "points": false, 577 | "renderer": "flot", 578 | "seriesOverrides": [], 579 | "span": 12, 580 | "stack": true, 581 | "steppedLine": false, 582 | "targets": [ 583 | { 584 | "expr": "avg(mongo_wt_cache_used_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\", idx=~\"\", coll=~\".+\"}) by (db, coll)", 585 | "intervalFactor": 2, 586 | "legendFormat": "{{db}}.{{coll}}", 587 | "metric": "mongo_wt_cache_read_into_bytes", 588 | "refId": "A", 589 | "step": 20 590 | } 591 | ], 592 | "thresholds": [], 593 | "timeFrom": null, 594 | "timeShift": null, 595 | "title": "WT Cache Used by Collections (Bytes)", 596 | "tooltip": { 597 | "msResolution": false, 598 | "shared": true, 599 | "sort": 2, 600 | "value_type": "individual" 601 | }, 602 | "type": "graph", 603 | "xaxis": { 604 | "mode": "time", 605 | "name": null, 606 | "show": true, 607 | "values": [] 608 | }, 609 | "yaxes": [ 610 | { 611 | "format": "decbytes", 612 | "label": null, 613 | "logBase": 1, 614 | "max": null, 615 | "min": null, 616 | "show": true 617 | }, 618 | { 619 | "format": "short", 620 | "label": null, 621 | "logBase": 1, 622 | "max": null, 623 | "min": null, 624 | "show": true 625 | } 626 | ] 627 | } 628 | ], 629 | "repeat": null, 630 | "repeatIteration": null, 631 | "repeatRowId": null, 632 | "showTitle": false, 633 | "title": "Dashboard Row", 634 | "titleSize": "h6" 635 | }, 636 | { 637 | "collapse": false, 638 | "height": 211, 639 | "panels": [ 640 | { 641 | "aliasColors": {}, 642 | "bars": false, 643 | "datasource": "${DS_PROMETHEUS}", 644 | "decimals": 0, 645 | "editable": true, 646 | "error": false, 647 | "fill": 1, 648 | "id": 12, 649 | "legend": { 650 | "alignAsTable": true, 651 | "avg": false, 652 | "current": true, 653 | "hideEmpty": true, 654 | "hideZero": true, 655 | "max": false, 656 | "min": false, 657 | "rightSide": true, 658 | "show": true, 659 | "sort": "current", 660 | "sortDesc": true, 661 | "total": false, 662 | "values": true 663 | }, 664 | "lines": true, 665 | "linewidth": 1, 666 | "links": [], 667 | "nullPointMode": "connected", 668 | "percentage": false, 669 | "pointradius": 5, 670 | "points": false, 671 | "renderer": "flot", 672 | "seriesOverrides": [], 673 | "span": 12, 674 | "stack": true, 675 | "steppedLine": false, 676 | "targets": [ 677 | { 678 | "expr": "avg(mongo_wt_cache_used_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\", idx=~\".+\"}) by (db, coll, idx)", 679 | "interval": "", 680 | "intervalFactor": 2, 681 | "legendFormat": "{{db}}.{{coll}} ({{idx}})", 682 | "metric": "mongo_wt_cache_read_into_bytes", 683 | "refId": "A", 684 | "step": 20 685 | } 686 | ], 687 | "thresholds": [], 688 | "timeFrom": null, 689 | "timeShift": null, 690 | "title": "WT Cache Used by Indexes (Bytes)", 691 | "tooltip": { 692 | "msResolution": false, 693 | "shared": true, 694 | "sort": 2, 695 | "value_type": "individual" 696 | }, 697 | "type": "graph", 698 | "xaxis": { 699 | "mode": "time", 700 | "name": null, 701 | "show": true, 702 | "values": [] 703 | }, 704 | "yaxes": [ 705 | { 706 | "format": "decbytes", 707 | "label": null, 708 | "logBase": 1, 709 | "max": null, 710 | "min": null, 711 | "show": true 712 | }, 713 | { 714 | "format": "short", 715 | "label": null, 716 | "logBase": 1, 717 | "max": null, 718 | "min": null, 719 | "show": true 720 | } 721 | ] 722 | } 723 | ], 724 | "repeat": null, 725 | "repeatIteration": null, 726 | "repeatRowId": null, 727 | "showTitle": false, 728 | "title": "WT Cache Usage (idx)", 729 | "titleSize": "h6" 730 | }, 731 | { 732 | "collapse": false, 733 | "height": 250, 734 | "panels": [ 735 | { 736 | "aliasColors": {}, 737 | "bars": false, 738 | "datasource": "${DS_PROMETHEUS}", 739 | "decimals": 2, 740 | "editable": true, 741 | "error": false, 742 | "fill": 1, 743 | "id": 2, 744 | "legend": { 745 | "alignAsTable": true, 746 | "avg": false, 747 | "current": true, 748 | "hideEmpty": true, 749 | "hideZero": true, 750 | "max": false, 751 | "min": false, 752 | "rightSide": true, 753 | "show": true, 754 | "sort": "current", 755 | "sortDesc": true, 756 | "total": false, 757 | "values": true 758 | }, 759 | "lines": true, 760 | "linewidth": 1, 761 | "links": [], 762 | "nullPointMode": "connected", 763 | "percentage": false, 764 | "pointradius": 5, 765 | "points": false, 766 | "renderer": "flot", 767 | "seriesOverrides": [], 768 | "span": 12, 769 | "stack": true, 770 | "steppedLine": false, 771 | "targets": [ 772 | { 773 | "expr": "topk($topk, avg(mongo_collection_size_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\"}) by (db, coll))", 774 | "intervalFactor": 2, 775 | "legendFormat": "{{db}}.{{coll}}", 776 | "metric": "mongo_collection_size_bytes", 777 | "refId": "A", 778 | "step": 20 779 | } 780 | ], 781 | "thresholds": [], 782 | "timeFrom": null, 783 | "timeShift": null, 784 | "title": "Real Size (Bytes)", 785 | "tooltip": { 786 | "msResolution": false, 787 | "shared": true, 788 | "sort": 2, 789 | "value_type": "individual" 790 | }, 791 | "type": "graph", 792 | "xaxis": { 793 | "mode": "time", 794 | "name": null, 795 | "show": true, 796 | "values": [] 797 | }, 798 | "yaxes": [ 799 | { 800 | "format": "decbytes", 801 | "label": null, 802 | "logBase": 1, 803 | "max": null, 804 | "min": null, 805 | "show": true 806 | }, 807 | { 808 | "format": "short", 809 | "label": null, 810 | "logBase": 1, 811 | "max": null, 812 | "min": null, 813 | "show": true 814 | } 815 | ] 816 | } 817 | ], 818 | "repeat": null, 819 | "repeatIteration": null, 820 | "repeatRowId": null, 821 | "showTitle": false, 822 | "title": "Real Size", 823 | "titleSize": "h6" 824 | }, 825 | { 826 | "collapse": false, 827 | "height": 243, 828 | "panels": [ 829 | { 830 | "aliasColors": {}, 831 | "bars": false, 832 | "datasource": "${DS_PROMETHEUS}", 833 | "decimals": 2, 834 | "editable": true, 835 | "error": false, 836 | "fill": 1, 837 | "id": 3, 838 | "legend": { 839 | "alignAsTable": true, 840 | "avg": false, 841 | "current": true, 842 | "max": false, 843 | "min": false, 844 | "rightSide": true, 845 | "show": true, 846 | "sort": "current", 847 | "sortDesc": true, 848 | "total": false, 849 | "values": true 850 | }, 851 | "lines": true, 852 | "linewidth": 1, 853 | "links": [], 854 | "nullPointMode": "connected", 855 | "percentage": false, 856 | "pointradius": 5, 857 | "points": false, 858 | "renderer": "flot", 859 | "seriesOverrides": [], 860 | "span": 12, 861 | "stack": true, 862 | "steppedLine": false, 863 | "targets": [ 864 | { 865 | "expr": "topk($topk, sum(mongo_collection_storage_size_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\"}) by (db, coll))", 866 | "intervalFactor": 2, 867 | "legendFormat": "{{db}}.{{coll}}", 868 | "metric": "mongo_collection_storage_size_bytes", 869 | "refId": "A", 870 | "step": 20 871 | } 872 | ], 873 | "thresholds": [], 874 | "timeFrom": null, 875 | "timeShift": null, 876 | "title": "On Disk Size (Bytes)", 877 | "tooltip": { 878 | "msResolution": false, 879 | "shared": true, 880 | "sort": 2, 881 | "value_type": "individual" 882 | }, 883 | "type": "graph", 884 | "xaxis": { 885 | "mode": "time", 886 | "name": null, 887 | "show": true, 888 | "values": [] 889 | }, 890 | "yaxes": [ 891 | { 892 | "format": "decbytes", 893 | "label": null, 894 | "logBase": 1, 895 | "max": null, 896 | "min": null, 897 | "show": true 898 | }, 899 | { 900 | "format": "short", 901 | "label": null, 902 | "logBase": 1, 903 | "max": null, 904 | "min": null, 905 | "show": true 906 | } 907 | ] 908 | } 909 | ], 910 | "repeat": null, 911 | "repeatIteration": null, 912 | "repeatRowId": null, 913 | "showTitle": false, 914 | "title": "On Disk Size", 915 | "titleSize": "h6" 916 | }, 917 | { 918 | "collapse": false, 919 | "height": 250, 920 | "panels": [ 921 | { 922 | "aliasColors": {}, 923 | "bars": false, 924 | "datasource": "${DS_PROMETHEUS}", 925 | "decimals": 2, 926 | "editable": true, 927 | "error": false, 928 | "fill": 1, 929 | "id": 22, 930 | "legend": { 931 | "alignAsTable": true, 932 | "avg": false, 933 | "current": true, 934 | "max": false, 935 | "min": false, 936 | "rightSide": true, 937 | "show": true, 938 | "sort": "current", 939 | "sortDesc": true, 940 | "total": false, 941 | "values": true 942 | }, 943 | "lines": true, 944 | "linewidth": 1, 945 | "links": [], 946 | "nullPointMode": "connected", 947 | "percentage": false, 948 | "pointradius": 5, 949 | "points": false, 950 | "renderer": "flot", 951 | "seriesOverrides": [], 952 | "span": 12, 953 | "stack": true, 954 | "steppedLine": false, 955 | "targets": [ 956 | { 957 | "expr": "topk($topk, sum(mongo_wt_block_manager_file_size_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\"}) by (db, coll))", 958 | "interval": "", 959 | "intervalFactor": 2, 960 | "legendFormat": "{{db}}.{{coll}}", 961 | "metric": "mongo_wt_block_manager_file_size_bytes", 962 | "refId": "A", 963 | "step": 20 964 | } 965 | ], 966 | "thresholds": [], 967 | "timeFrom": null, 968 | "timeShift": null, 969 | "title": "On Disk Size With Indexes (Bytes)", 970 | "tooltip": { 971 | "msResolution": false, 972 | "shared": true, 973 | "sort": 2, 974 | "value_type": "individual" 975 | }, 976 | "transparent": false, 977 | "type": "graph", 978 | "xaxis": { 979 | "mode": "time", 980 | "name": null, 981 | "show": true, 982 | "values": [] 983 | }, 984 | "yaxes": [ 985 | { 986 | "format": "decbytes", 987 | "label": null, 988 | "logBase": 1, 989 | "max": null, 990 | "min": null, 991 | "show": true 992 | }, 993 | { 994 | "format": "short", 995 | "label": null, 996 | "logBase": 1, 997 | "max": null, 998 | "min": null, 999 | "show": true 1000 | } 1001 | ] 1002 | } 1003 | ], 1004 | "repeat": null, 1005 | "repeatIteration": null, 1006 | "repeatRowId": null, 1007 | "showTitle": false, 1008 | "title": "Dashboard Row", 1009 | "titleSize": "h6" 1010 | }, 1011 | { 1012 | "collapse": false, 1013 | "height": 250, 1014 | "panels": [ 1015 | { 1016 | "aliasColors": {}, 1017 | "bars": false, 1018 | "datasource": "${DS_PROMETHEUS}", 1019 | "decimals": 0, 1020 | "editable": true, 1021 | "error": false, 1022 | "fill": 1, 1023 | "id": 19, 1024 | "legend": { 1025 | "alignAsTable": true, 1026 | "avg": false, 1027 | "current": true, 1028 | "max": false, 1029 | "min": false, 1030 | "rightSide": true, 1031 | "show": true, 1032 | "sort": "current", 1033 | "sortDesc": true, 1034 | "total": false, 1035 | "values": true 1036 | }, 1037 | "lines": true, 1038 | "linewidth": 1, 1039 | "links": [], 1040 | "nullPointMode": "connected", 1041 | "percentage": false, 1042 | "pointradius": 5, 1043 | "points": false, 1044 | "renderer": "flot", 1045 | "seriesOverrides": [ 1046 | { 1047 | "alias": "All Collections", 1048 | "fill": 5, 1049 | "yaxis": 2 1050 | } 1051 | ], 1052 | "span": 6, 1053 | "stack": false, 1054 | "steppedLine": false, 1055 | "targets": [ 1056 | { 1057 | "expr": "topk($topk, sum(delta(mongo_collection_storage_size_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\"}[$scale])) by (db, coll))", 1058 | "hide": false, 1059 | "intervalFactor": 2, 1060 | "legendFormat": "{{db}}.{{coll}}", 1061 | "metric": "mongo_collection_storage_size_bytes", 1062 | "refId": "A", 1063 | "step": 30 1064 | }, 1065 | { 1066 | "expr": "sum(delta(mongo_collection_storage_size_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\"}[$scale]))", 1067 | "hide": true, 1068 | "intervalFactor": 2, 1069 | "legendFormat": "All Collections", 1070 | "metric": "mongo_collection_storage_size_bytes", 1071 | "refId": "B", 1072 | "step": 20 1073 | } 1074 | ], 1075 | "thresholds": [], 1076 | "timeFrom": null, 1077 | "timeShift": null, 1078 | "title": "Disk Size Change (Bytes)", 1079 | "tooltip": { 1080 | "msResolution": false, 1081 | "shared": true, 1082 | "sort": 2, 1083 | "value_type": "individual" 1084 | }, 1085 | "type": "graph", 1086 | "xaxis": { 1087 | "mode": "time", 1088 | "name": null, 1089 | "show": true, 1090 | "values": [] 1091 | }, 1092 | "yaxes": [ 1093 | { 1094 | "format": "decbytes", 1095 | "label": null, 1096 | "logBase": 1, 1097 | "max": null, 1098 | "min": null, 1099 | "show": true 1100 | }, 1101 | { 1102 | "format": "decbytes", 1103 | "label": null, 1104 | "logBase": 1, 1105 | "max": null, 1106 | "min": null, 1107 | "show": true 1108 | } 1109 | ] 1110 | }, 1111 | { 1112 | "aliasColors": {}, 1113 | "bars": false, 1114 | "datasource": "${DS_PROMETHEUS}", 1115 | "decimals": 0, 1116 | "editable": true, 1117 | "error": false, 1118 | "fill": 1, 1119 | "id": 23, 1120 | "legend": { 1121 | "alignAsTable": true, 1122 | "avg": false, 1123 | "current": true, 1124 | "max": false, 1125 | "min": false, 1126 | "rightSide": true, 1127 | "show": true, 1128 | "sort": "current", 1129 | "sortDesc": true, 1130 | "total": false, 1131 | "values": true 1132 | }, 1133 | "lines": true, 1134 | "linewidth": 1, 1135 | "links": [], 1136 | "nullPointMode": "connected", 1137 | "percentage": false, 1138 | "pointradius": 5, 1139 | "points": false, 1140 | "renderer": "flot", 1141 | "seriesOverrides": [ 1142 | { 1143 | "alias": "All Collections", 1144 | "fill": 5, 1145 | "yaxis": 2 1146 | } 1147 | ], 1148 | "span": 6, 1149 | "stack": true, 1150 | "steppedLine": false, 1151 | "targets": [ 1152 | { 1153 | "expr": "topk($topk, sum(delta(mongo_wt_block_manager_file_size_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\", idx=~\".+\"}[$scale])) by (db, coll))", 1154 | "hide": false, 1155 | "intervalFactor": 2, 1156 | "legendFormat": "{{db}}.{{coll}}", 1157 | "metric": "mongo_wt_block_manager_file_size_bytes", 1158 | "refId": "A", 1159 | "step": 30 1160 | }, 1161 | { 1162 | "expr": "sum(delta(mongo_collection_storage_size_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\"}[$scale]))", 1163 | "hide": true, 1164 | "intervalFactor": 2, 1165 | "legendFormat": "All Collections", 1166 | "metric": "mongo_collection_storage_size_bytes", 1167 | "refId": "B", 1168 | "step": 20 1169 | } 1170 | ], 1171 | "thresholds": [], 1172 | "timeFrom": null, 1173 | "timeShift": null, 1174 | "title": "Index Size Change (Bytes)", 1175 | "tooltip": { 1176 | "msResolution": false, 1177 | "shared": true, 1178 | "sort": 2, 1179 | "value_type": "individual" 1180 | }, 1181 | "type": "graph", 1182 | "xaxis": { 1183 | "mode": "time", 1184 | "name": null, 1185 | "show": true, 1186 | "values": [] 1187 | }, 1188 | "yaxes": [ 1189 | { 1190 | "format": "decbytes", 1191 | "label": null, 1192 | "logBase": 1, 1193 | "max": null, 1194 | "min": null, 1195 | "show": true 1196 | }, 1197 | { 1198 | "format": "decbytes", 1199 | "label": null, 1200 | "logBase": 1, 1201 | "max": null, 1202 | "min": null, 1203 | "show": true 1204 | } 1205 | ] 1206 | } 1207 | ], 1208 | "repeat": null, 1209 | "repeatIteration": null, 1210 | "repeatRowId": null, 1211 | "showTitle": false, 1212 | "title": "Dashboard Row", 1213 | "titleSize": "h6" 1214 | }, 1215 | { 1216 | "collapse": false, 1217 | "height": 202, 1218 | "panels": [ 1219 | { 1220 | "aliasColors": {}, 1221 | "bars": false, 1222 | "datasource": "${DS_PROMETHEUS}", 1223 | "decimals": 3, 1224 | "editable": true, 1225 | "error": false, 1226 | "fill": 1, 1227 | "id": 1, 1228 | "legend": { 1229 | "alignAsTable": true, 1230 | "avg": false, 1231 | "current": true, 1232 | "max": false, 1233 | "min": false, 1234 | "rightSide": true, 1235 | "show": true, 1236 | "sort": "current", 1237 | "sortDesc": true, 1238 | "total": false, 1239 | "values": true 1240 | }, 1241 | "lines": true, 1242 | "linewidth": 1, 1243 | "links": [], 1244 | "nullPointMode": "connected", 1245 | "percentage": false, 1246 | "pointradius": 5, 1247 | "points": false, 1248 | "renderer": "flot", 1249 | "repeat": null, 1250 | "seriesOverrides": [], 1251 | "span": 12, 1252 | "stack": true, 1253 | "steppedLine": false, 1254 | "targets": [ 1255 | { 1256 | "expr": "topk($topk, avg(mongo_collection_count{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\"}) by (db, coll))", 1257 | "intervalFactor": 2, 1258 | "legendFormat": "{{db}}.{{coll}}", 1259 | "metric": "", 1260 | "refId": "A", 1261 | "step": 20 1262 | } 1263 | ], 1264 | "thresholds": [], 1265 | "timeFrom": null, 1266 | "timeShift": null, 1267 | "title": "Documents", 1268 | "tooltip": { 1269 | "msResolution": false, 1270 | "shared": true, 1271 | "sort": 2, 1272 | "value_type": "individual" 1273 | }, 1274 | "type": "graph", 1275 | "xaxis": { 1276 | "mode": "time", 1277 | "name": null, 1278 | "show": true, 1279 | "values": [] 1280 | }, 1281 | "yaxes": [ 1282 | { 1283 | "format": "short", 1284 | "label": null, 1285 | "logBase": 1, 1286 | "max": null, 1287 | "min": null, 1288 | "show": true 1289 | }, 1290 | { 1291 | "format": "short", 1292 | "label": null, 1293 | "logBase": 1, 1294 | "max": null, 1295 | "min": null, 1296 | "show": true 1297 | } 1298 | ] 1299 | } 1300 | ], 1301 | "repeat": null, 1302 | "repeatIteration": null, 1303 | "repeatRowId": null, 1304 | "showTitle": false, 1305 | "title": "Documents", 1306 | "titleSize": "h6" 1307 | }, 1308 | { 1309 | "collapse": false, 1310 | "height": 230, 1311 | "panels": [ 1312 | { 1313 | "aliasColors": {}, 1314 | "bars": false, 1315 | "datasource": "${DS_PROMETHEUS}", 1316 | "decimals": 3, 1317 | "editable": true, 1318 | "error": false, 1319 | "fill": 1, 1320 | "id": 4, 1321 | "legend": { 1322 | "alignAsTable": true, 1323 | "avg": false, 1324 | "current": true, 1325 | "hideEmpty": true, 1326 | "hideZero": true, 1327 | "max": false, 1328 | "min": false, 1329 | "rightSide": true, 1330 | "show": true, 1331 | "sort": "current", 1332 | "sortDesc": true, 1333 | "total": false, 1334 | "values": true 1335 | }, 1336 | "lines": true, 1337 | "linewidth": 1, 1338 | "links": [], 1339 | "nullPointMode": "connected", 1340 | "percentage": false, 1341 | "pointradius": 5, 1342 | "points": false, 1343 | "renderer": "flot", 1344 | "seriesOverrides": [], 1345 | "span": 12, 1346 | "stack": false, 1347 | "steppedLine": false, 1348 | "targets": [ 1349 | { 1350 | "expr": "topk($topk, avg(mongo_collection_size_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\"} / mongo_collection_storage_size_bytes{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\"}) by (db, coll))", 1351 | "intervalFactor": 2, 1352 | "legendFormat": "{{db}}.{{coll}}", 1353 | "metric": "mongo_collection_storage_size_bytes", 1354 | "refId": "A", 1355 | "step": 20 1356 | } 1357 | ], 1358 | "thresholds": [], 1359 | "timeFrom": null, 1360 | "timeShift": null, 1361 | "title": "Compression Ratio (Size / Storage)", 1362 | "tooltip": { 1363 | "msResolution": false, 1364 | "shared": true, 1365 | "sort": 0, 1366 | "value_type": "individual" 1367 | }, 1368 | "type": "graph", 1369 | "xaxis": { 1370 | "mode": "time", 1371 | "name": null, 1372 | "show": true, 1373 | "values": [] 1374 | }, 1375 | "yaxes": [ 1376 | { 1377 | "format": "short", 1378 | "label": null, 1379 | "logBase": 1, 1380 | "max": null, 1381 | "min": null, 1382 | "show": true 1383 | }, 1384 | { 1385 | "format": "short", 1386 | "label": null, 1387 | "logBase": 1, 1388 | "max": null, 1389 | "min": null, 1390 | "show": true 1391 | } 1392 | ] 1393 | } 1394 | ], 1395 | "repeat": null, 1396 | "repeatIteration": null, 1397 | "repeatRowId": null, 1398 | "showTitle": false, 1399 | "title": "Compression Ratio", 1400 | "titleSize": "h6" 1401 | }, 1402 | { 1403 | "collapse": false, 1404 | "height": 250, 1405 | "panels": [ 1406 | { 1407 | "aliasColors": {}, 1408 | "bars": false, 1409 | "datasource": "${DS_PROMETHEUS}", 1410 | "decimals": 0, 1411 | "editable": true, 1412 | "error": false, 1413 | "fill": 1, 1414 | "id": 16, 1415 | "legend": { 1416 | "alignAsTable": true, 1417 | "avg": false, 1418 | "current": true, 1419 | "max": false, 1420 | "min": false, 1421 | "rightSide": true, 1422 | "show": true, 1423 | "sort": "current", 1424 | "sortDesc": true, 1425 | "total": false, 1426 | "values": true 1427 | }, 1428 | "lines": true, 1429 | "linewidth": 1, 1430 | "links": [], 1431 | "nullPointMode": "null", 1432 | "percentage": false, 1433 | "pointradius": 5, 1434 | "points": false, 1435 | "renderer": "flot", 1436 | "seriesOverrides": [], 1437 | "span": 12, 1438 | "stack": true, 1439 | "steppedLine": false, 1440 | "targets": [ 1441 | { 1442 | "expr": "topk($topk, rate(mongo_wt_cache_evicted_pages{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\", idx=\"\"}[$scale]))", 1443 | "intervalFactor": 2, 1444 | "legendFormat": "{{db}}.{{coll}}", 1445 | "metric": "mongo_wt_cache_evicted_pages", 1446 | "refId": "A", 1447 | "step": 20 1448 | } 1449 | ], 1450 | "thresholds": [], 1451 | "timeFrom": null, 1452 | "timeShift": null, 1453 | "title": "Evicted Collection Pages", 1454 | "tooltip": { 1455 | "msResolution": false, 1456 | "shared": true, 1457 | "sort": 2, 1458 | "value_type": "individual" 1459 | }, 1460 | "type": "graph", 1461 | "xaxis": { 1462 | "mode": "time", 1463 | "name": null, 1464 | "show": true, 1465 | "values": [] 1466 | }, 1467 | "yaxes": [ 1468 | { 1469 | "format": "short", 1470 | "label": null, 1471 | "logBase": 1, 1472 | "max": null, 1473 | "min": null, 1474 | "show": true 1475 | }, 1476 | { 1477 | "format": "short", 1478 | "label": null, 1479 | "logBase": 1, 1480 | "max": null, 1481 | "min": null, 1482 | "show": true 1483 | } 1484 | ] 1485 | } 1486 | ], 1487 | "repeat": null, 1488 | "repeatIteration": null, 1489 | "repeatRowId": null, 1490 | "showTitle": false, 1491 | "title": "Dashboard Row", 1492 | "titleSize": "h6" 1493 | }, 1494 | { 1495 | "collapse": false, 1496 | "height": 250, 1497 | "panels": [ 1498 | { 1499 | "aliasColors": {}, 1500 | "bars": false, 1501 | "datasource": "${DS_PROMETHEUS}", 1502 | "decimals": 0, 1503 | "editable": true, 1504 | "error": false, 1505 | "fill": 1, 1506 | "id": 17, 1507 | "legend": { 1508 | "alignAsTable": true, 1509 | "avg": false, 1510 | "current": true, 1511 | "max": false, 1512 | "min": false, 1513 | "rightSide": true, 1514 | "show": true, 1515 | "sort": "current", 1516 | "sortDesc": true, 1517 | "total": false, 1518 | "values": true 1519 | }, 1520 | "lines": true, 1521 | "linewidth": 1, 1522 | "links": [], 1523 | "nullPointMode": "null", 1524 | "percentage": false, 1525 | "pointradius": 5, 1526 | "points": false, 1527 | "renderer": "flot", 1528 | "seriesOverrides": [], 1529 | "span": 12, 1530 | "stack": true, 1531 | "steppedLine": false, 1532 | "targets": [ 1533 | { 1534 | "expr": "topk($topk, rate(mongo_wt_cache_evicted_pages{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\", idx=~\".+\"}[$scale]))", 1535 | "intervalFactor": 2, 1536 | "legendFormat": "{{db}}.{{coll}} ({{idx}})", 1537 | "metric": "mongo_wt_cache_evicted_pages", 1538 | "refId": "A", 1539 | "step": 20 1540 | } 1541 | ], 1542 | "thresholds": [], 1543 | "timeFrom": null, 1544 | "timeShift": null, 1545 | "title": "Evicted Index Pages", 1546 | "tooltip": { 1547 | "msResolution": false, 1548 | "shared": true, 1549 | "sort": 2, 1550 | "value_type": "individual" 1551 | }, 1552 | "type": "graph", 1553 | "xaxis": { 1554 | "mode": "time", 1555 | "name": null, 1556 | "show": true, 1557 | "values": [] 1558 | }, 1559 | "yaxes": [ 1560 | { 1561 | "format": "short", 1562 | "label": null, 1563 | "logBase": 1, 1564 | "max": null, 1565 | "min": null, 1566 | "show": true 1567 | }, 1568 | { 1569 | "format": "short", 1570 | "label": null, 1571 | "logBase": 1, 1572 | "max": null, 1573 | "min": null, 1574 | "show": true 1575 | } 1576 | ] 1577 | } 1578 | ], 1579 | "repeat": null, 1580 | "repeatIteration": null, 1581 | "repeatRowId": null, 1582 | "showTitle": false, 1583 | "title": "Dashboard Row", 1584 | "titleSize": "h6" 1585 | }, 1586 | { 1587 | "collapse": false, 1588 | "height": 250, 1589 | "panels": [ 1590 | { 1591 | "aliasColors": {}, 1592 | "bars": false, 1593 | "datasource": "${DS_PROMETHEUS}", 1594 | "decimals": 0, 1595 | "editable": true, 1596 | "error": false, 1597 | "fill": 1, 1598 | "id": 18, 1599 | "legend": { 1600 | "alignAsTable": true, 1601 | "avg": false, 1602 | "current": true, 1603 | "max": false, 1604 | "min": false, 1605 | "rightSide": true, 1606 | "show": true, 1607 | "sort": "current", 1608 | "sortDesc": true, 1609 | "total": false, 1610 | "values": true 1611 | }, 1612 | "lines": true, 1613 | "linewidth": 1, 1614 | "links": [], 1615 | "nullPointMode": "null", 1616 | "percentage": false, 1617 | "pointradius": 5, 1618 | "points": false, 1619 | "renderer": "flot", 1620 | "seriesOverrides": [], 1621 | "span": 12, 1622 | "stack": false, 1623 | "steppedLine": false, 1624 | "targets": [ 1625 | { 1626 | "expr": "sum(rate(mongo_wt_cursor_calls{db=~\"$db\", coll=~\"$coll\", instance=~\"$instance\", role=~\"$role\", rs=~\"$rs\", idx=\"\"}[$scale])) by (type)", 1627 | "intervalFactor": 2, 1628 | "legendFormat": "{{type}}", 1629 | "metric": "mongo_wt_cursor_calls", 1630 | "refId": "A", 1631 | "step": 20 1632 | } 1633 | ], 1634 | "thresholds": [], 1635 | "timeFrom": null, 1636 | "timeShift": null, 1637 | "title": "Cursors", 1638 | "tooltip": { 1639 | "msResolution": false, 1640 | "shared": true, 1641 | "sort": 2, 1642 | "value_type": "individual" 1643 | }, 1644 | "type": "graph", 1645 | "xaxis": { 1646 | "mode": "time", 1647 | "name": null, 1648 | "show": true, 1649 | "values": [] 1650 | }, 1651 | "yaxes": [ 1652 | { 1653 | "format": "short", 1654 | "label": null, 1655 | "logBase": 1, 1656 | "max": null, 1657 | "min": null, 1658 | "show": true 1659 | }, 1660 | { 1661 | "format": "short", 1662 | "label": null, 1663 | "logBase": 1, 1664 | "max": null, 1665 | "min": null, 1666 | "show": true 1667 | } 1668 | ] 1669 | } 1670 | ], 1671 | "repeat": null, 1672 | "repeatIteration": null, 1673 | "repeatRowId": null, 1674 | "showTitle": false, 1675 | "title": "Dashboard Row", 1676 | "titleSize": "h6" 1677 | } 1678 | ], 1679 | "schemaVersion": 14, 1680 | "style": "dark", 1681 | "tags": [], 1682 | "templating": { 1683 | "list": [ 1684 | { 1685 | "allValue": ".*", 1686 | "current": {}, 1687 | "datasource": "${DS_PROMETHEUS}", 1688 | "hide": 0, 1689 | "includeAll": true, 1690 | "label": "Role", 1691 | "multi": false, 1692 | "name": "role", 1693 | "options": [], 1694 | "query": "label_values(mongo_scrape_ok, role)", 1695 | "refresh": 1, 1696 | "regex": "", 1697 | "sort": 1, 1698 | "tagValuesQuery": null, 1699 | "tags": [], 1700 | "tagsQuery": null, 1701 | "type": "query", 1702 | "useTags": false 1703 | }, 1704 | { 1705 | "allValue": ".*", 1706 | "current": {}, 1707 | "datasource": "${DS_PROMETHEUS}", 1708 | "hide": 0, 1709 | "includeAll": true, 1710 | "label": "Shard", 1711 | "multi": false, 1712 | "name": "rs", 1713 | "options": [], 1714 | "query": "label_values(mongo_scrape_ok{role=~\"$role\"}, rs)", 1715 | "refresh": 1, 1716 | "regex": "", 1717 | "sort": 1, 1718 | "tagValuesQuery": null, 1719 | "tags": [], 1720 | "tagsQuery": null, 1721 | "type": "query", 1722 | "useTags": false 1723 | }, 1724 | { 1725 | "allValue": ".*", 1726 | "current": {}, 1727 | "datasource": "${DS_PROMETHEUS}", 1728 | "hide": 0, 1729 | "includeAll": true, 1730 | "label": "Node", 1731 | "multi": false, 1732 | "name": "instance", 1733 | "options": [], 1734 | "query": "label_values(mongo_scrape_ok{role=~\"$role\", rs=~\"$rs\"}, instance)", 1735 | "refresh": 1, 1736 | "regex": "", 1737 | "sort": 1, 1738 | "tagValuesQuery": null, 1739 | "tags": [], 1740 | "tagsQuery": null, 1741 | "type": "query", 1742 | "useTags": false 1743 | }, 1744 | { 1745 | "allValue": ".*", 1746 | "current": {}, 1747 | "datasource": "${DS_PROMETHEUS}", 1748 | "hide": 0, 1749 | "includeAll": true, 1750 | "label": null, 1751 | "multi": false, 1752 | "name": "db", 1753 | "options": [], 1754 | "query": "label_values(mongo_collection_count, db)", 1755 | "refresh": 1, 1756 | "regex": "", 1757 | "sort": 0, 1758 | "tagValuesQuery": null, 1759 | "tags": [], 1760 | "tagsQuery": null, 1761 | "type": "query", 1762 | "useTags": false 1763 | }, 1764 | { 1765 | "allValue": ".*", 1766 | "current": {}, 1767 | "datasource": "${DS_PROMETHEUS}", 1768 | "hide": 0, 1769 | "includeAll": true, 1770 | "label": "Collection", 1771 | "multi": false, 1772 | "name": "coll", 1773 | "options": [], 1774 | "query": "label_values(mongo_collection_count, coll)", 1775 | "refresh": 1, 1776 | "regex": "", 1777 | "sort": 1, 1778 | "tagValuesQuery": null, 1779 | "tags": [], 1780 | "tagsQuery": null, 1781 | "type": "query", 1782 | "useTags": false 1783 | }, 1784 | { 1785 | "allValue": null, 1786 | "current": { 1787 | "tags": [], 1788 | "text": "5m", 1789 | "value": "5m" 1790 | }, 1791 | "hide": 0, 1792 | "includeAll": false, 1793 | "label": null, 1794 | "multi": false, 1795 | "name": "scale", 1796 | "options": [ 1797 | { 1798 | "selected": false, 1799 | "text": "2m", 1800 | "value": "2m" 1801 | }, 1802 | { 1803 | "selected": true, 1804 | "text": "5m", 1805 | "value": "5m" 1806 | }, 1807 | { 1808 | "selected": false, 1809 | "text": "10m", 1810 | "value": "10m" 1811 | }, 1812 | { 1813 | "selected": false, 1814 | "text": "15m", 1815 | "value": "15m" 1816 | }, 1817 | { 1818 | "selected": false, 1819 | "text": "30m", 1820 | "value": "30m" 1821 | }, 1822 | { 1823 | "selected": false, 1824 | "text": "1h", 1825 | "value": "1h" 1826 | } 1827 | ], 1828 | "query": "2m,5m,10m,15m,30m,1h", 1829 | "type": "custom" 1830 | }, 1831 | { 1832 | "allValue": null, 1833 | "current": { 1834 | "selected": true, 1835 | "tags": [], 1836 | "text": "5", 1837 | "value": "5" 1838 | }, 1839 | "hide": 0, 1840 | "includeAll": false, 1841 | "label": "Top", 1842 | "multi": false, 1843 | "name": "topk", 1844 | "options": [ 1845 | { 1846 | "selected": false, 1847 | "text": "1", 1848 | "value": "1" 1849 | }, 1850 | { 1851 | "selected": false, 1852 | "text": "3", 1853 | "value": "3" 1854 | }, 1855 | { 1856 | "selected": true, 1857 | "text": "5", 1858 | "value": "5" 1859 | }, 1860 | { 1861 | "selected": false, 1862 | "text": "10", 1863 | "value": "10" 1864 | } 1865 | ], 1866 | "query": "1,3,5,10", 1867 | "type": "custom" 1868 | } 1869 | ] 1870 | }, 1871 | "time": { 1872 | "from": "now-3h", 1873 | "to": "now" 1874 | }, 1875 | "timepicker": { 1876 | "refresh_intervals": [ 1877 | "5s", 1878 | "10s", 1879 | "30s", 1880 | "1m", 1881 | "5m", 1882 | "15m", 1883 | "30m", 1884 | "1h", 1885 | "2h", 1886 | "1d" 1887 | ], 1888 | "time_options": [ 1889 | "5m", 1890 | "15m", 1891 | "1h", 1892 | "6h", 1893 | "12h", 1894 | "24h", 1895 | "2d", 1896 | "7d", 1897 | "30d" 1898 | ] 1899 | }, 1900 | "timezone": "browser", 1901 | "title": "Mongo Collection", 1902 | "version": 2 1903 | } 1904 | -------------------------------------------------------------------------------- /vendor/prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 5s 3 | evaluation_interval: 5s 4 | external_labels: 5 | role: 'dev' 6 | 7 | scrape_configs: 8 | - job_name: 'prometheus' 9 | static_configs: 10 | - targets: 11 | - '127.0.0.1:9090' 12 | 13 | - job_name: 'mongo-metrics' 14 | static_configs: 15 | - targets: 16 | - '127.0.0.1:3000' 17 | --------------------------------------------------------------------------------