Merge ~stanley31/oem-qa-autosummary:add_logging into ~pieq/oem-qa-autosummary:master

Proposed by StanleyHuang
Status: Merged
Approved by: Pierre Equoy
Approved revision: 728d0b2934471dc223adb65bfe835c2edbddad1d
Merged at revision: a3d68bdfad0c05145dc32e11e9a62cf1373f6ab9
Proposed branch: ~stanley31/oem-qa-autosummary:add_logging
Merge into: ~pieq/oem-qa-autosummary:master
Diff against target: 231 lines (+52/-14)
3 files modified
autosummary/summary.py (+22/-11)
logging_conf.py (+22/-0)
webapp/__init__.py (+8/-3)
Reviewer Review Type Date Requested Status
Pierre Equoy Approve
Review via email: mp+404498@code.launchpad.net

Commit message

add logging into the front-end and back-end script.

Description of the change

Attached the logs under gunicorn and flask.

## The logging under gunicorn ##
(venv) stanley@stanley-ThinkPad-T490:~/Desktop/Git_Repos/oem-qa-autosummary$ gunicorn -w 2 -b 0.0.0.0:8080 -t 120 webapp:app
[2021-06-22 10:16:59 +0800] [16505] [INFO] Starting gunicorn 20.1.0
[2021-06-22 10:16:59 +0800] [16505] [INFO] Listening at: http://0.0.0.0:8080 (16505)
[2021-06-22 10:16:59 +0800] [16505] [INFO] Using worker: sync
[2021-06-22 10:16:59 +0800] [16507] [INFO] Booting worker with pid: 16507
[2021-06-22 10:16:59 +0800] [16508] [INFO] Booting worker with pid: 16508
[2021-06-22T10:16:59] [summary.py/MailContentNotFoundError] [ERROR] the mail.content file is not found on the WebDAV server
[2021-06-22T10:16:59] [summary.py/Sha256FileNotFoundError] [ERROR] sha256sum file for a given image is not found on the WebDAV server
[2021-06-22T10:16:59] [summary.py/MailContentNotFoundError] [ERROR] the mail.content file is not found on the WebDAV server
[2021-06-22T10:16:59] [summary.py/Sha256FileNotFoundError] [ERROR] sha256sum file for a given image is not found on the WebDAV server

[2021-06-22T10:17:17] [__init__.py/index] [INFO] Route to index page, method: GET
[2021-06-22T10:17:17] [__init__.py/index] [DEBUG] selected_project:
[2021-06-22T10:17:26] [__init__.py/index] [INFO] Route to index page, method: POST
[2021-06-22T10:17:33] [__init__.py/index] [DEBUG] selected_project: sutton
[2021-06-22T10:17:50] [__init__.py/generate_summary] [INFO] Route to summary page
[2021-06-22T10:17:50] [summary.py/__init__] [INFO] Summary object initailizing
[2021-06-22T10:17:50] [summary.py/__init__] [DEBUG] Prepare launchpad API for sutton - p350-tr-sff-alpha
[2021-06-22T10:17:51] [summary.py/__init__] [DEBUG] Prepare WEBDAV API with sutton
[2021-06-22T10:17:51] [summary.py/get_image_info_from_mail_content] [INFO] Try to get mail.content file from WebDAV server. URI: /share/sutton/bachman/p350-tr-sff-alpha/mail.content
[2021-06-22T10:17:55] [summary.py/get_image_info_from_mail_content] [DEBUG] Image: pc-sutton-bachman-focal-amd64-X00-20210601-872.iso, SHA256: e10a62404d8350a4927c2d693d2cf4ae99520e40460da58e3c471ba0c2088718
[2021-06-22T10:17:55] [summary.py/get_new_bugs] [INFO] Collecting new bugs
[2021-06-22T10:17:56] [summary.py/get_new_bugs] [DEBUG] Search bugs from 2021-06-01 00:00:00 to 2021-06-22 10:16:59.275233 for sutton project
[2021-06-22T10:17:57] [summary.py/get_new_bugs] [DEBUG] 47 bugs found, analysing
[2021-06-22T10:17:57] [summary.py/get_new_bugs] [DEBUG] handle https://api.launchpad.net/devel/sutton/+bug/1930543 bug
[2021-06-22T10:18:01] [summary.py/get_new_bugs] [DEBUG] handle https://api.launchpad.net/devel/sutton/+bug/1930786 bug
[2021-06-22T10:18:04] [summary.py/get_new_bugs] [DEBUG] handle https://api.launchpad.net/devel/sutton/+bug/1930789 bug
[2021-06-22T10:18:06] [summary.py/get_new_bugs] [DEBUG] handle https://api.launchpad.net/devel/sutton/+bug/1930791 bug
[2021-06-22T10:18:09] [summary.py/get_new_bugs] [DEBUG] handle https://api.launchpad.net/devel/sutton/+bug/1930793 bug

## The logging under flask ##
(venv) stanley@stanley-ThinkPad-T490:~/Desktop/Git_Repos/oem-qa-autosummary$ flask run
 * Serving Flask app 'webapp' (lazy loading)
 * Environment: development
 * Debug mode: on
[2021-06-22T10:19:18] [summary.py/MailContentNotFoundError] [ERROR] the mail.content file is not found on the WebDAV server
[2021-06-22T10:19:18] [summary.py/Sha256FileNotFoundError] [ERROR] sha256sum file for a given image is not found on the WebDAV server
[2021-06-22T10:19:22] [_internal.py/_log] [INFO] * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
[2021-06-22T10:19:22] [_internal.py/_log] [INFO] * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 143-224-034
[2021-06-22T10:19:22] [summary.py/MailContentNotFoundError] [ERROR] the mail.content file is not found on the WebDAV server
[2021-06-22T10:19:22] [summary.py/Sha256FileNotFoundError] [ERROR] sha256sum file for a given image is not found on the WebDAV server
[2021-06-22T10:19:40] [__init__.py/index] [INFO] Route to index page, method: GET
[2021-06-22T10:19:40] [__init__.py/index] [DEBUG] selected_project:
[2021-06-22T10:19:47] [__init__.py/index] [INFO] Route to index page, method: POST
[2021-06-22T10:19:54] [__init__.py/index] [DEBUG] selected_project: sutton
[2021-06-22T10:20:12] [__init__.py/generate_summary] [INFO] Route to summary page
[2021-06-22T10:20:12] [summary.py/__init__] [INFO] Summary object initailizing
[2021-06-22T10:20:12] [summary.py/__init__] [DEBUG] Prepare launchpad API for sutton - p350-tr-sff-alpha
[2021-06-22T10:20:14] [summary.py/__init__] [DEBUG] Prepare WEBDAV API with sutton
[2021-06-22T10:20:14] [summary.py/get_image_info_from_mail_content] [INFO] Try to get mail.content file from WebDAV server. URI: /share/sutton/bachman/p350-tr-sff-alpha/mail.content
[2021-06-22T10:20:18] [summary.py/get_image_info_from_mail_content] [DEBUG] Image: pc-sutton-bachman-focal-amd64-X00-20210601-872.iso, SHA256: e10a62404d8350a4927c2d693d2cf4ae99520e40460da58e3c471ba0c2088718
[2021-06-22T10:20:18] [summary.py/get_new_bugs] [INFO] Collecting new bugs
[2021-06-22T10:20:18] [summary.py/get_new_bugs] [DEBUG] Search bugs from 2021-06-01 00:00:00 to 2021-06-22 10:19:22.523878 for sutton project
[2021-06-22T10:20:20] [summary.py/get_new_bugs] [DEBUG] 47 bugs found, analysing
[2021-06-22T10:20:20] [summary.py/get_new_bugs] [DEBUG] handle https://api.launchpad.net/devel/sutton/+bug/1930543 bug
[2021-06-22T10:20:25] [summary.py/get_new_bugs] [DEBUG] handle https://api.launchpad.net/devel/sutton/+bug/1930786 bug
[2021-06-22T10:20:27] [summary.py/get_new_bugs] [DEBUG] handle https://api.launchpad.net/devel/sutton/+bug/1930789 bug
[2021-06-22T10:20:30] [summary.py/get_new_bugs] [DEBUG] handle https://api.launchpad.net/devel/sutton/+bug/1930791 bug

To post a comment you must log in.
Revision history for this message
Pierre Equoy (pieq) wrote (last edit ):

Thanks a lot, that will provide much more information that the current situation!

I added a bunch of comments below.

Since we use Python 3.6+, we can use f-strings instead of `.format()` or `%s`, such as:

    f"Preparing Launchpad API for {self.project_name} - {self.milestone_name}..."

Make sure you use this everywhere, cause I think it's easier to read :)

Then, you can amend your last commit (no need to create a new one) and push the update here.

review: Needs Fixing
Revision history for this message
Pierre Equoy (pieq) wrote :

Thanks for taking my comments into account!

The content looks good, but I would like to avoid having multiple commits for the same thing.

Could you squash your four commits into one ? This is explained in step 2 of the Checkbox contributing guide:

https://checkbox.readthedocs.io/en/latest/contributing.html#what-to-do-if-reviewers-suggest-changes-in-your-merge-request

It's basically using the `git rebase -i ...` command, and squashing your 4 commits into one. You can then rewrite the commit title/body (no need to mention "fixed bugs" since it will be one commit).

Don't hesitate to ask me if you need help, I know rebasing/squashing is a bit weird...

Thanks again!

review: Needs Fixing
Revision history for this message
StanleyHuang (stanley31) wrote :

@pieq,
I have squashing all commits into one, please help to review it again. Thanks.

> Thanks for taking my comments into account!
>
> The content looks good, but I would like to avoid having multiple commits for
> the same thing.
>
> Could you squash your four commits into one ? This is explained in step 2 of
> the Checkbox contributing guide:
>
> https://checkbox.readthedocs.io/en/latest/contributing.html#what-to-do-if-
> reviewers-suggest-changes-in-your-merge-request
>
> It's basically using the `git rebase -i ...` command, and squashing your 4
> commits into one. You can then rewrite the commit title/body (no need to
> mention "fixed bugs" since it will be one commit).
>
> Don't hesitate to ask me if you need help, I know rebasing/squashing is a bit
> weird...
>
> Thanks again!

Revision history for this message
Pierre Equoy (pieq) wrote :

Awesome, thanks a lot Stanley!

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/autosummary/summary.py b/autosummary/summary.py
2index 9d3b2b9..c38c071 100644
3--- a/autosummary/summary.py
4+++ b/autosummary/summary.py
5@@ -6,29 +6,32 @@ from datetime import datetime
6
7 from webdav3.client import Client
8
9-logger = logging.getLogger(__name__)
10
11 WEBDAV_CREDENTIALS = os.environ.get("WEBDAV_CREDENTIALS")
12
13
14 class MailContentNotFoundError(FileNotFoundError):
15 """Raised when the mail.content file is not found on the WebDAV server"""
16-
17+ logging.error("the mail.content file is not found on the WebDAV server")
18 pass
19
20
21 class Sha256FileNotFoundError(FileNotFoundError):
22 """Raised when the sha256sum file for a given image is not found on the WebDAV server"""
23-
24+ logging.error(
25+ "sha256sum file for a given image is not found on the WebDAV server")
26 pass
27
28
29 class Summary:
30 def __init__(self, launchpad, project_name, milestone_name, image_name=""):
31+ logging.info("Initailizing Summary object")
32 self.project_name = project_name
33 self.milestone_name = milestone_name
34 self.launchpad = launchpad
35
36+ logging.info((f"Preparing launchpad API for {self.project_name} "
37+ f"- {self.milestone_name}"))
38 self.lp_project = self.launchpad.projects[self.project_name]
39 self.lp_milestone = self.lp_project.getMilestone(name=self.milestone_name)
40 self.series_name = self.lp_milestone.series_target.name
41@@ -39,6 +42,7 @@ class Summary:
42 "webdav_login": user,
43 "webdav_password": passwd,
44 }
45+ logging.info(f"Preparing WebDAV API as user {user}")
46 self.webdav_client = Client(webdav_options)
47
48 if not image_name:
49@@ -47,10 +51,12 @@ class Summary:
50 self.image_name = image_name
51 self.image_sha256 = self.get_image_sha256()
52 self.image_date = get_date_from_image_name(self.image_name)
53-
54 self.new_bugs = self.get_new_bugs()
55 self.milestone_bugs = self.lp_milestone.searchTasks()
56+ logging.info(f"{len(self.milestone_bugs)} milestone bugs found.")
57 self.reopened_bugs = get_reopen_bugs(self.milestone_bugs)
58+ logging.info(f"{len(self.reopened_bugs)} reopen bugs found.")
59+ logging.info("Summary object initialized")
60
61 def get_webdav_credentials(self, config=WEBDAV_CREDENTIALS):
62 with open(config) as f:
63@@ -67,18 +73,23 @@ class Summary:
64 in the same project between `created_since` and `created_before`. Bugs
65 assigned to different series are ignored.
66 """
67+ logging.info("Collecting new bugs")
68 team = self.launchpad.people["oem-qa"]
69
70 if created_since is None:
71 created_since = self.image_date
72 new_bugs = []
73+ logging.info((f"Search bugs from {created_since} to {created_before}"
74+ f" for {self.project_name} project"))
75 bugs = self.lp_project.searchTasks(
76 created_since=created_since, created_before=created_before
77 )
78
79+ logging.info(f"{len(bugs)} bugs found, analysing")
80 check_pattern = ["[checkbox]", "plainbox"]
81-
82+ target_milestone = self.lp_milestone.series_target
83 for bug in bugs:
84+ logging.info(f"handle {bug} bug")
85 if bug.owner in team.members:
86 # To exclude checkbox-related bugs from summary report
87 if (
88@@ -86,17 +97,14 @@ class Summary:
89 and "checkbox" not in bug.bug.tags
90 ):
91 if bug.milestone:
92- if (
93- bug.milestone.series_target
94- == self.lp_milestone.series_target
95- ):
96+ if bug.milestone.series_target == target_milestone:
97 new_bugs.append(bug)
98 else:
99 # No milestone/series defined yet, assuming it should be part of
100 # the list
101 new_bugs.append(bug)
102 else:
103- logger.info(f"Excluding Checkbox-related {bug.title}")
104+ logging.info(f"Excluding Checkbox-related {bug.title}")
105 return new_bugs
106
107 def get_image_info_from_mail_content(self):
108@@ -109,7 +117,8 @@ class Summary:
109 image_sha256 = ""
110 buff = io.BytesIO()
111 uri = os.path.join(self.get_milestone_uri(), "mail.content")
112-
113+ logging.info(
114+ f"Try to get mail.content file from WebDAV server. URI: {uri}")
115 try:
116 self.webdav_client.download_from(buff, uri)
117 buff.seek(0)
118@@ -125,6 +134,7 @@ class Summary:
119 except Exception:
120 raise MailContentNotFoundError()
121
122+ logging.info(f"Image: {image_name}, SHA256: {image_sha256}")
123 return image_name, image_sha256
124
125 def get_image_sha256(self):
126@@ -178,6 +188,7 @@ def get_reopen_bugs(bugs):
127
128 Return a list of reopened bugs.
129 """
130+ logging.info("Collecting reopen bugs")
131 closed_statuses = ["Invalid", "Won't Fix", "Fix Committed", "Fix Released"]
132 open_statuses = ["Confirmed", "Incomplete", "Triaged", "In Progress"]
133 reopen_bugs = []
134diff --git a/logging_conf.py b/logging_conf.py
135new file mode 100644
136index 0000000..0143717
137--- /dev/null
138+++ b/logging_conf.py
139@@ -0,0 +1,22 @@
140+import os
141+from logging.config import dictConfig
142+
143+autosummary_logging_conf = dictConfig({
144+ 'version': 1,
145+ 'formatters': {
146+ 'default': {
147+ 'format': '[%(asctime)s] [%(filename)s/%(funcName)s] [%(levelname)s] %(message)s',
148+ 'datefmt': '%Y-%m-%dT%H:%M:%S'
149+ },
150+ },
151+ 'handlers': {
152+ 'stdout': {
153+ 'class': "logging.StreamHandler",
154+ 'stream': 'ext://sys.stdout',
155+ 'formatter': 'default'
156+ }
157+ },
158+ 'root': {
159+ 'handlers': ['stdout'],
160+ 'level': os.getenv('APP_LOG_LEVEL', 'INFO')},
161+})
162\ No newline at end of file
163diff --git a/webapp/__init__.py b/webapp/__init__.py
164index 93f4e0d..befaea5 100644
165--- a/webapp/__init__.py
166+++ b/webapp/__init__.py
167@@ -5,14 +5,12 @@ import os
168 import requests
169
170 from flask import Flask, redirect, request, render_template, url_for, jsonify
171-from flask.logging import default_handler
172 from launchpadlib.launchpad import Launchpad
173 from markupsafe import escape
174
175 from autosummary import summary
176+from logging_conf import autosummary_logging_conf
177
178-root = logging.getLogger()
179-root.addHandler(default_handler)
180
181 app = Flask(__name__)
182
183@@ -95,6 +93,7 @@ def bug_title(bug_task):
184
185 @app.route("/", methods=("GET", "POST"))
186 def index():
187+ logging.info(f"Route to index page, method: {request.method}")
188 milestones = None
189 selected_project = ""
190 projects = sorted(summary.get_available_projects())
191@@ -105,6 +104,7 @@ def index():
192 milestones = sorted(
193 summary.get_active_milestones(launchpad, selected_project)
194 )
195+ logging.info(f"selected_project: {selected_project}")
196
197 return render_template(
198 "index.html",
199@@ -116,6 +116,7 @@ def index():
200
201 @app.route("/summary", methods=("POST",))
202 def generate_summary():
203+ logging.info("Route to summary page")
204 project = request.form.get("project")
205 milestone = request.form.get("milestone")
206 image_name = request.form.get("image_name")
207@@ -140,6 +141,7 @@ def generate_summary():
208 nb_high_bugs = len(high_new_bugs) + len(high_reopened_bugs)
209 except summary.MailContentNotFoundError:
210 error = "No release e-mail was found for this release."
211+ logging.error(error)
212 # Asking for manual input of the image name instead
213 return render_template(
214 "image_info.html",
215@@ -157,6 +159,7 @@ def generate_summary():
216 f"Could not find sha256 for image named {image_name}. "
217 f"Please make sure this image is available on oem-share."
218 )
219+ logging.error(error)
220 return render_template(
221 "image_info.html",
222 error=error,
223@@ -208,6 +211,8 @@ def add_test_status():
224 )
225 response = res.json()
226 status_code = res.status_code
227+ logging.info((f"Add status status code: {status_code},"
228+ f" response: {response}"))
229 except requests.exceptions.ConnectionError:
230 response = None
231 logging.exception("Cannot connect to Auto Test Status Tracker Web Service")

Subscribers

People subscribed via source and target branches

to all changes: