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

Distributed error reporting: Task to ping telemetry with all the tracked errors #12357

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
2 changes: 2 additions & 0 deletions kolibri/core/analytics/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from kolibri.core.analytics.utils import DEFAULT_SERVER_URL
from kolibri.core.analytics.utils import ping_once
from kolibri.core.errorreports.tasks import ping_error_reports
from kolibri.core.tasks.decorators import register_task
from kolibri.core.tasks.exceptions import JobRunning
from kolibri.core.tasks.main import job_storage
Expand All @@ -25,6 +26,7 @@
def _ping(started, server, checkrate):
try:
ping_once(started, server=server)
ping_error_reports.enqueue(args=(server,))
except ConnectionError:
logger.warning(
"Ping failed (could not connect). Trying again in {} minutes.".format(
Expand Down
4 changes: 0 additions & 4 deletions kolibri/core/errorreports/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,6 @@ class ErrorReports(models.Model):
def __str__(self):
return f"{self.error_message} ({self.error_from})"

def mark_as_sent(self):
self.sent = True
self.save()

@classmethod
def insert_or_update_error(cls, error_from, error_message, traceback):
if not getattr(settings, "DEVELOPER_MODE", None):
Expand Down
55 changes: 55 additions & 0 deletions kolibri/core/errorreports/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import json
import logging

import requests
from django.core.serializers.json import DjangoJSONEncoder
from django.db import connection
from requests.exceptions import ConnectionError
from requests.exceptions import RequestException
from requests.exceptions import Timeout

from .models import ErrorReports
from kolibri.core.tasks.decorators import register_task
from kolibri.core.utils.urls import join_url

logger = logging.getLogger(__name__)


def serialize_error_reports_to_json_response(errors):
errors_list = []
for error in errors:
errors_list.append(
{
"error_from": error.error_from,
"error_message": error.error_message,
"traceback": error.traceback,
"first_occurred": error.first_occurred,
"last_occurred": error.last_occurred,
"no_of_errors": error.no_of_errors,
}
)
return json.dumps(errors_list, cls=DjangoJSONEncoder)


@register_task
def ping_error_reports(server):
try:
errors = ErrorReports.get_unsent_errors()
errors_json = serialize_error_reports_to_json_response(errors)
requests.post(
join_url(server, "/api/v1/errors/"),
data=errors_json,
headers={"Content-Type": "application/json"},
)
errors.update(sent=True)
except ConnectionError:
logger.warning("Reporting Error failed (could not connect).")
raise
except Timeout:
logger.warning("Reporting Error failed (connection timed out).")
raise
except RequestException as e:
logger.warning("Reporting Error failed ({})!".format(e))
raise
finally:
connection.close()
12 changes: 0 additions & 12 deletions kolibri/core/errorreports/test/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,3 @@ def test_get_unsent_errors(self):
self.assertEqual(unsent_errors.count(), 2)
self.assertFalse(unsent_errors[0].sent)
self.assertFalse(unsent_errors[1].sent)

def test_mark_as_sent(self):
error = ErrorReports.objects.create(
error_from=FRONTEND,
error_message="Test Error",
traceback="Test Traceback",
sent=False,
)
# first check error is unsent, then set True and assert again
self.assertFalse(error.sent)
error.mark_as_sent()
self.assertTrue(error.sent)