Skip to content
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

Addition of TimedRotatingFileHandler to log_config.yaml for iCtrl's logging configuration #46

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

li-ruihao
Copy link
Contributor

@li-ruihao li-ruihao commented Jan 19, 2025

Description

Since the logging integration pull requests such as PR #43 are still under review and the implementation of a CLP rotating handler is not completed yet, Python's native TimedRotatingFileHandler was added into log_config.yaml as a temporary solution to allow log messages to be outputted to log files.

Validation performed

The following are the manual tests performed:

  • Lines 32-34 in application/__init__.py successfully executes and the root logger was able to add the TimedRotatingFileHandler into its list of handlers.
  • After successful logging configuration, executing line 40 in application/__init__.py successfully logs the message into a log file.
  • Log some messages, manually call TimedRotatingFileHandler.doRollover(), then any new log messages will be logged to a new log file.
  • Upon file rotation, the date and time will be appended to old log file's name.
  • File rotation has been confirmed to occur every 3 hours
  • Logs are saved in the logs directory, which is under the directory that saves the private keys and user profile information
  • Total number of log files must not exceed 112 and they must be the log files from the last 112 rotation periods(the current period's logs are never included)

Additional Comments

  • During my local testing, logged messages on the current day are not immediately emitted until the program terminates.
  • The value for the filename field in log_config.yaml under TimedRotatingFileHandler contains a /, however windows paths normally prefer \\. This is something to pay attention to but I've already tested it on my machine(windows OS) and it works correctly.

Summary by CodeRabbit

  • New Features

    • Enhanced logging configuration with file rotation every 3 hours.
    • Added ability to log debug-level messages to a specified log file.
    • Configured log file retention for up to 112 backup files.
  • Improvements

    • Modified logger settings to preserve existing loggers.
    • Expanded logging output to include both console and file destinations.
    • Ensured the 'logs' directory is created if it does not exist before logging configuration is applied.

Copy link

coderabbitai bot commented Jan 19, 2025

Walkthrough

The pull request updates the logging configuration across several files. In log_config.yaml, a new timedRotatingFile handler is added to manage log file rotation every 3 hours, retaining up to 112 backup files. The root logger's handlers now include both console and file logging. In application/__init__.py, the logging configuration is modified to set the log file path and ensure the logs directory is created if it doesn't exist. Additionally, two new variables for logging paths are introduced in application/paths.py.

Changes

File Change Summary
log_config.yaml - Added timedRotatingFile handler with 3-hour rotation and 112 backup files
- Updated root logger to use both console and new file handler
application/__init__.py - Added import for application.paths
- Set timedRotatingFile handler filename to paths.LOG_FILE_PATH
- Added directory creation for logs
application/paths.py - Added new variables: LOGS_DIR_PATH and LOG_FILE_PATH for logging paths

Poem

🐰 Logging Rabbit's Midnight Dance 🌙

Logs spinning round at three-hour's chime,
One hundred twelve backups, a rotational rhyme,
Console and file in harmonious song,
Our logger now dances all night long!

Hop hop hooray! 🎉

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@li-ruihao li-ruihao changed the title Addition of TimedRotatingFileHandler to log_config.yaml that is used in iCtrl's logging configuration Addition of TimedRotatingFileHandler to log_config.yaml for iCtrl's logging configuration Jan 19, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 462ac75 and 1905de1.

📒 Files selected for processing (1)
  • log_config.yaml (2 hunks)
🔇 Additional comments (1)
log_config.yaml (1)

2-2: Verify impact of enabling existing loggers.

While the change is justified by the logger in application/__init__.py, let's verify there are no other loggers that could be affected.

✅ Verification successful

Setting disable_existing_loggers: False is correct and safe

All logger instances in the codebase follow the standard Python pattern using getLogger(__name__), which creates properly hierarchical module-level loggers. These loggers should remain enabled to maintain the logging hierarchy and proper configuration inheritance from the root logger.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for logger initializations across the codebase
rg -l "getLogger|basicConfig" --type py

# Search for potential custom logger implementations
ast-grep --pattern 'class $_(Logger|$_Logger)'

Length of output: 168


Script:

#!/bin/bash
# Check logger initialization patterns in the identified files
echo "=== application/__init__.py ==="
rg "getLogger|basicConfig" -A 2 application/__init__.py

echo -e "\n=== application/features/VNC.py ==="
rg "getLogger|basicConfig" -A 2 application/features/VNC.py

echo -e "\n=== application/routes/vnc.py ==="
rg "getLogger|basicConfig" -A 2 application/routes/vnc.py

Length of output: 723

log_config.yaml Outdated Show resolved Hide resolved
log_config.yaml Outdated
Comment on lines 15 to 22
file_rotating:
class: logging.handlers.TimedRotatingFileHandler
level: DEBUG
filename: ictrl_log.log
formatter: default
when: 'midnight'
interval: 1
backupCount: 14
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Consider enhancing the rotating file handler configuration.

While the basic setup is functional, consider the following improvements:

  1. Use absolute path or environment variable for log file location
  2. Add file permissions configuration
  3. Configure error handling for file operations
  4. Add size limits to prevent disk space issues

Example enhancement:

     file_rotating:
         class: logging.handlers.TimedRotatingFileHandler
         level: DEBUG
-        filename: ictrl_log.log
+        filename: ${ICTRL_LOG_DIR}/ictrl_log.log
         formatter: default
         when: 'midnight'
         interval: 1
         backupCount: 14
+        encoding: utf-8
+        delay: true
+        mode: 0o644
+        maxBytes: 52428800  # 50MB

Committable suggestion skipped: line range outside the PR's diff.

log_config.yaml Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
log_config.yaml (1)

Line range hint 1-26: Document temporary nature of this solution.

Since this is a temporary solution pending PR #43's custom CLP rotating handler:

 version: 1
+# TODO: Temporary logging configuration using TimedRotatingFileHandler
+# To be replaced with custom CLP rotating handler (see PR #43)
 disable_existing_loggers: False
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1905de1 and 0c148d0.

📒 Files selected for processing (2)
  • application/__init__.py (1 hunks)
  • log_config.yaml (2 hunks)
🔇 Additional comments (4)
log_config.yaml (4)

2-2: LGTM: Disabling existing loggers.

The change to disable_existing_loggers: False is appropriate given the logger initialization in application/__init__.py.


26-26: Consider environment-specific logging configurations.

This comment was previously made and remains valid. Consider separating configurations for different environments (development, staging, production).


15-22: 🛠️ Refactor suggestion

Enhance file handler security and robustness.

While the basic TimedRotatingFileHandler setup works, consider these security and robustness improvements:

     file_rotating:
         class: logging.handlers.TimedRotatingFileHandler
         level: DEBUG
-        filename: logs/ictrl_log.log
+        filename: %(ICTRL_LOG_DIR)s/ictrl_log.log
         formatter: default
         when: 'midnight'
         interval: 1
         backupCount: 14
+        encoding: utf-8
+        mode: 0o644
+        maxBytes: 52428800  # 50MB

Consider:

  1. Use environment variable for log directory
  2. Set explicit file permissions
  3. Add size limits to prevent disk space issues
  4. Specify UTF-8 encoding for proper character handling

Likely invalid or redundant comment.


15-22: Verify no conflicts with existing log rotation.

Let's verify there are no conflicts with existing log rotation mechanisms:

✅ Verification successful

No conflicts found with log rotation configuration

The log rotation setup in log_config.yaml is the only logging configuration in the codebase, and there are no conflicting rotation mechanisms present.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for existing log rotation configurations or handlers
rg -l "RotatingFileHandler|TimedRotatingFileHandler" --type py

Length of output: 64


Script:

#!/bin/bash
# Search for YAML/JSON files that might contain logging configuration
echo "=== Searching for logging config files ==="
fd -e yaml -e yml -e json | xargs rg -l "logging|handler|rotate"

echo -e "\n=== Searching for any log rotation related terms ==="
rg -i "log.?rotat|rotating.?log" --type yaml --type json --type py

Length of output: 415

application/__init__.py Outdated Show resolved Hide resolved
Copy link
Owner

@junhaoliao junhaoliao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed description and extensive validations performed. As discussed in the comments, please provide more details for the rationale of some configuration details.

application/__init__.py Outdated Show resolved Hide resolved
log_config.yaml Outdated Show resolved Hide resolved
log_config.yaml Outdated Show resolved Hide resolved
log_config.yaml Outdated Show resolved Hide resolved
log_config.yaml Outdated Show resolved Hide resolved
log_config.yaml Outdated Show resolved Hide resolved
log_config.yaml Outdated
formatter: default
when: 'midnight'
interval: 1
backupCount: 14
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How did we arrive at this count? Do we have an estimate of how many logs iCtrl generates per hour? Then how many (bytes of) logs do we plan to keep on the user's machine? Note this should not exceed the application environment requirements in your previous analysis, say in the Project Proposal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially, I just thought it was a good idea to keep a backup for the past 2 weeks' logs. However let's do some calculation given what we wrote in the project proposal.

We are using the following format for our log message:
'%(asctime)s %(levelname)s [%(name)s:%(lineno)d] %(message)s'.

Let's make some very bad assumptions for each value to estimate the length of a very long log message.

  • %(asctime)s: This value is fixed to be 23 characters
  • %(levelname)s: the longest level name is CRITICAL, which is 8 characters
  • %(name)s: Assume the longest Python file name to be 20 characters
  • %(lineno)d: Assume the longest line number to be 5 digits(characters)
  • %(message)s: Assume a very detailed log message that has 200 characters
  • Other characters such as space sum up to a total of 6 characters, and a newline character consists of CR and LF which adds 2 to 6 becomes 8 characters

In total, there are 264 characters, so each message has 528 bytes assuming each character is 2 bytes according to the UTF standard, which by default is 2 bytes each.

Assuming 5 log messages are generated each second, which is 2640 bytes/second. Then each 3-hour period will generate 60 x 60 x 3 x 2640 = 28,512,000 bytes of data which is 27.1912 MB. Let's round it up to 28 MB to include some metadata generated from file rotation and make the calculation easier.

The requirement on the project proposal said that the size of the logs generated by iCtrl cannot exceed 32GB. Originally we are backing up 2 weeks of data, that is 112 rotation periods. The total size for log backups would be 112 x 28 = 3,136 MB = 3.0625 GB, which is far from breaking the constraint requirement.

Therefore, I think 2 weeks of backup data is appropriate, and the calculations above show that the system can allow more backups, if the assumptions are bad enough.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0c148d0 and 5cac6ff.

📒 Files selected for processing (3)
  • application/__init__.py (1 hunks)
  • application/paths.py (1 hunks)
  • log_config.yaml (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
application/__init__.py

24-24: application.paths imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


34-34: Undefined name paths

(F821)


35-35: Undefined name paths

(F821)


35-35: Undefined name paths

(F821)

🔇 Additional comments (6)
log_config.yaml (3)

15-22: LGTM! The timedRotatingFile configuration is well-thought-out.

The 3-hour rotation interval and 112 backup count are justified by the storage calculations in the past review comments. The dynamic filename assignment is a good practice.


26-26: LGTM! Both console and file logging are correctly configured.

The root logger is properly configured to use both handlers.


Line range hint 2-2: Verify the impact of disable_existing_loggers: True.

Based on the past review comments and PR objectives, this setting might conflict with the logger initialized in application/__init__.py. Consider setting it to False as originally intended.

-disable_existing_loggers: True
+disable_existing_loggers: False
application/__init__.py (3)

33-35: LGTM! The logging setup is robust.

The code correctly:

  1. Sets the log file path dynamically
  2. Creates the logs directory if it doesn't exist
  3. Applies the configuration
🧰 Tools
🪛 Ruff (0.8.2)

34-34: Undefined name paths

(F821)


35-35: Undefined name paths

(F821)


35-35: Undefined name paths

(F821)


41-44: LGTM! Logger initialization is properly handled.

The logger initialization is correctly placed in both the exception and success paths, ensuring logging is available regardless of configuration success.


24-24: 🧹 Nitpick (assertive)

Fix the import statement.

The static analysis tool flags the import as unused. Use a direct import to make the usage clear.

-import application.paths
+from application import paths

Likely invalid or redundant comment.

🧰 Tools
🪛 Ruff (0.8.2)

24-24: application.paths imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

application/paths.py Show resolved Hide resolved
@li-ruihao li-ruihao requested a review from junhaoliao January 21, 2025 03:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants