def clear_zone_awareness(es): # There doesn't appear to be a proper way to unset settings # https://github.com/elastic/elasticsearch/issues/6732 cluster = ClusterClient(es) cmd = {"persistent": {"cluster.routing.allocation.awareness.force.zone.values": "", "cluster.routing.allocation.awareness.attributes": ""}} confirm("Remove the allocation awareness settings from the cluster?") pprint(cluster.put_settings(cmd)) print("Cleared")
def cluster_status(es): cluster = ClusterClient(es) print("\nCLUSTER HEALTH") pprint(cluster.health()) print("\nPENDING TASKS") pprint(cluster.pending_tasks()) print("\nNODES") for node in get_nodes_info(es): print(node.name, node.docs) print("\nSHARD ALLOCATION") cat = CatClient(es) print(cat.allocation(v=True))
def clear_zone_awareness(es): # There doesn't appear to be a proper way to unset settings # https://github.com/elastic/elasticsearch/issues/6732 cluster = ClusterClient(es) cmd = { "persistent": { "cluster.routing.allocation.awareness.force.zone.values": "", "cluster.routing.allocation.awareness.attributes": "" } } confirm("Remove the allocation awareness settings from the cluster?") pprint(cluster.put_settings(cmd)) print("Cleared")
def force_zone_awareness(es): cluster = ClusterClient(es) print("NODE SETTINGS:") for node in get_nodes_info(es): pprint(node.settings) zones = input("\nEnter the zone names, separated by a comma\n") confirm("Are you sure these zones exist?") cmd = {"persistent": {"cluster.routing.allocation.awareness.force.zone.values": zones, "cluster.routing.allocation.awareness.attributes": "zone"}} print("This will add the following settings") pprint(cmd) confirm("Okay?") pprint(cluster.put_settings(cmd)) print("Finished")
def force_zone_awareness(es): cluster = ClusterClient(es) print("NODE SETTINGS:") for node in get_nodes_info(es): pprint(node.settings) zones = raw_input("\nEnter the zone names, separated by a comma\n") confirm("Are you sure these zones exist?") cmd = {"persistent": {"cluster.routing.allocation.awareness.force.zone.values": zones, "cluster.routing.allocation.awareness.attributes": "zone"}} print("This will add the following settings") pprint(cmd) confirm("Okay?") pprint(cluster.put_settings(cmd)) print("Finished")
def decommission_node(es): cluster = ClusterClient(es) print("The nodes are:") nodes = get_nodes_info(es) for node in nodes: print(node.name, node.docs) confirm("Are you sure you want to decommission a node?") node_name = raw_input("Which one would you like to decommission?\nname:") names = [node.name for node in nodes] if node_name not in names: print("You must enter one of {}".format(", ".join(names))) return confirm("This will remove all shards from {}, okay?".format(node_name)) cmd = {"transient": {"cluster.routing.allocation.exclude._name": node_name}} pprint(cluster.put_settings(cmd)) print("The node is now being decommissioned.")
def decommission_node(es): cluster = ClusterClient(es) print "The nodes are:" nodes = get_nodes_info(es) for node in nodes: print node.name, node.docs confirm("Are you sure you want to decommission a node?") node_name = raw_input("Which one would you like to decommission?\nname:") names = [node.name for node in nodes] if node_name not in names: print "You must enter one of {}".format(", ".join(names)) return confirm("This will remove all shards from {}, okay?".format(node_name)) cmd = {"transient": {"cluster.routing.allocation.exclude._name": node_name}} pprint(cluster.put_settings(cmd)) print "The node is now being decommissioned."
def copy_index(self, from_index, to_index): ic = IndicesClient(self.es) ic.freeze(from_index) sys.stderr.write("copy {} to {}\n".format(from_index, to_index)) ic.clone(from_index, to_index, body={"settings": { "index": { "number_of_replicas": 0 } }}) ic.unfreeze(from_index) ic.unfreeze(to_index) status = ClusterClient(self.es).health(to_index)['status'] if status != 'green': sys.stderr.write("{}\n".format( ClusterClient(self.es).health(to_index))) raise Exception( "clonned index status {} is not green".format(to_index))
def relocate(): conf = config() try: es = Elasticsearch(conf['cluster_address']) escat = CatClient(es) escluster = ClusterClient(es) except Exception, e: print("Unable to connect to ES cluster. Reason: {}".format(e)) sys.exit(1)
def clean_urls(self): """Make sure the input urls are valid Elasticsearch hosts.""" input_urls = self.cleaned_data['urls'] # Create an Elasticsearch test client and see if a health check for the instance succeeds try: client = create_es_client(input_urls) ClusterClient(client).health() return input_urls except ConnectionError: raise ValidationError('Invalid Elasticsearch host url(s).')
def cluster_settings(es): cluster = ClusterClient(es) pprint(cluster.get_settings())
def pending_tasks(es): cluster = ClusterClient(es) pprint(cluster.pending_tasks())
def create_app( schema_path='schemas/', rest_subdir='indexes', template_subdir='templates', ): # type: (str, str, str) -> flask.app.Flask logging.basicConfig(level=logging.DEBUG) app = Flask(__name__) # Configure configure_app(app) @app.errorhandler(Exception) def jsonify_exceptions(error): # type: (Exception) -> flask.app.Response # TODO put in sentry/rollbar/airbrake app.logger.exception('Unhandled error: %s', error) try: # ES exception problem = error.info['error']['reason'] except AttributeError: problem = error.message return views.error_response(500, problem) # Connect to Elasticsearch es = configure_elasticsearch(app) app.cluster = ClusterClient(es) app.datastore = DataStore(es) # Connect to Database from .database import db db.init_app(app) app.db = db with app.app_context(): db.engine.execute('CREATE EXTENSION IF NOT EXISTS HSTORE') db.create_all() # Create Geocoder app.geocode = partial(GoogleV3().geocode, exactly_one=False) # Setup auth app.register_blueprint(auth) app.before_first_request(create_oauth_flow) app.before_request(authenticate_user) # Setup URL rules configure_endpoints(app) # Load schemas app.schemastore = SwaggerSchemaStore() schema_dir = Path(schema_path) rest_dir = schema_dir.joinpath(rest_subdir) template_dir = schema_dir.joinpath(rest_subdir, template_subdir) # Non-REST endpoints for json_file in schema_dir.glob('*.json'): _add_schema(app, json_file) # Load templates before configuring indexes for json_file in template_dir.glob('*.json'): _add_template(app, json_file) # REST'ish indexes for json_file in rest_dir.glob('*.json'): index, swagger_spec = _add_schema(app, json_file, force_security=True) configure_index( index, swagger_spec, app.config['ELASTICSEARCH_NON_RESETTABLE_INDEX_SETTINGS'], es) configure_mappings(index, swagger_spec, es) _list_routes(app) app.logger.info('RelES reporting for duty...') return app
class Indexer: INDEX_PREFIX = "pulsar" def __init__(self, conf, queue): self.conf = conf host = self.conf.get("host", "es") port = self.conf.get("port", 9200) self.log = logging.getLogger("pulsar.indexer") logging.getLogger("elasticsearch").setLevel(logging.INFO) self.log.debug("port: %r" % port) self.es = Elasticsearch([{"host": host, "port": port}]) self.cluster_client = ClusterClient(self.es) health = self.cluster_client.health() if not health or health.get("number_of_nodes") < 1: raise Exception("No Elasticsearch nodes found: %r" % health) # Put our template self.indices_client = IndicesClient(self.es) self.index_prefix = self.conf.get("index_prefix", self.INDEX_PREFIX) self.indices_client.put_template( name=self.index_prefix, body=open("conf/es-template.json").read()) self.log.info("Put template to ES for pulsar indexes") self.last_event_time = time() self.index_prefix = self.index_prefix + "-" self.index_name = self.get_index_name() self.queue = queue self.counter = 0 self.stats_checkpoint = time() self.stats_every = 10000 try: # This will block as it reads from the queue self.bulk(self.es, self.iterator(), stats_only=True) except Exception as e: self.log.exception("Error with bulk", exc_info=e) def bulk(self, client, actions, stats_only=False, **kwargs): success, failed = 0, 0 # list of errors to be collected is not stats_only errors = [] for ok, item in parallel_bulk(client, actions, **kwargs): # go through request-reponse pairs and detect failures if not ok: if not stats_only: errors.append(item) failed += 1 else: success += 1 return success, failed if stats_only else errors def iterator(self): for doc in (json.loads(x) for x in iter(self.queue.get, "STOP")): self.counter += 1 if self.counter >= self.stats_every: took = time() - self.stats_checkpoint rate = float(self.counter) / took self.log.info("STATS: rate: %f" % rate) self.stats_checkpoint = time() self.counter = 0 yield doc def get_index_name(self): return "%s%s" % (self.index_prefix, datetime.date.today().isoformat())
def _update_max_compilations_limit(es, limit="10000/1m"): print("Updating script.max_compilations_rate to ", limit) cluster_client = ClusterClient(es) body = {"transient": {"script.max_compilations_rate": limit}} cluster_client.put_settings(body=body)
def health(self, index_nm): """ check cluster health """ return ClusterClient(self.es_storage).health(index_nm)