Skip to content

Commit

Permalink
improvement(webhooks): Update format and save to logs
Browse files Browse the repository at this point in the history
  • Loading branch information
pneumojoseph committed Nov 6, 2024
1 parent 685f9eb commit 35150c4
Show file tree
Hide file tree
Showing 40 changed files with 1,321 additions and 451 deletions.
1 change: 1 addition & 0 deletions core/pneumatic_backend/authentication/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def process_response(self, request, response):
auth_token=token,
scheme=request.scheme,
method=request.method,
title='API request',
path=request.path,
body=body,
http_status=response.status_code,
Expand Down
51 changes: 47 additions & 4 deletions core/pneumatic_backend/logs/admin.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import json
from django.contrib import admin
from django.utils.safestring import mark_safe
from pneumatic_backend.logs.models import AccountEvent
from pneumatic_backend.logs.enums import AccountEventStatus
from pneumatic_backend.utils.dates import date_to_user_fmt
from pneumatic_backend.logs.filters import AccountAdminFilter
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import get_formatter_by_name


json_lexer = get_lexer_by_name('json')
formatter = get_formatter_by_name('html', style='colorful')


@admin.register(AccountEvent)
class AccountEventAdmin(admin.ModelAdmin):

list_display = (
'title',
'path',
'method',
'date_created_tz',
Expand All @@ -31,6 +41,7 @@ class AccountEventAdmin(admin.ModelAdmin):
)

search_fields = (
'title',
'path',
'body',
)
Expand All @@ -39,6 +50,7 @@ class AccountEventAdmin(admin.ModelAdmin):
(
None, {
'fields': (
'title',
'status',
'date_created_tz',
'event_type',
Expand All @@ -53,9 +65,9 @@ class AccountEventAdmin(admin.ModelAdmin):
'scheme',
'method',
'path',
'body',
'formatted_body',
'http_status',
'error'
'formatted_error'
)
}
),
Expand All @@ -72,6 +84,7 @@ class AccountEventAdmin(admin.ModelAdmin):
)

readonly_fields = (
'title',
'date_created_tz',
'event_type',
'http_status',
Expand All @@ -80,11 +93,11 @@ class AccountEventAdmin(admin.ModelAdmin):
'path',
'user',
'account',
'body',
'formatted_body',
'ip',
'auth_token',
'user_agent',
'error',
'formatted_error',
'event_type',
'direction',
'contractor',
Expand Down Expand Up @@ -116,3 +129,33 @@ def user_name(self, obj):

def has_add_permission(self, request):
return False

def formatted_body(self, instance):
if instance.body:
response = json.dumps(
instance.body,
sort_keys=True,
indent=2,
ensure_ascii=False
)
response = highlight(response, json_lexer, formatter)
style = "<style>" + formatter.get_style_defs() + "</style><br>"
return mark_safe(style + response)
else:
return '-'
formatted_body.short_description = 'body'

def formatted_error(self, instance):
if instance.error:
response = json.dumps(
instance.error,
sort_keys=True,
indent=2,
ensure_ascii=False
)
response = highlight(response, json_lexer, formatter)
style = "<style>" + formatter.get_style_defs() + "</style><br>"
return mark_safe(style + response)
else:
return '-'
formatted_error.short_description = 'error'
3 changes: 2 additions & 1 deletion core/pneumatic_backend/logs/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class AccountEvent(
class Meta:
ordering = ('-date_created', 'account')

title = models.CharField(max_length=500, blank=True, null=True)
user = models.ForeignKey(
UserModel,
on_delete=models.SET_NULL,
Expand Down Expand Up @@ -62,4 +63,4 @@ def is_sent(self):
return self.direction == RequestDirection.SENT

def __str__(self):
return f'{self.method} {self.path}'
return self.title
36 changes: 32 additions & 4 deletions core/pneumatic_backend/logs/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class AccountLogService(BaseModelService):
def _create_instance(
self,
event_type: AccountEventType,
title: Optional[str] = None,
path: Optional[str] = None,
method: Optional[str] = None,
scheme: Optional[str] = None,
Expand All @@ -36,6 +37,7 @@ def _create_instance(

self.instance = AccountEvent.objects.create(
event_type=event_type,
title=title,
ip=ip,
user_agent=user_agent,
auth_token=auth_token,
Expand Down Expand Up @@ -63,6 +65,7 @@ def api_request(
auth_token: str,
scheme: str,
method: str,
title: str,
path: str,
http_status: int,
direction: RequestDirection = RequestDirection.RECEIVED,
Expand All @@ -84,6 +87,7 @@ def api_request(
auth_token=auth_token,
scheme=scheme,
method=method,
title=title,
path=path,
body=body,
http_status=http_status,
Expand All @@ -97,15 +101,15 @@ def api_request(

def push_notification(
self,
path: str,
title: str,
body: dict,
account_id: int,
status: AccountEventStatus,
error: Optional[dict] = None,
):
self.create(
event_type=AccountEventType.API,
path=path,
title=title,
body=body,
status=status,
account_id=account_id,
Expand All @@ -116,7 +120,7 @@ def push_notification(

def email_message(
self,
path: str,
title: str,
body: dict,
account_id: int,
contractor: str,
Expand All @@ -125,11 +129,35 @@ def email_message(
):
self.create(
event_type=AccountEventType.API,
path=path,
title=title,
body=body,
status=status,
account_id=account_id,
error=error,
direction=RequestDirection.SENT,
contractor=contractor,
)

def webhook(
self,
title: str,
path: str,
body: dict,
account_id: int,
status: AccountEventStatus,
http_status: int,
error: Optional[dict] = None,
user_id: Optional[int] = None
):
self.create(
event_type=AccountEventType.WEBHOOK,
title=title,
path=path,
body=body,
http_status=http_status,
status=status,
account_id=account_id,
error=error,
direction=RequestDirection.SENT,
user_id=user_id,
)
2 changes: 1 addition & 1 deletion core/pneumatic_backend/notifications/services/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def _send_email_via_customerio(
client.send_email(request)
if self.logging:
AccountLogService().email_message(
path=f'Email to: {user_email}: {title}',
title=f'Email to: {user_email}: {title}',
body=data,
account_id=self.account_id,
status=AccountEventStatus.SUCCESS,
Expand Down
8 changes: 5 additions & 3 deletions core/pneumatic_backend/notifications/services/push.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ def _send_to_browsers(
else:
if self.logging:
AccountLogService().push_notification(
path=f'Push to browser: {user_email}: {data["title"]}',
title=(
f'Push to browser: {user_email}: {data["title"]}'
),
body=data,
account_id=self.account_id,
status=AccountEventStatus.SUCCESS,
Expand Down Expand Up @@ -145,7 +147,7 @@ def _send_to_apps(
else:
if self.logging:
AccountLogService().push_notification(
path=f'Push to app: {user_email}: {data["title"]}',
title=f'Push to app: {user_email}: {data["title"]}',
body=data,
account_id=self.account_id,
status=AccountEventStatus.SUCCESS,
Expand Down Expand Up @@ -197,7 +199,7 @@ def _handle_error(
):
if self.logging:
AccountLogService().push_notification(
path=f'Push to {device} {user_email}: {data["title"]}',
title=f'Push to {device} {user_email}: {data["title"]}',
body=data,
account_id=self.account_id,
status=AccountEventStatus.FAILED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def test_send_email_via_customerio__enable_logging__ok(mocker):
)
client_mock.send_email.assert_called_once_with(request_mock)
create_account_log_mock.assert_called_once_with(
path=f'Email to: {email}: {title}',
title=f'Email to: {email}: {title}',
body=data,
account_id=account_id,
status=AccountEventStatus.SUCCESS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ def test_send_to_browsers__enable_logging__ok(
send_mock.assert_called_once_with(message_mock)
log_service_init_mock.assert_called_once()
log_push_mock.assert_called_once_with(
path=f'Push to browser: {user.email}: {data["title"]}',
title=f'Push to browser: {user.email}: {data["title"]}',
body=data,
account_id=account.id,
status=AccountEventStatus.SUCCESS,
Expand Down Expand Up @@ -574,7 +574,7 @@ def test_send_to_apps__enable_logging__ok(
assert counter.count_unread_push_in_ios_app == 2
log_service_init_mock.assert_called_once()
log_push_mock.assert_called_once_with(
path=f'Push to app: {user.email}: {data["title"]}',
title=f'Push to app: {user.email}: {data["title"]}',
body=data,
account_id=account.id,
status=AccountEventStatus.SUCCESS,
Expand Down Expand Up @@ -1005,7 +1005,7 @@ def test_handle_error__enable_logging__create_account_log(self, mocker):
assert Device.objects.filter(token=broken_device.token).exists()
log_service_init_mock.assert_called_once()
log_push_mock.assert_called_once_with(
path=f'Push to browser {user.email}: {data["title"]}',
title=f'Push to browser {user.email}: {data["title"]}',
body=data,
account_id=user.account_id,
status=AccountEventStatus.FAILED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from pneumatic_backend.analytics.actions import (
WorkflowActions
)
from pneumatic_backend.webhooks.models import WebHook
from pneumatic_backend.processes.tasks.webhooks import (
send_workflow_started_webhook,
)
Expand Down Expand Up @@ -199,14 +200,9 @@ def _create_actions(self, **kwargs):
template=self.instance.template,
user_agent=kwargs.get('user_agent')
)

def create(
self,
**kwargs
) -> Workflow:
super().create(**kwargs)
send_workflow_started_webhook.delay(
user_id=self.user.id,
instance_id=self.instance.id
)
return self.instance
if WebHook.objects.on_account(self.account.id).wf_started().exists():
send_workflow_started_webhook.delay(
user_id=self.user.id,
account_id=self.account.id,
payload=self.instance.webhook_payload()
)
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,10 @@ def test_update__end_workflow__ok(self, mocker, api_client):
template=template
)
task = workflow.tasks.get(number=1)

mocker.patch(
'pneumatic_backend.processes.tasks.webhooks.'
'send_task_completed_webhook.delay'
)
deactivate_cache_mock = mocker.patch(
'pneumatic_backend.authentication.services.'
'GuestJWTAuthService.deactivate_task_guest_cache'
Expand Down
Loading

0 comments on commit 35150c4

Please sign in to comment.