-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
instrument NADE commands using metric spans #1844
Changes from 10 commits
a2a833e
46a3028
cf3a339
d26af10
6b3d12e
ca990d4
4edd8b2
f99a275
db00d94
84209f0
506bae2
7846c43
ec44e0c
d5e2376
15955f7
1b1d99a
a32a21b
b77d135
cef9f19
8a45192
bf8cf5b
ae43f25
93e5dc9
bfc4f21
5e1e38c
348aac2
c618da6
2fbdcb6
05d81a9
e96a0ee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,6 +43,7 @@ | |
from snowflake.cli._plugins.nativeapp.sf_facade import get_snowflake_facade | ||
from snowflake.cli._plugins.nativeapp.utils import needs_confirmation | ||
from snowflake.cli._plugins.workspace.context import ActionContext | ||
from snowflake.cli.api.cli_global_context import span | ||
from snowflake.cli.api.entities.common import EntityBase, get_sql_executor | ||
from snowflake.cli.api.entities.utils import ( | ||
drop_generic_object, | ||
|
@@ -146,6 +147,7 @@ def post_deploy_hooks(self) -> list[PostDeployHook] | None: | |
model = self._entity_model | ||
return model.meta and model.meta.post_deploy | ||
|
||
@span("deploy_app") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should consider some kind of standardized scheme for actions + entities, maybe something like |
||
def action_deploy( | ||
self, | ||
action_ctx: ActionContext, | ||
|
@@ -230,6 +232,7 @@ def action_deploy( | |
interactive=interactive, | ||
) | ||
|
||
@span("drop_app") | ||
def action_drop( | ||
self, | ||
action_ctx: ActionContext, | ||
|
@@ -513,10 +516,10 @@ def create_or_upgrade_app( | |
create_cursor = sql_executor.execute_query( | ||
dedent( | ||
f"""\ | ||
create application {self.name} | ||
from application package {package.name} {using_clause} {debug_mode_clause} | ||
comment = {SPECIAL_COMMENT} | ||
""" | ||
create application {self.name} | ||
from application package {package.name} {using_clause} {debug_mode_clause} | ||
comment = {SPECIAL_COMMENT} | ||
""" | ||
), | ||
) | ||
print_messages(console, create_cursor) | ||
|
@@ -769,6 +772,7 @@ def stream_events( | |
except KeyboardInterrupt: | ||
return | ||
|
||
@span("get_snowsight_url_for_app") | ||
sfc-gh-fcampbell marked this conversation as resolved.
Show resolved
Hide resolved
|
||
def get_snowsight_url(self) -> str: | ||
"""Returns the URL that can be used to visit this app via Snowsight.""" | ||
name = identifier_for_url(self.name) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,6 +43,7 @@ | |
from snowflake.cli._plugins.stage.diff import DiffResult | ||
from snowflake.cli._plugins.stage.manager import StageManager | ||
from snowflake.cli._plugins.workspace.context import ActionContext | ||
from snowflake.cli.api.cli_global_context import span | ||
from snowflake.cli.api.entities.common import EntityBase, get_sql_executor | ||
from snowflake.cli.api.entities.utils import ( | ||
drop_generic_object, | ||
|
@@ -218,6 +219,7 @@ def action_deploy( | |
force=force, | ||
) | ||
|
||
@span("drop_app_package") | ||
sfc-gh-fcampbell marked this conversation as resolved.
Show resolved
Hide resolved
|
||
def action_drop(self, action_ctx: ActionContext, force_drop: bool, *args, **kwargs): | ||
console = self._workspace_ctx.console | ||
sql_executor = get_sql_executor() | ||
|
@@ -548,6 +550,7 @@ def _bundle(self): | |
compiler.compile_artifacts() | ||
return bundle_map | ||
|
||
@span("deploy_app_package") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would rather do this on the action for consistency |
||
def _deploy( | ||
self, | ||
bundle_map: BundleMap | None, | ||
|
@@ -915,6 +918,7 @@ def validate_setup_script( | |
if validation_result["status"] == "FAIL": | ||
raise SetupScriptFailedValidation() | ||
|
||
@span("validate_setup_script") | ||
def get_validation_result( | ||
self, use_scratch_stage: bool, interactive: bool, force: bool | ||
): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
from contextlib import contextmanager | ||
from contextvars import ContextVar | ||
from dataclasses import dataclass, field, replace | ||
from functools import wraps | ||
from pathlib import Path | ||
from typing import TYPE_CHECKING, Iterator | ||
|
||
|
@@ -157,7 +158,7 @@ def enable_tracebacks(self) -> bool: | |
return self._manager.enable_tracebacks | ||
|
||
@property | ||
def metrics(self): | ||
def metrics(self) -> CLIMetrics: | ||
return self._manager.metrics | ||
|
||
@property | ||
|
@@ -213,6 +214,26 @@ def get_cli_context() -> _CliGlobalContextAccess: | |
return _CliGlobalContextAccess(get_cli_context_manager()) | ||
|
||
|
||
def span(span_name: str): | ||
""" | ||
Decorator to start a command metrics span that encompasses a whole function | ||
|
||
Must be used instead of directly calling @get_cli_context().metrics.start_span(span_name) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's |
||
as a decorator to ensure that the cli context is grabbed at run time instead of at | ||
module load time, which would not reflect forking | ||
""" | ||
|
||
def decorator(func): | ||
@wraps(func) | ||
def wrapper(*args, **kwargs): | ||
with get_cli_context().metrics.span(span_name): | ||
return func(*args, **kwargs) | ||
|
||
return wrapper | ||
|
||
return decorator | ||
|
||
|
||
@contextmanager | ||
def fork_cli_context( | ||
connection_overrides: dict | None = None, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -68,7 +68,11 @@ def _format_message(self, message: str, output: Output) -> Text: | |
return text | ||
|
||
@contextmanager | ||
def phase(self, enter_message: str, exit_message: Optional[str] = None): | ||
def phase( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you're no longer touching this, I'd revert the file entirely |
||
self, | ||
enter_message: str, | ||
exit_message: Optional[str] = None, | ||
): | ||
"""A context manager for organising steps into logical group.""" | ||
if self.in_phase: | ||
raise CliConsoleNestingProhibitedError("Only one phase allowed at a time.") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,7 +23,7 @@ | |
to_stage_path, | ||
) | ||
from snowflake.cli._plugins.stage.utils import print_diff_to_console | ||
from snowflake.cli.api.cli_global_context import get_cli_context | ||
from snowflake.cli.api.cli_global_context import get_cli_context, span | ||
from snowflake.cli.api.console.abc import AbstractConsole | ||
from snowflake.cli.api.entities.common import get_sql_executor | ||
from snowflake.cli.api.errno import ( | ||
|
@@ -76,6 +76,7 @@ def _get_stage_paths_to_sync( | |
return stage_paths | ||
|
||
|
||
@span("sync_remote_and_local_files") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is one of the rare cases where I'd use the actual function name, since it's exactly the logical concept we're timing. |
||
def sync_deploy_root_with_stage( | ||
console: AbstractConsole, | ||
deploy_root: Path, | ||
|
@@ -219,7 +220,9 @@ def execute_post_deploy_hooks( | |
|
||
get_cli_context().metrics.set_counter(CLICounterField.POST_DEPLOY_SCRIPTS, 1) | ||
|
||
with console.phase(f"Executing {deployed_object_type} post-deploy actions"): | ||
with console.phase( | ||
f"Executing {deployed_object_type} post-deploy actions", | ||
), get_cli_context().metrics.span("post_deploy_hooks"): | ||
sql_scripts_paths = [] | ||
display_paths = [] | ||
for hook in post_deploy_hooks: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not just
bundle
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my head
bundle
is the higher level container that does both this step (populating the deploy root) and then applying all the processors on it, but if we're fine just having the first step be called bundle then that's good with me