Merge lp:~thomir-deactivatedaccount/adt-image-mapper/trunk-fix-logging into lp:adt-image-mapper

Proposed by Thomi Richards
Status: Merged
Approved by: Thomi Richards
Approved revision: 10
Merged at revision: 10
Proposed branch: lp:~thomir-deactivatedaccount/adt-image-mapper/trunk-fix-logging
Merge into: lp:adt-image-mapper
Diff against target: 151 lines (+55/-6)
6 files modified
README.rst (+7/-0)
adt-service.conf (+5/-0)
adt_image_mapper/__init__.py (+38/-5)
adt_image_mapper/cloud.py (+1/-1)
adt_image_mapper/v1.py (+3/-0)
requirements.txt (+1/-0)
To merge this branch: bzr merge lp:~thomir-deactivatedaccount/adt-image-mapper/trunk-fix-logging
Reviewer Review Type Date Requested Status
Celso Providelo (community) Approve
Review via email: mp+253594@code.launchpad.net

Commit message

Enable logstash, configure logging properly.

Description of the change

Enable logstash, configure logging properly.

To post a comment you must log in.
Revision history for this message
Celso Providelo (cprov) wrote :

Thomi,

Just a minor point inline and one question.

Assuming ./logs/ exists for the apps (the upstart template creates it), gunicorn.log and access.log will only contain gunicorn specific messages, application INFO, WARN and ERROR will go to app.log, correct ?

It's odd because we can't really avoid looking in all 3 files almost always to completely figure out problems. Maybe with some time live we find alternatives to glue these streams together, perhaps in LS.

I was expecting more from gunicorn, µWSGI has a lot more logging options, but not logstash, http://uwsgi-docs.readthedocs.org/en/latest/Logging.html

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README.rst'
2--- README.rst 2015-03-16 21:00:16 +0000
3+++ README.rst 2015-03-19 22:31:03 +0000
4@@ -26,6 +26,13 @@
5 os_auth_url = http://172.20.161.138:5000/v2.0/
6 os_region_name = bot-prototype
7
8+Optionally, add a `[logstash]` section, which will enable the logstash logging handler::
9+
10+ [logstash]
11+ host = localhost
12+ port = 5959
13+ version = 1
14+
15 Run the servce::
16
17 $ gunicorn adt_image_mapper:app
18
19=== modified file 'adt-service.conf'
20--- adt-service.conf 2015-03-16 21:00:16 +0000
21+++ adt-service.conf 2015-03-19 22:31:03 +0000
22@@ -6,3 +6,8 @@
23 os_password = <redacted>
24 os_auth_url = http://172.20.161.138:5000/v2.0/
25 os_region_name = bot-prototype
26+
27+[logstash]
28+host = localhost
29+port = 5959
30+version = 1
31
32=== modified file 'adt_image_mapper/__init__.py'
33--- adt_image_mapper/__init__.py 2015-03-18 19:43:42 +0000
34+++ adt_image_mapper/__init__.py 2015-03-19 22:31:03 +0000
35@@ -17,9 +17,11 @@
36
37 import configparser
38 import logging
39+import os
40 import sys
41
42 import flask
43+import logstash
44
45 from adt_image_mapper import (
46 cloud,
47@@ -29,15 +31,12 @@
48
49
50 def create_flask_app(config=None):
51- logging.basicConfig(stream=sys.stdout, level=logging.INFO)
52- # Uncomment this next line if you want detailed debugging information about
53- # why candidate images are rejected. Shouldn't be needed.
54- # logging.getLogger(__name__).setLevel(logging.DEBUG)
55-
56 if config is None:
57 config = configparser.ConfigParser()
58 config.read("adt-service.conf")
59
60+ configure_logging(config)
61+
62 app = flask.Flask('adt_image_mapper')
63
64 app.add_url_rule(
65@@ -69,4 +68,38 @@
66 return app
67
68
69+
70+def configure_logging(config):
71+ root_logger = logging.getLogger()
72+ root_logger.setLevel(logging.INFO)
73+
74+ # silence requests logging, which is created by keystone & glance:
75+ requests_logger = logging.getLogger('requests')
76+ requests_logger.setLevel(logging.WARNING)
77+
78+ log_path = os.path.abspath(os.path.join(__file__, '../../logs/app.log'))
79+ log_dir = os.path.dirname(log_path)
80+ handler = None
81+ if os.path.exists(log_dir):
82+ handler = logging.FileHandler(log_path)
83+ else:
84+ print("'logs' directory '{}' does not exist, using stderr for app log.".format(log_dir))
85+ handler = logging.StreamHandler()
86+ handler.setFormatter(
87+ logging.Formatter(
88+ '%(asctime)s %(name)s %(levelname)s: %(message)s'
89+ )
90+ )
91+ root_logger.addHandler(handler)
92+
93+ if 'logstash' in config:
94+ root_logger.addHandler(
95+ logstash.LogstashHandler(
96+ config['logstash']['host'],
97+ int(config['logstash']['port']),
98+ int(config['logstash']['version'])
99+ )
100+ )
101+
102+
103 app = create_flask_app()
104
105=== modified file 'adt_image_mapper/cloud.py'
106--- adt_image_mapper/cloud.py 2015-03-19 02:55:47 +0000
107+++ adt_image_mapper/cloud.py 2015-03-19 22:31:03 +0000
108@@ -64,7 +64,7 @@
109 glance_client = self.get_glance_client(refresh=True)
110 candidate_image = self._get_candidate_image(
111 glance_client, series_name, architecture)
112- logger.info("Search finished, found %r", candidate_image)
113+ logger.info("Search finished, found image %s", candidate_image.name)
114 return candidate_image.name if candidate_image else None
115
116 def get_glance_client(self, refresh=False):
117
118=== modified file 'adt_image_mapper/v1.py'
119--- adt_image_mapper/v1.py 2015-03-13 01:08:05 +0000
120+++ adt_image_mapper/v1.py 2015-03-19 22:31:03 +0000
121@@ -14,6 +14,7 @@
122 # You should have received a copy of the GNU General Public License
123 # along with this program. If not, see <http://www.gnu.org/licenses/>.
124 #
125+import logging
126
127 from flask import (
128 current_app,
129@@ -26,11 +27,13 @@
130 MissingRequestParameters,
131 )
132
133+logger = logging.getLogger(__name__)
134
135 def get_image():
136 required = { 'series', 'architecture' }
137 missing = required.difference(request.args.keys())
138 if missing:
139+ logger.error("Got request '%r' with missing arguments %r", request.args, missing)
140 raise MissingRequestParameters(
141 missing,
142 'Must specify both series and architecture name'
143
144=== modified file 'requirements.txt'
145--- requirements.txt 2015-03-19 14:14:03 +0000
146+++ requirements.txt 2015-03-19 22:31:03 +0000
147@@ -8,3 +8,4 @@
148 gunicorn==19.3.0
149 python-glanceclient==0.16.1
150 python-keystoneclient==1.2.0
151+python-logstash==0.4.2

Subscribers

People subscribed via source and target branches

to all changes: