Skip to content

Commit

Permalink
Merge pull request #335 from roboflow/dedicated-deployment-add-log
Browse files Browse the repository at this point in the history
Add log support for dedicated deployment
  • Loading branch information
PacificDou authored Oct 30, 2024
2 parents 7fe28e5 + c0664b6 commit 0d6b37d
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 11 deletions.
14 changes: 14 additions & 0 deletions roboflow/adapters/deploymentapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,17 @@ def list_machine_types(api_key):
if response.status_code != 200:
return response.status_code, response.text
return response.status_code, response.json()


def get_deployment_log(api_key, deployment_name, from_timestamp=None, to_timestamp=None, max_entries=-1):
url = f"{DEDICATED_DEPLOYMENT_URL}/get_log?api_key={api_key}&deployment_name={deployment_name}"
if from_timestamp is not None:
url += f"&from_timestamp={from_timestamp.isoformat()}"
if to_timestamp is not None:
url += f"&to_timestamp={to_timestamp.isoformat()}"
if max_entries > 0:
url += f"&max_entries={max_entries}"
response = requests.get(url)
if response.status_code != 200:
return response.status_code, response.text
return response.status_code, response.json()
70 changes: 59 additions & 11 deletions roboflow/deployment.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json
import time
from datetime import datetime
from datetime import datetime, timedelta

from roboflow.adapters import deploymentapi
from roboflow.config import load_roboflow_api_key
Expand All @@ -19,6 +19,7 @@ def add_deployment_parser(subparsers):
)
deployment_list_parser = deployment_subparsers.add_parser("list", help="list dedicated deployments in a workspace")
deployment_delete_parser = deployment_subparsers.add_parser("delete", help="delete a dedicated deployment")
deployment_log_parser = deployment_subparsers.add_parser("log", help="show log info for a dedicated deployment")

deployment_machine_type_parser.set_defaults(func=list_machine_types)
deployment_machine_type_parser.add_argument("-a", "--api_key", help="api key")
Expand Down Expand Up @@ -69,24 +70,35 @@ def add_deployment_parser(subparsers):
deployment_delete_parser.add_argument("-a", "--api_key", help="api key")
deployment_delete_parser.add_argument("deployment_name", help="deployment name")

deployment_log_parser.set_defaults(func=get_deployment_log)
deployment_log_parser.add_argument("-a", "--api_key", help="api key")
deployment_log_parser.add_argument("deployment_name", help="deployment name")
deployment_log_parser.add_argument(
"-d", "--duration", help="duration of log (from now) in seconds", type=int, default=3600
)
deployment_log_parser.add_argument(
"-n", "--tail", help="number of lines to show from the end of the logs (<= 50)", type=int, default=10
)
deployment_log_parser.add_argument("-f", "--follow", help="follow log output", action="store_true")


def list_machine_types(args):
api_key = args.api_key or load_roboflow_api_key(None)
if api_key is None:
print("Please provide an api key")
return
exit(1)
status_code, msg = deploymentapi.list_machine_types(api_key)
if status_code != 200:
print(f"{status_code}: {msg}")
return
exit(status_code)
print(json.dumps(msg, indent=2))


def add_deployment(args):
api_key = args.api_key or load_roboflow_api_key(None)
if api_key is None:
print("Please provide an api key")
return
exit(1)
status_code, msg = deploymentapi.add_deployment(
api_key,
# args.security_level,
Expand All @@ -99,7 +111,7 @@ def add_deployment(args):

if status_code != 200:
print(f"{status_code}: {msg}")
return
exit(status_code)
else:
print(f"Deployment {args.deployment_name} created successfully")
print(json.dumps(msg, indent=2))
Expand All @@ -112,12 +124,12 @@ def get_deployment(args):
api_key = args.api_key or load_roboflow_api_key(None)
if api_key is None:
print("Please provide an api key")
return
exit(1)
while True:
status_code, msg = deploymentapi.get_deployment(api_key, args.deployment_name)
if status_code != 200:
print(f"{status_code}: {msg}")
return
exit(status_code)

if (not args.wait_on_pending) or msg["status"] != "pending":
print(json.dumps(msg, indent=2))
Expand All @@ -131,21 +143,57 @@ def list_deployment(args):
api_key = args.api_key or load_roboflow_api_key(None)
if api_key is None:
print("Please provide an api key")
return
exit(1)
status_code, msg = deploymentapi.list_deployment(api_key)
if status_code != 200:
print(f"{status_code}: {msg}")
return
exit(status_code)
print(json.dumps(msg, indent=2))


def delete_deployment(args):
api_key = args.api_key or load_roboflow_api_key(None)
if api_key is None:
print("Please provide an api key")
return
exit(1)
status_code, msg = deploymentapi.delete_deployment(api_key, args.deployment_name)
if status_code != 200:
print(f"{status_code}: {msg}")
return
exit(status_code)
print(json.dumps(msg, indent=2))


def get_deployment_log(args):
api_key = args.api_key or load_roboflow_api_key(None)
if api_key is None:
print("Please provide an api key")
exit(1)

to_timestamp = datetime.now()
from_timestamp = to_timestamp - timedelta(seconds=args.duration)
last_log_timestamp = from_timestamp
log_ids = set() # to avoid duplicate logs
max_entries = args.tail
while True:
status_code, msg = deploymentapi.get_deployment_log(
api_key, args.deployment_name, from_timestamp, to_timestamp, max_entries
)
if status_code != 200:
print(f"{status_code}: {msg}")
exit(status_code)

for log in msg[::-1]: # logs are sorted by reversed timestamp
log_timestamp = datetime.fromisoformat(log["timestamp"]).replace(tzinfo=None)
if (log["insert_id"] in log_ids) or (log_timestamp < last_log_timestamp):
continue
log_ids.add(log["insert_id"])
last_log_timestamp = log_timestamp
print(f'[{log_timestamp.strftime("%Y-%m-%d %H:%M:%S.%f")}] {log["payload"]}')

if not args.follow:
break

time.sleep(10)
from_timestamp = last_log_timestamp
to_timestamp = datetime.now()
max_entries = 300 # only set max_entries for the first request

0 comments on commit 0d6b37d

Please sign in to comment.