Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions sqlmesh/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,15 +188,23 @@ def configure_logging(
write_to_file: bool = True,
log_file_dir: t.Optional[t.Union[str, Path]] = None,
ignore_warnings: bool = False,
log_level: t.Optional[t.Union[str, int]] = None,
) -> None:
# Remove noisy grpc logs that are not useful for users
os.environ["GRPC_VERBOSITY"] = os.environ.get("GRPC_VERBOSITY", "NONE")

logger = logging.getLogger()
debug = force_debug or debug_mode_enabled()

# base logger needs to be the lowest level that we plan to log
level = logging.DEBUG if debug else logging.INFO
if log_level is not None:
if isinstance(log_level, str):
level = logging._nameToLevel.get(log_level.upper()) or logging.INFO
else:
level = log_level
else:
# base logger needs to be the lowest level that we plan to log
level = logging.DEBUG if debug else logging.INFO

logger.setLevel(level)

if debug:
Expand Down
14 changes: 13 additions & 1 deletion sqlmesh_dbt/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,20 @@ def _cleanup() -> None:
default=False,
help="Display debug logging during dbt execution. Useful for debugging and making bug reports events to help when debugging.",
)
@click.option(
"--log-level",
default="info",
type=click.Choice(["debug", "info", "warn", "error", "none"]),
help="Specify the minimum severity of events that are logged to the console and the log file.",
)
@click.pass_context
@cli_global_error_handler
def dbt(
ctx: click.Context,
profile: t.Optional[str] = None,
target: t.Optional[str] = None,
debug: bool = False,
log_level: t.Optional[str] = None,
) -> None:
"""
An ELT tool for managing your SQL transformations and data models, powered by the SQLMesh engine.
Expand All @@ -97,7 +104,12 @@ def dbt(
# we have a partially applied function here because subcommands might set extra options like --vars
# that need to be known before we attempt to load the project
ctx.obj = functools.partial(
create, project_dir=Path.cwd(), profile=profile, target=target, debug=debug
create,
project_dir=Path.cwd(),
profile=profile,
target=target,
debug=debug,
log_level=log_level,
)

if not ctx.invoked_subcommand:
Expand Down
3 changes: 2 additions & 1 deletion sqlmesh_dbt/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ def create(
vars: t.Optional[t.Dict[str, t.Any]] = None,
threads: t.Optional[int] = None,
debug: bool = False,
log_level: t.Optional[str] = None,
) -> DbtOperations:
with Progress(transient=True) as progress:
# Indeterminate progress bar before SQLMesh import to provide feedback to the user that something is indeed happening
Expand All @@ -256,7 +257,7 @@ def create(
while root_logger.hasHandlers():
root_logger.removeHandler(root_logger.handlers[0])

configure_logging(force_debug=debug)
configure_logging(force_debug=debug, log_level=log_level)
set_console(DbtCliConsole())

progress.update(load_task_id, description="Loading project", total=None)
Expand Down
14 changes: 14 additions & 0 deletions tests/dbt/cli/test_global_flags.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import typing as t
from pathlib import Path
import pytest
import logging
from pytest_mock import MockerFixture
from click.testing import Result
from sqlmesh.utils.errors import SQLMeshError
from sqlglot.errors import SqlglotError
from tests.dbt.conftest import EmptyProjectCreator

pytestmark = pytest.mark.slow

Expand Down Expand Up @@ -93,3 +95,15 @@ def test_run_error_handler(
assert result.exit_code == 1
assert "Error: Error with selector" in result.output
assert "Traceback" not in result.output


def test_log_level(invoke_cli: t.Callable[..., Result], create_empty_project: EmptyProjectCreator):
create_empty_project()

result = invoke_cli(["--log-level", "info", "list"])
assert result.exit_code == 0
assert logging.getLogger("sqlmesh").getEffectiveLevel() == logging.INFO

result = invoke_cli(["--log-level", "debug", "list"])
assert result.exit_code == 0
assert logging.getLogger("sqlmesh").getEffectiveLevel() == logging.DEBUG
11 changes: 11 additions & 0 deletions tests/dbt/cli/test_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from sqlmesh.core.plan import PlanBuilder
from sqlmesh.core.config.common import VirtualEnvironmentMode
from tests.dbt.conftest import EmptyProjectCreator
import logging

pytestmark = pytest.mark.slow

Expand Down Expand Up @@ -363,3 +364,13 @@ def test_create_sets_concurrent_tasks_based_on_threads(create_empty_project: Emp
g.connection and g.connection.concurrent_tasks == 16
for g in operations.context.config.gateways.values()
)


def test_create_configures_log_level(create_empty_project: EmptyProjectCreator):
project_dir, _ = create_empty_project()

create(project_dir=project_dir, log_level="info")
assert logging.getLogger("sqlmesh").getEffectiveLevel() == logging.INFO

create(project_dir=project_dir, log_level="error")
assert logging.getLogger("sqlmesh").getEffectiveLevel() == logging.ERROR