surahman commented on a change in pull request #3786:
URL: https://github.com/apache/incubator-heron/pull/3786#discussion_r835616292
##########
File path: heron/tools/common/src/python/clients/tracker.py
##########
@@ -54,8 +54,8 @@
SCHEDULER_LOCATION_URL_FMT = "%s/schedulerlocation" % TOPOLOGIES_URL_FMT
METRICS_URL_FMT = "%s/metrics" % TOPOLOGIES_URL_FMT
-METRICS_QUERY_URL_FMT = "%s/metricsquery" % TOPOLOGIES_URL_FMT
-METRICS_TIMELINE_URL_FMT = "%s/metricstimeline" % TOPOLOGIES_URL_FMT
+METRICS_QUERY_URL_FMT = "%s/metrics/query" % TOPOLOGIES_URL_FMT
+METRICS_TIMELINE_URL_FMT = "%s/metrics/timeline" % TOPOLOGIES_URL_FMT
Review comment:
Nitpick:
```suggestion
METRICS_QUERY_URL_FMT = METRICS_URL_FMT % "%s/query" %
TOPOLOGIES_URL_FMT
METRICS_TIMELINE_URL_FMT = METRICS_URL_FMT % "%s/timeline" %
TOPOLOGIES_URL_FMT
```
##########
File path: heron/tools/tracker/src/python/query_operators.py
##########
@@ -476,7 +477,7 @@ async def execute(self, tracker, tmanager:
TManagerLocation, start: int, end: in
# Initialize with first metrics timeline and its instance
met = Metrics(None, None, metric.instance, start, end,
metric.timeline.copy())
for timestamp in list(met.timeline.keys()):
- v = self._f(met.timeline[timestamp],
metrics2[""].timeline.get(timestamp))
+ v = self._f(met.timeline[timestamp], metrics2[""].timeline[timestamp])
Review comment:
Good change. It is better to use the `[]` instead of the `.get()` method
throughout to access the dictionary elements for consistency.
##########
File path: heron/tools/common/src/python/clients/tracker.py
##########
@@ -122,27 +122,26 @@ def strip_whitespace(s):
backpressure=backpressure
)
-def api_get(url: str, params=None) -> dict:
+def api_get(url: str, params=None) -> Any:
"""Make a GET request to a tracker URL and return the result."""
start = time.time()
try:
+ Log.debug(f"Requesting URL: {url} with params: {params}")
response = requests.get(url, params)
response.raise_for_status()
except Exception as e:
- Log.error(f"Unable to get response from {url}: {e}")
+ Log.error(f"Unable to get response from {url} with params {params}: {e}")
return None
end = time.time()
data = response.json()
- if data["status"] != "success":
- Log.error("error from tracker: %s", data["message"])
+ if response.status_code != requests.codes.ok:
+ Log.error("error from tracker: %s", response.status_code)
return None
- execution = data["executiontime"] * 1000
duration = (end - start) * 1000
- Log.debug(f"URL fetch took {execution:.2}ms server time for {url}")
Log.debug(f"URL fetch took {duration:.2}ms round trip time for {url}")
- return data["result"]
+ return data
Review comment:
This now returns the entire JSON response instead of just the `result`
tuple's value. We must make sure all upstream calls handle this return
correctly and unpack the tuple.
##########
File path: heron/tools/tracker/src/python/routers/metrics.py
##########
@@ -151,19 +152,19 @@ class TimelinePoint(BaseModel): # pylint:
disable=too-few-public-methods
class MetricsQueryResponse(BaseModel): # pylint: disable=too-few-public-methods
"""A metrics timeline over an interval."""
- start_time: int = Field(..., alias="starttime")
- end_time: int = Field(..., alias="endtime")
+ starttime: int = Field(..., alias="starttime")
+ endtime: int = Field(..., alias="endtime")
Review comment:
Would be best to switch these to `str` as well for consistency as you
have switched their similar definitions from `int` to `str` elsewhere? Or are
these used in some sort of numeric calculation somewhere?
##########
File path: heron/tools/tracker/src/python/routers/metrics.py
##########
@@ -151,19 +152,19 @@ class TimelinePoint(BaseModel): # pylint:
disable=too-few-public-methods
class MetricsQueryResponse(BaseModel): # pylint: disable=too-few-public-methods
"""A metrics timeline over an interval."""
- start_time: int = Field(..., alias="starttime")
- end_time: int = Field(..., alias="endtime")
+ starttime: int = Field(..., alias="starttime")
+ endtime: int = Field(..., alias="endtime")
timeline: List[TimelinePoint] = Field(
..., description="list of timeline point objects",
)
[email protected]("/metricsquery", response_model=MetricsQueryResponse)
[email protected]("/metrics/query", response_model=MetricsQueryResponse)
async def get_metrics_query( # pylint: disable=too-many-arguments
cluster: str,
- role: Optional[str],
environ: str,
query: str,
+ role: Optional[str] = None,
start_time: int = Query(..., alias="starttime"),
end_time: int = Query(..., alias="endtime"),
Review comment:
If you switch over to `str` in the class definition these will need to
be updated as well.
##########
File path: heron/tools/common/src/python/clients/tracker.py
##########
@@ -54,8 +54,8 @@
SCHEDULER_LOCATION_URL_FMT = "%s/schedulerlocation" % TOPOLOGIES_URL_FMT
METRICS_URL_FMT = "%s/metrics" % TOPOLOGIES_URL_FMT
-METRICS_QUERY_URL_FMT = "%s/metricsquery" % TOPOLOGIES_URL_FMT
-METRICS_TIMELINE_URL_FMT = "%s/metricstimeline" % TOPOLOGIES_URL_FMT
+METRICS_QUERY_URL_FMT = "%s/metrics/query" % TOPOLOGIES_URL_FMT
+METRICS_TIMELINE_URL_FMT = "%s/metrics/timeline" % TOPOLOGIES_URL_FMT
Review comment:
I also question whether these values should be located in a central
resource file so we can reference them for the request router URLs as well.
##########
File path: heron/tools/tracker/src/python/routers/container.py
##########
@@ -22,31 +22,34 @@
topology, particularly data about heron containers.
"""
+from asyncio import constants
+from subprocess import CompletedProcess
from typing import List, Optional
+from heron.common.src.python.utils.log import Log
from heron.proto import common_pb2, tmanager_pb2
from heron.tools.tracker.src.python import state, utils
-from heron.tools.tracker.src.python.utils import EnvelopingAPIRouter
import httpx
-from fastapi import Query
+# from fastapi import Query
+from fastapi import Query, APIRouter
from pydantic import BaseModel, Field
from starlette.responses import StreamingResponse
-router = EnvelopingAPIRouter()
+router = APIRouter()
[email protected]("/containerfiledata")
[email protected]("/container/filedata")
Review comment:
For better maintainability, it would be best to construct these URLs
from a central resource file. That way, if a URL needs to be updated we would
do it from one location and all updates would cascade without broken links.
##########
File path: heron/tools/tracker/src/python/app.py
##########
@@ -80,35 +79,23 @@ async def shutdown_event():
"""Stop recieving topology updates."""
state.tracker.stop_sync()
-
@app.exception_handler(Exception)
async def handle_exception(_, exc: Exception):
- payload = ResponseEnvelope[str](
- result=None,
- execution_time=0.0,
- message=f"request failed: {exc}",
- status=constants.RESPONSE_STATUS_FAILURE
- )
+ message=f"request failed: {exc}"
Review comment:
Whitespace fix:
```suggestion
message = f"request failed: {exc}"
```
##########
File path: heron/tools/tracker/src/python/app.py
##########
@@ -80,35 +79,23 @@ async def shutdown_event():
"""Stop recieving topology updates."""
state.tracker.stop_sync()
-
@app.exception_handler(Exception)
async def handle_exception(_, exc: Exception):
- payload = ResponseEnvelope[str](
- result=None,
- execution_time=0.0,
- message=f"request failed: {exc}",
- status=constants.RESPONSE_STATUS_FAILURE
- )
+ message=f"request failed: {exc}"
status_code = 500
if isinstance(exc, StarletteHTTPException):
status_code = exc.status_code
if isinstance(exc, RequestValidationError):
status_code = 400
- return JSONResponse(content=payload.dict(), status_code=status_code)
-
+ return JSONResponse(content=message, status_code=status_code)
[email protected]("/clusters", response_model=ResponseEnvelope[List[str]])
[email protected]("/clusters")
async def clusters() -> List[str]:
- return ResponseEnvelope[List[str]](
- execution_time=0.0,
- message="ok",
- status="success",
- result=[s.name for s in state.tracker.state_managers],
- )
-
+ return (s.name for s in state.tracker.state_managers)
+
Review comment:
Whitespace fix:
```suggestion
```
##########
File path: heron/tools/tracker/src/python/tracker.py
##########
@@ -89,7 +89,7 @@ def get_topology(
cluster: str,
role: Optional[str],
environ: str,
- topology_name: str,
+ topology_name: str,
Review comment:
Whitespace fix:
```suggestion
topology_name: str,
```
##########
File path: heron/tools/common/src/python/clients/tracker.py
##########
@@ -66,9 +66,9 @@
JMAP_URL_FMT = "%s/jmap" % TOPOLOGIES_URL_FMT
HISTOGRAM_URL_FMT = "%s/histo" % TOPOLOGIES_URL_FMT
-FILE_DATA_URL_FMT = "%s/containerfiledata" % TOPOLOGIES_URL_FMT
-FILE_DOWNLOAD_URL_FMT = "%s/containerfiledownload" % TOPOLOGIES_URL_FMT
-FILESTATS_URL_FMT = "%s/containerfilestats" % TOPOLOGIES_URL_FMT
+FILE_DATA_URL_FMT = "%s/container/filedata" % TOPOLOGIES_URL_FMT
+FILE_DOWNLOAD_URL_FMT = "%s/container/filedownload" % TOPOLOGIES_URL_FMT
+FILESTATS_URL_FMT = "%s/container/filestats" % TOPOLOGIES_URL_FMT
Review comment:
Nitpick:
```suggestion
CONTAINER_URL_FMT = "%s/container"
FILE_DATA_URL_FMT = CONTAINER_URL_FMT % "%s/filedata" %
TOPOLOGIES_URL_FMT
FILE_DOWNLOAD_URL_FMT = CONTAINER_URL_FMT % "%s/filedownload" %
TOPOLOGIES_URL_FMT
FILESTATS_URL_FMT = CONTAINER_URL_FMT % "%s/filestats" %
TOPOLOGIES_URL_FMT
```
##########
File path: heron/tools/tracker/src/python/metricstimeline.py
##########
@@ -73,21 +73,21 @@ async def get_metrics_timeline(
# Form and send the http request.
url = f"http://{tmanager.host}:{tmanager.stats_port}/stats"
- with httpx.AsyncClient() as client:
+ async with httpx.AsyncClient() as client:
result = await client.post(url,
data=request_parameters.SerializeToString())
# Check the response code - error if it is in 400s or 500s
- if result.code >= 400:
+ if result.status_code >= 400:
message = f"Error in getting metrics from Tmanager, code: {result.code}"
raise Exception(message)
# Parse the response from tmanager.
response_data = tmanager_pb2.MetricResponse()
response_data.ParseFromString(result.content)
- if response_data.status.status == common_pb2.NOTOK:
- if response_data.status.HasField("message"):
- Log.warn("Received response from Tmanager: %s",
response_data.status.message)
+ # if response_data.status.status == common_pb2.NOTOK:
+ # if response_data.status.HasField("message"):
+ # Log.warn("Received response from Tmanager: %s",
response_data.status.message)
Review comment:
Delete these commented out lines?
##########
File path: heron/tools/tracker/src/python/routers/container.py
##########
@@ -186,29 +189,30 @@ async def _get_exception_log_response(
@router.get("/exceptions", response_model=List[ExceptionLog])
async def get_exceptions( # pylint: disable=too-many-arguments
cluster: str,
- role: Optional[str],
environ: str,
component: str,
- instances: List[str] = Query(..., alias="instance"),
+ instances: Optional[List[str]] = Query(None, alias="instance"),
topology_name: str = Query(..., alias="topology"),
+ role: Optional[str] = None,
):
"""Return info about exceptions that have occurred per instance."""
exception_response = await _get_exception_log_response(
cluster, role, environ, component, instances, topology_name,
summary=False
)
-
- return [
- ExceptionLog(
- hostname=exception_log.hostname,
- instance_id=exception_log.instance_id,
- stack_trace=exception_log.stacktrace,
- lasttime=exception_log.lasttime,
- firsttime=exception_log.firsttime,
- count=str(exception_log.count),
- logging=exception_log.logging,
- )
- for exception_log in exception_response.exceptions
- ]
+ print(f"NICK: exception response: {exception_response}")
+
+ ret = []
+ for exception_log in exception_response.exceptions:
+ ret.append(ExceptionLog(
+ hostname = exception_log.hostname,
+ instance_id = exception_log.instance_id,
+ stacktrace = exception_log.stacktrace,
+ lasttime = exception_log.lasttime,
+ firsttime = exception_log.firsttime,
+ count = str(exception_log.count),
+ logging = exception_log.logging,
+ ))
Review comment:
Indentation and whitespace fix
```suggestion
ret.append(ExceptionLog(
hostname=exception_log.hostname,
instance_id=exception_log.instance_id,
stacktrace=exception_log.stacktrace,
lasttime=exception_log.lasttime,
firsttime=exception_log.firsttime,
count=str(exception_log.count),
logging=exception_log.logging,
))
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]