feat(logging): add centralized logger factory and replace print statements#21
Open
Kunal-Somani wants to merge 1 commit into
Open
feat(logging): add centralized logger factory and replace print statements#21Kunal-Somani wants to merge 1 commit into
Kunal-Somani wants to merge 1 commit into
Conversation
- Add utils/logger.py: a get_logger() factory that configures the root handler once via LOG_LEVEL env var, ensuring consistent structured output both locally and on Cloud Run - Refactor app.py: move logging init to module level so it applies on all deployment paths, not just __main__ - Refactor utils/utils.py: replace all print() calls with logger.info() / logger.debug() / logger.error() for production-grade observability
Kunal-Somani
added a commit
to Kunal-Somani/facial-sentiment-analysis-api
that referenced
this pull request
Mar 21, 2026
- Remove coloredlogs.install() calls from EmotionsAnalysisImp.__init__() and FirebaseImp.__init__() — reinstalling the log handler on every object instantiation was causing duplicate log entries - Replace instance-level self.logger with module-level logger via get_logger(__name__) for consistency with utils/logger.py (PR ruxailab#21) - Switch all f-string log calls to % formatting (Python logging best practice — avoids string interpolation when log level is disabled) - Add debug log to FirebaseImp._initialize_app() for the already- initialized path - Add logger.info() to upload_to_firestore() on successful Firestore write - Remove unused logging and coloredlogs imports from both files
Kunal-Somani
added a commit
to Kunal-Somani/facial-sentiment-analysis-api
that referenced
this pull request
Apr 3, 2026
Adds schemas/multimodal_output_schema.py — a Pydantic wrapper around
GetEmotionPercentagesResponse that standardizes the facial API output
for consumption by the MultimodalSentimentEngine in sentiment-analysis-api.
Key additions:
- FacialEmotionOutput.from_response(): converts GetEmotionPercentagesResponse
into a validated Pydantic model with field-level range constraints (0-100%)
- to_multimodal_dict(): produces the {emotion_label: percentage} dict
format expected by MultimodalSentimentEngine.analyze(facial_emotions=...)
- dominant_emotion(): returns the top emotion and its confidence as a
(label, float) tuple — useful for logging and single-label summaries
This is the integration boundary between the two RUXAILAB sentiment repos:
the facial API produces GetEmotionPercentagesResponse, FacialEmotionOutput
converts it, and the multimodal engine fuses it with text and prosody.
Closes the gap identified in PR ruxailab#21 and ruxailab#22 where the two pipelines
had no shared contract.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
The codebase had two observability gaps:
app.pyonly configured logging insideif __name__ == "__main__",meaning Cloud Run deployments received zero logging output — every
logger.info()call invideo_routes.pysilently did nothing in production.utils/utils.pyused rawprint()statements which cannot be filteredby log level, routed to external sinks, or controlled via environment variables.
Changes
utils/logger.py(new file)get_logger(name)factory function_configuredguard flagLOG_LEVELenvironment variable (default:INFO)stdoutin a structured format compatible with Cloud Run log ingestionapp.py(modified)coloredlogsdependency (was only active in__main__block)get_logger(__name__)at module levelutils/utils.py(modified)print()calls withlogger.info(),logger.debug(), andlogger.error()delete_video()andsplit_video_into_clips()delete_video()now useslogger.error()with%sformattingTesting
Confirmed structured log output appears at startup:
Motivation
This directly supports the Unified Logging and Traceability System outlined in the GSoC 2026 ideas — establishing a structured, environment-aware logging foundation that future traceability features can build on.