-
Notifications
You must be signed in to change notification settings - Fork 29
Add logging to Flo library #21
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
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
79423e1
added logging to Flo library
thomastomy5 cb85bfd
added sessionid and option for custom logger
thomastomy5 86a9342
created common set of loggers and included readmefile for logging
thomastomy5 05e5b51
updated README and changed the config updation location to core
thomastomy5 dd9cc1d
Minor fixes before merging
vizsatiz fc06c20
Merge branch 'develop' into flolog
vizsatiz c74877c
Minor fixes around logging
vizsatiz 4cddb37
Fix for notebooks
vizsatiz 892f3d5
Final fixes to log levels
vizsatiz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,4 +11,5 @@ dataset | |
| bin | ||
| .DS_Store | ||
| *.sql | ||
| *.png | ||
| *.png | ||
| *.log | ||
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| # Understanding Log Levels in FloAI | ||
|
|
||
| FloAI uses standard Python logging levels to indicate the severity of logged messages. Here are the common levels used (from least to most severe): | ||
|
|
||
| - **DEBUG**: Detailed information for debugging purposes. | ||
| - **INFO**: Informational messages about the normal operation of the system. | ||
| - **WARNING**: Potential issues or unexpected conditions. | ||
| - **ERROR**: Errors that may have caused the system to malfunction. | ||
| - **CRITICAL**: Critical errors that have caused the system to crash. | ||
|
|
||
| By adjusting the log level, you can control how much information is logged and the verbosity of the output. | ||
|
|
||
| ## Controlling Log Levels | ||
|
|
||
| FloAI provides multiple ways to control log levels: | ||
|
|
||
| ### 1. Environment Variables for Log Level Control | ||
|
|
||
| Export environment variables to set the log level for specific components before running the application: | ||
|
|
||
| - `FLO_LOG_LEVEL_COMMON`: Controls the level for the "CommonLogs" logger. | ||
| - CommonLogs: General-purpose logging used across the entire FloAI system. It captures broad, system-wide events and information. | ||
|
|
||
| - `FLO_LOG_LEVEL_BUILDER`: Controls the level for the "BuilderLogs" logger. | ||
| - BuilderLogs: Specific to the process of building and configuring FloAI instances. It logs information about YAML parsing, component creation, and FloAI structure setup. | ||
|
|
||
| - `FLO_LOG_LEVEL_SESSION`: Controls the level for the "SessionLogs" logger. | ||
| - SessionLogs: Dedicated to logging session-specific information. It captures events and data related to individual FloAI sessions, including session creation, tool registration, and session-level operations. | ||
|
|
||
| These loggers allow for granular control over logging output in different parts of the FloAI system. By adjusting their levels independently, you can focus on debugging or monitoring specific aspects of FloAI's operation. | ||
|
|
||
| Example: | ||
|
|
||
| ```bash | ||
| export FLO_LOG_LEVEL_COMMON=DEBUG | ||
| export FLO_LOG_LEVEL_BUILDER=INFO | ||
| export FLO_LOG_LEVEL_SESSION=WARNING | ||
| ``` | ||
|
|
||
| ### 2. FloSession Creation | ||
|
|
||
| When creating a FloSession object, you can specify the desired log level: | ||
|
|
||
| ```python | ||
| session = FloSession(llm, log_level="DEBUG") | ||
|
vizsatiz marked this conversation as resolved.
|
||
| ``` | ||
|
|
||
| This session will log messages at DEBUG level and above. | ||
|
|
||
| ### 3. Flo Instance Creation | ||
|
|
||
| Similar to FloSession, you can set the log level when creating a Flo instance: | ||
|
|
||
| ```python | ||
| flo = Flo.build(session, yaml_config, log_level="DEBUG") | ||
| ``` | ||
|
|
||
| This Flo instance will inherit the specified log level. | ||
|
|
||
| ### 4. Global Log Level Change (Runtime) | ||
|
|
||
| You can dynamically change the global log level at runtime using the set_global_log_level function from flo_ai.common.logging_config: | ||
|
|
||
| ```python | ||
| from flo_ai.common.logging_config import set_global_log_level | ||
|
|
||
| set_global_log_level("DEBUG") # Set the global log level to DEBUG | ||
| ``` | ||
|
|
||
| This will affect all logging throughout the application. | ||
|
|
||
| ### 5. Specific Logger Level Change (Runtime) | ||
|
|
||
| If you need to adjust the level for a specific logger, use the set_log_level method of the FloLogger class: | ||
|
|
||
| ```python | ||
| from flo_ai.common.logging_config import FloLogger | ||
|
|
||
| FloLogger.set_log_level("COMMON", "DEBUG") # Set COMMON logger to DEBUG level | ||
| ``` | ||
|
|
||
| ## Best Practices | ||
|
|
||
| - **Environment variables**: Use these for setting default levels without modifying code, useful in different deployment environments. | ||
| - **Object creation**: This approach allows setting specific levels for individual sessions or Flo instances. | ||
| - **Runtime changes**: Use these methods for dynamic adjustments during program execution. | ||
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| from typing import Any, Dict, List, Union | ||
| from langchain.callbacks.base import BaseCallbackHandler | ||
| from langchain.schema import AgentAction, AgentFinish, LLMResult | ||
| from flo_ai.common.flo_logger import get_logger, FloLogConfig | ||
| from typing import Optional | ||
|
|
||
| class FloLangchainLogger(BaseCallbackHandler): | ||
|
|
||
| def __init__(self, | ||
| session_id: str, | ||
| logger_name: Optional[str] = "FloLangChainLogger", | ||
| log_level: Optional[str] = "WARN"): | ||
| self.logger = get_logger(FloLogConfig(logger_name, log_level)) | ||
| self.session_id = session_id | ||
|
|
||
| def on_llm_start(self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any) -> None: | ||
| self.logger.info(f"Session ID: {self.session_id}: onLLMStart: {prompts}") | ||
|
|
||
| def on_llm_new_token(self, token: str, **kwargs: Any) -> None: | ||
| self.logger.debug(f"Session ID: {self.session_id}: onNewToken: {token}") | ||
|
|
||
| def on_llm_end(self, response: LLMResult, **kwargs: Any) -> None: | ||
| self.logger.info(f"Session ID: {self.session_id}: onLLMEnd: {response.generations}") | ||
|
|
||
| def on_llm_error(self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any) -> None: | ||
| self.logger.error(f"Session ID: {self.session_id}: onLLMError: {error}") | ||
|
|
||
| def on_chain_start(self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs: Any) -> None: | ||
| self.logger.info(f"Session ID: {self.session_id}: onChainStart: {inputs}") | ||
|
|
||
| def on_chain_end(self, outputs: Dict[str, Any], **kwargs: Any) -> None: | ||
| self.logger.info(f"Session ID: {self.session_id}: onChainEnd: {outputs}") | ||
|
|
||
| def on_chain_error(self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any) -> None: | ||
| self.logger.error(f"Session ID: {self.session_id}: onChainError: {error}") | ||
|
|
||
| def on_tool_start(self, serialized: Dict[str, Any], input_str: str, **kwargs: Any) -> None: | ||
| self.logger.info(f"Session ID: {self.session_id}: onToolStart: {input_str}") | ||
|
|
||
| def on_tool_end(self, output: str, **kwargs: Any) -> None: | ||
| self.logger.info(f"Session ID: {self.session_id}: onToolEnd: {output}") | ||
|
|
||
| def on_tool_error(self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any) -> None: | ||
| self.logger.error(f"Session ID: {self.session_id}: onToolError: {error}") | ||
|
|
||
| def on_text(self, text: str, **kwargs: Any) -> None: | ||
| self.logger.info(f"Session ID: {self.session_id}: onText: {text}") | ||
|
|
||
| def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any: | ||
| self.logger.info(f"Session ID: {self.session_id}: onAgentAction: {action.tool} - {action.tool_input}") | ||
|
|
||
| def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> None: | ||
| self.logger.info(f"Session ID: {self.session_id}: onAgentFinish: {finish.return_values}") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| import os | ||
| import logging | ||
| from logging.handlers import RotatingFileHandler | ||
| from dataclasses import dataclass | ||
|
|
||
| @dataclass | ||
| class FloLogConfig: | ||
| name: str | ||
| level: str = "INFO" | ||
| file_path: str = None | ||
| max_bytes: int = 1048576 | ||
|
|
||
| class FloLoggerUtil(logging.Logger): | ||
| def __init__(self, config: FloLogConfig): | ||
| super().__init__(config.name, config.level) | ||
| self.setLevel(config.level) | ||
|
|
||
| formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') | ||
|
|
||
| console_handler = logging.StreamHandler() | ||
| console_handler.setFormatter(formatter) | ||
| self.addHandler(console_handler) | ||
|
|
||
| if config.file_path: | ||
| file_handler = RotatingFileHandler(config.file_path, maxBytes=config.max_bytes) | ||
| file_handler.setFormatter(formatter) | ||
| self.addHandler(file_handler) | ||
|
|
||
| class FloLogger: | ||
| _loggers = {} | ||
|
|
||
| @classmethod | ||
| def get_logger(cls, config: FloLogConfig) -> FloLoggerUtil: | ||
| if config.name not in cls._loggers: | ||
| level = config.level or os.environ.get(f"FLO_LOG_LEVEL_{config.name.upper()}", "INFO") | ||
| config.level = level | ||
| cls._loggers[config.name] = FloLoggerUtil(config) | ||
| return cls._loggers[config.name] | ||
|
|
||
| @classmethod | ||
| def set_log_level(cls, name: str, level: str): | ||
| if name in cls._loggers: | ||
| cls._loggers[name].setLevel(level) | ||
|
|
||
| def get_logger(config: FloLogConfig) -> FloLoggerUtil: | ||
| return FloLogger.get_logger(config) | ||
|
|
||
| common_logger = get_logger(FloLogConfig("COMMON")) | ||
| builder_logger = get_logger(FloLogConfig("BUILDER")) | ||
| session_logger = get_logger(FloLogConfig("SESSION")) | ||
|
|
||
| def set_global_log_level(level: str): | ||
| for name in ["COMMON", "BUILDER", "SESSION"]: | ||
| FloLogger.set_log_level(name, level) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.