##// END OF EJS Templates
elasticsearch: bump to ES 6.x
ergo -
Show More
@@ -1,43 +1,46 b''
1 language: python
1 language: python
2
2
3 dist: xenial
3 dist: xenial
4
4
5 notifications:
5 notifications:
6 on_success: change
6 on_success: change
7 on_failure: always
7 on_failure: always
8
8
9 matrix:
9 matrix:
10 include:
10 include:
11 - python: 3.5
11 - python: 3.5
12 env: TOXENV=py35
12 env: TOXENV=py35 ES_VERSION=6.6.2 ES_DOWNLOAD_URL=https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-oss-${ES_VERSION}.tar.gz
13 - python: 3.6
13 - python: 3.6
14 env: TOXENV=py36
14 env: TOXENV=py36 ES_VERSION=6.6.2 ES_DOWNLOAD_URL=https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-oss-${ES_VERSION}.tar.gz
15 addons:
15 addons:
16 postgresql: "9.6"
16 postgresql: "9.6"
17 - python: 3.6
17 - python: 3.6
18 env: TOXENV=py36 PGPORT=5432
18 env: TOXENV=py36 PGPORT=5432 ES_VERSION=6.6.2 ES_DOWNLOAD_URL=https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-oss-${ES_VERSION}.tar.gz
19 addons:
19 addons:
20 postgresql: "10"
20 postgresql: "10"
21 apt:
21 apt:
22 packages:
22 packages:
23 - postgresql-10
23 - postgresql-10
24 - postgresql-client-10
24 - postgresql-client-10
25
25
26 install:
26 install:
27 - wget ${ES_DOWNLOAD_URL}
28 - tar -xzf elasticsearch-${ES_VERSION}.tar.gz
29 - ./elasticsearch-${ES_VERSION}/bin/elasticsearch &
27 - travis_retry pip install -U setuptools pip tox
30 - travis_retry pip install -U setuptools pip tox
28
31
29 script:
32 script:
30 - travis_retry tox
33 - travis_retry tox
31
34
32 services:
35 services:
33 - postgresql
36 - postgresql
34 - elasticsearch
37 - elasticsearch
35 - redis
38 - redis
36
39
37 before_script:
40 before_script:
38 - psql -c "create user test with encrypted password 'test';" -U postgres
41 - psql -c "create user test with encrypted password 'test';" -U postgres
39 - psql -c 'create database appenlight_test owner test;' -U postgres
42 - psql -c 'create database appenlight_test owner test;' -U postgres
40
43
41 after_success:
44 after_success:
42 - pip install coveralls
45 - pip install coveralls
43 - coveralls
46 - coveralls
@@ -1,577 +1,572 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright 2010 - 2017 RhodeCode GmbH and the AppEnlight project authors
3 # Copyright 2010 - 2017 RhodeCode GmbH and the AppEnlight project authors
4 #
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
7 # You may obtain a copy of the License at
8 #
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
10 #
11 # Unless required by applicable law or agreed to in writing, software
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
15 # limitations under the License.
16
16
17 import argparse
17 import argparse
18 import datetime
18 import datetime
19 import logging
19 import logging
20 import copy
20 import copy
21
21
22 import sqlalchemy as sa
22 import sqlalchemy as sa
23 import elasticsearch.exceptions
23 import elasticsearch.exceptions
24 import elasticsearch.helpers
24 import elasticsearch.helpers
25
25
26 from collections import defaultdict
26 from collections import defaultdict
27 from pyramid.paster import setup_logging
27 from pyramid.paster import setup_logging
28 from pyramid.paster import bootstrap
28 from pyramid.paster import bootstrap
29 from appenlight.models import DBSession, Datastores, metadata
29 from appenlight.models import DBSession, Datastores, metadata
30 from appenlight.lib import get_callable
30 from appenlight.lib import get_callable
31 from appenlight.models.report_group import ReportGroup
31 from appenlight.models.report_group import ReportGroup
32 from appenlight.models.report import Report
32 from appenlight.models.report import Report
33 from appenlight.models.report_stat import ReportStat
33 from appenlight.models.report_stat import ReportStat
34 from appenlight.models.log import Log
34 from appenlight.models.log import Log
35 from appenlight.models.slow_call import SlowCall
35 from appenlight.models.slow_call import SlowCall
36 from appenlight.models.metric import Metric
36 from appenlight.models.metric import Metric
37
37
38 log = logging.getLogger(__name__)
38 log = logging.getLogger(__name__)
39
39
40 tables = {
40 tables = {
41 "slow_calls_p_": [],
41 "slow_calls_p_": [],
42 "reports_stats_p_": [],
42 "reports_stats_p_": [],
43 "reports_p_": [],
43 "reports_p_": [],
44 "reports_groups_p_": [],
44 "reports_groups_p_": [],
45 "logs_p_": [],
45 "logs_p_": [],
46 "metrics_p_": [],
46 "metrics_p_": [],
47 }
47 }
48
48
49
49
50 def detect_tables(table_prefix):
50 def detect_tables(table_prefix):
51 found_tables = []
51 found_tables = []
52 db_tables_query = """
52 db_tables_query = """
53 SELECT tablename FROM pg_tables WHERE tablename NOT LIKE 'pg_%' AND
53 SELECT tablename FROM pg_tables WHERE tablename NOT LIKE 'pg_%' AND
54 tablename NOT LIKE 'sql_%' ORDER BY tablename ASC;"""
54 tablename NOT LIKE 'sql_%' ORDER BY tablename ASC;"""
55
55
56 for table in DBSession.execute(db_tables_query).fetchall():
56 for table in DBSession.execute(db_tables_query).fetchall():
57 tablename = table.tablename
57 tablename = table.tablename
58 if tablename.startswith(table_prefix):
58 if tablename.startswith(table_prefix):
59 t = sa.Table(
59 t = sa.Table(
60 tablename, metadata, autoload=True, autoload_with=DBSession.bind.engine
60 tablename, metadata, autoload=True, autoload_with=DBSession.bind.engine
61 )
61 )
62 found_tables.append(t)
62 found_tables.append(t)
63 return found_tables
63 return found_tables
64
64
65
65
66 def main():
66 def main():
67 """
67 """
68 Recreates Elasticsearch indexes
68 Recreates Elasticsearch indexes
69 Performs reindex of whole db to Elasticsearch
69 Performs reindex of whole db to Elasticsearch
70
70
71 """
71 """
72
72
73 # need parser twice because we first need to load ini file
73 # need parser twice because we first need to load ini file
74 # bootstrap pyramid and then load plugins
74 # bootstrap pyramid and then load plugins
75 pre_parser = argparse.ArgumentParser(
75 pre_parser = argparse.ArgumentParser(
76 description="Reindex AppEnlight data", add_help=False
76 description="Reindex AppEnlight data", add_help=False
77 )
77 )
78 pre_parser.add_argument(
78 pre_parser.add_argument(
79 "-c", "--config", required=True, help="Configuration ini file of application"
79 "-c", "--config", required=True, help="Configuration ini file of application"
80 )
80 )
81 pre_parser.add_argument("-h", "--help", help="Show help", nargs="?")
81 pre_parser.add_argument("-h", "--help", help="Show help", nargs="?")
82 pre_parser.add_argument(
82 pre_parser.add_argument(
83 "-t", "--types", nargs="+", help="Which parts of database should get reindexed"
83 "-t", "--types", nargs="+", help="Which parts of database should get reindexed"
84 )
84 )
85 args = pre_parser.parse_args()
85 args = pre_parser.parse_args()
86
86
87 config_uri = args.config
87 config_uri = args.config
88 setup_logging(config_uri)
88 setup_logging(config_uri)
89 log.setLevel(logging.INFO)
89 log.setLevel(logging.INFO)
90 env = bootstrap(config_uri)
90 env = bootstrap(config_uri)
91 parser = argparse.ArgumentParser(description="Reindex AppEnlight data")
91 parser = argparse.ArgumentParser(description="Reindex AppEnlight data")
92 choices = {
92 choices = {
93 "reports": "appenlight.scripts.reindex_elasticsearch:reindex_reports",
93 "reports": "appenlight.scripts.reindex_elasticsearch:reindex_reports",
94 "logs": "appenlight.scripts.reindex_elasticsearch:reindex_logs",
94 "logs": "appenlight.scripts.reindex_elasticsearch:reindex_logs",
95 "metrics": "appenlight.scripts.reindex_elasticsearch:reindex_metrics",
95 "metrics": "appenlight.scripts.reindex_elasticsearch:reindex_metrics",
96 "slow_calls": "appenlight.scripts.reindex_elasticsearch:reindex_slow_calls",
96 "slow_calls": "appenlight.scripts.reindex_elasticsearch:reindex_slow_calls",
97 "template": "appenlight.scripts.reindex_elasticsearch:update_template",
97 "template": "appenlight.scripts.reindex_elasticsearch:update_template",
98 }
98 }
99 for k, v in env["registry"].appenlight_plugins.items():
99 for k, v in env["registry"].appenlight_plugins.items():
100 if v.get("fulltext_indexer"):
100 if v.get("fulltext_indexer"):
101 choices[k] = v["fulltext_indexer"]
101 choices[k] = v["fulltext_indexer"]
102 parser.add_argument(
102 parser.add_argument(
103 "-t",
103 "-t",
104 "--types",
104 "--types",
105 nargs="*",
105 nargs="*",
106 choices=["all"] + list(choices.keys()),
106 choices=["all"] + list(choices.keys()),
107 default=[],
107 default=[],
108 help="Which parts of database should get reindexed",
108 help="Which parts of database should get reindexed",
109 )
109 )
110 parser.add_argument(
110 parser.add_argument(
111 "-c", "--config", required=True, help="Configuration ini file of application"
111 "-c", "--config", required=True, help="Configuration ini file of application"
112 )
112 )
113 args = parser.parse_args()
113 args = parser.parse_args()
114
114
115 if "all" in args.types:
115 if "all" in args.types:
116 args.types = list(choices.keys())
116 args.types = list(choices.keys())
117
117
118 print("Selected types to reindex: {}".format(args.types))
118 print("Selected types to reindex: {}".format(args.types))
119
119
120 log.info("settings {}".format(args.types))
120 log.info("settings {}".format(args.types))
121
121
122 if "template" in args.types:
122 if "template" in args.types:
123 get_callable(choices["template"])()
123 get_callable(choices["template"])()
124 args.types.remove("template")
124 args.types.remove("template")
125 for selected in args.types:
125 for selected in args.types:
126 get_callable(choices[selected])()
126 get_callable(choices[selected])()
127
127
128
128
129 def update_template():
129 def update_template():
130 try:
130 try:
131 Datastores.es.indices.delete_template("rcae_reports")
131 Datastores.es.indices.delete_template("rcae_reports")
132 except elasticsearch.exceptions.NotFoundError as e:
132 except elasticsearch.exceptions.NotFoundError as e:
133 log.error(e)
133 log.error(e)
134
134
135 try:
135 try:
136 Datastores.es.indices.delete_template("rcae_logs")
136 Datastores.es.indices.delete_template("rcae_logs")
137 except elasticsearch.exceptions.NotFoundError as e:
137 except elasticsearch.exceptions.NotFoundError as e:
138 log.error(e)
138 log.error(e)
139 try:
139 try:
140 Datastores.es.indices.delete_template("rcae_slow_calls")
140 Datastores.es.indices.delete_template("rcae_slow_calls")
141 except elasticsearch.exceptions.NotFoundError as e:
141 except elasticsearch.exceptions.NotFoundError as e:
142 log.error(e)
142 log.error(e)
143 try:
143 try:
144 Datastores.es.indices.delete_template("rcae_metrics")
144 Datastores.es.indices.delete_template("rcae_metrics")
145 except elasticsearch.exceptions.NotFoundError as e:
145 except elasticsearch.exceptions.NotFoundError as e:
146 log.error(e)
146 log.error(e)
147 log.info("updating elasticsearch template")
147 log.info("updating elasticsearch template")
148 tag_templates = [
148 tag_templates = [
149 {
149 {
150 "values": {
150 "values": {
151 "path_match": "tags.*",
151 "path_match": "tags.*",
152 "mapping": {
152 "mapping": {
153 "type": "object",
153 "type": "object",
154 "properties": {
154 "properties": {
155 "values": {"type": "text", "analyzer": "tag_value",
155 "values": {"type": "text", "analyzer": "tag_value",
156 "fields": {
156 "fields": {
157 "keyword": {
157 "keyword": {
158 "type": "keyword",
158 "type": "keyword",
159 "ignore_above": 256
159 "ignore_above": 256
160 }
160 }
161 }},
161 }},
162 "numeric_values": {"type": "float"},
162 "numeric_values": {"type": "float"},
163 },
163 },
164 },
164 },
165 }
165 }
166 }
166 }
167 ]
167 ]
168
168
169 shared_analysis = {
169 shared_analysis = {
170 "analyzer": {
170 "analyzer": {
171 "url_path": {
171 "url_path": {
172 "type": "custom",
172 "type": "custom",
173 "char_filter": [],
173 "char_filter": [],
174 "tokenizer": "path_hierarchy",
174 "tokenizer": "path_hierarchy",
175 "filter": [],
175 "filter": [],
176 },
176 },
177 "tag_value": {
177 "tag_value": {
178 "type": "custom",
178 "type": "custom",
179 "char_filter": [],
179 "char_filter": [],
180 "tokenizer": "keyword",
180 "tokenizer": "keyword",
181 "filter": ["lowercase"],
181 "filter": ["lowercase"],
182 },
182 },
183 }
183 }
184 }
184 }
185
185
186 shared_log_mapping = {
186 shared_log_mapping = {
187 "_all": {"enabled": False},
187 "_all": {"enabled": False},
188 "dynamic_templates": tag_templates,
188 "dynamic_templates": tag_templates,
189 "properties": {
189 "properties": {
190 "pg_id": {"type": "keyword", "index": True},
190 "pg_id": {"type": "keyword", "index": True},
191 "delete_hash": {"type": "keyword", "index": True},
191 "delete_hash": {"type": "keyword", "index": True},
192 "resource_id": {"type": "integer"},
192 "resource_id": {"type": "integer"},
193 "timestamp": {"type": "date"},
193 "timestamp": {"type": "date"},
194 "permanent": {"type": "boolean"},
194 "permanent": {"type": "boolean"},
195 "request_id": {"type": "keyword", "index": True},
195 "request_id": {"type": "keyword", "index": True},
196 "log_level": {"type": "text", "analyzer": "simple"},
196 "log_level": {"type": "text", "analyzer": "simple"},
197 "message": {"type": "text", "analyzer": "simple"},
197 "message": {"type": "text", "analyzer": "simple"},
198 "namespace": {
198 "namespace": {
199 "type": "text",
199 "type": "text",
200 "fields": {"keyword": {"type": "keyword", "ignore_above": 256}},
200 "fields": {"keyword": {"type": "keyword", "ignore_above": 256}},
201 },
201 },
202 "tags": {"type": "object"},
202 "tags": {"type": "object"},
203 "tag_list": {"type": "text", "analyzer": "tag_value",
203 "tag_list": {"type": "text", "analyzer": "tag_value",
204 "fields": {
204 "fields": {
205 "keyword": {
205 "keyword": {
206 "type": "keyword",
206 "type": "keyword",
207 "ignore_above": 256
207 "ignore_above": 256
208 }
208 }
209 }},
209 }},
210 },
210 },
211 }
211 }
212
212
213 report_schema = {
213 report_schema = {
214 "template": "rcae_r_*",
214 "template": "rcae_r_*",
215 "settings": {
215 "settings": {
216 "index": {
216 "index": {
217 "refresh_interval": "5s",
217 "refresh_interval": "5s",
218 "translog": {"sync_interval": "5s", "durability": "async"},
218 "translog": {"sync_interval": "5s", "durability": "async"}
219 "mapping": {"single_type": True}
220 },
219 },
221 "number_of_shards": 5,
220 "number_of_shards": 5,
222 "analysis": shared_analysis,
221 "analysis": shared_analysis,
223 },
222 },
224 "mappings": {
223 "mappings": {
225 "report": {
224 "report": {
226 "_all": {"enabled": False},
225 "_all": {"enabled": False},
227 "dynamic_templates": tag_templates,
226 "dynamic_templates": tag_templates,
228 "properties": {
227 "properties": {
229 "type": {"type": "keyword", "index": True},
228 "type": {"type": "keyword", "index": True},
230 # report group
229 # report group
231 "group_id": {"type": "keyword", "index": True},
230 "group_id": {"type": "keyword", "index": True},
232 "resource_id": {"type": "integer"},
231 "resource_id": {"type": "integer"},
233 "priority": {"type": "integer"},
232 "priority": {"type": "integer"},
234 "error": {"type": "text", "analyzer": "simple"},
233 "error": {"type": "text", "analyzer": "simple"},
235 "read": {"type": "boolean"},
234 "read": {"type": "boolean"},
236 "occurences": {"type": "integer"},
235 "occurences": {"type": "integer"},
237 "fixed": {"type": "boolean"},
236 "fixed": {"type": "boolean"},
238 "first_timestamp": {"type": "date"},
237 "first_timestamp": {"type": "date"},
239 "last_timestamp": {"type": "date"},
238 "last_timestamp": {"type": "date"},
240 "average_duration": {"type": "float"},
239 "average_duration": {"type": "float"},
241 "summed_duration": {"type": "float"},
240 "summed_duration": {"type": "float"},
242 "public": {"type": "boolean"},
241 "public": {"type": "boolean"},
243 # report
242 # report
244
243
245 "report_id": {"type": "keyword", "index": True},
244 "report_id": {"type": "keyword", "index": True},
246 "http_status": {"type": "integer"},
245 "http_status": {"type": "integer"},
247 "ip": {"type": "keyword", "index": True},
246 "ip": {"type": "keyword", "index": True},
248 "url_domain": {"type": "text", "analyzer": "simple"},
247 "url_domain": {"type": "text", "analyzer": "simple"},
249 "url_path": {"type": "text", "analyzer": "url_path"},
248 "url_path": {"type": "text", "analyzer": "url_path"},
250 "report_type": {"type": "integer"},
249 "report_type": {"type": "integer"},
251 "start_time": {"type": "date"},
250 "start_time": {"type": "date"},
252 "request_id": {"type": "keyword", "index": True},
251 "request_id": {"type": "keyword", "index": True},
253 "end_time": {"type": "date"},
252 "end_time": {"type": "date"},
254 "duration": {"type": "float"},
253 "duration": {"type": "float"},
255 "tags": {"type": "object"},
254 "tags": {"type": "object"},
256 "tag_list": {"type": "text", "analyzer": "tag_value",
255 "tag_list": {"type": "text", "analyzer": "tag_value",
257 "fields": {
256 "fields": {
258 "keyword": {
257 "keyword": {
259 "type": "keyword",
258 "type": "keyword",
260 "ignore_above": 256
259 "ignore_above": 256
261 }
260 }
262 }},
261 }},
263 "extra": {"type": "object"},
262 "extra": {"type": "object"},
264
263
265 # report stats
264 # report stats
266
265
267 "report_stat_id": {"type": "keyword", "index": True},
266 "report_stat_id": {"type": "keyword", "index": True},
268 "timestamp": {"type": "date"},
267 "timestamp": {"type": "date"},
269 "permanent": {"type": "boolean"},
268 "permanent": {"type": "boolean"},
270 "log_level": {"type": "text", "analyzer": "simple"},
269 "log_level": {"type": "text", "analyzer": "simple"},
271 "message": {"type": "text", "analyzer": "simple"},
270 "message": {"type": "text", "analyzer": "simple"},
272 "namespace": {
271 "namespace": {
273 "type": "text",
272 "type": "text",
274 "fields": {"keyword": {"type": "keyword", "ignore_above": 256}},
273 "fields": {"keyword": {"type": "keyword", "ignore_above": 256}},
275 },
274 },
276
275
277 "join_field": {
276 "join_field": {
278 "type": "join",
277 "type": "join",
279 "relations": {
278 "relations": {
280 "report_group": ["report", "report_stat"]
279 "report_group": ["report", "report_stat"]
281 }
280 }
282 }
281 }
283
282
284 },
283 },
285 }
284 }
286 }
285 }
287 }
286 }
288
287
289 Datastores.es.indices.put_template("rcae_reports", body=report_schema)
288 Datastores.es.indices.put_template("rcae_reports", body=report_schema)
290
289
291 logs_mapping = copy.deepcopy(shared_log_mapping)
290 logs_mapping = copy.deepcopy(shared_log_mapping)
292 logs_mapping["properties"]["log_id"] = logs_mapping["properties"]["pg_id"]
291 logs_mapping["properties"]["log_id"] = logs_mapping["properties"]["pg_id"]
293 del logs_mapping["properties"]["pg_id"]
292 del logs_mapping["properties"]["pg_id"]
294
293
295 log_template = {
294 log_template = {
296 "template": "rcae_l_*",
295 "template": "rcae_l_*",
297 "settings": {
296 "settings": {
298 "index": {
297 "index": {
299 "refresh_interval": "5s",
298 "refresh_interval": "5s",
300 "translog": {"sync_interval": "5s", "durability": "async"},
299 "translog": {"sync_interval": "5s", "durability": "async"},
301 "mapping": {"single_type": True}
302 },
300 },
303 "number_of_shards": 5,
301 "number_of_shards": 5,
304 "analysis": shared_analysis,
302 "analysis": shared_analysis,
305 },
303 },
306 "mappings": {
304 "mappings": {
307 "log": logs_mapping,
305 "log": logs_mapping,
308 },
306 },
309 }
307 }
310
308
311 Datastores.es.indices.put_template("rcae_logs", body=log_template)
309 Datastores.es.indices.put_template("rcae_logs", body=log_template)
312
310
313 slow_call_mapping = copy.deepcopy(shared_log_mapping)
311 slow_call_mapping = copy.deepcopy(shared_log_mapping)
314 slow_call_mapping["properties"]["slow_call_id"] = slow_call_mapping["properties"]["pg_id"]
312 slow_call_mapping["properties"]["slow_call_id"] = slow_call_mapping["properties"]["pg_id"]
315 del slow_call_mapping["properties"]["pg_id"]
313 del slow_call_mapping["properties"]["pg_id"]
316
314
317 slow_call_template = {
315 slow_call_template = {
318 "template": "rcae_sc_*",
316 "template": "rcae_sc_*",
319 "settings": {
317 "settings": {
320 "index": {
318 "index": {
321 "refresh_interval": "5s",
319 "refresh_interval": "5s",
322 "translog": {"sync_interval": "5s", "durability": "async"},
320 "translog": {"sync_interval": "5s", "durability": "async"},
323 "mapping": {"single_type": True}
324 },
321 },
325 "number_of_shards": 5,
322 "number_of_shards": 5,
326 "analysis": shared_analysis,
323 "analysis": shared_analysis,
327 },
324 },
328 "mappings": {
325 "mappings": {
329 "log": slow_call_mapping,
326 "log": slow_call_mapping,
330 },
327 },
331 }
328 }
332
329
333 Datastores.es.indices.put_template("rcae_slow_calls", body=slow_call_template)
330 Datastores.es.indices.put_template("rcae_slow_calls", body=slow_call_template)
334
331
335 metric_mapping = copy.deepcopy(shared_log_mapping)
332 metric_mapping = copy.deepcopy(shared_log_mapping)
336 metric_mapping["properties"]["metric_id"] = metric_mapping["properties"]["pg_id"]
333 metric_mapping["properties"]["metric_id"] = metric_mapping["properties"]["pg_id"]
337 del metric_mapping["properties"]["pg_id"]
334 del metric_mapping["properties"]["pg_id"]
338
335
339 metrics_template = {
336 metrics_template = {
340 "template": "rcae_m_*",
337 "template": "rcae_m_*",
341 "settings": {
338 "settings": {
342 "index": {
339 "index": {
343 "refresh_interval": "5s",
340 "refresh_interval": "5s",
344 "translog": {"sync_interval": "5s", "durability": "async"},
341 "translog": {"sync_interval": "5s", "durability": "async"},
345 "mapping": {"single_type": True}
346 },
342 },
347 "number_of_shards": 5,
343 "number_of_shards": 5,
348 "analysis": shared_analysis,
344 "analysis": shared_analysis,
349 },
345 },
350 "mappings": {
346 "mappings": {
351 "log": metric_mapping,
347 "log": metric_mapping,
352 },
348 },
353 }
349 }
354
350
355 Datastores.es.indices.put_template("rcae_metrics", body=metrics_template)
351 Datastores.es.indices.put_template("rcae_metrics", body=metrics_template)
356
352
357 uptime_metric_mapping = copy.deepcopy(shared_log_mapping)
353 uptime_metric_mapping = copy.deepcopy(shared_log_mapping)
358 uptime_metric_mapping["properties"]["uptime_id"] = uptime_metric_mapping["properties"]["pg_id"]
354 uptime_metric_mapping["properties"]["uptime_id"] = uptime_metric_mapping["properties"]["pg_id"]
359 del uptime_metric_mapping["properties"]["pg_id"]
355 del uptime_metric_mapping["properties"]["pg_id"]
360
356
361 uptime_metrics_template = {
357 uptime_metrics_template = {
362 "template": "rcae_uptime_ce_*",
358 "template": "rcae_uptime_ce_*",
363 "settings": {
359 "settings": {
364 "index": {
360 "index": {
365 "refresh_interval": "5s",
361 "refresh_interval": "5s",
366 "translog": {"sync_interval": "5s", "durability": "async"},
362 "translog": {"sync_interval": "5s", "durability": "async"},
367 "mapping": {"single_type": True}
368 },
363 },
369 "number_of_shards": 5,
364 "number_of_shards": 5,
370 "analysis": shared_analysis,
365 "analysis": shared_analysis,
371 },
366 },
372 "mappings": {
367 "mappings": {
373 "log": shared_log_mapping,
368 "log": shared_log_mapping,
374 },
369 },
375 }
370 }
376
371
377 Datastores.es.indices.put_template("rcae_uptime_metrics", body=uptime_metrics_template)
372 Datastores.es.indices.put_template("rcae_uptime_metrics", body=uptime_metrics_template)
378
373
379
374
380 def reindex_reports():
375 def reindex_reports():
381 reports_groups_tables = detect_tables("reports_groups_p_")
376 reports_groups_tables = detect_tables("reports_groups_p_")
382 try:
377 try:
383 Datastores.es.indices.delete("`rcae_r_*")
378 Datastores.es.indices.delete("`rcae_r_*")
384 except elasticsearch.exceptions.NotFoundError as e:
379 except elasticsearch.exceptions.NotFoundError as e:
385 log.error(e)
380 log.error(e)
386
381
387 log.info("reindexing report groups")
382 log.info("reindexing report groups")
388 i = 0
383 i = 0
389 task_start = datetime.datetime.now()
384 task_start = datetime.datetime.now()
390 for partition_table in reports_groups_tables:
385 for partition_table in reports_groups_tables:
391 conn = DBSession.connection().execution_options(stream_results=True)
386 conn = DBSession.connection().execution_options(stream_results=True)
392 result = conn.execute(partition_table.select())
387 result = conn.execute(partition_table.select())
393 while True:
388 while True:
394 chunk = result.fetchmany(2000)
389 chunk = result.fetchmany(2000)
395 if not chunk:
390 if not chunk:
396 break
391 break
397 es_docs = defaultdict(list)
392 es_docs = defaultdict(list)
398 for row in chunk:
393 for row in chunk:
399 i += 1
394 i += 1
400 item = ReportGroup(**dict(list(row.items())))
395 item = ReportGroup(**dict(list(row.items())))
401 d_range = item.partition_id
396 d_range = item.partition_id
402 es_docs[d_range].append(item.es_doc())
397 es_docs[d_range].append(item.es_doc())
403 if es_docs:
398 if es_docs:
404 name = partition_table.name
399 name = partition_table.name
405 log.info("round {}, {}".format(i, name))
400 log.info("round {}, {}".format(i, name))
406 for k, v in es_docs.items():
401 for k, v in es_docs.items():
407 to_update = {"_index": k, "_type": "report"}
402 to_update = {"_index": k, "_type": "report"}
408 [i.update(to_update) for i in v]
403 [i.update(to_update) for i in v]
409 elasticsearch.helpers.bulk(Datastores.es, v)
404 elasticsearch.helpers.bulk(Datastores.es, v)
410
405
411 log.info("total docs {} {}".format(i, datetime.datetime.now() - task_start))
406 log.info("total docs {} {}".format(i, datetime.datetime.now() - task_start))
412
407
413 i = 0
408 i = 0
414 log.info("reindexing reports")
409 log.info("reindexing reports")
415 task_start = datetime.datetime.now()
410 task_start = datetime.datetime.now()
416 reports_tables = detect_tables("reports_p_")
411 reports_tables = detect_tables("reports_p_")
417 for partition_table in reports_tables:
412 for partition_table in reports_tables:
418 conn = DBSession.connection().execution_options(stream_results=True)
413 conn = DBSession.connection().execution_options(stream_results=True)
419 result = conn.execute(partition_table.select())
414 result = conn.execute(partition_table.select())
420 while True:
415 while True:
421 chunk = result.fetchmany(2000)
416 chunk = result.fetchmany(2000)
422 if not chunk:
417 if not chunk:
423 break
418 break
424 es_docs = defaultdict(list)
419 es_docs = defaultdict(list)
425 for row in chunk:
420 for row in chunk:
426 i += 1
421 i += 1
427 item = Report(**dict(list(row.items())))
422 item = Report(**dict(list(row.items())))
428 d_range = item.partition_id
423 d_range = item.partition_id
429 es_docs[d_range].append(item.es_doc())
424 es_docs[d_range].append(item.es_doc())
430 if es_docs:
425 if es_docs:
431 name = partition_table.name
426 name = partition_table.name
432 log.info("round {}, {}".format(i, name))
427 log.info("round {}, {}".format(i, name))
433 for k, v in es_docs.items():
428 for k, v in es_docs.items():
434 to_update = {"_index": k, "_type": "report"}
429 to_update = {"_index": k, "_type": "report"}
435 [i.update(to_update) for i in v]
430 [i.update(to_update) for i in v]
436 elasticsearch.helpers.bulk(Datastores.es, v)
431 elasticsearch.helpers.bulk(Datastores.es, v)
437
432
438 log.info("total docs {} {}".format(i, datetime.datetime.now() - task_start))
433 log.info("total docs {} {}".format(i, datetime.datetime.now() - task_start))
439
434
440 log.info("reindexing reports stats")
435 log.info("reindexing reports stats")
441 i = 0
436 i = 0
442 task_start = datetime.datetime.now()
437 task_start = datetime.datetime.now()
443 reports_stats_tables = detect_tables("reports_stats_p_")
438 reports_stats_tables = detect_tables("reports_stats_p_")
444 for partition_table in reports_stats_tables:
439 for partition_table in reports_stats_tables:
445 conn = DBSession.connection().execution_options(stream_results=True)
440 conn = DBSession.connection().execution_options(stream_results=True)
446 result = conn.execute(partition_table.select())
441 result = conn.execute(partition_table.select())
447 while True:
442 while True:
448 chunk = result.fetchmany(2000)
443 chunk = result.fetchmany(2000)
449 if not chunk:
444 if not chunk:
450 break
445 break
451 es_docs = defaultdict(list)
446 es_docs = defaultdict(list)
452 for row in chunk:
447 for row in chunk:
453 rd = dict(list(row.items()))
448 rd = dict(list(row.items()))
454 # remove legacy columns
449 # remove legacy columns
455 # TODO: remove the column later
450 # TODO: remove the column later
456 rd.pop("size", None)
451 rd.pop("size", None)
457 item = ReportStat(**rd)
452 item = ReportStat(**rd)
458 i += 1
453 i += 1
459 d_range = item.partition_id
454 d_range = item.partition_id
460 es_docs[d_range].append(item.es_doc())
455 es_docs[d_range].append(item.es_doc())
461 if es_docs:
456 if es_docs:
462 name = partition_table.name
457 name = partition_table.name
463 log.info("round {}, {}".format(i, name))
458 log.info("round {}, {}".format(i, name))
464 for k, v in es_docs.items():
459 for k, v in es_docs.items():
465 to_update = {"_index": k, "_type": "report"}
460 to_update = {"_index": k, "_type": "report"}
466 [i.update(to_update) for i in v]
461 [i.update(to_update) for i in v]
467 elasticsearch.helpers.bulk(Datastores.es, v)
462 elasticsearch.helpers.bulk(Datastores.es, v)
468
463
469 log.info("total docs {} {}".format(i, datetime.datetime.now() - task_start))
464 log.info("total docs {} {}".format(i, datetime.datetime.now() - task_start))
470
465
471
466
472 def reindex_logs():
467 def reindex_logs():
473 try:
468 try:
474 Datastores.es.indices.delete("rcae_l_*")
469 Datastores.es.indices.delete("rcae_l_*")
475 except elasticsearch.exceptions.NotFoundError as e:
470 except elasticsearch.exceptions.NotFoundError as e:
476 log.error(e)
471 log.error(e)
477
472
478 # logs
473 # logs
479 log.info("reindexing logs")
474 log.info("reindexing logs")
480 i = 0
475 i = 0
481 task_start = datetime.datetime.now()
476 task_start = datetime.datetime.now()
482 log_tables = detect_tables("logs_p_")
477 log_tables = detect_tables("logs_p_")
483 for partition_table in log_tables:
478 for partition_table in log_tables:
484 conn = DBSession.connection().execution_options(stream_results=True)
479 conn = DBSession.connection().execution_options(stream_results=True)
485 result = conn.execute(partition_table.select())
480 result = conn.execute(partition_table.select())
486 while True:
481 while True:
487 chunk = result.fetchmany(2000)
482 chunk = result.fetchmany(2000)
488 if not chunk:
483 if not chunk:
489 break
484 break
490 es_docs = defaultdict(list)
485 es_docs = defaultdict(list)
491
486
492 for row in chunk:
487 for row in chunk:
493 i += 1
488 i += 1
494 item = Log(**dict(list(row.items())))
489 item = Log(**dict(list(row.items())))
495 d_range = item.partition_id
490 d_range = item.partition_id
496 es_docs[d_range].append(item.es_doc())
491 es_docs[d_range].append(item.es_doc())
497 if es_docs:
492 if es_docs:
498 name = partition_table.name
493 name = partition_table.name
499 log.info("round {}, {}".format(i, name))
494 log.info("round {}, {}".format(i, name))
500 for k, v in es_docs.items():
495 for k, v in es_docs.items():
501 to_update = {"_index": k, "_type": "log"}
496 to_update = {"_index": k, "_type": "log"}
502 [i.update(to_update) for i in v]
497 [i.update(to_update) for i in v]
503 elasticsearch.helpers.bulk(Datastores.es, v)
498 elasticsearch.helpers.bulk(Datastores.es, v)
504
499
505 log.info("total docs {} {}".format(i, datetime.datetime.now() - task_start))
500 log.info("total docs {} {}".format(i, datetime.datetime.now() - task_start))
506
501
507
502
508 def reindex_metrics():
503 def reindex_metrics():
509 try:
504 try:
510 Datastores.es.indices.delete("rcae_m_*")
505 Datastores.es.indices.delete("rcae_m_*")
511 except elasticsearch.exceptions.NotFoundError as e:
506 except elasticsearch.exceptions.NotFoundError as e:
512 log.error(e)
507 log.error(e)
513
508
514 log.info("reindexing applications metrics")
509 log.info("reindexing applications metrics")
515 i = 0
510 i = 0
516 task_start = datetime.datetime.now()
511 task_start = datetime.datetime.now()
517 metric_tables = detect_tables("metrics_p_")
512 metric_tables = detect_tables("metrics_p_")
518 for partition_table in metric_tables:
513 for partition_table in metric_tables:
519 conn = DBSession.connection().execution_options(stream_results=True)
514 conn = DBSession.connection().execution_options(stream_results=True)
520 result = conn.execute(partition_table.select())
515 result = conn.execute(partition_table.select())
521 while True:
516 while True:
522 chunk = result.fetchmany(2000)
517 chunk = result.fetchmany(2000)
523 if not chunk:
518 if not chunk:
524 break
519 break
525 es_docs = defaultdict(list)
520 es_docs = defaultdict(list)
526 for row in chunk:
521 for row in chunk:
527 i += 1
522 i += 1
528 item = Metric(**dict(list(row.items())))
523 item = Metric(**dict(list(row.items())))
529 d_range = item.partition_id
524 d_range = item.partition_id
530 es_docs[d_range].append(item.es_doc())
525 es_docs[d_range].append(item.es_doc())
531 if es_docs:
526 if es_docs:
532 name = partition_table.name
527 name = partition_table.name
533 log.info("round {}, {}".format(i, name))
528 log.info("round {}, {}".format(i, name))
534 for k, v in es_docs.items():
529 for k, v in es_docs.items():
535 to_update = {"_index": k, "_type": "log"}
530 to_update = {"_index": k, "_type": "log"}
536 [i.update(to_update) for i in v]
531 [i.update(to_update) for i in v]
537 elasticsearch.helpers.bulk(Datastores.es, v)
532 elasticsearch.helpers.bulk(Datastores.es, v)
538
533
539 log.info("total docs {} {}".format(i, datetime.datetime.now() - task_start))
534 log.info("total docs {} {}".format(i, datetime.datetime.now() - task_start))
540
535
541
536
542 def reindex_slow_calls():
537 def reindex_slow_calls():
543 try:
538 try:
544 Datastores.es.indices.delete("rcae_sc_*")
539 Datastores.es.indices.delete("rcae_sc_*")
545 except elasticsearch.exceptions.NotFoundError as e:
540 except elasticsearch.exceptions.NotFoundError as e:
546 log.error(e)
541 log.error(e)
547
542
548 log.info("reindexing slow calls")
543 log.info("reindexing slow calls")
549 i = 0
544 i = 0
550 task_start = datetime.datetime.now()
545 task_start = datetime.datetime.now()
551 slow_calls_tables = detect_tables("slow_calls_p_")
546 slow_calls_tables = detect_tables("slow_calls_p_")
552 for partition_table in slow_calls_tables:
547 for partition_table in slow_calls_tables:
553 conn = DBSession.connection().execution_options(stream_results=True)
548 conn = DBSession.connection().execution_options(stream_results=True)
554 result = conn.execute(partition_table.select())
549 result = conn.execute(partition_table.select())
555 while True:
550 while True:
556 chunk = result.fetchmany(2000)
551 chunk = result.fetchmany(2000)
557 if not chunk:
552 if not chunk:
558 break
553 break
559 es_docs = defaultdict(list)
554 es_docs = defaultdict(list)
560 for row in chunk:
555 for row in chunk:
561 i += 1
556 i += 1
562 item = SlowCall(**dict(list(row.items())))
557 item = SlowCall(**dict(list(row.items())))
563 d_range = item.partition_id
558 d_range = item.partition_id
564 es_docs[d_range].append(item.es_doc())
559 es_docs[d_range].append(item.es_doc())
565 if es_docs:
560 if es_docs:
566 name = partition_table.name
561 name = partition_table.name
567 log.info("round {}, {}".format(i, name))
562 log.info("round {}, {}".format(i, name))
568 for k, v in es_docs.items():
563 for k, v in es_docs.items():
569 to_update = {"_index": k, "_type": "log"}
564 to_update = {"_index": k, "_type": "log"}
570 [i.update(to_update) for i in v]
565 [i.update(to_update) for i in v]
571 elasticsearch.helpers.bulk(Datastores.es, v)
566 elasticsearch.helpers.bulk(Datastores.es, v)
572
567
573 log.info("total docs {} {}".format(i, datetime.datetime.now() - task_start))
568 log.info("total docs {} {}".format(i, datetime.datetime.now() - task_start))
574
569
575
570
576 if __name__ == "__main__":
571 if __name__ == "__main__":
577 main()
572 main()
General Comments 4
Under Review
author

Auto status change to "Under Review"

Under Review
author

Auto status change to "Under Review"

You need to be logged in to leave comments. Login now