Skip to content

Commit 75ac53e

Browse files
authored
Add-audit-progress-logging (#1416)
* Improve logging of object loading * Fixes #1415 * Don't request same component tree 4 times to detect project type * Fix log on project type * Improve pro_type algo * Fixes #1417
1 parent 0dab65d commit 75ac53e

File tree

3 files changed

+34
-27
lines changed

3 files changed

+34
-27
lines changed

sonar/platform.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
import tempfile
3636
import requests
3737
import jprops
38-
from requests import HTTPError, RequestException, Timeout
38+
from requests import HTTPError, RequestException
3939

4040
import sonar.logging as log
4141
import sonar.utilities as util
@@ -254,8 +254,6 @@ def __run_request(
254254
lvl = log.DEBUG if r.status_code in mute else log.ERROR
255255
log.log(lvl, "%s (%s request)", util.error_msg(e), req_type)
256256
raise e
257-
except Timeout as e:
258-
util.exit_fatal(str(e), errcodes.HTTP_TIMEOUT)
259257
except (ConnectionError, RequestException) as e:
260258
if exit_on_error: # or (r.status_code not in mute and r.status_code not in _NORMAL_HTTP_ERRORS):
261259
util.exit_fatal(str(e), errcodes.SONAR_API)
@@ -539,9 +537,15 @@ def _audit_logs(self, audit_settings: types.ConfigSettings) -> list[Problem]:
539537
log.info("Logs audit is disabled, skipping logs audit...")
540538
return []
541539
log_map = {"app": "sonar.log", "ce": "ce.log", "web": "web.log", "es": "es.log"}
540+
if self.edition() == "datacenter":
541+
log_map.pop("es")
542542
problems = []
543543
for logtype, logfile in log_map.items():
544-
logs = self.get("system/logs", params={"name": logtype}).text
544+
try:
545+
logs = self.get("system/logs", params={"name": logtype}).text
546+
except (ConnectionError, RequestException) as e:
547+
log.error("%s while retrieving %s logs", util.error_msg(e), logtype)
548+
continue
545549
for line in logs.splitlines():
546550
log.debug("Inspection log line %s", line)
547551
try:

sonar/projects.py

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -578,21 +578,19 @@ def get_type(self) -> str:
578578
if "gradle" in comp["name"]:
579579
return "GRADLE"
580580
data = json.loads(self.get(api=_TREE_API, params={"component": self.key, "ps": 500}).text)
581+
projtype = "UNKNOWN"
581582
for comp in data["components"]:
582583
if re.match(r".*\.(cs|csx|vb)$", comp["name"]):
583-
log.info("%s is a DOTNET project", str(self))
584-
return "DOTNET"
585-
data = json.loads(self.get(api=_TREE_API, params={"component": self.key, "ps": 500}).text)
586-
for comp in data["components"]:
584+
projtype = "DOTNET"
585+
break
587586
if re.match(r".*\.(java)$", comp["name"]):
588-
log.info("%s is a JAVA project", str(self))
589-
return "JAVA"
590-
data = json.loads(self.get(api=_TREE_API, params={"component": self.key, "ps": 500}).text)
591-
for comp in data["components"]:
587+
projtype = "JAVA"
588+
break
592589
if re.match(r".*\.(py|rb|cbl|vbs|go|js|ts)$", comp["name"]):
593-
log.info("%s is a DOTNET project", str(self))
594-
return "CLI"
595-
return "UNKNOWN"
590+
projtype = "CLI"
591+
break
592+
log.info("%s is a %s project", str(self), projtype)
593+
return projtype
596594

597595
def last_task(self) -> Optional[tasks.Task]:
598596
"""Returns the last analysis background task of a problem, or none if not found"""
@@ -667,10 +665,7 @@ def audit(self, audit_settings: types.ConfigSettings) -> list[Problem]:
667665
problems += self.__audit_binding_valid(audit_settings)
668666
problems += self.__audit_scanner(audit_settings)
669667
except (ConnectionError, RequestException) as e:
670-
if isinstance(e, HTTPError) and e.response.status_code == HTTPStatus.FORBIDDEN:
671-
log.error("Not enough permission to fully audit %s", str(self))
672-
else:
673-
log.error("%s while auditing %s", util.error_msg(e), str(self))
668+
log.error("%s while auditing %s", util.error_msg(e), str(self))
674669
return problems
675670

676671
def export_zip(self, timeout: int = 180) -> dict[str, str]:
@@ -1430,9 +1425,10 @@ def __audit_thread(queue: Queue[Project], results: list[Problem], audit_settings
14301425
bindings[bindkey] = project
14311426
except (ConnectionError, RequestException) as e:
14321427
log.error("%s while auditing %s", util.error_msg(e), str(project))
1428+
__increment_processed(audit_settings)
14331429
queue.task_done()
1434-
log.debug("%s audit complete", str(project))
1435-
log.debug("Queue empty, exiting thread")
1430+
1431+
log.debug("Audit of projects completed")
14361432

14371433

14381434
def audit(endpoint: pf.Platform, audit_settings: types.ConfigSettings, key_list: types.KeyList = None) -> list[Problem]:
@@ -1448,6 +1444,8 @@ def audit(endpoint: pf.Platform, audit_settings: types.ConfigSettings, key_list:
14481444
plist = get_list(endpoint, key_list)
14491445
problems = []
14501446
q = Queue(maxsize=0)
1447+
audit_settings["NBR_PROJECTS"] = len(plist)
1448+
audit_settings["PROCESSED"] = 0
14511449
for p in plist.values():
14521450
q.put(p)
14531451
bindings = {}
@@ -1469,6 +1467,15 @@ def audit(endpoint: pf.Platform, audit_settings: types.ConfigSettings, key_list:
14691467
return problems
14701468

14711469

1470+
def __increment_processed(counters: dict[str, str]) -> None:
1471+
"""Increments the counter of processed projects and display log"""
1472+
with _CLASS_LOCK:
1473+
counters["PROCESSED"] += 1
1474+
nb, tot = counters["PROCESSED"], counters["NBR_PROJECTS"]
1475+
lvl = log.INFO if nb % 10 == 0 or tot - nb < 10 else log.DEBUG
1476+
log.log(lvl, "%d/%d projects exported (%d%%)", nb, tot, (nb * 100) // tot)
1477+
1478+
14721479
def __export_thread(queue: Queue[Project], results: dict[str, str], export_settings: types.ConfigSettings, write_q: Optional[Queue] = None) -> None:
14731480
"""Project export callback function for multitheaded export"""
14741481
while not queue.empty():
@@ -1479,11 +1486,7 @@ def __export_thread(queue: Queue[Project], results: dict[str, str], export_setti
14791486
else:
14801487
results[project.key] = exp_json
14811488
results[project.key].pop("key", None)
1482-
with _CLASS_LOCK:
1483-
export_settings["EXPORTED"] += 1
1484-
nb, tot = export_settings["EXPORTED"], export_settings["NBR_PROJECTS"]
1485-
lvl = log.INFO if nb % 10 == 0 or tot - nb < 10 else log.DEBUG
1486-
log.log(lvl, "%d/%d projects exported (%d%%)", nb, tot, (nb * 100) // tot)
1489+
__increment_processed(export_settings)
14871490
queue.task_done()
14881491
log.info("Project export queue empty, export complete")
14891492

sonar/sqobject.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def search_objects(endpoint: object, object_class: any, params: types.ApiParams,
135135
data = json.loads(endpoint.get(api, params=new_params).text)
136136
nb_pages = utilities.nbr_pages(data)
137137
nb_objects = max(len(data[returned_field]), utilities.nbr_total_elements(data))
138-
log.info("%d %s to load", nb_objects, object_class.__name__)
138+
log.info("Loading %d %ss...", nb_objects, object_class.__name__)
139139
for obj in data[returned_field]:
140140
if object_class.__name__ in ("Portfolio", "Group", "QualityProfile", "User", "Application", "Project", "Organization"):
141141
objects_list[obj[key_field]] = object_class.load(endpoint=endpoint, data=obj)

0 commit comments

Comments
 (0)