Skip to content

Commit 61848b6

Browse files
author
Yesid Cano Castro
committed
Enhance logging with specific tags for better traceability and debugging. Log user query and bot's anwer for all requests.
1 parent 7d5b52a commit 61848b6

File tree

4 files changed

+75
-36
lines changed

4 files changed

+75
-36
lines changed

pages/ask_uos_chat.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def _validate_user_id(self, user_id: str) -> Optional[str]:
9292
def get_history(self, user_id: str) -> LimitedRedisChatMessageHistory:
9393
validated_user_id = self._validate_user_id(user_id)
9494
if not validated_user_id:
95-
logger.warning(f"Invalid user_id attempted: {user_id!r}")
95+
logger.warning(f"[AUTH] Invalid user_id attempted: {user_id!r}")
9696
st.warning(
9797
"Invalid session. Please refresh the page or clear your browser cookies."
9898
)
@@ -105,7 +105,7 @@ def get_history(self, user_id: str) -> LimitedRedisChatMessageHistory:
105105
)
106106
return history
107107
except Exception as e:
108-
logger.error(f"Error retrieving chat history for user: {e}")
108+
logger.error(f"[REDIS] Error retrieving chat history for user: {e}")
109109
st.warning(
110110
"There was an error while loading previous messages. If this issue persists, try using a different browser or contact support."
111111
)
@@ -255,7 +255,7 @@ def display_references():
255255

256256
else:
257257
logger.error(
258-
f"Unknown message type: {m.type}. Expected one of {ROLES}."
258+
f"[LANGGRAPH] Unknown message type: {m.type}. Expected one of {ROLES}."
259259
)
260260

261261
def handle_user_input(self):
@@ -449,7 +449,7 @@ def _get_stream():
449449

450450
except GraphRecursionError as e:
451451
# TODO handle recursion limit error
452-
logger.exception(f"Recursion Limit reached: {e}")
452+
logger.exception(f"[LANGGRAPH] Recursion Limit reached: {e}")
453453
response = session_state["_"](
454454
"I'm sorry, but I couldn't find enough information to fully answer your question. Could you please try rephrasing your query and ask again?"
455455
)
@@ -478,7 +478,6 @@ def _get_stream():
478478

479479
with st.chat_message(ROLES[0], avatar="./static/Icon-chatbot.svg"):
480480
with st.spinner(session_state["_"]("Generating response...")):
481-
logger.info(f"User's query: {prompt}")
482481

483482
start_time = time.time()
484483
settings.time_request_sent = start_time
@@ -492,7 +491,7 @@ def _get_stream():
492491
time_taken = end_time - start_time
493492
session_state["time_taken"] = time_taken
494493
logger.info(
495-
f"Time taken to serve whole answer to the user: {time_taken} seconds"
494+
f"[METRICS]Time taken to serve whole answer to the user: {time_taken} seconds"
496495
)
497496

498497
self.store_response(response, prompt, graph)
@@ -570,6 +569,11 @@ def store_response(
570569
# "avatar": "./static/Icon-chatbot.svg",
571570
# }
572571
# )
572+
573+
# Log user query and bot answer
574+
logger.info(f"[USERQUERY] User's query: {prompt}")
575+
logger.info(f"[BOTANSWER] Assistant's response: {output}")
576+
573577
st.session_state.user_query = prompt
574578

575579
# summarize the conversation
@@ -725,7 +729,7 @@ def show_feedback_faces(self):
725729
try:
726730
st.markdown(msg.format(selected + 1))
727731
except Exception as e:
728-
logger.error(f"Error displaying feedback message: {e}")
732+
logger.error(f"[FEEDBACK] Error displaying feedback message: {e}")
729733

730734
def ask_further_feedback(self):
731735
if (
@@ -787,7 +791,7 @@ def log_feedback(self):
787791
feedback["response"] = st.session_state.messages[-1].content
788792
feedback["time_taken"] = session_state.time_taken
789793

790-
logger.info(f"Feedback= {feedback}")
794+
logger.info(f"[FEEDBACK] Feedback= {feedback}")
791795
session_state.feedback_saved = True
792796

793797
@st.dialog("ask.UOS")

src/chatbot/agents/agent_lang_graph.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def grade_documents(self, state: State) -> Literal["generate", "rewrite"]:
134134

135135
tool_messages = state.get("tool_messages", "")
136136
if len(tool_messages) < 10:
137-
logger.debug("[GRADE DOCUMENTS EDGE] No tool messages found")
137+
logger.debug("[LANGGRAPH] GRADE DOCUMENTS EDGE: No tool messages found")
138138
return "rewrite"
139139

140140
tool_query = " ".join(state["search_query"])
@@ -172,7 +172,7 @@ class GradeResult(BaseModel):
172172
# TODO Further process the relevant paragraphs
173173
# self._clean_tool_message = scored_result.relevant_paragraphs
174174
logger.debug(
175-
f"[GRADE DOCUMENTS EDGE] DECISION: DOCS RELEVANT. Reason: {scored_result.reason}"
175+
f"[LANGGRAPH][GRADE DOCUMENTS EDGE] DECISION: DOCS RELEVANT. Reason: {scored_result.reason}"
176176
)
177177
if state.get("teaching_degree", False):
178178
return "generate_teaching_degree_node"
@@ -184,12 +184,12 @@ class GradeResult(BaseModel):
184184

185185
else:
186186
logger.debug(
187-
f"[GRADE DOCUMENTS EDGE] DECISION: DOCS NOT RELEVANT. Reason: {scored_result.reason}"
187+
f"[LANGGRAPH][GRADE DOCUMENTS EDGE] DECISION: DOCS NOT RELEVANT. Reason: {scored_result.reason}"
188188
)
189189
return "rewrite"
190190
except Exception as e:
191191
logger.error(
192-
f"[GRADE DOCUMENTS EDGE] Error occurred while grading documents: {e}"
192+
f"[LANGGRAPH][GRADE DOCUMENTS EDGE] Error occurred while grading documents: {e}"
193193
)
194194
raise e
195195

@@ -315,7 +315,7 @@ def judge_node(self, state: State) -> Dict:
315315
Dict: Updated state with judgement result
316316
"""
317317

318-
logger.debug("[JUDGE NODE] Evaluating agent's decision to use tools")
318+
logger.debug("[LANGGRAPH][JUDGE NODE] Evaluating agent's decision to use tools")
319319

320320
class JudgementResult(BaseModel):
321321
"""Result of agent's tool usage judgement."""
@@ -363,7 +363,7 @@ class JudgementResult(BaseModel):
363363
if score.judgement_binary.lower() == "no":
364364
msg = [HumanMessage(content=translate_prompt()["use_tool_msg"])]
365365
logger.debug(
366-
f"[JUGE NODE] The agent should have used a tool. Reason: {score.reason}"
366+
f"[LANGGRAPH][JUGE NODE] The agent should have used a tool. Reason: {score.reason}"
367367
)
368368
return {
369369
"messages": state["messages"] + msg,
@@ -429,11 +429,11 @@ def tool_node(self, state: Dict) -> Dict:
429429
tool_call["args"]
430430
)
431431
logger.debug(
432-
f'[TOOL NODE] Successfully executed tool call:{tool_call["name"]}. Length of tool_resul: {len(tool_call)}'
432+
f'[LANGGRAPH][TOOL NODE] Successfully executed tool call:{tool_call["name"]}. Length of tool_resul: {len(tool_call)}'
433433
)
434434
except Exception as e:
435435
logger.exception(
436-
f"Error invoking tool: {tool_call['name']} with args: tool_call['args']: {e}"
436+
f"[LANGGRAPH]Error invoking tool: {tool_call['name']} with args: tool_call['args']: {e}"
437437
)
438438
raise e
439439

@@ -523,7 +523,7 @@ def generate_helper(self, state, system_message_generate):
523523
response = self._llm.invoke(list(message_deque))
524524
else:
525525
logger.warning(
526-
"No messages history found. Using system message only for generation."
526+
"[LANGGRAPH] No messages history found. Using system message only for generation."
527527
)
528528
response = self._llm.invoke([system_message_generate])
529529
return {"messages": messages_history + [response]}
@@ -537,7 +537,7 @@ def generate(self, state: State) -> Dict:
537537
Returns:
538538
Dict: Updated state with generated response
539539
"""
540-
logger.debug("[GENERATE NODE] Generating answer")
540+
logger.debug("[LANGGRAPH][GENERATE NODE] Generating answer")
541541

542542
# tool_message = self._clean_tool_message or state.get("tool_messages", None)
543543
tool_message = state.get("tool_messages", None)
@@ -553,7 +553,7 @@ def generate(self, state: State) -> Dict:
553553

554554
def generate_application(self, state: State) -> Dict:
555555

556-
logger.debug(["GENERATE APPLICATION NODE] Generating answer"])
556+
logger.debug(["[LANGGRAPH][GENERATE APPLICATION NODE] Generating answer"])
557557
# tool_message = self._clean_tool_message or state.get("tool_messages", None)
558558
tool_message = state.get("tool_messages", None)
559559
system_message_generate = SystemMessage(
@@ -575,7 +575,7 @@ def generate_teaching_degree_node(self, state: State) -> Dict:
575575
Returns:
576576
Dict: Updated state with generated response
577577
"""
578-
logger.debug("[GENERATE TEACHING DEGREE NODE] Generating answer")
578+
logger.debug("[LANGGRAPH][GENERATE TEACHING DEGREE NODE] Generating answer")
579579
# tool_message = self._clean_tool_message or state.get("tool_messages", None)
580580
tool_message = state.get("tool_messages", None)
581581
system_message_generate = SystemMessage(
@@ -593,7 +593,7 @@ def generate_teaching_degree_node(self, state: State) -> Dict:
593593
def juge_answer(self, state: State) -> Dict:
594594
"""Judge the generated answer."""
595595

596-
logger.debug("[JUDGE ANSWER NODE] Judging the answer")
596+
logger.debug("[LANGGRAPH][JUDGE ANSWER NODE] Judging the answer")
597597

598598
class JudgeAnswerResult(BaseModel):
599599
"""Result of answer judgement."""
@@ -720,7 +720,9 @@ def __init__(self, **data):
720720
def shorten_conversation_summary(self, summary: str) -> str:
721721
"""Shorten the conversation summary if it exceeds the maximum token limit."""
722722

723-
logger.warning(f"[SHORTEN CONVERSATION SUMMARY] Summary length: {len(summary)}")
723+
logger.warning(
724+
f"[LANGGRAPH][SHORTEN CONVERSATION SUMMARY] Summary length: {len(summary)}"
725+
)
724726
template = translate_prompt()["shorten_conversation_summary"]
725727

726728
prompt = PromptTemplate(template=template, input_variables=["summary"])
@@ -879,7 +881,9 @@ def __call__(self, input: str) -> Union[str, Dict]:
879881
return response["messages"][-1].content
880882

881883
except Exception as e:
882-
logger.exception(f"An error occurred while generating response: {e}")
884+
logger.exception(
885+
f"[LANGGRAPH] An error occurred while generating response: {e}"
886+
)
883887
return {
884888
"output": "An error has occurred while trying to connect to the data source or APIs. Please try asking the question again."
885889
}

src/chatbot/tools/search_web_tool.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,13 @@ def extract_cached_content(cached_content):
134134
try:
135135
return ast.literal_eval(cached_content)
136136
except Exception as e:
137-
logger.exception(f"Could not extract cached content: {e}")
137+
logger.exception(f"[CACHE] Could not extract cached content: {e}")
138138
return None
139139

140140

141141
async def generate_summary(text: str, query: str) -> str:
142142
"""Generate a summary of the provided text."""
143-
logger.info(f"Summarizing content, query: {query}")
143+
logger.info(f"[LMM-OPERATION] Summarizing content, query: {query}")
144144

145145
chunk_size = (settings.model.context_window * 4) // 2
146146
text_splitter = RecursiveCharacterTextSplitter(
@@ -230,7 +230,7 @@ async def get_web_content(
230230
return result_url, result_content
231231

232232
except Exception as e:
233-
logger.exception(f"Error while crawling the URL: {url}", exc_info=True)
233+
logger.exception(f"[CRAWL] Error while crawling the URL: {url}", exc_info=True)
234234
return result_url, result_content
235235
finally:
236236
# Cache the result
@@ -240,7 +240,7 @@ async def get_web_content(
240240
await client.setex(cache_key, TTL, cache_value)
241241
except Exception as e:
242242
logger.exception(
243-
f"Error while caching content for URL: {url}", exc_info=True
243+
f"[REDIS] Error while caching content for URL: {url}", exc_info=True
244244
)
245245

246246

@@ -277,11 +277,11 @@ async def visit_urls_extract(
277277
if int(total_results) > 0:
278278
links_search = [item["link"] for item in dict_response["items"]]
279279
logger.debug(
280-
f"[ProgrammableSearch] Search Engine returned {len(links_search)} results (links)"
280+
f"[SEARCH] Search Engine returned {len(links_search)} results (links)"
281281
)
282282
else:
283283
logger.warning(
284-
f"[ProgrammableSearch] No results found by the search engine while requesting this URL: {url}"
284+
f"[SEARCH] No results found by the search engine while requesting this URL: {url}"
285285
)
286286
return [], []
287287

@@ -312,7 +312,7 @@ async def visit_urls_extract(
312312
if result_content:
313313
if len(result_content) < 20:
314314
logger.warning(
315-
f"[Crawling] The URL content could not be extracted. Make sure the content is contained in current target elements: {target_elements}. URL: {url}"
315+
f"[CRAWL] The URL content could not be extracted. Make sure the content is contained in current target elements: {target_elements}. URL: {url}"
316316
)
317317
continue
318318
contents.append(
@@ -379,8 +379,10 @@ async def async_search(client, **kwargs) -> Tuple[str, List]:
379379
final_output_tokens, final_search_tokens = compute_tokens(
380380
final_output, query, agent_executor
381381
)
382-
logger.info(f"Search tokens: {final_search_tokens}")
383-
logger.info(f"Final output (search + prompt): {final_output_tokens}")
382+
logger.info(f"[SEARCH] Search tokens: {final_search_tokens}")
383+
logger.info(
384+
f"[SEARCH] Final output (search + prompt): {final_output_tokens}"
385+
)
384386

385387
# Cache results
386388
if len(final_output) > 20:
@@ -390,13 +392,13 @@ async def async_search(client, **kwargs) -> Tuple[str, List]:
390392
return (final_output, visited_urls) if contents else ([], [])
391393

392394
except ProgrammableSearchException as e:
393-
logger.exception(f"Error: search engine: {e}", exc_info=True)
395+
logger.exception(f"[SEARCH] Error: search engine: {e}", exc_info=True)
394396
raise ProgrammableSearchException(
395397
f"Failed: Programmable Search Engine. Status: {e}"
396398
)
397399

398400
except Exception as e:
399-
logger.exception(f"Error while searching the web: {e}", exc_info=True)
401+
logger.exception(f"[SEARCH] Error while searching the web: {e}", exc_info=True)
400402
return [], []
401403

402404

@@ -410,7 +412,7 @@ def search_uni_web(**kwargs) -> Tuple[str, List]:
410412
try:
411413
loop = asyncio.get_running_loop()
412414
nest_asyncio.apply()
413-
logger.debug("Running within an existing event loop")
415+
logger.debug("[SYSTEM] Running within an existing event loop")
414416
client = redis.Redis(host="redis", port=6379, decode_responses=True)
415417
return asyncio.run_coroutine_threadsafe(
416418
async_search(client, **kwargs), loop
@@ -426,7 +428,7 @@ async def complete_search_flow():
426428

427429
return asyncio.run(complete_search_flow())
428430
except Exception as e:
429-
logger.exception(f"Error in search execution: {str(e)}")
431+
logger.exception(f"[SEARCH] Error in search execution: {str(e)}")
430432
return [], []
431433

432434
# try:

src/chatbot_log/log_tags.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Log Tags
2+
3+
- API: API called
4+
- AUTH: Authentication
5+
- REDIS
6+
- LANGGRAPH
7+
- USERQUERY
8+
- BOTANSWER
9+
- FEEDBACK
10+
- CRAWL
11+
- SEARCH: e.g., Programmable search engine related logs
12+
- LMM-OPERATION
13+
- FILEIO: File input/output operations
14+
- SECURITY: Security-related events
15+
- METRICS: Performance or usage metrics
16+
- TASK: Background tasks or jobs
17+
- CONFIG: Configuration changes
18+
- SYSTEM: System-level events
19+
- CACHE: Caching operations
20+
21+
22+
## Example Usage
23+
```python
24+
logger.info("[API] Received GET request for /users")
25+
logger.error("[DB] Database connection failed")
26+
logger.debug("[AUTH] Token validation started")
27+
```
28+
29+

0 commit comments

Comments
 (0)