├── .gitignore ├── LICENSE ├── README.md ├── app.js ├── lib ├── actions.js ├── metrics.json └── stats.js ├── package.json ├── pres └── elasticsearch.png └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Keymetrics Team 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | PM2 module to monitor a ElasticSearch cluster with Keymetrics 4 | 5 | ## Install 6 | 7 | `pm2 install pm2-elasticsearch` 8 | 9 | ## Configure 10 | 11 | - `elasticsearchUri` (Defaults to `http://localhost:9200/`): Set the URI to connect to your Elastic cluster (can be load from `PM2_ELASTICSEARCH_URI` env var) 12 | 13 | #### How to set these values ? 14 | 15 | After having installed the module you have to type : 16 | `pm2 set pm2-elasticsearch: ` 17 | 18 | e.g: 19 | - `pm2 set pm2-elasticsearch:elasticsearchUri https://user:password@host:port` (use simple auth to connect to the cluster) 20 | 21 | ## Uninstall 22 | 23 | `pm2 uninstall pm2-elasticsearch` -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const io = require('@pm2/io') 4 | const elasticsearch = require('elasticsearch') 5 | const stats = require('./lib/stats') 6 | const Actions = require('./lib/actions') 7 | 8 | io.initModule({ 9 | widget: { 10 | type: 'generic', 11 | logo: 'https://www.elastic.co/static/img/logo-elastic.png', 12 | theme: ['#39bdb1', '#1B2228', 'white', '#807C7C'], 13 | el: { 14 | probes: true, 15 | actions: true 16 | }, 17 | 18 | block: { 19 | issues: true, 20 | meta: true, 21 | main_probes: ['Elastic status', 'Nodes', 'Shards', 'Indices', 'Documents', 'Store size'] 22 | } 23 | } 24 | }, function (err, conf) { 25 | if (err) { 26 | console.error(err) 27 | return process.exit(1) 28 | } 29 | const ELASTICSEARCH_URI = conf.elasticsearchUri || process.env.PM2_ELASTICSEARCH_URI || 'localhost:9200' 30 | 31 | const client = new elasticsearch.Client({ 32 | host: ELASTICSEARCH_URI, 33 | log: 'error' 34 | }) 35 | 36 | // init all probes 37 | stats.init() 38 | stats.update(client) 39 | 40 | // start all workers 41 | setInterval(function () { 42 | return stats.update(client) 43 | }, 1000) 44 | 45 | // Register PMX actions 46 | const actions = new Actions(client) 47 | actions.register() 48 | }) 49 | -------------------------------------------------------------------------------- /lib/actions.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const io = require('@pm2/io') 4 | const filesize = require('filesize') 5 | 6 | module.exports = class Actions { 7 | constructor (es) { 8 | this.es = es 9 | } 10 | 11 | register () { 12 | io.action('indices stats', (reply) => { 13 | this.es.cat.indices({ bytes: 'k' }, (err, data, code) => { 14 | return err ? reply(`An error has occured, \n ${err}`) : reply(data) 15 | }) 16 | }) 17 | 18 | io.action('shards stats', (reply) => { 19 | this.es.cat.shards({}, (err, data, code) => { 20 | return err ? reply(`An error has occured, \n ${err}`) : reply(data) 21 | }) 22 | }) 23 | 24 | io.action('cluster infos', (reply) => { 25 | this.es.nodes.info({}, (err, data, code) => { 26 | return err ? reply(`An error has occured, \n ${err}`) : reply(data) 27 | }) 28 | }) 29 | 30 | io.action('cluster stats', (reply) => { 31 | this.es.nodes.stats({}, (err, data, code) => { 32 | return err ? reply(`An error has occured, \n ${err}`) : reply(data) 33 | }) 34 | }) 35 | 36 | io.action('cluster health', (reply) => { 37 | this.es.cluster.health({}, (err, data, code) => { 38 | return err ? reply(`An error has occured, \n ${err}`) : reply(data) 39 | }) 40 | }) 41 | 42 | io.action('get unassigned shards', (reply) => { 43 | this.es.cat.shards({ 44 | h: [ 'index', 'state', 'unassigned.reason' ] 45 | }, (err, data) => { 46 | return err 47 | ? reply(`An error has occured, \n ${err}`) 48 | : reply(data.split('\n').filter(line => line.indexOf('UNASSIGNED') !== -1).join('\n')) 49 | }) 50 | }) 51 | 52 | io.action('get biggers indices', (reply) => { 53 | this.es.cat.indices({ 54 | s: [ 'docs.count:desc' ] 55 | }, (err, data) => { 56 | return err ? reply(`An error has occured, \n ${err}`) : reply(data) 57 | }) 58 | }) 59 | 60 | io.action('get biggers indices stats', async reply => { 61 | const final = {} 62 | 63 | const stats = await this.es.indices.stats() 64 | await Promise.all(Object.keys(stats.indices) 65 | .map(name => { 66 | stats.indices[name].name = name 67 | return stats.indices[name] 68 | }) 69 | .sort((a, b) => { 70 | return b.total.docs.count - a.total.docs.count 71 | }) 72 | .slice(0, 10) 73 | .map(async indice => { 74 | final[indice.name] = { 75 | docs: indice.total.docs.count, 76 | size: filesize(indice.total.store.size_in_bytes), 77 | types: {} 78 | } 79 | const mapping = await this.es.indices.getMapping({ 80 | index: indice.name 81 | }) 82 | const types = Object.keys(mapping[indice.name].mappings) 83 | await Promise.all(types.map(async type => { 84 | const typeStats = await this.es.indices.stats({ 85 | index: indice.name, 86 | types: type 87 | }) 88 | final[indice.name].types[type] = { 89 | docs: typeStats._all.primaries.docs.count, 90 | size: filesize(typeStats._all.primaries.store.size_in_bytes) 91 | } 92 | })) 93 | })) 94 | 95 | reply(final) 96 | }) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /lib/metrics.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "from": "node", 4 | "path": "fs.io_stats.total.write_operations", 5 | "compareToLastValue": true, 6 | "name": "Write Ops", 7 | "unit": "/min" 8 | }, 9 | { 10 | "from": "node", 11 | "path": "fs.io_stats.total.read_operations", 12 | "compareToLastValue": true, 13 | "name": "Read Ops", 14 | "unit": "/min" 15 | }, 16 | { 17 | "from": "node", 18 | "path": "fs.io_stats.total.read_kilobytes", 19 | "compareToLastValue": true, 20 | "name": "Read Bandwith", 21 | "unit": "ko/min" 22 | }, 23 | { 24 | "from": "node", 25 | "path": "fs.io_stats.total.write_kilobytes", 26 | "compareToLastValue": true, 27 | "name": "Write Bandwith", 28 | "unit": "ko/min" 29 | }, 30 | { 31 | "from": "node", 32 | "path": "fs.total.available_in_bytes", 33 | "divide_by": "fs.total.total_in_bytes", 34 | "multiply_by": 100, 35 | "name": "Free Disk Space", 36 | "unit": "%" 37 | }, 38 | { 39 | "from": "node", 40 | "path": "process.open_file_descriptors", 41 | "name": "Open FDs" 42 | }, 43 | { 44 | "from": "node", 45 | "path": "jvm.mem.heap_used_percent", 46 | "name": "Heap Usage", 47 | "unit": "%" 48 | }, 49 | { 50 | "from": "node", 51 | "path": "jvm.threads.count", 52 | "name": "Threads count" 53 | }, 54 | { 55 | "from": "node", 56 | "path": "http.current_open", 57 | "name": "HTTP request" 58 | }, 59 | { 60 | "from": "node", 61 | "path": "jvm.gc.collectors.young.collection_time_in_millis", 62 | "divide_by": "jvm.gc.collectors.young.collection_count", 63 | "name": "GC Young Avg", 64 | "unit": "ms" 65 | }, 66 | { 67 | "from": "node", 68 | "path": "jvm.gc.collectors.old.collection_time_in_millis", 69 | "divide_by": "jvm.gc.collectors.old.collection_count", 70 | "name": "GC Old Avg", 71 | "unit": "ms" 72 | }, 73 | { 74 | "from": "node", 75 | "path": "indices.indexing.index_time_in_millis", 76 | "divide_by": "indices.indexing.index_total", 77 | "name": "Index Latency", 78 | "unit": "ms" 79 | }, 80 | { 81 | "from": "node", 82 | "path": "indices.get.time_in_millis", 83 | "divide_by": "indices.get.total", 84 | "name": "Get Latency", 85 | "unit": "ms" 86 | }, 87 | { 88 | "from": "node", 89 | "path": "indices.search.query_time_in_millis", 90 | "divide_by": "indices.search.query_total", 91 | "name": "Query Latency", 92 | "unit": "ms" 93 | }, 94 | { 95 | "from": "node", 96 | "path": "indices.search.fetch_time_in_millis", 97 | "divide_by": "indices.search.fetch_total", 98 | "name": "Fetch Latency", 99 | "unit": "ms" 100 | }, 101 | { 102 | "from": "node", 103 | "path": "indices.merges.total_time_in_millis", 104 | "divide_by": "indices.merges.total", 105 | "name": "Merge Latency", 106 | "unit": "ms" 107 | }, 108 | { 109 | "from": "node", 110 | "path": "indices.refresh.total_time_in_millis", 111 | "divide_by": "indices.refresh.total", 112 | "name": "Refresh Latency", 113 | "unit": "ms" 114 | }, 115 | { 116 | "from": "node", 117 | "path": "indices.segments.count", 118 | "name": "Segments Count" 119 | }, 120 | { 121 | "from": "node", 122 | "path": "indices.indexing.index_current", 123 | "name": "Current Indexing" 124 | }, 125 | { 126 | "from": "node", 127 | "path": "indices.search.query_current", 128 | "name": "Current Queries" 129 | }, 130 | { 131 | "from": "node", 132 | "path": "indices.docs.count", 133 | "name": "Documents" 134 | }, 135 | { 136 | "from": "node", 137 | "path": "indices.docs.deleted", 138 | "name": "Deleted Documents" 139 | }, 140 | { 141 | "from": "node", 142 | "path": "indices.store.size", 143 | "name": "Store size" 144 | }, 145 | { 146 | "from": "node", 147 | "path": "process.cpu.percent", 148 | "name": "CPU Usage", 149 | "unit": "%" 150 | }, 151 | { 152 | "from": "node", 153 | "path": "os.mem.used_percent", 154 | "name": "Memory Usage", 155 | "unit": "%" 156 | }, 157 | { 158 | "from": "node", 159 | "path": "os.swap.used_in_bytes", 160 | "divide_by": "os.swap.total_in_bytes", 161 | "multiply_by": 100, 162 | "name": "Swap Memory Usage", 163 | "unit": "%" 164 | }, 165 | { 166 | "from": "node", 167 | "path": "thread_pool.bulk.completed", 168 | "name": "Bulk Op. Completed", 169 | "compareToLastValue": true, 170 | "unit": "/min" 171 | }, 172 | { 173 | "from": "node", 174 | "path": "thread_pool.bulk.rejected", 175 | "name": "Bulk Op. Failed", 176 | "compareToLastValue": true, 177 | "unit": "/min" 178 | }, 179 | { 180 | "from": "cluster", 181 | "path": "nodes.count.total", 182 | "name": "Nodes" 183 | }, 184 | { 185 | "from": "cluster", 186 | "path": "nodes.jvm.max_uptime", 187 | "name": "Uptime" 188 | }, 189 | { 190 | "from": "cluster", 191 | "path": "indices.count", 192 | "name": "Indices" 193 | }, 194 | { 195 | "from": "cluster", 196 | "path": "status", 197 | "name": "Elastic status" 198 | }, 199 | { 200 | "from": "cluster", 201 | "path": "cluster_name", 202 | "name": "Cluster" 203 | }, 204 | { 205 | "from": "cluster", 206 | "path": "indices.shards.replication", 207 | "name": "Active Secondy Shards" 208 | }, 209 | { 210 | "from": "cluster", 211 | "path": "indices.shards.index.shards.avg", 212 | "name": "Avg. Shards per Index" 213 | }, 214 | { 215 | "from": "cluster", 216 | "path": "indices.shards.index.primaries.avg", 217 | "name": "Avg. Primary Shards per Index" 218 | }, 219 | { 220 | "from": "cluster", 221 | "path": "indices.shards.index.replication.avg", 222 | "name": "Avg. Secondary Shards per Index" 223 | }, 224 | { 225 | "from": "cluster_health", 226 | "path": "active_shards", 227 | "name": "Active Shards" 228 | }, 229 | { 230 | "from": "cluster_health", 231 | "path": "active_primary_shards", 232 | "name": "Active Primary Shards" 233 | }, 234 | { 235 | "from": "cluster_health", 236 | "path": "unassigned_shards", 237 | "name": "Unassigned Shards" 238 | }, 239 | { 240 | "from": "cluster_health", 241 | "path": "relocating_shards", 242 | "name": "Relocating Shards" 243 | }, 244 | { 245 | "from": "cluster_health", 246 | "path": "number_of_pending_tasks", 247 | "name": "Pending Tasks" 248 | }, 249 | { 250 | "from": "cluster_health", 251 | "path": "task_max_waiting_in_queue_millis", 252 | "name": "Max Task Queue Duration", 253 | "unit": "ms" 254 | } 255 | ] -------------------------------------------------------------------------------- /lib/stats.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const io = require('@pm2/io') 4 | const async = require('async') 5 | const getObject = require('object-path').get 6 | const metrics = require('./metrics.json') 7 | 8 | const values = new Map() 9 | 10 | /** Init all probes */ 11 | exports.init = function () { 12 | metrics.forEach(function (metric) { 13 | // instanciate each probe 14 | metric.probe = io.metric({ 15 | name: metric.name, 16 | unit: metric.unit || '' 17 | }) 18 | }) 19 | } 20 | 21 | /** Update all probes */ 22 | exports.update = function (esClient) { 23 | // query cluster and node stats 24 | async.parallel([ 25 | function (next) { 26 | return esClient.cluster.stats({ 27 | human: true 28 | }, next) 29 | }, 30 | function (next) { 31 | return esClient.nodes.stats({ 32 | human: true, 33 | nodeId: '_local' 34 | }, next) 35 | }, 36 | function (next) { 37 | return esClient.cluster.health({ 38 | human: true 39 | }, next) 40 | } 41 | ], (err, data) => { 42 | if (err) { 43 | console.error(err) 44 | return io.notifyError(err) 45 | } 46 | // lets update metrics 47 | for (let i = 0, max = metrics.length; i < max; i++) { 48 | var metric = metrics[i] 49 | let stats = {} 50 | 51 | // depending on the stats source 52 | switch (metric.from) { 53 | case 'cluster': { 54 | stats = data[0][0] 55 | break 56 | } 57 | case 'cluster_health': { 58 | stats = data[2][0] 59 | break 60 | } 61 | case 'node': { 62 | var nodes = Object.keys(data[1][0].nodes) 63 | stats = data[1][0].nodes[nodes[0]] 64 | break 65 | } 66 | } 67 | 68 | let value = getObject(stats, metric.path) 69 | if (typeof value === 'undefined') continue 70 | 71 | if (metric.compareToLastValue) { 72 | if (typeof metric.counter !== 'number') { 73 | metric.counter = 0 74 | values.set(metric.path, value) 75 | } 76 | // increment the counter 77 | metric.counter++ 78 | // when we are arrive at one minute, compare & update 79 | if (metric.counter === 60) { 80 | metric.counter = 0 81 | const old = values.get(metric.path) + 0 82 | values.set(metric.path, value) 83 | // continue to next metric if old value isnt found (must be the first run) 84 | if (old === undefined) continue 85 | metric.probe.set(value - old) 86 | } 87 | } else if (metric.divide_by) { 88 | let divideBy = getObject(stats, metric.divide_by) 89 | if (typeof divideBy === 'undefined') continue 90 | if (divideBy === '0' || divideBy === 0) continue 91 | 92 | const finalValue = parseFloat(value / divideBy * (metric.multiply_by || 1)).toFixed(2) 93 | metric.probe.set(finalValue) 94 | } else { 95 | metric.probe.set(value) 96 | } 97 | } 98 | }) 99 | } 100 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pm2-elasticsearch", 3 | "version": "2.1.0", 4 | "homepage": "https://keymetrics.io/", 5 | "description": "Monitoring module for elasticsearch", 6 | "engines": { 7 | "node": ">=4.0.0" 8 | }, 9 | "keywords": [ 10 | "elasticsearch", 11 | "es", 12 | "monitoring", 13 | "timeseries" 14 | ], 15 | "scripts": { 16 | "start": "node app" 17 | }, 18 | "dependencies": { 19 | "@pm2/io": "^2.4.5", 20 | "async": "^2.5.0", 21 | "elasticsearch": "*", 22 | "filesize": "^4.1.2", 23 | "object-path": "^0.11.4" 24 | }, 25 | "config": { 26 | "elasticsearchUri": "http://localhost:9200/" 27 | }, 28 | "author": "vmarchaud", 29 | "license": "MIT", 30 | "apps": [ 31 | { 32 | "name": "pm2-elasticsearch", 33 | "script": "app.js" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /pres/elasticsearch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keymetrics/pm2-elasticsearch/89b4e9c7236245af6c891e8980f62a0918f78ce8/pres/elasticsearch.png -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@pm2/agent-node@^1.0.6": 6 | version "1.0.7" 7 | resolved "https://registry.yarnpkg.com/@pm2/agent-node/-/agent-node-1.0.7.tgz#2f0e12b889c4d4731f5d1e0e968a0bd53edb3c28" 8 | integrity sha512-09m5zCJM9lpdA4MjHS+nahEVf+bjdvj5OepqiQiLxh+Jz1L5VSFmXyT9tUszanhJg3AajRfNKup1ASNtzVnPMg== 9 | dependencies: 10 | debug "^3.1.0" 11 | eventemitter2 "^5.0.1" 12 | ws "^6.0.0" 13 | 14 | "@pm2/io@^2.4.5": 15 | version "2.4.5" 16 | resolved "https://registry.yarnpkg.com/@pm2/io/-/io-2.4.5.tgz#17971da22ff716ded4a3db5e0372daf5c1e2f851" 17 | integrity sha512-+JPRL7T/5uoLzUnYV5SlrU1jWNOVfSRBeX386cx68EpotWRH0qS9HjGwh+DjBTeMRdvI9aVyhiBYqqRq8Lb6eg== 18 | dependencies: 19 | "@pm2/agent-node" "^1.0.6" 20 | async "^2.6.1" 21 | debug "3.1.0" 22 | deep-metrics "0.0.2" 23 | deepmerge "2.1.1" 24 | event-loop-inspector "^1.2.0" 25 | json-stringify-safe "5.0.1" 26 | semver "5.5.0" 27 | signal-exit "3.0.2" 28 | tslib "1.9.3" 29 | vxx "1.2.2" 30 | 31 | agentkeepalive@^2.2.0: 32 | version "2.2.0" 33 | resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-2.2.0.tgz#c5d1bd4b129008f1163f236f86e5faea2026e2ef" 34 | integrity sha1-xdG9SxKQCPEWPyNvhuX66iAm4u8= 35 | 36 | ansi-regex@^2.0.0: 37 | version "2.1.1" 38 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 39 | integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= 40 | 41 | ansi-styles@^2.2.1: 42 | version "2.2.1" 43 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 44 | integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= 45 | 46 | async-limiter@~1.0.0: 47 | version "1.0.0" 48 | resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" 49 | integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== 50 | 51 | async-listener@^0.6.0: 52 | version "0.6.8" 53 | resolved "https://registry.yarnpkg.com/async-listener/-/async-listener-0.6.8.tgz#d3556ef905d5ad77b52e52b37d68b1d8a02481f5" 54 | integrity sha512-1Sy1jDhjlgxcSd9/ICHqiAHT8VSJ9R1lzEyWwP/4Hm9p8nVTNtU0SxG/Z15XHD/aZvQraSw9BpDU3EBcFnOVrw== 55 | dependencies: 56 | semver "^5.3.0" 57 | shimmer "^1.1.0" 58 | 59 | async@^2.5.0: 60 | version "2.5.0" 61 | resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" 62 | integrity sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw== 63 | dependencies: 64 | lodash "^4.14.0" 65 | 66 | async@^2.6.1: 67 | version "2.6.1" 68 | resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" 69 | integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== 70 | dependencies: 71 | lodash "^4.17.10" 72 | 73 | chalk@^1.0.0: 74 | version "1.1.3" 75 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 76 | integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= 77 | dependencies: 78 | ansi-styles "^2.2.1" 79 | escape-string-regexp "^1.0.2" 80 | has-ansi "^2.0.0" 81 | strip-ansi "^3.0.0" 82 | supports-color "^2.0.0" 83 | 84 | continuation-local-storage@^3.1.4: 85 | version "3.2.0" 86 | resolved "https://registry.yarnpkg.com/continuation-local-storage/-/continuation-local-storage-3.2.0.tgz#e19fc36b597090a5d4e4a3b2ea3ebc5e29694a24" 87 | integrity sha1-4Z/Da1lwkKXU5KOy6j68XilpSiQ= 88 | dependencies: 89 | async-listener "^0.6.0" 90 | emitter-listener "^1.0.1" 91 | 92 | debug@3.1.0: 93 | version "3.1.0" 94 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 95 | integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== 96 | dependencies: 97 | ms "2.0.0" 98 | 99 | debug@^2.6.3: 100 | version "2.6.9" 101 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 102 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 103 | dependencies: 104 | ms "2.0.0" 105 | 106 | debug@^3.1.0: 107 | version "3.2.6" 108 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" 109 | integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== 110 | dependencies: 111 | ms "^2.1.1" 112 | 113 | deep-metrics@0.0.2: 114 | version "0.0.2" 115 | resolved "https://registry.yarnpkg.com/deep-metrics/-/deep-metrics-0.0.2.tgz#180900dea82a2c4b976be2b7684914748f5a0931" 116 | integrity sha512-2b4DO8YcPWSHrZ7XW9YjjJajmflw2EhKUMmeriZmGYsC8XvCWIyztsEjCQ3f5kIQO+ItzBK7BqVjSWlFZQtONQ== 117 | dependencies: 118 | semver "^5.3.0" 119 | 120 | deepmerge@2.1.1: 121 | version "2.1.1" 122 | resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.1.1.tgz#e862b4e45ea0555072bf51e7fd0d9845170ae768" 123 | integrity sha512-urQxA1smbLZ2cBbXbaYObM1dJ82aJ2H57A1C/Kklfh/ZN1bgH4G/n5KWhdNfOK11W98gqZfyYj7W4frJJRwA2w== 124 | 125 | elasticsearch@*: 126 | version "13.3.1" 127 | resolved "https://registry.yarnpkg.com/elasticsearch/-/elasticsearch-13.3.1.tgz#c530aea9afb17ea91c3d0a56f1f111ba49bc9239" 128 | integrity sha1-xTCuqa+xfqkcPQpW8fERukm8kjk= 129 | dependencies: 130 | agentkeepalive "^2.2.0" 131 | chalk "^1.0.0" 132 | lodash "2.4.2" 133 | lodash.get "^4.4.2" 134 | lodash.isempty "^4.4.0" 135 | lodash.trimend "^4.5.1" 136 | 137 | emitter-listener@^1.0.1: 138 | version "1.0.1" 139 | resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.0.1.tgz#b2499ea6e58230a52c268d5df261eecd9f10fe97" 140 | integrity sha1-skmepuWCMKUsJo1d8mHuzZ8Q/pc= 141 | dependencies: 142 | shimmer "1.0.0" 143 | 144 | escape-string-regexp@^1.0.2: 145 | version "1.0.5" 146 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 147 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 148 | 149 | event-loop-inspector@^1.2.0: 150 | version "1.2.2" 151 | resolved "https://registry.yarnpkg.com/event-loop-inspector/-/event-loop-inspector-1.2.2.tgz#e56ed73f50a8b0b9193cc36be877fea18641aceb" 152 | integrity sha512-v7OqIPmO0jqpmSH4Uc6IrY/H6lOidYzrXHE8vPHLDDOfV1Pw+yu+KEIE/AWnoFheWYlunZbxzKpZBAezVlrU9g== 153 | 154 | eventemitter2@^5.0.1: 155 | version "5.0.1" 156 | resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-5.0.1.tgz#6197a095d5fb6b57e8942f6fd7eaad63a09c9452" 157 | integrity sha1-YZegldX7a1folC9v1+qtY6CclFI= 158 | 159 | extend@^3.0.0: 160 | version "3.0.1" 161 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" 162 | integrity sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ= 163 | 164 | filesize@^4.1.2: 165 | version "4.1.2" 166 | resolved "https://registry.yarnpkg.com/filesize/-/filesize-4.1.2.tgz#fcd570af1353cea97897be64f56183adb995994b" 167 | integrity sha512-iSWteWtfNcrWQTkQw8ble2bnonSl7YJImsn9OZKpE2E4IHhXI78eASpDYUljXZZdYj36QsEKjOs/CsiDqmKMJw== 168 | 169 | has-ansi@^2.0.0: 170 | version "2.0.0" 171 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 172 | integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= 173 | dependencies: 174 | ansi-regex "^2.0.0" 175 | 176 | is@^3.2.0: 177 | version "3.2.1" 178 | resolved "https://registry.yarnpkg.com/is/-/is-3.2.1.tgz#d0ac2ad55eb7b0bec926a5266f6c662aaa83dca5" 179 | integrity sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU= 180 | 181 | json-stringify-safe@5.0.1: 182 | version "5.0.1" 183 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 184 | integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= 185 | 186 | lodash.findindex@^4.4.0: 187 | version "4.6.0" 188 | resolved "https://registry.yarnpkg.com/lodash.findindex/-/lodash.findindex-4.6.0.tgz#a3245dee61fb9b6e0624b535125624bb69c11106" 189 | integrity sha1-oyRd7mH7m24GJLU1ElYku2nBEQY= 190 | 191 | lodash.get@^4.4.2: 192 | version "4.4.2" 193 | resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" 194 | integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= 195 | 196 | lodash.isempty@^4.4.0: 197 | version "4.4.0" 198 | resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" 199 | integrity sha1-b4bL7di+TsmHvpqvM8loTbGzHn4= 200 | 201 | lodash.isequal@^4.0.0: 202 | version "4.5.0" 203 | resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" 204 | integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= 205 | 206 | lodash.merge@^4.6.0: 207 | version "4.6.0" 208 | resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" 209 | integrity sha1-aYhLoUSsM/5plzemCG3v+t0PicU= 210 | 211 | lodash.trimend@^4.5.1: 212 | version "4.5.1" 213 | resolved "https://registry.yarnpkg.com/lodash.trimend/-/lodash.trimend-4.5.1.tgz#12804437286b98cad8996b79414e11300114082f" 214 | integrity sha1-EoBENyhrmMrYmWt5QU4RMAEUCC8= 215 | 216 | lodash@2.4.2: 217 | version "2.4.2" 218 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e" 219 | integrity sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4= 220 | 221 | lodash@^4.14.0: 222 | version "4.17.4" 223 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" 224 | integrity sha1-eCA6TRwyiuHYbcpkYONptX9AVa4= 225 | 226 | lodash@^4.17.10: 227 | version "4.17.11" 228 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" 229 | integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== 230 | 231 | methods@^1.1.1: 232 | version "1.1.2" 233 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 234 | integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= 235 | 236 | ms@2.0.0: 237 | version "2.0.0" 238 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 239 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 240 | 241 | ms@^2.1.1: 242 | version "2.1.1" 243 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 244 | integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== 245 | 246 | object-path@^0.11.4: 247 | version "0.11.4" 248 | resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" 249 | integrity sha1-NwrnUvvzfePqcKhhwju6iRVpGUk= 250 | 251 | semver@5.5.0: 252 | version "5.5.0" 253 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" 254 | integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== 255 | 256 | semver@^5.0.1, semver@^5.3.0: 257 | version "5.4.1" 258 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" 259 | integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== 260 | 261 | shimmer@1.0.0: 262 | version "1.0.0" 263 | resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.0.0.tgz#49c2d71c678360b802be18b278382d1cbb805c39" 264 | integrity sha1-ScLXHGeDYLgCvhiyeDgtHLuAXDk= 265 | 266 | shimmer@^1.0.0, shimmer@^1.1.0: 267 | version "1.1.0" 268 | resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.1.0.tgz#97d7377137ffbbab425522e429fe0aa89a488b35" 269 | integrity sha1-l9c3cTf/u6tCVSLkKf4KqJpIizU= 270 | 271 | signal-exit@3.0.2: 272 | version "3.0.2" 273 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" 274 | integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= 275 | 276 | strip-ansi@^3.0.0: 277 | version "3.0.1" 278 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 279 | integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= 280 | dependencies: 281 | ansi-regex "^2.0.0" 282 | 283 | supports-color@^2.0.0: 284 | version "2.0.0" 285 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 286 | integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= 287 | 288 | tslib@1.9.3: 289 | version "1.9.3" 290 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" 291 | integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== 292 | 293 | uuid@^3.0.1: 294 | version "3.1.0" 295 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" 296 | integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g== 297 | 298 | vxx@1.2.2: 299 | version "1.2.2" 300 | resolved "https://registry.yarnpkg.com/vxx/-/vxx-1.2.2.tgz#741fb51c6f11d3383da6f9b92018a5d7ba807611" 301 | integrity sha1-dB+1HG8R0zg9pvm5IBil17qAdhE= 302 | dependencies: 303 | continuation-local-storage "^3.1.4" 304 | debug "^2.6.3" 305 | extend "^3.0.0" 306 | is "^3.2.0" 307 | lodash.findindex "^4.4.0" 308 | lodash.isequal "^4.0.0" 309 | lodash.merge "^4.6.0" 310 | methods "^1.1.1" 311 | semver "^5.0.1" 312 | shimmer "^1.0.0" 313 | uuid "^3.0.1" 314 | 315 | ws@^6.0.0: 316 | version "6.1.0" 317 | resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.0.tgz#119a9dbf92c54e190ec18d10e871d55c95cf9373" 318 | integrity sha512-H3dGVdGvW2H8bnYpIDc3u3LH8Wue3Qh+Zto6aXXFzvESkTVT6rAfKR6tR/+coaUvxs8yHtmNV0uioBF62ZGSTg== 319 | dependencies: 320 | async-limiter "~1.0.0" 321 | --------------------------------------------------------------------------------