Files
opensearch-pyd/elasticsearch/connection/base.py
T
Jim Kelly 032a1aa799 Fixes issue introduced in 482f166 where the tracer spams when
unconfigured.

In the aforementioned commit, the existing behavior was changed,
I believe in advertantly, to set propagate to False if the
trace logger already has been configured. This seems to be the
opposite of the internet, and this change restores what appears
to have been the intent, and silences the tracer unless
it has been configured, in which case it will propagate.
2015-04-28 22:32:57 +02:00

108 lines
4.2 KiB
Python

import logging
try:
import simplejson as json
except ImportError:
import json
from ..exceptions import TransportError, HTTP_EXCEPTIONS
logger = logging.getLogger('elasticsearch')
# create the elasticsearch.trace logger, but only set propagate to False if the
# logger hasn't already been configured
_tracer_already_configured = 'elasticsearch.trace' in logging.Logger.manager.loggerDict
tracer = logging.getLogger('elasticsearch.trace')
if not _tracer_already_configured:
tracer.propagate = False
class Connection(object):
"""
Class responsible for maintaining a connection to an Elasticsearch node. It
holds persistent connection pool to it and it's main interface
(`perform_request`) is thread-safe.
Also responsible for logging.
"""
transport_schema = 'http'
def __init__(self, host='localhost', port=9200, url_prefix='', timeout=10, **kwargs):
"""
:arg host: hostname of the node (default: localhost)
:arg port: port to use (integer, default: 9200)
:arg url_prefix: optional url prefix for elasticsearch
:arg timeout: default timeout in seconds (float, default: 10)
"""
self.host = '%s://%s:%s' % (self.transport_schema, host, port)
if url_prefix:
url_prefix = '/' + url_prefix.strip('/')
self.url_prefix = url_prefix
self.timeout = timeout
def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, self.host)
def log_request_success(self, method, full_url, path, body, status_code, response, duration):
""" Log a successful API call. """
# TODO: optionally pass in params instead of full_url and do urlencode only when needed
def _pretty_json(data):
# pretty JSON in tracer curl logs
try:
return json.dumps(json.loads(data), sort_keys=True, indent=2, separators=(',', ': ')).replace("'", r'\u0027')
except (ValueError, TypeError):
# non-json data or a bulk request
return data
# body has already been serialized to utf-8, deserialize it for logging
# TODO: find a better way to avoid (de)encoding the body back and forth
if body:
body = body.decode('utf-8')
logger.info(
'%s %s [status:%s request:%.3fs]', method, full_url,
status_code, duration
)
logger.debug('> %s', body)
logger.debug('< %s', response)
if tracer.isEnabledFor(logging.INFO):
# include pretty in trace curls
path = path.replace('?', '?pretty&', 1) if '?' in path else path + '?pretty'
if self.url_prefix:
path = path.replace(self.url_prefix, '', 1)
tracer.info("curl -X%s 'http://localhost:9200%s' -d '%s'", method, path, _pretty_json(body) if body else '')
if tracer.isEnabledFor(logging.DEBUG):
tracer.debug('#[%s] (%.3fs)\n#%s', status_code, duration, _pretty_json(response).replace('\n', '\n#') if response else '')
def log_request_fail(self, method, full_url, body, duration, status_code=None, exception=None):
""" Log an unsuccessful API call. """
logger.warning(
'%s %s [status:%s request:%.3fs]', method, full_url,
status_code or 'N/A', duration, exc_info=exception is not None
)
# body has already been serialized to utf-8, deserialize it for logging
# TODO: find a better way to avoid (de)encoding the body back and forth
if body:
body = body.decode('utf-8')
logger.debug('> %s', body)
def _raise_error(self, status_code, raw_data):
""" Locate appropriate exception and raise it. """
error_message = raw_data
additional_info = None
try:
additional_info = json.loads(raw_data)
error_message = additional_info.get('error', error_message)
if isinstance(error_message, dict) and 'type' in error_message:
error_message = error_message['type']
except:
# we don't care what went wrong
pass
raise HTTP_EXCEPTIONS.get(status_code, TransportError)(status_code, error_message, additional_info)