Skip to content

Commit 0f50223

Browse files
authored
Error Logs for failed tranformer requests (#360)
* Added CLI option "logs" to redirect user to transform ids error logs * removed the URL optional opening, added info and error level, removed the table * Added loglevel in models for info and error * Removed Log Level from models.py * Logic to add the filters in the URL, _a parameters for request id, log level and g parameters for time frame * edited the logs cli option to use the log url from transformation status message
1 parent 332fc3e commit 0f50223

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed

servicex/app/transforms.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
import asyncio
2929
from pathlib import Path
3030
from typing import Optional, List
31+
import webbrowser
32+
import re
33+
from enum import Enum
3134

3235
import rich
3336
import typer
@@ -138,3 +141,83 @@ async def download_with_progress(filename) -> Path:
138141

139142
for path in result_files:
140143
print(path.as_posix())
144+
145+
146+
class TimeFrame(str, Enum):
147+
r"""
148+
Time Frame levels: 'day', 'week' & 'month'
149+
"""
150+
day = ("day",)
151+
week = ("week",)
152+
month = ("month")
153+
154+
155+
class LogLevel(str, Enum):
156+
r"""
157+
Level of the log messages: INFO & ERROR
158+
"""
159+
info = ("INFO",)
160+
error = ("ERROR",)
161+
162+
163+
def add_query(key, value):
164+
"""
165+
Creates query string from the key and value pairs
166+
"""
167+
query_string = "(query:(match_phrase:({0}:'{1}')))".format(key, value)
168+
return query_string
169+
170+
171+
def select_time(time_frame=TimeFrame.day):
172+
"""
173+
Takes input as 'day','week','month' and returns the time filter
174+
"""
175+
time_string = time_frame
176+
if time_frame.lower() == TimeFrame.day:
177+
time_string = "time:(from:now%2Fd,to:now%2Fd)"
178+
elif time_frame.lower() == TimeFrame.week:
179+
time_string = "time:(from:now%2Fw,to:now%2Fw)"
180+
elif time_frame.lower() == TimeFrame.month:
181+
time_string = "time:(from:now-30d%2Fd,to:now)"
182+
else:
183+
rich.print("Got a time frame apart from 'day', 'week', 'month'")
184+
return time_string
185+
186+
187+
def create_kibana_link_parameters(log_url, transform_id=None, log_level=None, time_frame=None):
188+
"""
189+
Create the _a and _g parameters for the kibana dashboard link
190+
"""
191+
a_parameter = f"&_a=(filters:!({add_query('requestId', transform_id)},"\
192+
f"{add_query('level', log_level.value.lower())}))"
193+
g_parameter = f"&_g=({select_time(time_frame.value.lower())})"
194+
kibana_link = re.sub(r"\&\_g\=\(\)", g_parameter + a_parameter, log_url)
195+
return kibana_link
196+
197+
198+
@transforms_app.command(no_args_is_help=True)
199+
def logs(
200+
url: Optional[str] = url_cli_option,
201+
backend: Optional[str] = backend_cli_option,
202+
transform_id: str = typer.Option(None, "-t", "--transform-id", help="Transform ID"),
203+
log_level: Optional[LogLevel] = typer.Option("ERROR", "-l", "--log-level",
204+
help="Level of Logs",
205+
case_sensitive=False),
206+
time_frame: Optional[TimeFrame] = typer.Option("month", "-f", "--time-frame",
207+
help="Time Frame",
208+
case_sensitive=False)
209+
):
210+
"""
211+
Open the URL to the Kibana dashboard of the logs of a tranformer
212+
"""
213+
sx = ServiceXClient(backend=backend, url=url)
214+
transforms = sx.get_transform_status(transform_id)
215+
if transforms and transforms.request_id == transform_id:
216+
kibana_link = create_kibana_link_parameters(transforms.log_url,
217+
transform_id=transform_id,
218+
log_level=log_level,
219+
time_frame=time_frame)
220+
print(kibana_link)
221+
webbrowser.open(kibana_link)
222+
else:
223+
rich.print("Invalid Request ID")

tests/test_servicex_app_transforms.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from servicex.app.transforms import LogLevel, TimeFrame
2+
from servicex.app.transforms import add_query, select_time, create_kibana_link_parameters
3+
4+
5+
def test_add_query():
6+
key = "abc"
7+
value = "123-345-567"
8+
query = "(query:(match_phrase:(abc:'123-345-567')))"
9+
assert add_query(key, value) == query
10+
11+
key = "requestId"
12+
value = "d2ede739-9779-4075-95b1-0c7fae1de408"
13+
query = "(query:(match_phrase:(requestId:'d2ede739-9779-4075-95b1-0c7fae1de408')))"
14+
assert add_query(key, value) == query
15+
16+
17+
def test_select_time():
18+
time_frame = TimeFrame.week
19+
time_filter = "time:(from:now%2Fw,to:now%2Fw)"
20+
assert time_filter == select_time(time_frame)
21+
22+
time_frame = "month"
23+
time_filter = "time:(from:now-30d%2Fd,to:now)"
24+
assert time_filter == select_time(time_frame)
25+
26+
time_frame = "daY"
27+
time_filter = "time:(from:now%2Fd,to:now%2Fd)"
28+
assert time_filter == select_time(time_frame)
29+
30+
31+
def test_create_kibana_link_parameters():
32+
initial_log_url = "https://atlas-kibana.mwt2.org:5601/s/servicex/app"\
33+
"/dashboards?auth_provider_hint=anonymous1#/view/"\
34+
"2d2b3b40-f34e-11ed-a6d8-9f6a16cd6d78?embed=true&_g=()"\
35+
"&show-time-filter=true&hide-filter-bar=true"
36+
transform_id = "d2ede739-9779-4075-95b1-0c7fae1de408"
37+
log_level = LogLevel.error
38+
time_frame = TimeFrame.day
39+
final_url = "https://atlas-kibana.mwt2.org:5601/s/servicex/app/dashboards?"\
40+
"auth_provider_hint=anonymous1#/view/2d2b3b40-f34e-11ed-a6d8-9f6a16cd6d78?"\
41+
"embed=true&_g=(time:(from:now%2Fd,to:now%2Fd))"\
42+
"&_a=(filters:!((query:(match_phrase:"\
43+
"(requestId:'d2ede739-9779-4075-95b1-0c7fae1de408'))),"\
44+
"(query:(match_phrase:(level:'error')))))&show-time-filter=true"\
45+
"&hide-filter-bar=true"
46+
assert create_kibana_link_parameters(initial_log_url, transform_id,
47+
log_level, time_frame) == final_url
48+
49+
transform_id = "93713b34-2f0b-4d53-8412-8afa98626516"
50+
log_level = LogLevel.info
51+
time_frame = TimeFrame.month
52+
final_url = "https://atlas-kibana.mwt2.org:5601/s/servicex/app/dashboards?"\
53+
"auth_provider_hint=anonymous1#/view/2d2b3b40-f34e-11ed-a6d8-9f6a16cd6d78?"\
54+
"embed=true&_g=(time:(from:now-30d%2Fd,to:now))"\
55+
"&_a=(filters:!((query:(match_phrase:"\
56+
"(requestId:'93713b34-2f0b-4d53-8412-8afa98626516'))),"\
57+
"(query:(match_phrase:(level:'info')))))&show-time-filter=true"\
58+
"&hide-filter-bar=true"
59+
assert create_kibana_link_parameters(initial_log_url, transform_id,
60+
log_level, time_frame) == final_url

0 commit comments

Comments
 (0)