Skip to content

Feat/logservice#132

Open
Fabito97 wants to merge 4 commits into
devfrom
feat/logservice
Open

Feat/logservice#132
Fabito97 wants to merge 4 commits into
devfrom
feat/logservice

Conversation

@Fabito97

@Fabito97 Fabito97 commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

📋 PR Checklist

Type of Change

  • ✨ New feature

Service(s) Affected

  • logservice (FastAPI log streaming utility)
  • [x ] deploy.yml (App deployment script)

Description

This PR introduces the initial implementation of the logservice, a FastAPI‑based utility that exposes PM2 logs via HTTP endpoint and integrates it into the deployment script.

Key additions:

  • main.py: FastAPI app with /logs/{service} endpoints for streaming logs.
  • requirements.txt: Python dependencies (fastapi, uvicorn).
  • start.sh: Script to launch logservice with Uvicorn.
  • Directory structure aligned with existing staging/production deploy directories.

Testing

  • Manually tested locally

How was this is to be tested?

  • Install dependencies with pip3 install -r requirements.txt.
  • Start service using ./start.sh.
  • Verify endpoints return logs for api-staging, api-production, worker-staging, and worker-production.

Breaking Changes

  • This PR introduces breaking changes

Security

  • No secrets or credentials are hardcoded
  • No sensitive data is logged
  • Dependencies reviewed for known vulnerabilities

Reviewer Notes

  • This PR adds the logservice implementation.
  • Deployment script integration (PM2 start/stop, dependency install) was also handled.
  • Please confirm directory placement ($DEPLOY_DIR/logservice) matches repo expectations.

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a dedicated log streaming service enabling real-time monitoring of process logs via API endpoint, supporting both text and JSON output formats.
  • Chores

    • Updated deployment workflow to automate logservice installation and lifecycle management as part of the application deployment pipeline.

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Fabito97, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 20 minutes and 48 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ea0efd88-de1d-4e06-bf75-dedd37808241

📥 Commits

Reviewing files that changed from the base of the PR and between 84a76e2 and 3e3dd1e.

📒 Files selected for processing (4)
  • .github/workflows/deploy.yml
  • logservice/main.py
  • logservice/requirements.txt
  • logservice/start.sh
📝 Walkthrough

Walkthrough

This PR introduces logservice, a new FastAPI microservice that streams real-time logs from PM2-managed processes via Server-Sent Events. The service validates process existence, handles client disconnections gracefully, and formats output as either raw text or JSON. Deployment is integrated into the existing workflow with environment setup and automated PM2 lifecycle management.

Changes

Logservice Log Streaming Feature

Layer / File(s) Summary
PM2 Log Streaming Service Implementation
logservice/main.py
FastAPI endpoint /logs/{service} validates PM2 processes via pm2 describe, spawns pm2 logs subprocesses to read combined stdout/stderr, terminates on client disconnect, and yields SSE frames formatted as either text or JSON payloads.
Service Startup Requirements and Script
logservice/requirements.txt, logservice/start.sh
Python runtime dependencies (fastapi, uvicorn) declared, and startup script configured to change directory to /var/www/logservice and launch the app on 0.0.0.0:8000.
Deployment Configuration and Workflow Steps
.github/workflows/deploy.yml
Workflow environment variables define logservice name, target directory, and start script path; deployment steps install dependencies, clear existing PM2 processes, and start logservice after API and Java worker.

Sequence Diagram

sequenceDiagram
  participant Client
  participant FastAPI
  participant PM2
  participant PM2Logs as pm2 logs subprocess
  Client->>FastAPI: GET /logs/{service}?lines=N&output_format=text
  FastAPI->>PM2: pm2 describe service
  PM2-->>FastAPI: process metadata or error
  FastAPI->>PM2Logs: spawn pm2 logs process
  loop Stream until disconnect
    PM2Logs-->>FastAPI: log line from stdout/stderr
    FastAPI->>FastAPI: format as SSE text or JSON
    FastAPI-->>Client: SSE data frame
  end
  Client-xClient: disconnect
  FastAPI->>PM2Logs: terminate subprocess
Loading

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Feat/logservice' is vague and lacks specificity about what the feature does or its purpose. Replace with a more descriptive title that clarifies the main change, e.g., 'Add logservice with PM2 log streaming API and deployment integration'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The PR description covers most required sections including type of change, services affected, description, testing, security, and reviewer notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/logservice

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/deploy.yml (1)

220-244: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Logservice is not stopped during rollback.

When the health check fails (Lines 220-244), the rollback deletes $API_NAME and $WORKER_NAME but not $LOGSERVICE_NAME. This leaves logservice running while API/worker are rolled back, which may cause inconsistent state if logservice depends on a specific version of the other services.

♻️ Proposed fix to include logservice in rollback
             if [ "$HEALTHY" = "false" ]; then
               echo "Health check failed. Rolling back..."
 
               pm2 delete $API_NAME || true
               pm2 delete $WORKER_NAME || true
+              pm2 delete $LOGSERVICE_NAME || true
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/deploy.yml around lines 220 - 244, The rollback sequence
fails to stop/restart the log service; add pm2 delete $LOGSERVICE_NAME || true
alongside the existing pm2 delete $API_NAME and pm2 delete $WORKER_NAME, and
then restart the log service after restoring backups using the same pm2 start
pattern used for API/WORKER (i.e., a pm2 start invocation that names the process
"$LOGSERVICE_NAME" and uses the appropriate start command/--cwd), and include
"$LOGSERVICE_NAME" in the pm2 save step and in backup cleanup so the logservice
is returned to the previous version as part of the rollback.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/deploy.yml:
- Around line 178-180: Remove the extra consecutive blank lines in the GitHub
Actions workflow so there are no more than two consecutive empty lines in
deploy.yml; open the workflow file and collapse the three consecutive blank
lines down to at most two (ensure surrounding YAML structure/indentation is
unchanged).
- Around line 175-177: Replace the direct system installation command pip3
install -r "$LOGSERVICE_DIR/requirements.txt" with a user-scoped or isolated
install; either add the --user flag to pip3 install (e.g., pip3 install --user
-r "$LOGSERVICE_DIR/requirements.txt") or create/activate a virtual environment
first and then install into it (ensure the deploy step creates a venv, activates
it, and runs pip3 install -r "$LOGSERVICE_DIR/requirements.txt" inside that
venv) so the workflow no longer requires root or pollutes the system Python
environment.

In `@logservice/main.py`:
- Around line 10-29: The validate_pm2_process function currently passes the
service parameter directly to subprocess calls; add an explicit allowlist check
at the start of validate_pm2_process (and the other call site that uses
asyncio.create_subprocess_exec) to only permit the four known services:
"api-staging", "api-production", "worker-staging", "worker-production"; if
service is not one of these, raise an HTTPException (400 or 404 as appropriate)
before calling subprocess.run or asyncio.create_subprocess_exec to prevent
injection or unexpected names.
- Around line 19-23: The except FileNotFoundError block that raises
HTTPException should capture the original exception and chain it so the
traceback is preserved: change the handler to bind the FileNotFoundError (e.g.,
"except FileNotFoundError as err:") and re-raise the HTTPException using "raise
HTTPException(... ) from err" so the original error is attached to the
HTTPException; update the except block that currently does "except
FileNotFoundError: raise HTTPException(...)" to use this pattern.
- Around line 83-90: The SSE response returned by StreamingResponse (wrapping
pm2_log_stream) needs the X-Accel-Buffering: no header to disable proxy
buffering; update the headers dict in the return of StreamingResponse (the block
that constructs the response for pm2_log_stream) to include "X-Accel-Buffering":
"no" alongside the existing "Cache-Control" and "Connection" entries so
nginx/other reverse proxies won’t buffer or delay SSE events.
- Around line 47-55: The loop currently awaits request.is_disconnected() before
calling process.stdout.readline(), but readline() can block indefinitely and
prevent timely disconnection detection; modify the read loop to race or timeout
the readline so you can periodically re-check request.is_disconnected() — e.g.,
create a readline task (process.stdout.readline()) and use asyncio.wait or
asyncio.wait_for with a short timeout to await either the line or a timeout,
then if the timeout occurs re-check request.is_disconnected() and continue, and
when the readline completes handle the line as before; reference
process.stdout.readline and request.is_disconnected in your changes.

In `@logservice/requirements.txt`:
- Around line 1-2: Pin the packages in logservice/requirements.txt to fixed
versions to ensure reproducible deployments: replace the unpinned entries for
fastapi and uvicorn with explicit versions (e.g., fastapi==0.136.3 and
uvicorn==0.49.0) or at minimum pinned major versions (e.g.,
fastapi>=0.136,<0.137) and consider adding a constraints or hash-locked
requirements file for stronger supply-chain integrity.

In `@logservice/start.sh`:
- Around line 2-3: The start.sh currently hardcodes cd /var/www/logservice which
breaks when LOGSERVICE_DIR is set by the deploy workflow; update start.sh to
derive the working dir dynamically (recommended: use the script's directory via
dirname "$0" or respect an environment variable/first argument like
LOGSERVICE_DIR) and remove the hardcoded path; ensure you check cd's return
status and exit with a non‑zero code on failure (handle per shellcheck) before
running exec uvicorn main:app so the service won't start in the wrong directory.

---

Outside diff comments:
In @.github/workflows/deploy.yml:
- Around line 220-244: The rollback sequence fails to stop/restart the log
service; add pm2 delete $LOGSERVICE_NAME || true alongside the existing pm2
delete $API_NAME and pm2 delete $WORKER_NAME, and then restart the log service
after restoring backups using the same pm2 start pattern used for API/WORKER
(i.e., a pm2 start invocation that names the process "$LOGSERVICE_NAME" and uses
the appropriate start command/--cwd), and include "$LOGSERVICE_NAME" in the pm2
save step and in backup cleanup so the logservice is returned to the previous
version as part of the rollback.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0e2f1a96-4fd9-46da-a374-95955e68afff

📥 Commits

Reviewing files that changed from the base of the PR and between 1f76734 and 84a76e2.

📒 Files selected for processing (4)
  • .github/workflows/deploy.yml
  • logservice/main.py
  • logservice/requirements.txt
  • logservice/start.sh

Comment thread .github/workflows/deploy.yml Outdated
Comment thread .github/workflows/deploy.yml
Comment thread logservice/main.py
Comment thread logservice/main.py Outdated
Comment thread logservice/main.py
Comment thread logservice/main.py
Comment thread logservice/requirements.txt Outdated
Comment thread logservice/start.sh Outdated
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.

1 participant