-
Notifications
You must be signed in to change notification settings - Fork 28
feat: comprehensive logging improvements to reduce log volume #1369
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
Conversation
- Add HealthCheckFilter to filter /health access logs (62% reduction) - Downgrade worker polling/claim logs to DEBUG level - Downgrade consensus intermediate state logs to DEBUG level - Keep business events (tx finalized, tx processed) at INFO level - Add run_server.py and run_worker.py entry points for uvicorn logging - Update Dockerfiles to use new entry points - Add LOGGING_POLICY.md documentation for logging guidelines Key changes: - Health check access logs now filtered in uvicorn config - _log_query_result in worker.py changed to DEBUG - Claim operations (tx, appeal, finalization) changed to DEBUG - TX_PROCESSOR internal logs changed to DEBUG - TX_EXEC intermediate states changed to DEBUG - Recovery and appeal loop summaries changed to DEBUG Expected log volume reduction: ~80% with these changes combined with updated DISABLE_INFO_LOGS_ENDPOINTS in deployment configs.
📝 WalkthroughWalkthroughAdds a centralized uvicorn logging configuration with a HealthCheckFilter, new Python entrypoints to start server and worker (applying that config), lowers routine consensus/worker log levels to DEBUG, introduces a JSON-RPC Changes
Sequence Diagram(s)(omitted) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~30 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this 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
🤖 Fix all issues with AI agents
In @backend/protocol_rpc/logging_config.py:
- Around line 31-41: The function configure_uvicorn_logging is defined but never
used; either remove it to eliminate dead code or retain it with a clear
doc/comment explaining when it should be invoked; if keeping, add a note
referencing HealthCheckFilter and the "uvicorn.access" logger stating it must be
called before starting uvicorn (e.g., in server bootstrap) so readers know its
intended usage, otherwise delete the configure_uvicorn_logging function and any
unused HealthCheckFilter import/definition if not used elsewhere.
🧹 Nitpick comments (6)
asgi.py (1)
12-14: Clarify the comment about logging configuration.The comment "Configure logging before importing the app" is misleading. Line 13 imports the
get_uvicorn_log_configfunction but doesn't actually configure logging—that happens at line 36 when the function is called and passed touvicorn.run(log_config=...).Consider revising to:
# Import logging configuration for uvicorn from backend.protocol_rpc.logging_config import get_uvicorn_log_configIf there's a specific reason this import must occur before the app import (e.g., side effects), please document that reason explicitly.
backend/protocol_rpc/run_server.py (2)
10-11: Hardcoded/apppath reduces portability.This assumes execution only from Docker. Consider deriving the path dynamically for local development:
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))Or use a fallback that checks if
/appexists.
16-30: Add return type annotation.Per coding guidelines, include type hints in all Python code:
-def main(): +def main() -> None:backend/consensus/run_worker.py (1)
16-28: Add return type annotation for consistency.Same as
run_server.py, add type hint per coding guidelines:-def main(): +def main() -> None:backend/protocol_rpc/logging_config.py (2)
14-15: Annotate class-level mutable attribute withClassVar.Per Ruff RUF012, mutable class attributes should be annotated:
+from typing import ClassVar + class HealthCheckFilter(logging.Filter): """Filter out health check requests from access logs.""" # Endpoints to filter (no logging for these paths) - FILTERED_PATHS = {"/health", "/ready", "/status"} + FILTERED_PATHS: ClassVar[set[str]] = {"/health", "/ready", "/status"}
22-26: Consider handling paths with query strings.The current pattern matching won't filter requests like
/health?check=1or/ready?timeout=5. While health probes typically don't use query strings, a more robust approach would handle this:for path in self.FILTERED_PATHS: # Match patterns like: GET /health HTTP/1.1 - if f'"{path} ' in message or f" {path} " in message: + if f'"{path} ' in message or f" {path} " in message or f'"{path}?' in message or f" {path}?" in message: return FalseAlternatively, use regex for cleaner matching.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
asgi.pybackend/consensus/base.pybackend/consensus/run_worker.pybackend/consensus/worker.pybackend/protocol_rpc/logging_config.pybackend/protocol_rpc/run_server.pydocker/Dockerfile.backenddocker/Dockerfile.consensus-workerdocs/LOGGING_POLICY.md
🧰 Additional context used
📓 Path-based instructions (3)
**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
Target Python 3.12, use 4-space indentation, and rely on Black via pre-commit for formatting consistency
**/*.py: Apply Black formatter for Python code formatting
Include type hints in all Python code
Files:
asgi.pybackend/protocol_rpc/logging_config.pybackend/consensus/base.pybackend/consensus/worker.pybackend/protocol_rpc/run_server.pybackend/consensus/run_worker.py
backend/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
Align backend filenames with their behavior (e.g.,
validators/llm_validator.py) and mirror that pattern in tests
Files:
backend/protocol_rpc/logging_config.pybackend/consensus/base.pybackend/consensus/worker.pybackend/protocol_rpc/run_server.pybackend/consensus/run_worker.py
backend/consensus/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Implement validator rotation using VRF (Verifiable Random Function) in the consensus system
Files:
backend/consensus/base.pybackend/consensus/worker.pybackend/consensus/run_worker.py
🧠 Learnings (2)
📚 Learning: 2025-12-04T13:40:47.132Z
Learnt from: CR
Repo: genlayerlabs/genlayer-studio PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-04T13:40:47.132Z
Learning: Applies to backend/{asgi.py,uvicorn_config.py} : FastAPI backend bootstraps in `asgi.py` and `uvicorn_config.py`
Applied to files:
docker/Dockerfile.backendasgi.pybackend/protocol_rpc/run_server.py
📚 Learning: 2025-09-08T16:24:56.379Z
Learnt from: cgmello
Repo: genlayerlabs/genlayer-studio PR: 1310
File: vector.yaml:17-18
Timestamp: 2025-09-08T16:24:56.379Z
Learning: The GenLayer Studio logging architecture uses GCP Stackdriver Logs and GCP Pub/Sub as sinks, where top-level fields like .host work well for filtering, rather than Loki-style labels.
Applied to files:
docs/LOGGING_POLICY.md
🧬 Code graph analysis (5)
asgi.py (1)
backend/protocol_rpc/logging_config.py (1)
get_uvicorn_log_config(44-101)
backend/consensus/base.py (2)
backend/node/genvm/origin/logger.py (1)
debug(14-15)examples/contracts/_hello_world.py (1)
debug(34-38)
backend/consensus/worker.py (1)
backend/node/genvm/origin/logger.py (1)
debug(14-15)
backend/protocol_rpc/run_server.py (2)
backend/protocol_rpc/logging_config.py (1)
get_uvicorn_log_config(44-101)backend/consensus/run_worker.py (1)
main(16-28)
backend/consensus/run_worker.py (3)
backend/protocol_rpc/logging_config.py (1)
get_uvicorn_log_config(44-101)backend/protocol_rpc/run_server.py (1)
main(16-30)backend/consensus/worker.py (1)
run(1056-1150)
🪛 Ruff (0.14.10)
backend/protocol_rpc/logging_config.py
15-15: Mutable class attributes should be annotated with typing.ClassVar
(RUF012)
backend/protocol_rpc/run_server.py
25-25: Possible binding to all interfaces
(S104)
backend/consensus/run_worker.py
24-24: Possible binding to all interfaces
(S104)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: test
- GitHub Check: load-test
- GitHub Check: backend-unit-tests
🔇 Additional comments (14)
backend/consensus/base.py (4)
525-525: LGTM: Recovery loop logging appropriately downgraded to DEBUG.The crawl_snapshot recovery loop logs (start, periodic summaries, stop) are internal housekeeping operations that don't require INFO-level visibility in production.
Also applies to: 638-645, 657-659
741-741: LGTM: Transaction processor internal logs appropriately downgraded to DEBUG.Internal lifecycle events (starting loops, activating transactions, spawning processors, cleanup) are moved to DEBUG while preserving INFO-level logs for actual business outcomes (lines 887, 1140: "Successfully processed transaction"). This maintains visibility of critical events while reducing log noise.
Also applies to: 760-762, 848-850, 854-856, 874-876, 904-906, 933-938, 945-948, 986-988
1029-1031: LGTM: Transaction execution intermediate states appropriately downgraded to DEBUG.Starting and intermediate execution steps are internal details, while the final success message at line 1140 remains at INFO level for visibility of completed transactions.
Also applies to: 1111-1113
1468-1468: LGTM: Appeal window loop logging appropriately downgraded to DEBUG.The appeal window loop lifecycle logs (start, periodic summaries, stop) are internal operations that don't require INFO-level visibility. Critical appeal outcomes are handled elsewhere at appropriate log levels.
Also applies to: 1641-1645, 1654-1656
backend/consensus/worker.py (3)
188-190: LGTM: Claim operations appropriately downgraded to DEBUG.Internal claim operations are internal state transitions that occur frequently during polling. Business outcomes (successful processing, finalization) remain at INFO level at lines 632, 893, 909.
Also applies to: 395-395
1029-1054: LGTM: Query result logging with clear documentation.The docstring at line 1037 clearly explains the DEBUG-level intent for internal polling operations, and the implementation at line 1049 correctly uses DEBUG level for query results. The low-frequency logging pattern (60-second intervals) further reduces noise.
1083-1085: LGTM: Run loop claim operations appropriately downgraded to DEBUG.Consistent with other claim operations in the file. These internal polling results are moved to DEBUG while preserving INFO-level logs for actual processing outcomes (lines 1009-1011: "Successfully processed appeal").
Also applies to: 1134-1136
asgi.py (1)
36-36: LGTM: Logging configuration correctly applied.Replacing
access_log=Truewithlog_config=get_uvicorn_log_config()properly delegates logging configuration to the centralized logging module, enabling health check filtering and environment-driven log levels.docker/Dockerfile.backend (1)
96-97: LGTM: Entrypoint correctly updated to use new logging-aware server script.The change from direct uvicorn invocation to
python3 -m backend.protocol_rpc.run_serverproperly delegates startup to the new entrypoint script that configures uvicorn logging, including health check filtering and environment-driven log levels.docker/Dockerfile.consensus-worker (1)
113-116: LGTM: Worker entrypoint correctly updated to use new logging-aware script.The change from direct uvicorn invocation to
python3 -m backend.consensus.run_workerproperly delegates startup to the new worker entrypoint script that configures uvicorn logging, mirroring the approach used in the backend Dockerfile.backend/consensus/run_worker.py (1)
1-32: LGTM - consistent structure with run_server.py.The entry point correctly configures uvicorn with the centralized logging config. The absence of a
workersparameter (unlikerun_server.py) is appropriate since consensus workers shouldn't scale horizontally within the same container.docs/LOGGING_POLICY.md (2)
1-193: Well-structured logging policy.The document provides clear, actionable guidance with good examples. The decision framework (lines 128-145) for adding new logs is particularly useful. This will help maintain consistency across the codebase.
162-169: No issues found. The documentation accurately reflects the implementation. The worker maintains separatepoll_interval(5 seconds) and_query_log_interval(60 seconds) values, making the documented claim "logged every 60s, not per-poll" correct. Query polling results are intentionally sampled at 60-second intervals rather than logged on every 5-second poll cycle.backend/protocol_rpc/logging_config.py (1)
44-101: LGTM - well-structured logging configuration.The configuration correctly applies the health check filter to access logs while preserving standard logging for other requests. The separation of handlers (stderr for errors, stdout for access) follows best practices for container environments.
Add NotFoundError exception class for expected "not found" responses. These are valid query responses, not system failures. Changes: - Add NotFoundError class in exceptions.py (code -32001) - Update endpoint decorator to log NotFoundError at DEBUG level - Update fastapi_handler to handle EventType.DEBUG properly - Change transaction not found errors to use NotFoundError Before: "Transaction X not found" logged as ERROR After: "Transaction X not found" logged as DEBUG This prevents log noise from normal queries for non-existent transactions.
Consistent error handling for expected "not found" responses: - Contract not found (deployer check, validation, send_raw_transaction) - Block not found - Contract name not found These are logged at DEBUG level instead of ERROR since they're valid query outcomes, not system failures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
backend/protocol_rpc/message_handler/base.py (1)
1-361: Critical: Black formatting check failed.The pre-commit hook detected formatting issues in this file. Please run Black to apply the required formatting:
black backend/protocol_rpc/message_handler/base.pyOr apply all formatting fixes:
pre-commit run --all-files
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
backend/protocol_rpc/endpoints.pybackend/protocol_rpc/exceptions.pybackend/protocol_rpc/message_handler/base.pybackend/protocol_rpc/message_handler/fastapi_handler.pydocs/LOGGING_POLICY.md
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
Target Python 3.12, use 4-space indentation, and rely on Black via pre-commit for formatting consistency
**/*.py: Apply Black formatter for Python code formatting
Include type hints in all Python code
Files:
backend/protocol_rpc/exceptions.pybackend/protocol_rpc/message_handler/fastapi_handler.pybackend/protocol_rpc/message_handler/base.pybackend/protocol_rpc/endpoints.py
backend/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
Align backend filenames with their behavior (e.g.,
validators/llm_validator.py) and mirror that pattern in tests
Files:
backend/protocol_rpc/exceptions.pybackend/protocol_rpc/message_handler/fastapi_handler.pybackend/protocol_rpc/message_handler/base.pybackend/protocol_rpc/endpoints.py
🧠 Learnings (1)
📚 Learning: 2025-09-08T16:24:56.379Z
Learnt from: cgmello
Repo: genlayerlabs/genlayer-studio PR: 1310
File: vector.yaml:17-18
Timestamp: 2025-09-08T16:24:56.379Z
Learning: The GenLayer Studio logging architecture uses GCP Stackdriver Logs and GCP Pub/Sub as sinks, where top-level fields like .host work well for filtering, rather than Loki-style labels.
Applied to files:
docs/LOGGING_POLICY.md
🧬 Code graph analysis (3)
backend/protocol_rpc/message_handler/fastapi_handler.py (2)
backend/protocol_rpc/message_handler/types.py (1)
EventType(5-10)backend/node/genvm/origin/logger.py (1)
debug(14-15)
backend/protocol_rpc/message_handler/base.py (2)
backend/protocol_rpc/exceptions.py (2)
JSONRPCError(8-40)NotFoundError(87-97)backend/protocol_rpc/message_handler/types.py (3)
EventType(5-10)LogEvent(21-41)EventScope(13-17)
backend/protocol_rpc/endpoints.py (1)
backend/protocol_rpc/exceptions.py (2)
JSONRPCError(8-40)NotFoundError(87-97)
🪛 GitHub Actions: pre-commit
backend/protocol_rpc/message_handler/base.py
[error] 1-1: Black formatting check failed. The hook reformatted 1 file (backend/protocol_rpc/message_handler/base.py) and exited with code 1. Run 'pre-commit run --all-files' to apply formatting locally.
🪛 Ruff (0.14.10)
backend/protocol_rpc/message_handler/base.py
277-277: Use explicit conversion flag
Replace with conversion flag
(RUF010)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: backend-unit-tests
🔇 Additional comments (5)
backend/protocol_rpc/endpoints.py (1)
8-8: LGTM! NotFoundError correctly replaces JSONRPCError for "not found" cases.The introduction of
NotFoundErrorfor transaction lookup failures is appropriate. These are expected query outcomes (soft errors) that should be logged at DEBUG level rather than ERROR, reducing log noise from normal polling operations.All three endpoints (
get_transaction_by_hash,get_studio_transaction_by_hash,get_transaction_status) consistently use the new error type while preserving message format and data structure.Also applies to: 1057-1060, 1074-1077, 1086-1089
backend/protocol_rpc/exceptions.py (1)
85-97: LGTM! Well-documented soft error for expected "not found" responses.The
NotFoundErrorclass is well-designed with clear documentation explaining its purpose as a soft error for expected query outcomes. The error code-32001appropriately sits in the application-specific range defined by the JSON-RPC specification.docs/LOGGING_POLICY.md (1)
1-199: Excellent comprehensive logging policy documentation.This policy document provides clear, actionable guidance for logging across the backend services. Key strengths:
- Well-defined log levels with specific audiences and use cases
- Concrete examples for each level
- Clear distinction between final states (INFO) and intermediate states (DEBUG)
- Explicit guidance on NotFoundError as a soft error at DEBUG level
- Helpful decision tree for adding new logs
The document aligns well with the PR's goal of reducing log volume (~80%) while maintaining visibility for business events and errors.
backend/protocol_rpc/message_handler/fastapi_handler.py (1)
139-140: LGTM! Essential fix for DEBUG-level event handling.Adding explicit handling for
EventType.DEBUGensures these events are logged at the debug level rather than falling through to theelsebranch where they would incorrectly be logged as INFO. This change is necessary to support the new logging policy's distinction between routine operations (DEBUG) and business events (INFO).backend/protocol_rpc/message_handler/base.py (1)
12-12: LGTM! NotFoundError correctly treated as soft error.The special handling for
NotFoundErrorproperly distinguishes expected query outcomes from actual system failures:
NotFoundError→ logged at DEBUG level with event name "endpoint_not_found"- Other exceptions → logged at ERROR level with event name "endpoint_error"
- Traceback included only for ERROR-level events (line 281)
This reduces log noise from normal polling operations that return "not found" responses.
Also applies to: 263-286
Previously DISABLE_INFO_LOGS_ENDPOINTS would completely skip logging. Now these methods are logged at DEBUG level, making them available for troubleshooting when LOG_LEVEL=debug while keeping production logs clean.
Replace DISABLE_INFO_LOGS_ENDPOINTS env var with per-endpoint log level configuration. Each endpoint now declares its log level in the endpoint definition using LogPolicy.debug() for high-frequency polling methods. Benefits: - Self-documenting: log level is visible in endpoint definition - Type-safe: no JSON parsing from env vars - Consistent: same behavior across all environments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
backend/protocol_rpc/logging_config.py (1)
11-28: Annotate class attribute withClassVarfor type safety.The
FILTERED_PATHSclass attribute should be annotated withtyping.ClassVar[set[str]]to clarify that it's shared across all instances and not an instance attribute.🔎 Proposed fix
+from typing import ClassVar + class HealthCheckFilter(logging.Filter): """Filter out health check requests from access logs.""" # Endpoints to filter (no logging for these paths) - FILTERED_PATHS = {"/health", "/ready", "/status"} + FILTERED_PATHS: ClassVar[set[str]] = {"/health", "/ready", "/status"}Based on static analysis hints (Ruff RUF012).
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
backend/protocol_rpc/endpoints.pybackend/protocol_rpc/logging_config.pybackend/protocol_rpc/message_handler/base.pybackend/protocol_rpc/rpc_endpoint_manager.pybackend/protocol_rpc/rpc_methods.pydocs/LOGGING_POLICY.md
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/LOGGING_POLICY.md
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
Target Python 3.12, use 4-space indentation, and rely on Black via pre-commit for formatting consistency
**/*.py: Apply Black formatter for Python code formatting
Include type hints in all Python code
Files:
backend/protocol_rpc/rpc_endpoint_manager.pybackend/protocol_rpc/rpc_methods.pybackend/protocol_rpc/endpoints.pybackend/protocol_rpc/logging_config.pybackend/protocol_rpc/message_handler/base.py
backend/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
Align backend filenames with their behavior (e.g.,
validators/llm_validator.py) and mirror that pattern in tests
Files:
backend/protocol_rpc/rpc_endpoint_manager.pybackend/protocol_rpc/rpc_methods.pybackend/protocol_rpc/endpoints.pybackend/protocol_rpc/logging_config.pybackend/protocol_rpc/message_handler/base.py
🧠 Learnings (4)
📚 Learning: 2025-09-03T15:21:09.877Z
Learnt from: epsjunior
Repo: genlayerlabs/genlayer-studio PR: 1302
File: backend/protocol_rpc/endpoints.py:431-438
Timestamp: 2025-09-03T15:21:09.877Z
Learning: ContractSnapshot class in backend/database_handler/contract_snapshot.py handles deployment validation by raising Exception("Contract {address} not found") for missing contracts and Exception("Contract {address} not deployed") for contracts with empty data, centralizing validation logic that was previously in RPC endpoints.
Applied to files:
backend/protocol_rpc/endpoints.py
📚 Learning: 2025-09-03T15:21:09.877Z
Learnt from: epsjunior
Repo: genlayerlabs/genlayer-studio PR: 1302
File: backend/protocol_rpc/endpoints.py:431-438
Timestamp: 2025-09-03T15:21:09.877Z
Learning: ContractSnapshot class in backend/database_handler/contract_snapshot.py handles deployment validation and raises appropriate exceptions for contracts that aren't deployed, eliminating the need for additional error handling in the RPC endpoints.
Applied to files:
backend/protocol_rpc/endpoints.py
📚 Learning: 2025-06-16T02:16:55.779Z
Learnt from: kstroobants
Repo: genlayerlabs/genlayer-studio PR: 1204
File: backend/database_handler/contract_processor.py:61-73
Timestamp: 2025-06-16T02:16:55.779Z
Learning: In the GenLayer Studio backend, when a contract transaction exists, endpoints.py ensures that an empty contract is created via accounts_manager.create_new_account_with_address(new_contract_address), so reset_contract() won't encounter NoResultFound exceptions.
Applied to files:
backend/protocol_rpc/endpoints.py
📚 Learning: 2025-06-16T02:16:55.779Z
Learnt from: kstroobants
Repo: genlayerlabs/genlayer-studio PR: 1204
File: backend/database_handler/contract_processor.py:61-73
Timestamp: 2025-06-16T02:16:55.779Z
Learning: In the GenLayer Studio backend, when a contract transaction exists, endpoint.py ensures that an empty contract is created via accounts_manager.create_new_account_with_address(new_contract_address), so reset_contract() won't encounter NoResultFound exceptions.
Applied to files:
backend/protocol_rpc/endpoints.py
🧬 Code graph analysis (4)
backend/protocol_rpc/rpc_endpoint_manager.py (2)
backend/protocol_rpc/message_handler/types.py (2)
EventType(5-10)EventScope(13-17)backend/protocol_rpc/rpc_decorators.py (1)
method(17-34)
backend/protocol_rpc/rpc_methods.py (2)
backend/protocol_rpc/rpc_endpoint_manager.py (2)
LogPolicy(58-76)debug(74-76)backend/protocol_rpc/rpc_decorators.py (1)
method(17-34)
backend/protocol_rpc/endpoints.py (1)
backend/protocol_rpc/exceptions.py (2)
JSONRPCError(8-40)NotFoundError(87-97)
backend/protocol_rpc/message_handler/base.py (2)
backend/protocol_rpc/exceptions.py (2)
JSONRPCError(8-40)NotFoundError(87-97)backend/protocol_rpc/message_handler/types.py (3)
EventType(5-10)LogEvent(21-41)EventScope(13-17)
🪛 Ruff (0.14.10)
backend/protocol_rpc/endpoints.py
558-561: Abstract raise to an inner function
(TRY301)
backend/protocol_rpc/logging_config.py
15-15: Mutable class attributes should be annotated with typing.ClassVar
(RUF012)
backend/protocol_rpc/message_handler/base.py
277-277: Use explicit conversion flag
Replace with conversion flag
(RUF010)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: backend-unit-tests
🔇 Additional comments (10)
backend/protocol_rpc/logging_config.py (1)
31-88: LGTM! Well-structured uvicorn logging configuration.The logging configuration properly integrates the health check filter with uvicorn's access logger and follows uvicorn's expected dictionary configuration format.
backend/protocol_rpc/rpc_endpoint_manager.py (3)
57-76: LGTM! Clean per-endpoint logging policy design.The
LogPolicydataclass with adebug()classmethod provides a clear, type-safe way to configure logging levels per endpoint. The design aligns well with the PR's goal to reduce log volume for high-frequency methods.
175-218: LGTM! Per-endpoint log levels properly applied.The logging calls now correctly use
definition.log_policy.log_levelinstead of fixedEventType.INFO, enabling per-endpoint control over request and success log verbosity while keeping errors at ERROR level.
407-409: LGTM! Simplified logging control.Removing the dependency on
GlobalConfigurationand relying solely on per-endpointLogPolicyflags is cleaner and more maintainable.backend/protocol_rpc/rpc_methods.py (1)
27-27: LGTM! Appropriate endpoints demoted to DEBUG level.The selected endpoints (
ping, balance/transaction/schema getters, and Ethereum-compatible read methods) are well-chosen for DEBUG-level logging. These are high-frequency, low-impact operations that would otherwise dominate INFO logs.Also applies to: 35-35, 248-248, 276-276, 321-321, 336-336, 413-413, 426-426, 452-452, 463-463, 507-507, 520-520, 525-525, 562-562
backend/protocol_rpc/message_handler/base.py (1)
12-12: LGTM! Appropriate soft-error handling for NotFoundError.The special handling for
NotFoundErrorcorrectly treats it as an expected outcome (DEBUG level,endpoint_not_foundevent) rather than a system failure, and only includes tracebacks for actual ERROR-level events. This aligns well with the PR's goal to reduce noise in logs.Also applies to: 263-290
backend/protocol_rpc/endpoints.py (4)
8-8: LGTM! Appropriate use of NotFoundError for missing contracts.The replacement of
JSONRPCErrorwithNotFoundErrorfor contract-not-found scenarios inadmin_upgrade_contract_codeis correct. These are expected query outcomes that should be logged at DEBUG level rather than ERROR.Also applies to: 558-602
1055-1088: LGTM! Consistent NotFoundError usage for transaction queries.The three transaction query endpoints (
get_transaction_by_hash,get_studio_transaction_by_hash,get_transaction_status) correctly raiseNotFoundErrorwhen transactions don't exist, treating these as expected outcomes rather than system errors.
1281-1284: LGTM! NotFoundError for missing contract target.Raising
NotFoundErrorwhen the target contract doesn't exist duringsend_raw_transactionis appropriate, as this is a validation failure rather than an internal system error.
1401-1404: LGTM! NotFoundError for block and consensus contract queries.Both
get_block_by_numberandget_contract(consensus service) correctly useNotFoundErrorfor missing resources, treating these as normal query outcomes rather than errors requiring investigation.Also applies to: 1535-1538
|
|
🎉 This PR is included in version 0.87.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |


Summary
This PR implements a comprehensive logging policy to significantly reduce log volume (estimated ~80% reduction) while maintaining visibility for business events and errors.
Changes
New Files:
backend/protocol_rpc/logging_config.py- HealthCheckFilter to suppress /health access logsbackend/protocol_rpc/run_server.py- JSONRPC server entry point with logging configbackend/consensus/run_worker.py- Worker entry point with logging configdocs/LOGGING_POLICY.md- Logging guidelines documentationLog Level Changes:
_log_query_result): INFO → DEBUG (~21% of volume)Kept at INFO (business events):
Dockerfile Updates:
docker/Dockerfile.backend: Userun_server.pyentry pointdocker/Dockerfile.consensus-worker: Userun_worker.pyentry pointRelated Deployment Changes
The
DISABLE_INFO_LOGS_ENDPOINTSconfig in devexp-apps-workload should be updated to include:Test plan
docker compose updocker logs)Summary by CodeRabbit
New Features
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.