Commit 287fa7ac authored by Stavros Sachtouris's avatar Stavros Sachtouris
Browse files

Merge branch 'feature-logging' into develop

parents 6287a048 31a30991
......@@ -24,7 +24,7 @@ try:
PooledHTTPConnection
except ImportError:
stderr.write("`objpool` package is required to build kamaki docs.\n")
raise
# raise
path.insert(0, os.path.join(os.path.abspath(os.path.dirname(__file__)), '..'))
......
......@@ -120,6 +120,15 @@ The [global] group is treated by kamaki as a generic group for arbitrary options
* global.token <user authentication token>
* global.log_file <logfile full path>
set a custom location for kamaki logging. Default values are /var/log/kamaki.log, /var/log/kamaki/clients.log /tmp/kamaki.log and ./kamaki.log
* global.log_token <on|off>
allow kamaki to log user tokens
* global.log_data <on|off>
allow kamaki to log http data (by default, it logs only method, URL and headers)
* store.cli <UI command specifications for store>
a special package that is used to load storage commands to kamaki UIs. Don't touch this unless if you know what you are doing.
......@@ -159,6 +168,21 @@ The [global] group is treated by kamaki as a generic group for arbitrary options
Additional features
^^^^^^^^^^^^^^^^^^^
Log file location
"""""""""""""""""
Kamaki log file path is set by the following command::
$ kamaki config set log_file <logfile path>
By default, kamaki keeps a list of possible logfile locations::
/var/log/kamaki.log, /var/log/kamaki/clients.log, /tmp/kamaki.log, ./kamaki.log
When initialized, kamaki attempts to open one of these locations for writing, in the order presented above and uses the first accessible for appending logs. If the log_file option is set, kamaki prepends the value of this option to the logfile list, so the custom location will be the first one kamaki will attetmpt to log at.
Kamaki will not crush if the logging location is not accessible.
Richer connection logs
""""""""""""""""""""""
......
......@@ -388,6 +388,11 @@ def main():
if parser.arguments['version'].value:
exit(0)
log_file = parser.arguments['config'].get('global', 'log_file')
if log_file:
from kamaki.logger import set_log_filename
set_log_filename(log_file)
_init_session(parser.arguments)
from kamaki.cli.utils import suggest_missing
......
......@@ -31,10 +31,10 @@
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.command
import logging
from kamaki import logger
sendlog = logging.getLogger('clients.send')
recvlog = logging.getLogger('clients.recv')
logger.add_file_logger('cli', __name__, filename=logger.get_log_filename())
sendlog = logger.get_logger('cli')
class _command_init(object):
......@@ -49,7 +49,7 @@ class _command_init(object):
except KeyError:
pass
def _update_low_level_log(self):
def _set_log_params(self):
try:
self.client.LOG_TOKEN, self.client.LOG_DATA = (
self['config'].get('global', 'log_token') == 'on',
......
......@@ -51,7 +51,7 @@ class _astakos_init(_command_init):
base_url = self.config.get('astakos', 'url')\
or self.config.get('global', 'url')
self.client = AstakosClient(base_url=base_url, token=token)
self._update_low_level_log()
self._set_log_params()
self._update_max_threads()
def main(self):
......
......@@ -72,7 +72,7 @@ class _init_cyclades(_command_init):
base_url = self.config.get(service, 'url')\
or self.config.get('global', 'url')
self.client = CycladesClient(base_url=base_url, token=token)
self._update_low_level_log()
self._set_log_params()
self._update_max_threads()
def main(self):
......
......@@ -59,7 +59,7 @@ class _init_image(_command_init):
or self.config.get('compute', 'url')\
or self.config.get('global', 'url')
self.client = ImageClient(base_url=base_url, token=token)
self._update_low_level_log()
self._set_log_params()
self._update_max_threads()
def main(self):
......
......@@ -173,7 +173,7 @@ class _pithos_init(_command_init):
token=self.token,
account=self.account,
container=self.container)
self._update_low_level_log()
self._set_log_params()
self._update_max_threads()
def main(self):
......
......@@ -42,26 +42,26 @@ from random import random
from objpool.http import PooledHTTPConnection
from kamaki.clients.utils import logger
from kamaki import logger
DEBUG_LOG = logger.get_log_filename()
LOG_FILE = logger.get_log_filename()
TIMEOUT = 60.0 # seconds
HTTP_METHODS = ['GET', 'POST', 'PUT', 'HEAD', 'DELETE', 'COPY', 'MOVE']
logger.add_file_logger('clients.send', __name__, filename=DEBUG_LOG)
logger.add_file_logger('clients.send', __name__, filename=LOG_FILE)
sendlog = logger.get_logger('clients.send')
sendlog.debug('Logging location: %s' % DEBUG_LOG)
sendlog.debug('Logging location: %s' % LOG_FILE)
logger.add_file_logger('data.send', __name__, filename=DEBUG_LOG)
logger.add_file_logger('data.send', __name__, filename=LOG_FILE)
datasendlog = logger.get_logger('data.send')
logger.add_file_logger('clients.recv', __name__, filename=DEBUG_LOG)
logger.add_file_logger('clients.recv', __name__, filename=LOG_FILE)
recvlog = logger.get_logger('clients.recv')
logger.add_file_logger('data.recv', __name__, filename=DEBUG_LOG)
logger.add_file_logger('data.recv', __name__, filename=LOG_FILE)
datarecvlog = logger.get_logger('data.recv')
logger.add_file_logger('ClientError', __name__, filename=DEBUG_LOG)
logger.add_file_logger('ClientError', __name__, filename=LOG_FILE)
clienterrorlog = logger.get_logger('ClientError')
......@@ -186,7 +186,7 @@ class RequestManager(Logged):
headers=self.headers,
body=self.data)
self.log()
keep_trying = 60.0
keep_trying = TIMEOUT
while keep_trying > 0:
try:
return conn.getresponse()
......
......@@ -34,16 +34,17 @@
import logging
def get_log_filename(filename=(
'/var/log/kamaki.log',
'/var/log/kamaki/clients.log',
'/tmp/kamaki.log',
'kamaki.log')):
if not (isinstance(filename, list) or isinstance(filename, tuple)):
filename = (filename,)
for logfile in filename:
LOG_FILE = [
'/var/log/kamaki.log',
'/var/log/kamaki/clients.log',
'/tmp/kamaki.log',
'kamaki.log']
def get_log_filename():
for logfile in LOG_FILE:
try:
with open(logfile) as f:
with open(logfile, 'a+') as f:
f.seek(0)
except IOError:
continue
......@@ -51,6 +52,11 @@ def get_log_filename(filename=(
print('Failed to open any logging locations, file-logging aborted')
def set_log_filename(filename):
global LOG_FILE
LOG_FILE = [filename] + LOG_FILE
def add_file_logger(
name, caller,
level=logging.DEBUG, prefix='', filename='/tmp/kamaki.log'):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment