Skip to content

Filter and color emulator log lines#137

Merged
carole-lavillonniere merged 4 commits intomainfrom
carole/drg-589
Mar 19, 2026
Merged

Filter and color emulator log lines#137
carole-lavillonniere merged 4 commits intomainfrom
carole/drg-589

Conversation

@carole-lavillonniere
Copy link
Collaborator

@carole-lavillonniere carole-lavillonniere commented Mar 18, 2026

Motivation

Raw emulator logs are noisy for users — they mix HTTP internals, provider debug info, and other low-signal lines with useful output. This filters out identified noise and adds color coding to make the remaining logs easier to scan.

Changes

  • Add log line parser to extract log level and logger name from LocalStack log format
  • Filter out noisy log lines: localstack.request.http, l.aws.handlers.internal, *.provider loggers, and "Docker not available"
  • Add Level field to LogLineEvent so renderers can apply level-aware styling
  • Add renderLogLine in the UI layer: metadata prefix in grey, message colored by level (WARN → orange, ERROR → red)
  • Switch lstk logs to TUI mode when running interactively, plain sink otherwise

TODO

Will add --verbose flag to bypass the filtering in a subsequent PR.

Closes DRG-589

image image

@carole-lavillonniere carole-lavillonniere marked this pull request as ready for review March 19, 2026 09:53
@coderabbitai
Copy link

coderabbitai bot commented Mar 19, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 5971e80f-8a7a-4073-ae81-bcd490458743

📥 Commits

Reviewing files that changed from the base of the PR and between 32b27b5 and 1f0cad8.

📒 Files selected for processing (4)
  • internal/container/logfilter.go
  • internal/output/events.go
  • internal/ui/logrender.go
  • internal/ui/styles/styles.go

📝 Walkthrough

Walkthrough

Adds log-level-aware processing and filtering, renders level-styled logs in a new interactive TUI, and wires the logs command to use the TUI when in interactive mode. New parsing/filtering utilities extract severity and logger metadata and emit level-annotated log events.

Changes

Cohort / File(s) Summary
CLI wiring
cmd/logs.go
Branch logs command to call ui.RunLogs when interactive mode is enabled.
Log event system
internal/output/events.go, internal/output/plain_format_test.go
Added LogLevel type and constants; extended LogLineEvent with Level and updated EmitLogLine to accept level; added tests for formatting with levels.
Container log streaming
internal/container/logs.go, internal/update/update.go
Preprocess scanned lines with shouldFilter and parseLogLine; emit lines with level metadata. logLineWriter updated to emit LogLevelUnknown for unparsed writes.
Log parsing & filtering
internal/container/logfilter.go, internal/container/logfilter_test.go
New unexported helpers parseLogLine and shouldFilter to extract level/logger and drop noisy lines; comprehensive tests added.
Interactive TUI
internal/ui/run_logs.go, internal/ui/app.go, internal/ui/logrender.go, internal/ui/styles/styles.go
New RunLogs to run a Bubble Tea program tied to async container log streaming; renderLogLine and renderLogMessage added to style metadata and message by level; new LogError style variable.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI as CLI (logs)
    participant UI as TUI.RunLogs
    participant Gor as Goroutine
    participant Container as container.Logs
    participant Sink as Output Sink
    participant Renderer as UI Renderer

    User->>CLI: run `lstk logs`
    CLI->>UI: RunLogs(ctx, rt, containers, follow)
    UI->>UI: start Bubble Tea Program
    UI->>Gor: launch goroutine for logs
    Gor->>Container: container.Logs(ctx, sink, containers, follow)
    Container->>Container: scan lines
    Container->>Container: shouldFilter(line)?
    alt filtered
        Container-->>Sink: (skip)
    else pass
        Container->>Container: parseLogLine -> level
        Container->>Sink: EmitLogLine(line, level)
        Sink->>Renderer: deliver LogLineEvent(level, line)
        Renderer->>UI: styled line
        UI->>User: display
    end
    Container->>Gor: complete (done/error)
    Gor->>UI: send completion message
    UI->>User: exit TUI
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • gtsiolis
  • anisaoshafi
  • silv-io
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Filter and color emulator log lines' accurately summarizes the main changes: filtering noisy log lines and adding color coding to logs for better readability.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, covering motivation, specific filtering rules, UI changes, and the switch to TUI mode for interactive logs.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch carole/drg-589
📝 Coding Plan
  • Generate coding plan for human review comments

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.

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

🧹 Nitpick comments (1)
internal/ui/logrender.go (1)

22-29: Prefer log-specific severity styles here.

styles.ErrorTitle is tied to the error panel and also brings title emphasis via bolding. A dedicated log severity style in internal/ui/styles/styles.go would keep inline log rendering decoupled from error-dialog styling. Based on learnings, "Define styles with semantic names in internal/ui/styles/styles.go."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/ui/logrender.go` around lines 22 - 29, The inline log renderer
renderLogMessage currently uses styles.ErrorTitle (which is for the error panel
and includes title emphasis); add a dedicated log-severity style in
internal/ui/styles/styles.go (e.g., ErrorSeverity or LogError) and replace uses
of styles.ErrorTitle in renderLogMessage with the new semantic style; ensure the
new style mirrors appropriate color/weight for inline logs (but without title
bolding) and update any imports/usages so renderLogMessage, styles.Warning, and
the new styles.ErrorSeverity are used for Warn/Error cases respectively.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/container/logs.go`:
- Around line 32-37: The code currently always drops lines via shouldFilter
before emitting them in the loop (see shouldFilter, parseLogLine, and
output.EmitLogLine), which makes filtered lines unrecoverable; instead gate that
filtering behind the new raw/verbose option: add a boolean parameter (e.g.,
rawLogs or verboseRaw) to the logs streaming function and only call shouldFilter
when that flag indicates filtering is enabled, or until the flag is plumbed in
keep plain mode unfiltered by skipping shouldFilter; ensure you propagate the
flag from the callers in cmd/logs.go and internal/ui/run_logs.go so the decision
is controlled by the CLI option rather than always dropping lines.

---

Nitpick comments:
In `@internal/ui/logrender.go`:
- Around line 22-29: The inline log renderer renderLogMessage currently uses
styles.ErrorTitle (which is for the error panel and includes title emphasis);
add a dedicated log-severity style in internal/ui/styles/styles.go (e.g.,
ErrorSeverity or LogError) and replace uses of styles.ErrorTitle in
renderLogMessage with the new semantic style; ensure the new style mirrors
appropriate color/weight for inline logs (but without title bolding) and update
any imports/usages so renderLogMessage, styles.Warning, and the new
styles.ErrorSeverity are used for Warn/Error cases respectively.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: a390f7b8-6d45-4b27-9206-570198d1ece3

📥 Commits

Reviewing files that changed from the base of the PR and between 8b4c9e6 and 32b27b5.

📒 Files selected for processing (10)
  • cmd/logs.go
  • internal/container/logfilter.go
  • internal/container/logfilter_test.go
  • internal/container/logs.go
  • internal/output/events.go
  • internal/output/plain_format_test.go
  • internal/ui/app.go
  • internal/ui/logrender.go
  • internal/ui/run_logs.go
  • internal/update/update.go

Copy link
Member

@silv-io silv-io left a comment

Choose a reason for hiding this comment

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

LGTM! improves the usability a lot IMO.

To make it better we can try pushing for structured logs in the emulator. it's something that was thought of earlier but didn't get through.

Also some of the comments maybe are more descriptive than explanatory

Copy link
Member

Choose a reason for hiding this comment

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

nit: This one has a lot of comments in it :D

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks 😆
Removed.

// parseLogLine extracts the log level and logger name from a LocalStack log line.
// Expected format: 2026-03-16T17:56:00.810 INFO --- [ MainThread] l.p.c.extensions.plugins : message
// Returns LogLevelUnknown and empty string if the line does not match the expected format.
func parseLogLine(line string) (output.LogLevel, string) {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should push for introducing structured logs again. This seems quite brittle, but it's the best we can do at the moment

Copy link
Collaborator Author

@carole-lavillonniere carole-lavillonniere Mar 19, 2026

Choose a reason for hiding this comment

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

💯 log format could be configurable, plain text is better for humans but json would make it easier to parse them. However I think the biggest issue with the logs at the moment is the fact that are not consistent (some are formatted, others not)

Copy link
Member

Choose a reason for hiding this comment

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

Go PRO-236! 🤖

@silv-io
Copy link
Member

silv-io commented Mar 19, 2026

added feature idea: shortcut to collapse the greyed out part :)

@carole-lavillonniere carole-lavillonniere merged commit 20b1038 into main Mar 19, 2026
6 of 7 checks passed
@carole-lavillonniere carole-lavillonniere deleted the carole/drg-589 branch March 19, 2026 10:32
@gtsiolis
Copy link
Member

Didn't get a chance to review this, but looks great in action! Good first iteration. ❤️

imagediff (50)

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.

3 participants