diff --git a/Containerfile.c9s-tests b/Containerfile.c9s-tests index 412812dde..d3a24d81f 100644 --- a/Containerfile.c9s-tests +++ b/Containerfile.c9s-tests @@ -30,6 +30,7 @@ RUN python3.11 -m venv --system-site-packages /opt/beeai-venv \ arize-phoenix-otel \ aiohttp \ redis \ + sentry-sdk \ specfile \ pytest \ pytest-asyncio \ diff --git a/ymir/agents/backport_agent.py b/ymir/agents/backport_agent.py index d551f94f5..0b1acbac8 100644 --- a/ymir/agents/backport_agent.py +++ b/ymir/agents/backport_agent.py @@ -88,7 +88,7 @@ GitPreparePackageSources, ) -logger = logging.getLogger(__name__) +logger = logging.getLogger(__file__) redis_logger = logging.getLogger("agent.redis") @@ -1388,7 +1388,7 @@ async def main() -> None: ): upstream_patches = upstream_patches_raw.split(",") logger.info("Running in direct mode with environment variables") - with span_processor.jira_issue_context(jira_issue): + with span_processor.start_transaction(jira_issue, workflow="backport"): state = await run_workflow( package=package, dist_git_branch=branch, @@ -1465,7 +1465,7 @@ async def retry(task, error, backport_data=backport_data, user_triggered=user_tr try: logger.info(f"Starting backport processing for {backport_data.jira_issue}") - with span_processor.jira_issue_context(backport_data.jira_issue): + with span_processor.start_transaction(backport_data.jira_issue, workflow="backport"): state = await run_workflow( package=backport_data.package, dist_git_branch=dist_git_branch, diff --git a/ymir/agents/observability.py b/ymir/agents/observability.py index 1c26e2d0e..bfc80b6fd 100644 --- a/ymir/agents/observability.py +++ b/ymir/agents/observability.py @@ -2,6 +2,7 @@ import contextlib from contextvars import ContextVar +import sentry_sdk from openinference.instrumentation.beeai import BeeAIInstrumentor from opentelemetry import trace as trace_api from opentelemetry.context import Context @@ -19,12 +20,22 @@ def set_jira_issue(self, jira_issue: str | None) -> None: self._jira_issue_var.set(jira_issue) @contextlib.contextmanager - def jira_issue_context(self, jira_issue: str | None): - token = self._jira_issue_var.set(jira_issue) - try: - yield - finally: - self._jira_issue_var.reset(token) + def start_transaction( + self, + jira_issue: str | None, + workflow: str | None, + ): + with sentry_sdk.start_transaction( + op=f"agent.{workflow}", name=f"{workflow} for {jira_issue}" + ) as transaction: + transaction.set_data("workflow", workflow) + transaction.set_data("jira_issue", jira_issue) + + token = self._jira_issue_var.set(jira_issue) + try: + yield + finally: + self._jira_issue_var.reset(token) def on_start(self, span: Span, parent_context: Context | None = None) -> None: if span.is_recording(): diff --git a/ymir/agents/preliminary_testing_agent.py b/ymir/agents/preliminary_testing_agent.py index 38c423915..efc926043 100644 --- a/ymir/agents/preliminary_testing_agent.py +++ b/ymir/agents/preliminary_testing_agent.py @@ -33,7 +33,7 @@ from ymir.common.logging_setup import configure_logging from ymir.tools.unprivileged.greenwave import FetchGreenWaveTool, FetchTestingFarmResultsTool -logger = logging.getLogger(__name__) +logger = logging.getLogger(__file__) FIXED_IN_BUILD_CUSTOM_FIELD = "customfield_10578" TEST_COVERAGE_CUSTOM_FIELD = "customfield_10638" @@ -519,7 +519,7 @@ async def main() -> None: sys.exit(1) logger.info("Running preliminary testing analysis for %s (dry_run=%s)", jira_issue, dry_run) - with span_processor.jira_issue_context(jira_issue): + with span_processor.start_transaction(jira_issue, workflow="preliminary_testing"): result = await run_preliminary_testing( jira_issue, dry_run=dry_run, diff --git a/ymir/agents/rebase_agent.py b/ymir/agents/rebase_agent.py index 8396f8bb6..0b7bea0c8 100644 --- a/ymir/agents/rebase_agent.py +++ b/ymir/agents/rebase_agent.py @@ -64,7 +64,7 @@ ViewTool, ) -logger = logging.getLogger(__name__) +logger = logging.getLogger(__file__) redis_logger = logging.getLogger("agent.redis") @@ -513,7 +513,7 @@ async def comment_in_jira(state): and (branch := os.getenv("BRANCH", None)) ): logger.info("Running in direct mode with environment variables") - with span_processor.jira_issue_context(jira_issue): + with span_processor.start_transaction(jira_issue, workflow="rebase"): state = await run_workflow( package=package, dist_git_branch=branch, @@ -585,7 +585,7 @@ async def retry(task, error, rebase_data=rebase_data, user_triggered=user_trigge try: logger.info(f"Starting rebase processing for {rebase_data.jira_issue}") - with span_processor.jira_issue_context(rebase_data.jira_issue): + with span_processor.start_transaction(rebase_data.jira_issue, workflow="rebase"): state = await run_workflow( package=rebase_data.package, dist_git_branch=dist_git_branch, diff --git a/ymir/agents/rebuild_agent.py b/ymir/agents/rebuild_agent.py index 5a229398f..0a53213cf 100644 --- a/ymir/agents/rebuild_agent.py +++ b/ymir/agents/rebuild_agent.py @@ -38,7 +38,7 @@ Task, ) -logger = logging.getLogger(__name__) +logger = logging.getLogger(__file__) redis_logger = logging.getLogger("agent.redis") @@ -313,7 +313,7 @@ async def comment_in_jira(state): consolidated_raw = os.getenv("CONSOLIDATED_ISSUES", None) consolidated_issues = json.loads(consolidated_raw) if consolidated_raw else None logger.info("Running in direct mode with environment variables") - with span_processor.jira_issue_context(jira_issue): + with span_processor.start_transaction(jira_issue, workflow="rebuild"): state = await run_workflow( package=package, dist_git_branch=branch, @@ -402,7 +402,7 @@ async def retry(task, error, rebuild_data=rebuild_data, user_triggered=user_trig await fix_await(redis.lpush(RedisQueues.ERROR_LIST.value, error)) try: - with span_processor.jira_issue_context(rebuild_data.jira_issue): + with span_processor.start_transaction(rebuild_data.jira_issue, workflow="rebuild"): state = await run_workflow( package=rebuild_data.package, dist_git_branch=dist_git_branch, diff --git a/ymir/agents/triage_agent.py b/ymir/agents/triage_agent.py index 45f0c6c1a..d068e18b6 100644 --- a/ymir/agents/triage_agent.py +++ b/ymir/agents/triage_agent.py @@ -75,7 +75,7 @@ # from ymir.tools.unprivileged.upstream_search import UpstreamSearchTool from ymir.tools.unprivileged.version_mapper import VersionMapperTool -logger = logging.getLogger(__name__) +logger = logging.getLogger(__file__) redis_logger = logging.getLogger("agent.redis") @@ -1254,7 +1254,7 @@ async def main() -> None: if jira_issue := os.getenv("JIRA_ISSUE", None): logger.info("Running in direct mode with environment variable") - with span_processor.jira_issue_context(jira_issue): + with span_processor.start_transaction(jira_issue, workflow="triage"): agent_factory = build_agent_factory_with_mock_repos(create_triage_agent, jira_issue) state = await run_workflow( jira_issue, @@ -1398,7 +1398,7 @@ async def retry(task, error, input=input, user_triggered=user_triggered): try: logger.info(f"Starting triage processing for {input.issue}") - with span_processor.jira_issue_context(input.issue): + with span_processor.start_transaction(input.issue, workflow="triage"): state = await run_workflow( input.issue, dry_run,