Skip to content

Commit 262744e

Browse files
committed
add example of context_log
1 parent 3fbfb1c commit 262744e

File tree

4 files changed

+99
-2
lines changed

4 files changed

+99
-2
lines changed

superset/commands/report/execute.py

+2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
from superset.utils.celery import session_scope
7272
from superset.utils.core import HeaderDataType, override_user
7373
from superset.utils.csv import get_chart_csv_data, get_chart_dataframe
74+
from superset.utils.decorators import logs_context
7475
from superset.utils.screenshots import ChartScreenshot, DashboardScreenshot
7576
from superset.utils.urls import get_url_path
7677

@@ -81,6 +82,7 @@ class BaseReportState:
8182
current_states: list[ReportState] = []
8283
initial: bool = False
8384

85+
@logs_context()
8486
def __init__(
8587
self,
8688
session: Session,

superset/reports/notifications/slack.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import backoff
2424
import pandas as pd
25+
from flask import g
2526
from flask_babel import gettext as __
2627
from slack_sdk import WebClient
2728
from slack_sdk.errors import (
@@ -175,6 +176,7 @@ def send(self) -> None:
175176
channel = self._get_channel()
176177
body = self._get_body()
177178
file_type = "csv" if self._content.csv else "png"
179+
global_logs_context = getattr(g, "logs_context", {}) or {}
178180
try:
179181
token = app.config["SLACK_API_TOKEN"]
180182
if callable(token):
@@ -192,7 +194,12 @@ def send(self) -> None:
192194
)
193195
else:
194196
client.chat_postMessage(channel=channel, text=body)
195-
logger.info("Report sent to slack")
197+
logger.info(
198+
"Report sent to slack",
199+
extra={
200+
"execution_id": global_logs_context.get("execution_id"),
201+
},
202+
)
196203
except (
197204
BotUserAccessError,
198205
SlackRequestError,

superset/utils/decorators.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ def wrapped(*args: Any, **kwargs: Any) -> Any:
9191
if ctx_kwargs.get(key) is not None:
9292
logs_context_data[key] = ctx_kwargs[key]
9393
try:
94-
# override value from local kwargs from function execution if it exists
94+
# override value from local kwargs from
95+
# function execution if it exists
9596
# e.g. @logs_context(slice_id=1, dashboard_id=1)
9697
# def my_func(slice_id=None, **kwargs)
9798
#
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
import uuid
18+
from unittest.mock import MagicMock, patch
19+
20+
import pandas as pd
21+
from flask import g
22+
23+
24+
@patch("superset.reports.notifications.slack.logger")
25+
def test_send_slack(
26+
logger_mock: MagicMock,
27+
) -> None:
28+
# `superset.models.helpers`, a dependency of following imports,
29+
# requires app context
30+
from superset.reports.models import ReportRecipients, ReportRecipientType
31+
from superset.reports.notifications.base import NotificationContent
32+
from superset.reports.notifications.slack import SlackNotification, WebClient
33+
34+
execution_id = uuid.uuid4()
35+
g.logs_context = {"execution_id": execution_id}
36+
content = NotificationContent(
37+
name="test alert",
38+
header_data={
39+
"notification_format": "PNG",
40+
"notification_type": "Alert",
41+
"owners": [1],
42+
"notification_source": None,
43+
"chart_id": None,
44+
"dashboard_id": None,
45+
},
46+
embedded_data=pd.DataFrame(
47+
{
48+
"A": [1, 2, 3],
49+
"B": [4, 5, 6],
50+
"C": ["111", "222", '<a href="http://www.example.com">333</a>'],
51+
}
52+
),
53+
description='<p>This is <a href="#">a test</a> alert</p><br />',
54+
)
55+
with patch.object(
56+
WebClient, "chat_postMessage", return_value=True
57+
) as chat_post_message_mock:
58+
SlackNotification(
59+
recipient=ReportRecipients(
60+
type=ReportRecipientType.SLACK,
61+
recipient_config_json='{"target": "some_channel"}',
62+
),
63+
content=content,
64+
).send()
65+
logger_mock.info.assert_called_with(
66+
"Report sent to slack", extra={"execution_id": execution_id}
67+
)
68+
chat_post_message_mock.assert_called_with(
69+
channel="some_channel",
70+
text="""*test alert*
71+
72+
<p>This is <a href="#">a test</a> alert</p><br />
73+
74+
<None|Explore in Superset>
75+
76+
```
77+
| | A | B | C |
78+
|---:|----:|----:|:-----------------------------------------|
79+
| 0 | 1 | 4 | 111 |
80+
| 1 | 2 | 5 | 222 |
81+
| 2 | 3 | 6 | <a href="http://www.example.com">333</a> |
82+
```
83+
""",
84+
)
85+
86+
# reset g.logs_context
87+
g.logs_context = None

0 commit comments

Comments
 (0)