Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean logging and sentry logging setup #4611

Merged
merged 4 commits into from
Mar 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/hct_mis_api/apps/account/admin/ad.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def sync_multi(self, request: HttpRequest) -> None:
messages.SUCCESS,
)
except Exception as e:
logger.exception(e)
logger.warning(e)
self.message_user(request, str(e), messages.ERROR)

@button(label="Sync", permission="account.can_sync_with_ad")
Expand All @@ -115,7 +115,7 @@ def sync_single(self, request: HttpRequest, pk: int) -> None:
self._sync_ad_data(self.get_object(request, pk))
self.message_user(request, "Active Directory data successfully fetched", messages.SUCCESS)
except Exception as e:
logger.exception(e)
logger.warning(e)
self.message_user(request, str(e), messages.ERROR)

@button(permission="account.can_load_from_ad")
Expand Down Expand Up @@ -190,7 +190,7 @@ def load_ad_users(self, request: HttpRequest) -> TemplateResponse:
ctx["results"] = results
return TemplateResponse(request, "admin/load_users.html", ctx)
except Exception as e:
logger.exception(e)
logger.warning(e)
self.message_user(request, str(e), messages.ERROR)
ctx["form"] = form
return TemplateResponse(request, "admin/load_users.html", ctx)
2 changes: 1 addition & 1 deletion src/hct_mis_api/apps/account/admin/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,5 @@ def queryset(self, request: HttpRequest, queryset: QuerySet) -> QuerySet:
Q(role_one=self.value()) | Q(role_two=self.value()),
)
except (ValueError, ValidationError) as e:
logger.exception(e)
logger.warning(e)
raise IncorrectLookupParameters(e)
2 changes: 1 addition & 1 deletion src/hct_mis_api/apps/account/admin/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def clean_emails(self) -> Dict:
except ValidationError:
errors.append(e)
if errors:
logger.error("Invalid emails {}".format(", ".join(errors)))
logger.warning("Invalid emails {}".format(", ".join(errors)))
raise ValidationError("Invalid emails {}".format(", ".join(errors)))
return self.cleaned_data["emails"]

Expand Down
12 changes: 6 additions & 6 deletions src/hct_mis_api/apps/account/admin/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def login(self, request: Optional[HttpRequest] = None, twin: Optional[Any] = Non
)

except Exception as e:
logger.exception(e)
logger.warning(e)
raise

def _get(self, url: str) -> Any:
Expand Down Expand Up @@ -220,7 +220,7 @@ def create_kobo_user_qs(self, request: HttpRequest, queryset: QuerySet) -> None:
try:
self._grant_kobo_accesss_to_user(user)
except Exception as e:
logger.exception(e)
logger.warning(e)
self.message_user(request, f"{e.__class__.__name__}: {str(e)}", messages.ERROR)
self.message_user(
request,
Expand All @@ -237,7 +237,7 @@ def create_kobo_user(self, request: HttpRequest, pk: "UUID") -> None:
self._grant_kobo_accesss_to_user(self.get_queryset(request).get(pk=pk))
self.message_user(request, f"Granted access to {settings.KOBO_KF_URL}", messages.SUCCESS)
except Exception as e:
logger.exception(e)
logger.warning(e)
self.message_user(request, f"{e.__class__.__name__}: {str(e)}", messages.ERROR)

def delete_view(self, request: HttpRequest, object_id: str, extra_context: Optional[Dict] = None) -> HttpResponse:
Expand Down Expand Up @@ -273,7 +273,7 @@ def delete_model(self, request: HttpRequest, obj: Any) -> None:
api.delete_user(obj.custom_fields["kobo_username"], obj.custom_fields["kobo_pk"])
super().delete_model(request, obj)
except Exception as e:
logger.exception(e)
logger.warning(e)
self.message_user(request, str(e), messages.ERROR)
raise

Expand All @@ -295,7 +295,7 @@ def remove_kobo_access(self, request: HttpRequest, pk: "UUID") -> None:
messages.WARNING,
)
except Exception as e:
logger.exception(e)
logger.warning(e)
self.message_user(request, f"{e.__class__.__name__}: {str(e)}", messages.ERROR)

@button(label="Sync users from Kobo", permission="account.can_import_from_kobo")
Expand Down Expand Up @@ -335,6 +335,6 @@ def kobo_users_sync(self, request: HttpRequest) -> TemplateResponse:
ctx["users"] = users

except Exception as e:
logger.exception(e)
logger.warning(e)
self.message_user(request, str(e), messages.ERROR)
return TemplateResponse(request, "admin/kobo_users.html", ctx)
2 changes: 1 addition & 1 deletion src/hct_mis_api/apps/account/admin/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ def import_csv(self, request: HttpRequest) -> TemplateResponse:
except Exception:
raise
except Exception as e:
logger.exception(e)
logger.warning(e)
context["form"] = form
context["errors"] = [str(e)]
self.message_user(request, f"{e.__class__.__name__}: {str(e)}", messages.ERROR)
Expand Down
2 changes: 1 addition & 1 deletion src/hct_mis_api/apps/account/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def require_email(
if user and user.email:
return
elif is_new and not details.get("email"):
logger.error("Email couldn't be validated")
logger.warning("Email couldn't be validated")
raise InvalidEmail(strategy)


Expand Down
8 changes: 4 additions & 4 deletions src/hct_mis_api/apps/account/microsoft_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def get_results(self, url: str) -> Dict:
try:
response.raise_for_status()
except requests.exceptions.HTTPError as e:
logger.exception(e)
logger.warning(e)
raise
json_response = response.json()
return json_response
Expand All @@ -71,12 +71,12 @@ def get_user_data(self, *, email: Optional[str] = None, uuid: Optional[str] = No
data = self.get_results(q)
value = data["value"][0]
else:
logger.error("You must provide 'uuid' or 'email' argument.")
logger.warning("You must provide 'uuid' or 'email' argument.")
raise ValueError("You must provide 'uuid' or 'email' argument.")
except IndexError:
logger.error(f"User not found using email={email},uuid={uuid}")
logger.warning(f"User not found using email={email},uuid={uuid}")
raise Http404("User not found")
if not value:
logger.error(f"User not found using email={email},uuid={uuid}")
logger.warning(f"User not found using email={email},uuid={uuid}")
raise Http404("User not found")
return value
6 changes: 3 additions & 3 deletions src/hct_mis_api/apps/account/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ class Meta:
def clean(self) -> None:
super().clean()
if self.role_one == self.role_two:
logger.error(f"Provided roles are the same role={self.role_one}")
logger.warning(f"Provided roles are the same role={self.role_one}")
raise ValidationError(_("Choose two different roles."))
failing_users = set()

Expand All @@ -440,7 +440,7 @@ def clean(self) -> None:
failing_users.add(userrole.user.email)

if failing_users:
logger.error(
logger.warning(
f"Users: [{', '.join(failing_users)}] have these roles assigned to them in the same business area. "
"Please fix them before creating this incompatible roles pair."
)
Expand All @@ -456,7 +456,7 @@ def validate_unique(self, *args: Any, **kwargs: Any) -> None:
# unique_together will take care of unique couples only if order is the same
# since it doesn't matter if role is one or two, we need to check for reverse uniqueness as well
if IncompatibleRoles.objects.filter(role_one=self.role_two, role_two=self.role_one).exists():
logger.error(
logger.warning(
f"This combination of roles ({self.role_one}, {self.role_two}) already exists as incompatible pair."
)
raise ValidationError(_("This combination of roles already exists as incompatible pair."))
2 changes: 1 addition & 1 deletion src/hct_mis_api/apps/accountability/celery_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def export_survey_sample_task(survey_id: str, user_id: str) -> None:
send_email_notification(service, user)

except Exception as e:
logger.exception(e)
logger.warning(e)
raise


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def create(cls, user: AbstractUser, business_area: BusinessArea, input_data: dic

if message.number_of_recipients == 0:
err_msg = "No recipients found for the given criteria"
logger.error(err_msg)
logger.warning(err_msg)
raise GraphQLError(err_msg)

message.save()
Expand Down
8 changes: 4 additions & 4 deletions src/hct_mis_api/apps/accountability/services/verifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ def verify(self) -> None:
last_1 = fields.pop()
if not any(inputs):
err_msg = f"Must provide any one of {', '.join(fields)} or {last_1}"
logger.error(err_msg)
logger.warning(err_msg)
raise GraphQLError(err_msg)
if len([value for value in inputs if value]) > 1:
err_msg = f"Must provide only one of {', '.join(fields)} or {last_1}"
logger.error(err_msg)
logger.warning(err_msg)
raise GraphQLError(err_msg)

options = self.ARGUMENTS.get("sampling_type")
Expand All @@ -47,10 +47,10 @@ def verify(self) -> None:
for required in value.get("required"):
if self.input_data.get(required) is None:
err_msg = f"Must provide {required} for {key}"
logger.error(err_msg)
logger.warning(err_msg)
raise GraphQLError(err_msg)
for not_allowed in value.get("not_allowed"):
if self.input_data.get(not_allowed) is not None:
err_msg = f"Must not provide {not_allowed} for {key}"
logger.error(err_msg)
logger.warning(err_msg)
raise GraphQLError(err_msg)
2 changes: 1 addition & 1 deletion src/hct_mis_api/apps/administration/panels/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def email(self: Any, request: HttpRequest, extra_context: Optional[Dict] = None)
if return_value == 1:
messages.add_message(request, messages.SUCCESS, f"Email sent to {request.user.email}")
except Exception as e:
logger.exception(e)
logger.warning(e)
messages.add_message(request, messages.ERROR, f"{e.__class__.__name__}: {e}")
context["logs"] = logs
context["results"] = results
Expand Down
2 changes: 1 addition & 1 deletion src/hct_mis_api/apps/administration/panels/es.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def __call__(self, model_admin: Any, request: HttpRequest, extra_context: Option
else:
raise ValueError(opt)
except Exception as exc:
logger.exception(exc)
logger.warning(exc)
messages.add_message(request, messages.ERROR, f"{exc.__class__.__name__}: {exc}")
else:
form = EsForm()
Expand Down
4 changes: 2 additions & 2 deletions src/hct_mis_api/apps/core/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ def mark_submissions(self, request: HttpRequest, pk: "UUID") -> HttpResponseRedi
result = task.execute()
self.message_user(request, result["message"], messages.SUCCESS)
except Exception as e:
logger.exception(e)
logger.warning(e)
self.message_user(request, str(e), messages.ERROR)
return HttpResponseRedirect(reverse("admin:core_businessarea_change", args=[business_area.id]))
else:
Expand Down Expand Up @@ -480,7 +480,7 @@ def add_view(
self, request: HttpRequest, form_url: str = "", extra_context: Optional[Dict] = None
) -> Union[HttpResponsePermanentRedirect, TemplateResponse]:
if not self.has_add_permission(request):
logger.error("The user did not have permission to do that")
logger.warning("The user did not have permission to do that")
raise PermissionDenied

opts = self.model._meta
Expand Down
8 changes: 4 additions & 4 deletions src/hct_mis_api/apps/core/attributes_qet_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ def age_to_birth_date_query(comparison_method: str, args: Any, is_social_worker_
}
args_count = comparison_method_args_count.get(comparison_method)
if args_count is None:
logger.error(f"Age filter query don't supports {comparison_method} type")
logger.warning(f"Age filter query don't supports {comparison_method} type")
raise ValidationError(f"Age filter query don't supports {comparison_method} type")
if len(args) != args_count:
logger.error(f"Age {comparison_method} filter query expect {args_count} arguments")
logger.warning(f"Age {comparison_method} filter query expect {args_count} arguments")
raise ValidationError(f"Age {comparison_method} filter query expect {args_count} arguments")
if comparison_method == "RANGE":
return age_to_birth_date_range_query(field_name, *args, is_social_worker_query=is_social_worker_query)
Expand All @@ -69,7 +69,7 @@ def age_to_birth_date_query(comparison_method: str, args: Any, is_social_worker_
return age_to_birth_date_range_query(field_name, args[0], None, is_social_worker_query=is_social_worker_query)
if comparison_method == "LESS_THAN":
return age_to_birth_date_range_query(field_name, None, args[0], is_social_worker_query=is_social_worker_query)
logger.error(f"Age filter query don't supports {comparison_method} type") # pragma: no cover
logger.warning(f"Age filter query don't supports {comparison_method} type") # pragma: no cover
raise ValidationError(f"Age filter query don't supports {comparison_method} type") # pragma: no cover


Expand Down Expand Up @@ -248,7 +248,7 @@ def country_generic_query(comparison_method: str, args: Any, lookup: Any, is_soc
return query
elif comparison_method == "NOT_EQUALS":
return ~query
logger.error(f"Country filter query does not support {comparison_method} type")
logger.warning(f"Country filter query does not support {comparison_method} type")
raise ValidationError(f"Country filter query does not support {comparison_method} type")


Expand Down
4 changes: 2 additions & 2 deletions src/hct_mis_api/apps/core/celery_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def wrapper_func(*args: Any, **kwargs: Any) -> None:
with transaction.atomic():
return func(*args, **kwargs)
except Exception as e:
logger.error(e)
logger.exception(e)

task_func = app.task(*self.task_args, **self.task_kwargs)(wrapper_func)
return task_func
Expand Down Expand Up @@ -55,7 +55,7 @@ def upload_new_kobo_template_and_update_flex_fields_task_with_retry(self: Any, x
else:
exc.xlsx_kobo_template_object.status = XLSXKoboTemplate.UNSUCCESSFUL
except Exception as e:
logger.exception(e)
logger.warning(e)
raise


Expand Down
8 changes: 4 additions & 4 deletions src/hct_mis_api/apps/core/countries.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def get_countries(cls) -> List[Tuple[str, str, str]]:
@classmethod
def get_choices(cls, output_code: str = "alpha2") -> List:
if output_code not in ("alpha2", "alpha3"):
logger.error(f"output_code have to be one of: alpha2, alpha3, provided output_code={output_code}")
logger.warning(f"output_code have to be one of: alpha2, alpha3, provided output_code={output_code}")
raise ValueError("output_code have to be one of: alpha2, alpha3")
return [
{"label": {"English(EN)": name}, "value": alpha2 if output_code == "alpha2" else alpha3}
Expand All @@ -42,7 +42,7 @@ def get_country_value(
}

if output_type not in ("name", "alpha2", "alpha3"):
logger.error(f"output_type have to be one of: name, alpha2, alpha3, provided output_type={output_type}")
logger.warning(f"output_type have to be one of: name, alpha2, alpha3, provided output_type={output_type}")
raise ValueError("output_type have to be one of: name, alpha2, alpha3")

for country_tuple in cls.get_countries():
Expand Down Expand Up @@ -1279,7 +1279,7 @@ class SanctionListCountries:
@classmethod
def get_choices(cls, output_code: str = "alpha2") -> List:
if output_code not in ("alpha2", "alpha3"):
logger.error(f"output_code have to be one of: alpha2, alpha3, provided output_code={output_code}")
logger.warning(f"output_code have to be one of: alpha2, alpha3, provided output_code={output_code}")
raise ValueError("output_code have to be one of: alpha2, alpha3")
return [
{"label": {"English(EN)": name}, "value": alpha2 if output_code == "alpha2" else alpha3}
Expand All @@ -1301,7 +1301,7 @@ def get_country_value(
}

if output_type not in ("name", "alpha2", "alpha3"):
logger.error(f"output_type have to be one of: alpha2, alpha3, provided output_type={output_type}")
logger.warning(f"output_type have to be one of: alpha2, alpha3, provided output_type={output_type}")
raise ValueError("output_type have to be one of: name, alpha2, alpha3")

for country_tuple in cls.COUNTRIES:
Expand Down
2 changes: 1 addition & 1 deletion src/hct_mis_api/apps/core/exchange_rates/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def fetch_exchange_rates(self, with_history: bool = True) -> Dict:
try:
response.raise_for_status()
except Exception as e:
logger.exception(e)
logger.warning(e)
raise
return response.json()

Expand Down
2 changes: 1 addition & 1 deletion src/hct_mis_api/apps/core/extended_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def cache_count(cls, connection: Connection, args: Dict, iterable: QuerySet) ->
cache_key = f"count_{business_area}_{connection}_{hashed_args}"
return save_data_in_cache(cache_key, lambda: iterable.count(), 60 * 5)
except Exception as e:
logger.exception(e)
logger.warning(e)
return iterable.count()

@classmethod
Expand Down
Loading