Skip to content

Commit 159f692

Browse files
kevin-batesdimon222
authored andcommitted
Enable logging for all components, remove print stmts (#80)
This change enables a logger for each module of yarn-api-client. By default, nothing will be logged unless the calling application has configured logging. Once configured, entries will be logged relative to the configured log level. The calling application is also responsible for specifying the appropriate log formats, etc. An accessor method, get_logger(logger_name), has been created in case we need to add configuration for the loggers. In those cases, we'd probably configure the logger "yarn_api_client", so that each of the submodule loggers would inherit from that logger. Likewise, applications can configure "yarn_api_client" themselves and those changes will be picked up by the individual loggers. The previous INFO log statement has been changed to DEBUG and I've added timing results for the request. In addition, the previous print statements have been replaced with calls to apiLogger().warning(). Fixes: #73 Co-authored-by: Dmitry Romanenko <[email protected]>
1 parent 25c29b6 commit 159f692

File tree

8 files changed

+54
-26
lines changed

8 files changed

+54
-26
lines changed

tests/test_base.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,12 @@ def test_uri_parsing(self):
7070
self.assertEqual(result_uri.hostname, '123.45.67.89')
7171
self.assertEqual(result_uri.port, 1234)
7272
self.assertEqual(result_uri.is_https, False)
73-
73+
7474
result_uri = base.Uri('https://test-domain.com:1234')
7575
self.assertEqual(result_uri.scheme, 'https')
7676
self.assertEqual(result_uri.hostname, 'test-domain.com')
7777
self.assertEqual(result_uri.port, 1234)
7878
self.assertEqual(result_uri.is_https, True)
79-
8079

8180
def get_client(self):
8281
client = base.BaseYarnAPI()

yarn_api_client/application_master.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
# -*- coding: utf-8 -*-
22
from __future__ import unicode_literals
3-
from .base import BaseYarnAPI
3+
4+
from .base import BaseYarnAPI, get_logger
45
from .hadoop_conf import get_webproxy_endpoint
56

67

8+
log = get_logger(__name__)
9+
10+
711
class ApplicationMaster(BaseYarnAPI):
812
"""
913
The MapReduce Application Master REST API's allow the user to get status
@@ -24,7 +28,6 @@ class ApplicationMaster(BaseYarnAPI):
2428
"""
2529
def __init__(self, service_endpoint=None, timeout=30, auth=None, verify=True):
2630
if not service_endpoint:
27-
self.logger.debug('Get configuration from hadoop conf dir')
2831
service_endpoint = get_webproxy_endpoint(timeout, auth, verify)
2932

3033
super(ApplicationMaster, self).__init__(service_endpoint, timeout, auth, verify)

yarn_api_client/base.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
from __future__ import unicode_literals
33

44
import logging
5+
import os
56
import requests
67

8+
from datetime import datetime
9+
710
from .errors import APIError, ConfigurationError
811

912
try:
@@ -12,6 +15,14 @@
1215
from urllib.parse import urlparse, urlunparse
1316

1417

18+
def get_logger(logger_name):
19+
logger = logging.getLogger(logger_name)
20+
return logger
21+
22+
23+
log = get_logger(__name__)
24+
25+
1526
class Response(object):
1627
"""
1728
Basic container for response dictionary
@@ -49,7 +60,6 @@ def to_url(self, api_path=None):
4960

5061

5162
class BaseYarnAPI(object):
52-
__logger = None
5363
response_class = Response
5464

5565
def __init__(self, service_endpoint=None, timeout=None, auth=None, verify=True):
@@ -72,8 +82,6 @@ def request(self, api_path, method='GET', **kwargs):
7282
self._validate_configuration()
7383
api_endpoint = self.service_uri.to_url(api_path)
7484

75-
self.logger.info('API Endpoint {}'.format(api_endpoint))
76-
7785
if method == 'GET':
7886
headers = {}
7987
else:
@@ -82,20 +90,26 @@ def request(self, api_path, method='GET', **kwargs):
8290
if 'headers' in kwargs and kwargs['headers']:
8391
headers.update(kwargs['headers'])
8492

93+
begin = datetime.now()
8594
response = self.session.request(method=method, url=api_endpoint, headers=headers, timeout=self.timeout, **kwargs)
95+
end = datetime.now()
96+
log.debug(
97+
"'{method}' request against endpoint '{endpoint}' took {duration} ms".format(
98+
method=method,
99+
endpoint=api_endpoint,
100+
duration=round((end-begin).total_seconds()*1000,3)
101+
)
102+
)
86103

87104
if response.status_code in (200, 202):
88105
return self.response_class(response)
89106
else:
90-
msg = 'Response finished with status: %s. Details: %s' % (response.status_code, response.text)
107+
msg = "Response finished with status: {status}. Details: {msg}".format(
108+
status=response.status_code,
109+
msg=response.text
110+
)
91111
raise APIError(msg)
92112

93113
def construct_parameters(self, arguments):
94114
params = dict((key, value) for key, value in arguments if value is not None)
95115
return params
96-
97-
@property
98-
def logger(self):
99-
if self.__logger is None:
100-
self.__logger = logging.getLogger(self.__module__)
101-
return self.__logger

yarn_api_client/hadoop_conf.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
import xml.etree.ElementTree as ET
44
import requests
55

6+
from .base import get_logger
7+
8+
log = get_logger(__name__)
9+
610
CONF_DIR = os.getenv('HADOOP_CONF_DIR', '/etc/hadoop/conf')
711

812

@@ -14,7 +18,8 @@ def _get_rm_ids(hadoop_conf_path):
1418

1519

1620
def _get_maximum_container_memory(hadoop_conf_path):
17-
container_memory = int(parse(os.path.join(hadoop_conf_path,'yarn-site.xml'), 'yarn.nodemanager.resource.memory-mb'))
21+
container_memory = int(parse(os.path.join(hadoop_conf_path, 'yarn-site.xml'),
22+
'yarn.nodemanager.resource.memory-mb'))
1823
return container_memory
1924

2025

@@ -46,17 +51,19 @@ def _get_resource_manager(hadoop_conf_path, rm_id=None):
4651
def check_is_active_rm(url, timeout=30, auth=None, verify=True):
4752
try:
4853
response = requests.get(url + "/cluster", timeout=timeout, auth=auth, verify=verify)
49-
except:
54+
except Exception as e:
55+
log.warning("Exception encountered accessing RM '{url}': '{err}', continuing...".format(url=url, err=e))
5056
return False
5157

5258
if response.status_code != 200:
53-
print("Error to access RM - HTTP Code {}".format(response.status_code))
59+
log.warning("Failed to access RM '{url}' - HTTP Code '{status}', continuing...".format(url=url, status=response.status_code))
5460
return False
5561
else:
5662
return True
5763

5864

5965
def get_resource_manager_endpoint(timeout=30, auth=None, verify=True):
66+
log.info('Getting resource manager endpoint from config: {config_path}'.format(config_path=os.path.join(CONF_DIR, 'yarn-site.xml')))
6067
hadoop_conf_path = CONF_DIR
6168
rm_ids = _get_rm_ids(hadoop_conf_path)
6269
if rm_ids:
@@ -72,18 +79,21 @@ def get_resource_manager_endpoint(timeout=30, auth=None, verify=True):
7279

7380
def get_jobhistory_endpoint():
7481
config_path = os.path.join(CONF_DIR, 'mapred-site.xml')
82+
log.info('Getting jobhistory endpoint from config: {config_path}'.format(config_path=config_path))
7583
prop_name = 'mapreduce.jobhistory.webapp.address'
7684
return parse(config_path, prop_name)
7785

7886

7987
def get_nodemanager_endpoint():
8088
config_path = os.path.join(CONF_DIR, 'yarn-site.xml')
89+
log.info('Getting nodemanager endpoint from config: {config_path}'.format(config_path=config_path))
8190
prop_name = 'yarn.nodemanager.webapp.address'
8291
return parse(config_path, prop_name)
8392

8493

8594
def get_webproxy_endpoint(timeout=30, auth=None, verify=True):
8695
config_path = os.path.join(CONF_DIR, 'yarn-site.xml')
96+
log.info('Getting webproxy endpoint from config: {config_path}'.format(config_path=config_path))
8797
prop_name = 'yarn.web-proxy.address'
8898
value = parse(config_path, prop_name)
8999
return value or get_resource_manager_endpoint(timeout, auth, verify)

yarn_api_client/history_server.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
# -*- coding: utf-8 -*-
22
from __future__ import unicode_literals
3-
from .base import BaseYarnAPI
3+
4+
from .base import BaseYarnAPI, get_logger
45
from .constants import JobStateInternal
56
from .errors import IllegalArgumentError
67
from .hadoop_conf import get_jobhistory_endpoint
78

9+
log = get_logger(__name__)
10+
811

912
class HistoryServer(BaseYarnAPI):
1013
"""
@@ -24,7 +27,6 @@ class HistoryServer(BaseYarnAPI):
2427
"""
2528
def __init__(self, service_endpoint=None, timeout=30, auth=None, verify=True):
2629
if not service_endpoint:
27-
self.logger.debug('Get information from hadoop conf dir')
2830
service_endpoint = get_jobhistory_endpoint()
2931

3032
super(HistoryServer, self).__init__(service_endpoint, timeout, auth, verify)

yarn_api_client/main.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
# -*- coding: utf-8 -*-
22
from __future__ import unicode_literals
33
import argparse
4-
import logging
54
from pprint import pprint
6-
import sys
75

6+
from .base import get_logger
87
from .constants import (YarnApplicationState, FinalApplicationStatus,
98
ApplicationState, JobStateInternal)
109
from . import ResourceManager, NodeManager, HistoryServer, ApplicationMaster
1110

12-
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
11+
log = get_logger(__name__)
1312

1413

1514
def get_parser():

yarn_api_client/node_manager.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# -*- coding: utf-8 -*-
2-
from .base import BaseYarnAPI
2+
from .base import BaseYarnAPI, get_logger
33
from .constants import ApplicationState
44
from .errors import IllegalArgumentError
55
from .hadoop_conf import get_nodemanager_endpoint
66

7+
log = get_logger(__name__)
8+
79
LEGAL_APPLICATION_STATES = {s for s, _ in ApplicationState}
810

911

@@ -35,7 +37,6 @@ class NodeManager(BaseYarnAPI):
3537
"""
3638
def __init__(self, service_endpoint=None, timeout=30, auth=None, verify=True):
3739
if not service_endpoint:
38-
self.logger.debug('Get configuration from hadoop conf dir')
3940
service_endpoint = get_nodemanager_endpoint()
4041

4142
super(NodeManager, self).__init__(service_endpoint, timeout, auth, verify)

yarn_api_client/resource_manager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# -*- coding: utf-8 -*-
22
from __future__ import unicode_literals
3-
from .base import BaseYarnAPI
3+
from .base import BaseYarnAPI, get_logger
44
from .constants import YarnApplicationState, FinalApplicationStatus
55
from .errors import IllegalArgumentError
66
from .hadoop_conf import get_resource_manager_endpoint, check_is_active_rm, CONF_DIR, _get_maximum_container_memory
77
from collections import deque
88

9+
log = get_logger(__name__)
910
LEGAL_STATES = {s for s, _ in YarnApplicationState}
1011
LEGAL_FINAL_STATUSES = {s for s, _ in FinalApplicationStatus}
1112

@@ -73,7 +74,6 @@ class ResourceManager(BaseYarnAPI):
7374
def __init__(self, service_endpoints=None, timeout=30, auth=None, verify=True):
7475
active_service_endpoint = None
7576
if not service_endpoints:
76-
self.logger.debug('Get configuration from hadoop conf dir: {conf_dir}'.format(conf_dir=CONF_DIR))
7777
active_service_endpoint = get_resource_manager_endpoint(timeout, auth, verify)
7878
else:
7979
for endpoint in service_endpoints:

0 commit comments

Comments
 (0)