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
23 changes: 14 additions & 9 deletions prometheus/app/services/issue_service.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import logging
import threading
import traceback
from datetime import datetime
from pathlib import Path
from typing import Mapping, Optional, Sequence

Expand All @@ -10,11 +13,6 @@
from prometheus.graph.knowledge_graph import KnowledgeGraph
from prometheus.lang_graph.graphs.issue_graph import IssueGraph
from prometheus.lang_graph.graphs.issue_state import IssueType
from prometheus.utils.logger_manager import (
clear_current_thread_session,
get_thread_logger,
remove_multi_threads_log_file_handler,
)


class IssueService(BaseService):
Expand Down Expand Up @@ -81,8 +79,15 @@ def answer_issue(
- issue_type (IssueType): The type of the issue (BUG or QUESTION).
"""

# Create thread-specific logger with file handler - ONE LINE!
logger, file_handler = get_thread_logger(__name__, force_new_file=True)
# Set up a dedicated logger for this thread
logger = logging.getLogger(f"thread-{threading.get_ident()}.prometheus")
logger.setLevel(getattr(logging, self.logging_level))
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
log_file = self.answer_issue_log_dir / f"{timestamp}_{threading.get_ident()}.log"
file_handler = logging.FileHandler(log_file)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)

# Construct the working directory
if dockerfile_content or image_name:
Expand Down Expand Up @@ -137,5 +142,5 @@ def answer_issue(
return None, False, False, False, None, None
finally:
# Remove multi-thread file handler
remove_multi_threads_log_file_handler(file_handler, logger.name)
clear_current_thread_session()
logger.removeHandler(file_handler)
file_handler.close()
4 changes: 2 additions & 2 deletions prometheus/docker/base_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import shutil
import tarfile
import tempfile
import threading
from abc import ABC, abstractmethod
from pathlib import Path
from typing import Optional, Sequence
Expand All @@ -10,7 +11,6 @@
import pexpect

from prometheus.exceptions.docker_exception import DockerException
from prometheus.utils.logger_manager import get_thread_logger


class BaseContainer(ABC):
Expand Down Expand Up @@ -47,7 +47,7 @@ def __init__(
Args:
project_path: Path to the project directory to be containerized.
"""
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")
temp_dir = Path(tempfile.mkdtemp())
temp_project_path = temp_dir / project_path.name
shutil.copytree(project_path, temp_project_path)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import logging
import threading

from langchain_core.language_models.chat_models import BaseChatModel
from langgraph.errors import GraphRecursionError

from prometheus.docker.base_container import BaseContainer
from prometheus.git.git_repository import GitRepository
from prometheus.lang_graph.subgraphs.bug_fix_verification_subgraph import BugFixVerificationSubgraph
from prometheus.lang_graph.subgraphs.issue_verified_bug_state import IssueVerifiedBugState
from prometheus.utils.logger_manager import get_thread_logger


class BugFixVerificationSubgraphNode:
Expand All @@ -15,7 +17,7 @@ def __init__(
container: BaseContainer,
git_repo: GitRepository,
):
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")
self.git_repo = git_repo
self.subgraph = BugFixVerificationSubgraph(
model=model,
Expand Down
5 changes: 3 additions & 2 deletions prometheus/lang_graph/nodes/bug_fix_verify_node.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import functools
import logging
import threading

from langchain.tools import StructuredTool
from langchain_core.language_models.chat_models import BaseChatModel
Expand All @@ -7,7 +9,6 @@
from prometheus.docker.base_container import BaseContainer
from prometheus.lang_graph.subgraphs.bug_fix_verification_state import BugFixVerificationState
from prometheus.tools.container_command import ContainerCommandTool
from prometheus.utils.logger_manager import get_thread_logger


class BugFixVerifyNode:
Expand Down Expand Up @@ -54,7 +55,7 @@ def __init__(self, model: BaseChatModel, container: BaseContainer):
self.tools = self._init_tools()
self.model_with_tools = model.bind_tools(self.tools)
self.system_prompt = SystemMessage(self.SYS_PROMPT)
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")

def _init_tools(self):
tools = []
Expand Down
6 changes: 4 additions & 2 deletions prometheus/lang_graph/nodes/bug_fix_verify_structured_node.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import logging
import threading

from langchain_core.language_models.chat_models import BaseChatModel
from langchain_core.prompts import ChatPromptTemplate
from pydantic import BaseModel, Field

from prometheus.lang_graph.subgraphs.bug_fix_verification_state import BugFixVerificationState
from prometheus.utils.lang_graph_util import get_last_message_content
from prometheus.utils.logger_manager import get_thread_logger


class BugFixVerifyStructureOutput(BaseModel):
Expand Down Expand Up @@ -89,7 +91,7 @@ def __init__(self, model: BaseChatModel):
)
structured_llm = model.with_structured_output(BugFixVerifyStructureOutput)
self.model = prompt | structured_llm
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")

def __call__(self, state: BugFixVerificationState):
bug_fix_verify_message = get_last_message_content(state["bug_fix_verify_messages"])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import logging
import threading

from prometheus.lang_graph.subgraphs.bug_get_regression_tests_state import (
BugGetRegressionTestsState,
)
from prometheus.utils.issue_util import format_issue_info
from prometheus.utils.logger_manager import get_thread_logger


class BugGetRegressionContextMessageNode:
Expand Down Expand Up @@ -84,7 +86,7 @@ def test_offset_preserved(self):
"""

def __init__(self):
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")

def __call__(self, state: BugGetRegressionTestsState):
select_regression_query = self.SELECT_REGRESSION_QUERY.format(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import logging
import threading

from langchain_core.language_models.chat_models import BaseChatModel
from langchain_core.prompts import ChatPromptTemplate
from pydantic import BaseModel, Field
Expand All @@ -6,7 +9,6 @@
BugGetRegressionTestsState,
)
from prometheus.utils.issue_util import format_issue_info
from prometheus.utils.logger_manager import get_thread_logger


class RegressionTestStructuredOutPut(BaseModel):
Expand Down Expand Up @@ -89,7 +91,7 @@ def __init__(self, model: BaseChatModel):
)
structured_llm = model.with_structured_output(RegressionTestsStructuredOutPut)
self.model = prompt | structured_llm
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")

def format_human_message(self, state: BugGetRegressionTestsState):
return self.HUMAN_PROMPT.format(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import logging
import threading
from typing import Dict

from langchain_core.language_models.chat_models import BaseChatModel
Expand All @@ -9,7 +11,6 @@
from prometheus.lang_graph.subgraphs.bug_get_regression_tests_subgraph import (
BugGetRegressionTestsSubgraph,
)
from prometheus.utils.logger_manager import get_thread_logger


class BugGetRegressionTestsSubgraphNode:
Expand All @@ -21,7 +22,7 @@ def __init__(
kg: KnowledgeGraph,
git_repo: GitRepository,
):
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")
self.subgraph = BugGetRegressionTestsSubgraph(
advanced_model=advanced_model,
base_model=base_model,
Expand Down
5 changes: 3 additions & 2 deletions prometheus/lang_graph/nodes/bug_reproducing_execute_node.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import functools
import logging
import threading
from pathlib import Path
from typing import Optional, Sequence

Expand All @@ -10,7 +12,6 @@
from prometheus.lang_graph.subgraphs.bug_reproduction_state import BugReproductionState
from prometheus.tools.container_command import ContainerCommandTool
from prometheus.utils.issue_util import format_test_commands
from prometheus.utils.logger_manager import get_thread_logger
from prometheus.utils.patch_util import get_updated_files


Expand Down Expand Up @@ -56,7 +57,7 @@ def __init__(
self.tools = self._init_tools()
self.model_with_tools = model.bind_tools(self.tools)
self.system_prompt = SystemMessage(self.SYS_PROMPT)
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")

def _init_tools(self):
tools = []
Expand Down
5 changes: 3 additions & 2 deletions prometheus/lang_graph/nodes/bug_reproducing_file_node.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import functools
import logging
import threading

from langchain.tools import StructuredTool
from langchain_core.language_models.chat_models import BaseChatModel
Expand All @@ -8,7 +10,6 @@
from prometheus.lang_graph.subgraphs.bug_reproduction_state import BugReproductionState
from prometheus.tools.file_operation import FileOperationTool
from prometheus.utils.lang_graph_util import get_last_message_content
from prometheus.utils.logger_manager import get_thread_logger


class BugReproducingFileNode:
Expand Down Expand Up @@ -41,7 +42,7 @@ def __init__(self, model: BaseChatModel, kg: KnowledgeGraph, local_path: str):
self.tools = self._init_tools()
self.model_with_tools = model.bind_tools(self.tools)
self.system_prompt = SystemMessage(self.SYS_PROMPT)
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")

def _init_tools(self):
"""Initializes file operation tools."""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import logging
import threading
from typing import Sequence

from langchain_core.language_models.chat_models import BaseChatModel
Expand All @@ -10,7 +12,6 @@
format_agent_tool_message_history,
get_last_message_content,
)
from prometheus.utils.logger_manager import get_thread_logger


class BugReproducingStructuredOutput(BaseModel):
Expand Down Expand Up @@ -135,7 +136,7 @@ def __init__(self, model: BaseChatModel):
)
structured_llm = model.with_structured_output(BugReproducingStructuredOutput)
self.model = prompt | structured_llm
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")

def __call__(self, state: BugReproductionState):
bug_reproducing_log = format_agent_tool_message_history(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import logging
import threading

from langchain_core.messages import HumanMessage

from prometheus.lang_graph.subgraphs.bug_reproduction_state import BugReproductionState
from prometheus.utils.issue_util import format_issue_info
from prometheus.utils.logger_manager import get_thread_logger


class BugReproducingWriteMessageNode:
Expand All @@ -23,7 +25,7 @@ class BugReproducingWriteMessageNode:
"""

def __init__(self):
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")

def format_human_message(self, state: BugReproductionState):
if "reproduced_bug_failure_log" in state and state["reproduced_bug_failure_log"]:
Expand Down
5 changes: 3 additions & 2 deletions prometheus/lang_graph/nodes/bug_reproducing_write_node.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import functools
import logging
import threading

from langchain.tools import StructuredTool
from langchain_core.language_models.chat_models import BaseChatModel
Expand All @@ -7,7 +9,6 @@
from prometheus.graph.knowledge_graph import KnowledgeGraph
from prometheus.lang_graph.subgraphs.bug_reproduction_state import BugReproductionState
from prometheus.tools.file_operation import FileOperationTool
from prometheus.utils.logger_manager import get_thread_logger


class BugReproducingWriteNode:
Expand Down Expand Up @@ -116,7 +117,7 @@ def __init__(self, model: BaseChatModel, local_path: str, kg: KnowledgeGraph):
self.tools = self._init_tools()
self.system_prompt = SystemMessage(self.SYS_PROMPT)
self.model_with_tools = model.bind_tools(self.tools)
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")

def _init_tools(self):
"""Initializes file operation tools with the given root path.
Expand Down
5 changes: 3 additions & 2 deletions prometheus/lang_graph/nodes/bug_reproduction_subgraph_node.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import logging
import threading
from typing import Optional, Sequence

from langchain_core.language_models.chat_models import BaseChatModel
Expand All @@ -8,7 +10,6 @@
from prometheus.graph.knowledge_graph import KnowledgeGraph
from prometheus.lang_graph.subgraphs.bug_reproduction_subgraph import BugReproductionSubgraph
from prometheus.lang_graph.subgraphs.issue_bug_state import IssueBugState
from prometheus.utils.logger_manager import get_thread_logger


class BugReproductionSubgraphNode:
Expand All @@ -21,7 +22,7 @@ def __init__(
git_repo: GitRepository,
test_commands: Optional[Sequence[str]],
):
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")
self.git_repo = git_repo
self.bug_reproduction_subgraph = BugReproductionSubgraph(
advanced_model=advanced_model,
Expand Down
5 changes: 3 additions & 2 deletions prometheus/lang_graph/nodes/build_and_test_subgraph_node.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import logging
import threading
from typing import Optional, Sequence

from langchain_core.language_models.chat_models import BaseChatModel
Expand All @@ -6,7 +8,6 @@
from prometheus.graph.knowledge_graph import KnowledgeGraph
from prometheus.lang_graph.subgraphs.build_and_test_subgraph import BuildAndTestSubgraph
from prometheus.lang_graph.subgraphs.issue_bug_state import IssueBugState
from prometheus.utils.logger_manager import get_thread_logger


class BuildAndTestSubgraphNode:
Expand All @@ -25,7 +26,7 @@ def __init__(
build_commands=build_commands,
test_commands=test_commands,
)
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")

def __call__(self, state: IssueBugState):
exist_build = None
Expand Down
5 changes: 3 additions & 2 deletions prometheus/lang_graph/nodes/context_extraction_node.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import logging
import threading
from typing import Sequence

from langchain_core.language_models.chat_models import BaseChatModel
Expand All @@ -14,7 +16,6 @@
extract_last_tool_messages,
transform_tool_messages_to_str,
)
from prometheus.utils.logger_manager import get_thread_logger

SYS_PROMPT = """\
You are a context summary agent that summarizes code contexts which is relevant to a given query.
Expand Down Expand Up @@ -137,7 +138,7 @@ def __init__(self, model: BaseChatModel, root_path: str):
structured_llm = model.with_structured_output(ContextExtractionStructuredOutput)
self.model = prompt | structured_llm
self.root_path = root_path
self._logger, file_handler = get_thread_logger(__name__)
self._logger = logging.getLogger(f"thread-{threading.get_ident()}.{__name__}")

def __call__(self, state: ContextRetrievalState):
"""
Expand Down
Loading