Skip to content

feat(diagnostics): add memory-analysis.sh for sizing diagnostics#41816

Open
wyattwalter wants to merge 4 commits into
releasefrom
ww-memory-analysis-script
Open

feat(diagnostics): add memory-analysis.sh for sizing diagnostics#41816
wyattwalter wants to merge 4 commits into
releasefrom
ww-memory-analysis-script

Conversation

@wyattwalter
Copy link
Copy Markdown
Contributor

@wyattwalter wyattwalter commented May 14, 2026

Summary

  • Adds memory-analysis.sh — a single-page memory diagnostic that runs inside the Appsmith container. Reports system/cgroup RAM, per-role RSS, JVM flag origins (ergonomic vs. explicit), MongoDB WiredTiger cache state + data-dir size, live usage vs. configured budget, and a verdict (OK / TIGHT / AT RISK).
  • Wires it into diagnostics.sh so every support tarball includes a readable memory report alongside the existing heap/thread dumps.

How to use

docker exec <container> /opt/appsmith/memory-analysis.sh
docker exec <container> /opt/appsmith/memory-analysis.sh --threads
docker exec <container> /opt/appsmith/memory-analysis.sh --threads-sample=20

The script is also invoked from diagnostics.sh --threads, so the report ends up at memory-analysis.txt inside the support tarball.

Test plan

  • `bash -n` clean
  • Run on a CE all-in-one container; report renders end-to-end with embedded Mongo topology
  • Run on a Kubernetes deployment with external MongoDB; topology detected correctly, WT cache shown as informational
  • Trigger `diagnostics.sh`; verify `memory-analysis.txt` is in the tarball

Summary by CodeRabbit

  • New Features

    • Diagnostics now include a one-page memory analysis: container caps/usage, per-component memory breakdown, JVM heap/native metrics, optional thread dumps/sampling, optional MongoDB probing, and an OK/TIGHT/AT RISK sizing verdict.
  • Chores

    • Memory analysis is executed as part of diagnostics collection but is allowed to fail without aborting the overall diagnostics.

Review Change Stack

Warning

Tests have not run on the HEAD 4055d63 yet


Thu, 14 May 2026 20:14:06 UTC

Self-contained shell script that prints a single-page memory report
from inside the Appsmith container: system/cgroup RAM, per-role RSS,
JVM flag origins (ergonomic vs. explicit), MongoDB WiredTiger cache
state + data-dir size, live usage vs. configured budget, and a verdict
(OK / TIGHT / AT RISK).

Wired into diagnostics.sh so every support tarball includes the report
alongside the existing heap/thread dumps.

Optional --threads flag adds a single-snapshot thread breakdown
(state histogram, name-prefix groups, hot stacks, deadlock check).
--threads-sample takes two snapshots N seconds apart to surface
threads that stayed RUNNABLE on the same frame.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

Walkthrough

Adds a new memory-analysis.sh that emits a single-page container memory snapshot and sizing verdict (OK/TIGHT/AT RISK) with optional JVM thread sampling and MongoWT probing; updates diagnostics.sh to run it and write stdout+stderr to memory-analysis.txt without failing diagnostics on error.

Changes

Memory analysis and diagnostics integration

Layer / File(s) Summary
Script entry, CLI and helpers
deploy/docker/fs/opt/appsmith/memory-analysis.sh
New script with usage/help, parses --no-mongo, --threads, and --threads-sample[=SECONDS], clamps sample window (3–60s), and provides formatting and helper functions.
Host and cgroup memory discovery
deploy/docker/fs/opt/appsmith/memory-analysis.sh
Reads /proc/meminfo, detects cgroup v2/v1 limits/usages (memory.max/memory.current or memory.limit_in_bytes/memory.usage_in_bytes), and falls back to host RAM when uncapped.
Per-role process RSS aggregation
deploy/docker/fs/opt/appsmith/memory-analysis.sh
Matches full ps command lines by regex to attribute RSS to roles (server JVM, rts, mongod, postgres, redis, keycloak, temporal, caddy, supervisord), uses postmaster for PostgreSQL to avoid shared-memory double counting, and prints top RSS processes.
JVM discovery and introspection
deploy/docker/fs/opt/appsmith/memory-analysis.sh
Finds server.jar PID, prints PID/uptime/RSS/thread-count; uses jcmd when available to extract GC selection, MaxHeapSize with origin, InitialHeapSize, metaspace/direct caps, GC.heap_info used heap, and optional NMT reserved totals.
Thread snapshot and stuck-thread sampling
deploy/docker/fs/opt/appsmith/memory-analysis.sh
--threads runs jcmd Thread.print for thread counts, deadlock output, state histogram, normalized thread-name families and hot frames; --threads-sample captures two snapshots across the clamped window and reports threads remaining RUNNABLE on the same top frame.
MongoDB embedded detection and WiredTiger probe
deploy/docker/fs/opt/appsmith/memory-analysis.sh
Detects embedded vs external mongod via local RSS; for embedded can report --dbpath sizes and probes db.serverStatus().wiredTiger.cache using mongosh/mongo with APPSMITH_DB_URL sourced from JVM /proc/<pid>/environ (redacting secrets); falls back to estimated WT cache ceiling when probing fails.
Usage reconciliation, budget composition, and verdict
deploy/docker/fs/opt/appsmith/memory-analysis.sh
Computes in-use memory (cgroup current or MemTotal–MemAvailable fallback), subtracts tracked JVM/Mongo/other RSS to estimate unaccounted/kernel buffers, composes budget from JVM Xmx + fixed non-heap + optional WT ceiling + observed other RSS + 1GiB headroom, and prints OK/TIGHT/AT RISK verdict, UTC timestamp, Dynatrace OneAgent note when detected, and rerun-under-load reminder.
Diagnostics integration
deploy/docker/fs/opt/appsmith/diagnostics.sh
Invokes memory-analysis.sh --threads, redirects stdout+stderr into "$tmpdir/memory-analysis.txt", and ignores errors (`

Sequence Diagram(s)

sequenceDiagram
  participant Diagnostics as diagnostics.sh
  participant MemoryScript as memory-analysis.sh
  participant CGroupFS as cgroupFS
  participant JCmd as jcmd
  participant MongoClient as mongosh/mongo

  Diagnostics->>MemoryScript: run --threads, capture output
  MemoryScript->>CGroupFS: read memory limits/usage or /proc/meminfo
  MemoryScript->>JCmd: jcmd (GC, Thread.print) [optional]
  MemoryScript->>MongoClient: query wiredTiger.cache via APPSMITH_DB_URL [optional]
  MemoryScript->>Diagnostics: emit snapshot, verdict, exit 0
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🧭 A script that listens to heaps and threads,
Counts caches, caps, and memory treads,
It probes the JVM, peeks Mongo’s cache,
Writes a verdict, then exits with a dash—
Diagnostics keep singing while it treads.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description covers the summary, usage examples, and test plan comprehensively. However, it lacks the required elements from the template: no issue link/number, no Automation section with /ok-to-test tags, no Communication checkbox about DevRel/Marketing notification. Add issue reference (Fixes #XXXXX), include /ok-to-test tags in Automation section, and mark the Communication checkbox to indicate whether DevRel/Marketing should be notified.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely describes the main change: adding memory-analysis.sh for sizing diagnostics. It is specific, actionable, and reflects the primary contribution.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ww-memory-analysis-script

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
Copy Markdown
Contributor

@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 (2)
deploy/docker/fs/opt/appsmith/memory-analysis.sh (2)

33-49: 💤 Low value

Argument parsing is forgiving to a fault.

Two small ergonomics gaps:

  • Unknown flags fall through silently (no *) arm), so a typo like --no-mongoo looks accepted but does nothing.
  • --threads-sample=0 keeps WITH_THREADS=1 while leaving SAMPLE_SECS=0, which quietly disables stuck-thread sampling but still runs the single-snapshot section. Treating 0 like any other sub-3 value (clamp to 3) would match the documented "3-60s" contract.
🛠 Proposed fix
     --threads-sample=*)    WITH_THREADS=1; SAMPLE_SECS="${arg#*=}" ;;
     -h|--help)
       sed -n '2,24p' "$0"; exit 0 ;;
+    *)
+      echo "memory-analysis.sh: unknown argument '$arg' (try --help)" >&2
+      exit 2 ;;
   esac
 done
 # Clamp sample window to a sane range.
 if [[ "$SAMPLE_SECS" =~ ^[0-9]+$ ]]; then
-  [[ "$SAMPLE_SECS" -gt 0 && "$SAMPLE_SECS" -lt 3 ]] && SAMPLE_SECS=3
+  [[ "$SAMPLE_SECS" -lt 3 ]] && SAMPLE_SECS=3
   [[ "$SAMPLE_SECS" -gt 60 ]] && SAMPLE_SECS=60
 else
   SAMPLE_SECS=10
 fi
🤖 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 `@deploy/docker/fs/opt/appsmith/memory-analysis.sh` around lines 33 - 49, Add a
default case to the argument-parsing case block to detect unknown flags and fail
or warn (e.g., a *) arm that prints usage and exits or sets an error flag, so
typos like --no-mongoo don't silently pass; also tighten the SAMPLE_SECS clamp
logic used with WITH_THREADS so that values of 0 are treated as below the
minimum (i.e., treat any numeric SAMPLE_SECS < 3 as SAMPLE_SECS=3 and still set
WITH_THREADS=1) by changing the numeric checks around SAMPLE_SECS, referencing
the existing variables/constructs SKIP_MONGO, WITH_THREADS, SAMPLE_SECS and the
case "$arg" in parsing logic to locate and update the behavior.

494-512: ⚡ Quick win

Add a short server-selection timeout on the WT cache probe.

mongosh/mongo defaults to ~30s server-selection. When APPSMITH_DB_URL points at an unreachable external host, this section (and diagnostics.sh by extension) will pause for the full timeout before falling through. Adding serverSelectionTimeoutMS=5000&connectTimeoutMS=5000 to the connection URL keeps the probe fast and predictable.

🛠 Proposed fix
-  url="${url:-mongodb://localhost:27017/appsmith?replicaSet=mr1}"
+  url="${url:-mongodb://localhost:27017/appsmith?replicaSet=mr1}"
+  # Keep the probe snappy when an external Mongo is unreachable.
+  if [[ "$url" == *\?* ]]; then
+    probe_url="${url}&serverSelectionTimeoutMS=5000&connectTimeoutMS=5000"
+  else
+    probe_url="${url}?serverSelectionTimeoutMS=5000&connectTimeoutMS=5000"
+  fi
   # Hide creds when echoing
-  safe_url=$(sed -E 's#(mongodb(\+srv)?://)[^@/]+@#\1***:***@#' <<<"$url")
+  safe_url=$(sed -E 's#(mongodb(\+srv)?://)[^@/]+@#\1***:***@#' <<<"$probe_url")
   echo "  URL:        $safe_url  (via $mclient)"
   js='var s=db.serverStatus().wiredTiger.cache;
 print("WT_MAX="+s["maximum bytes configured"]);
 print("WT_USED="+s["bytes currently in the cache"]);'
-  out=$("$mclient" --quiet "$url" --eval "$js" 2>&1 || true)
+  out=$("$mclient" --quiet "$probe_url" --eval "$js" 2>&1 || 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 `@deploy/docker/fs/opt/appsmith/memory-analysis.sh` around lines 494 - 512, The
WT cache probe can hang on default 30s server-selection; update the probe to add
a short server-selection and connect timeout by passing
serverSelectionTimeoutMS=5000&connectTimeoutMS=5000 to the Mongo URL used for
the probe: when building the probe invocation that uses js and calls
out=$("$mclient" --quiet "$url" --eval "$js" ...), construct a probe-specific
URL (e.g. probe_url from url) that appends the query params (taking care of
existing query string separator ? vs &) and use probe_url in the mclient call so
wt_max_bytes/wt_used_bytes parsing remains unchanged but the probe completes
quickly on unreachable hosts.
🤖 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 `@deploy/docker/fs/opt/appsmith/memory-analysis.sh`:
- Around line 422-428: The sed substitution never matches because it expects the
pool suffix at EOL instead of before the tab-separated frame; update the sed in
the pipeline that processes "$stuck" so it strips the "-N[-M]" suffix only on
the name field before the tab—for example change the sed expression used in the
pipe (the line starting with: echo "$stuck" | sed -E ...) to match the suffix
followed by a tab and replace it with the name plus the tab (e.g. use a pattern
like 's/^([^\t]+)-[0-9]+(-[0-9]+)*\t/\1\t/' so pool-1, pool-2 collapse into a
single name for grouping).

---

Nitpick comments:
In `@deploy/docker/fs/opt/appsmith/memory-analysis.sh`:
- Around line 33-49: Add a default case to the argument-parsing case block to
detect unknown flags and fail or warn (e.g., a *) arm that prints usage and
exits or sets an error flag, so typos like --no-mongoo don't silently pass; also
tighten the SAMPLE_SECS clamp logic used with WITH_THREADS so that values of 0
are treated as below the minimum (i.e., treat any numeric SAMPLE_SECS < 3 as
SAMPLE_SECS=3 and still set WITH_THREADS=1) by changing the numeric checks
around SAMPLE_SECS, referencing the existing variables/constructs SKIP_MONGO,
WITH_THREADS, SAMPLE_SECS and the case "$arg" in parsing logic to locate and
update the behavior.
- Around line 494-512: The WT cache probe can hang on default 30s
server-selection; update the probe to add a short server-selection and connect
timeout by passing serverSelectionTimeoutMS=5000&connectTimeoutMS=5000 to the
Mongo URL used for the probe: when building the probe invocation that uses js
and calls out=$("$mclient" --quiet "$url" --eval "$js" ...), construct a
probe-specific URL (e.g. probe_url from url) that appends the query params
(taking care of existing query string separator ? vs &) and use probe_url in the
mclient call so wt_max_bytes/wt_used_bytes parsing remains unchanged but the
probe completes quickly on unreachable hosts.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5d1a7adf-9441-4ba6-bfd8-a2d70d28addb

📥 Commits

Reviewing files that changed from the base of the PR and between d75495a and 54d5ad1.

📒 Files selected for processing (2)
  • deploy/docker/fs/opt/appsmith/diagnostics.sh
  • deploy/docker/fs/opt/appsmith/memory-analysis.sh

Comment thread deploy/docker/fs/opt/appsmith/memory-analysis.sh
The pattern `(-[0-9]+(-[0-9]+)*)$` never matched because the suffix it's
stripping lives between the thread name and the top frame (separated by
a tab), not at end-of-line. Result: pool members like boundedElastic-1,
boundedElastic-2 never collapsed into a single grouping row.

Anchor on \t instead so the trailing -N(-M)* is stripped from the name
field before the tab.
Copy link
Copy Markdown
Contributor

@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: 2

🧹 Nitpick comments (2)
deploy/docker/fs/opt/appsmith/memory-analysis.sh (2)

33-42: 💤 Low value

Unknown flags are silently swallowed.

The case block has no default arm, so a typo like --threds is accepted, parsed as a no-op, and the report runs in default mode — making it easy to think you enabled sampling when you didn't. A one-liner default arm with a friendly hint (and still exit 0 to honor the "always succeed" contract) goes a long way:

🛠 Suggested guard
     --threads-sample=*)    WITH_THREADS=1; SAMPLE_SECS="${arg#*=}" ;;
     -h|--help)
       sed -n '2,24p' "$0"; exit 0 ;;
+    *)
+      echo "memory-analysis.sh: unknown option '$arg' — see --help" >&2 ;;
   esac
🤖 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 `@deploy/docker/fs/opt/appsmith/memory-analysis.sh` around lines 33 - 42, The
case block that parses arguments in memory-analysis.sh currently swallows
unknown flags (so typos like --threds are ignored); add a default (*) case to
that case statement which prints a friendly hint mentioning the unrecognized
flag and usage (e.g., echo "Unknown option: $arg — see --help"), and then exit 0
to preserve the script's "always succeed" behavior; ensure this default arm is
placed alongside the existing arms that set SKIP_MONGO, WITH_THREADS, and
SAMPLE_SECS so typos to those flags are detected and reported.

149-189: 💤 Low value

role_n is populated but never read — dead bookkeeping.

role_n[$role]=$n is set on line 180 and never consulted anywhere else in the script (the per-row count is printed inline as n=%d on line 182). Shellcheck's SC2034 is correct here; the role_pattern_* warnings are false positives because of the indirect ${!var} expansion. Drop the array and its declare if you'd like to keep the file quiet under linters:

🧹 Suggested cleanup
 declare -A role_kb
-declare -A role_n
 declare -a role_order=(java rts mongod postgres redis keycloak temporal caddy supervisord)
@@
   kb=$(sum_rss_kb "$pat")
   n=$(count_procs "$pat")
   role_kb[$role]=$kb
-  role_n[$role]=$n
   if [[ "$kb" -gt 0 ]]; then
🤖 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 `@deploy/docker/fs/opt/appsmith/memory-analysis.sh` around lines 149 - 189, The
role_n associative array is unused (populated via role_n[$role]=$n) and triggers
ShellCheck SC2034; remove the dead bookkeeping by deleting the declare -A role_n
line and the assignment role_n[$role]=$n, and keep printing the per-row count
using the existing n variable (from count_procs "$pat") so functionality and the
inline printf 'n=%d' remain unchanged; references to role_n, declare -A role_n,
role_n[$role]=$n, and count_procs appear in this loop.
🤖 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 `@deploy/docker/fs/opt/appsmith/memory-analysis.sh`:
- Around line 33-49: The --threads-sample parsing currently sets WITH_THREADS=1
and assigns SAMPLE_SECS before validation which lets values like 0 or negatives
disable sampling silently; change the handling so that when parsing
--threads-sample=* you validate SAMPLE_SECS immediately: if it is not an
integer, set SAMPLE_SECS=10; if it is an integer and SAMPLE_SECS < 3 (including
0 or negatives) set SAMPLE_SECS=3; if > 60 set SAMPLE_SECS=60; KEEP
WITH_THREADS=1 for any --threads-sample invocation so the flag's intent is
honored and the later stall/stack sampling code (which checks SAMPLE_SECS and
WITH_THREADS) behaves predictably.
- Line 200: The pgrep call that sets java_pid uses a PCRE-style escape `\s*`
which POSIX ERE doesn't support, so update the pgrep -f pattern used to find the
java process (the line assigning java_pid) to use a POSIX-compliant whitespace
class or literal space, e.g. replace `-jar\s*server\.jar` with a pattern using
`[[:space:]]*` or a single space (e.g. `-jar[[:space:]]*server\.jar` or `-jar
server\.jar`) so the process lookup reliably matches the java -jar server.jar
invocation.

---

Nitpick comments:
In `@deploy/docker/fs/opt/appsmith/memory-analysis.sh`:
- Around line 33-42: The case block that parses arguments in memory-analysis.sh
currently swallows unknown flags (so typos like --threds are ignored); add a
default (*) case to that case statement which prints a friendly hint mentioning
the unrecognized flag and usage (e.g., echo "Unknown option: $arg — see
--help"), and then exit 0 to preserve the script's "always succeed" behavior;
ensure this default arm is placed alongside the existing arms that set
SKIP_MONGO, WITH_THREADS, and SAMPLE_SECS so typos to those flags are detected
and reported.
- Around line 149-189: The role_n associative array is unused (populated via
role_n[$role]=$n) and triggers ShellCheck SC2034; remove the dead bookkeeping by
deleting the declare -A role_n line and the assignment role_n[$role]=$n, and
keep printing the per-row count using the existing n variable (from count_procs
"$pat") so functionality and the inline printf 'n=%d' remain unchanged;
references to role_n, declare -A role_n, role_n[$role]=$n, and count_procs
appear in this loop.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 43eb5e80-1e9c-4ebc-9e31-775a726ded2c

📥 Commits

Reviewing files that changed from the base of the PR and between 54d5ad1 and 6b9815d.

📒 Files selected for processing (1)
  • deploy/docker/fs/opt/appsmith/memory-analysis.sh

Comment thread deploy/docker/fs/opt/appsmith/memory-analysis.sh
# ---------- 3. JVM ----------------------------------------------------------

hdr "JVM (Appsmith server)"
java_pid=$(pgrep -f -- "-jar\s*server\.jar" | head -1 || true)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does pgrep from procps-ng support \s as a whitespace shorthand in its regex, or does it only support POSIX extended regular expressions?

💡 Result:

pgrep from procps-ng supports only POSIX Extended Regular Expressions (ERE), not Perl-compatible shorthands like \s for whitespace. It uses the standard regcomp function with the REG_EXTENDED flag, which implements POSIX ERE where \s is not defined.[1][2][3][4] POSIX ERE lacks \s; use [[:space:]] instead for whitespace matching.[4][5] No evidence of PCRE or extended regex support in procps-ng pgrep source code or documentation.[6][7]

Citations:


🏁 Script executed:

#!/bin/bash

# Test pgrep behavior with \s vs [[:space:]]
# Simulate the Java process running appsmith server

# Create test scenarios
echo "=== Testing pgrep patterns ==="

# Test 1: Check if pgrep is available and test with a sample command
if command -v pgrep &> /dev/null; then
  # Create a test process by running a background command that matches the pattern
  # Simulate: java -jar /opt/appsmith/server/server.jar
  bash -c 'sleep 300 &' &
  
  # Get the PID for testing
  TEST_PID=$!
  
  echo "Test with typical Java command format: java -jar /opt/appsmith/server/server.jar"
  
  # Test pattern 1: Original pattern with \s
  echo -e "\nPattern 1 (with \\s): -jar\\s*server\\.jar"
  pgrep -f -- "-jar\s*server\.jar" 2>&1 || echo "No match found"
  
  # Test pattern 2: Corrected pattern with [[:space:]]
  echo -e "\nPattern 2 (with [[:space:]]): -jar[[:space:]]+server\\.jar"
  pgrep -f -- "-jar[[:space:]]+server\.jar" 2>&1 || echo "No match found"
  
  # Clean up
  kill $TEST_PID 2>/dev/null
else
  echo "pgrep not available"
fi

# Test 2: Check procps-ng source to understand \s handling
echo -e "\n=== Checking regex handling in procps-ng ==="

# Let's look at the pgrep man page for regex information
if command -v man &> /dev/null; then
  man pgrep 2>/dev/null | grep -A 10 "regex\|expression" | head -20
fi

Repository: appsmithorg/appsmith

Length of output: 161


🏁 Script executed:

#!/bin/bash

# Find and examine the memory-analysis.sh file
find . -name "memory-analysis.sh" -type f 2>/dev/null | head -5

# If found, check the specific line context
if [ -f "deploy/docker/fs/opt/appsmith/memory-analysis.sh" ]; then
  echo "=== File found. Examining lines around 200 ==="
  sed -n '195,205p' deploy/docker/fs/opt/appsmith/memory-analysis.sh | cat -n
fi

Repository: appsmithorg/appsmith

Length of output: 749


pgrep -f regex pattern uses \s, which isn't recognized in POSIX ERE — server.jar discovery will fail.

pgrep from procps-ng uses POSIX extended regex (via regcomp(3) with REG_EXTENDED), where \s is not a valid escape sequence. The pattern -jar\s*server\.jar will be interpreted as literal -jar followed by the character s repeated zero or more times, then server.jar. This won't match the actual command line format java … -jar /opt/appsmith/server/server.jar (with a space between -jar and the path), causing the process lookup to fail and the entire JVM section to be skipped.

Fix — use POSIX-compliant whitespace class
-java_pid=$(pgrep -f -- "-jar\s*server\.jar" | head -1 || true)
+java_pid=$(pgrep -f -- "-jar[[:space:]]+server\.jar" | head -1 || true)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
java_pid=$(pgrep -f -- "-jar\s*server\.jar" | head -1 || true)
java_pid=$(pgrep -f -- "-jar[[:space:]]+server\.jar" | head -1 || 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 `@deploy/docker/fs/opt/appsmith/memory-analysis.sh` at line 200, The pgrep call
that sets java_pid uses a PCRE-style escape `\s*` which POSIX ERE doesn't
support, so update the pgrep -f pattern used to find the java process (the line
assigning java_pid) to use a POSIX-compliant whitespace class or literal space,
e.g. replace `-jar\s*server\.jar` with a pattern using `[[:space:]]*` or a
single space (e.g. `-jar[[:space:]]*server\.jar` or `-jar server\.jar`) so the
process lookup reliably matches the java -jar server.jar invocation.

Previous clamp only nudged 1/2 up to 3, leaving 0 untouched. A user
passing --threads-sample=0 then got WITH_THREADS=1 with SAMPLE_SECS=0,
which silently skipped the sampling section while still printing the
basic threads view. Honor the flag's intent by clamping any in-range
integer below 3 up to 3.
Copy link
Copy Markdown
Contributor

@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: 2

♻️ Duplicate comments (1)
deploy/docker/fs/opt/appsmith/memory-analysis.sh (1)

200-200: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use a POSIX ERE here or JVM discovery can disappear.

Line 200 still uses \s, which pgrep does not treat as whitespace. On procps-based images this can miss the Appsmith JVM entirely, and the JVM section, thread diagnostics, and /proc/<pid>/environ Mongo URL lookup all degrade silently.

💡 Minimal fix
-java_pid=$(pgrep -f -- "-jar\s*server\.jar" | head -1 || true)
+java_pid=$(pgrep -f -- "-jar[[:space:]]+(/opt/appsmith/server/)?server\.jar" | head -1 || 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 `@deploy/docker/fs/opt/appsmith/memory-analysis.sh` at line 200, The pgrep
pattern used to set java_pid currently relies on the Perl-style \s which pgrep
doesn't recognize; update the pgrep invocation that assigns java_pid to use a
POSIX ERE whitespace class (e.g., replace \s with [[:space:]] or an equivalent
POSIX ERE) so the "-jar ... server.jar" match reliably finds the JVM on
procps-based images; adjust only the pattern used where java_pid is defined to
ensure downstream JVM diagnostics and /proc/<pid>/environ-based Mongo lookup
work.
🤖 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 `@deploy/docker/fs/opt/appsmith/memory-analysis.sh`:
- Around line 32-49: The problem is SAMPLE_SECS is defaulted to 0 but the
numeric clamping unconditionally raises any numeric value to >=3, so invoking
--threads (which sets WITH_THREADS but leaves SAMPLE_SECS as 0) ends up treated
as a 3s sample; update the clamp logic so it only enforces the 3–60 bounds when
SAMPLE_SECS is a non-zero numeric value. Concretely, change the block that tests
SAMPLE_SECS (the existing regex check and subsequent [[ "$SAMPLE_SECS" -lt 3 ]]
and -gt 60 checks) to first verify SAMPLE_SECS is numeric and not equal to 0
(e.g., if [[ "$SAMPLE_SECS" =~ ^[0-9]+$ && "$SAMPLE_SECS" -ne 0 ]]; then apply
the min/max clamps; else set SAMPLE_SECS=0 or the current default for
non-numeric flags), so --threads (WITH_THREADS) leaves SAMPLE_SECS at 0 while
--threads-sample still sets and clamps its explicit value.
- Around line 494-511: The script currently redacts credentials for the
connection URL into safe_url but later prints raw mongosh/mongo client output
stored in out (from "$mclient" --eval ...), which may contain the full URI;
modify the code that prints the probe failure line to sanitize out first using
the same redaction regex (for example apply sed -E
's#(mongodb(\+srv)?://)[^@/]+@#\1***:***@#' to $out) and then echo the sanitized
variable (e.g. safe_out) instead of raw $out when building the "(probe failed) —
..." message; update references to out in this block only so other logic
(wt_max_bytes parsing) still operates on the original out if needed.

---

Duplicate comments:
In `@deploy/docker/fs/opt/appsmith/memory-analysis.sh`:
- Line 200: The pgrep pattern used to set java_pid currently relies on the
Perl-style \s which pgrep doesn't recognize; update the pgrep invocation that
assigns java_pid to use a POSIX ERE whitespace class (e.g., replace \s with
[[:space:]] or an equivalent POSIX ERE) so the "-jar ... server.jar" match
reliably finds the JVM on procps-based images; adjust only the pattern used
where java_pid is defined to ensure downstream JVM diagnostics and
/proc/<pid>/environ-based Mongo lookup work.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a98a8a8b-ec58-4c9d-adcf-9c39770ddf68

📥 Commits

Reviewing files that changed from the base of the PR and between 6b9815d and 2fd6ea6.

📒 Files selected for processing (1)
  • deploy/docker/fs/opt/appsmith/memory-analysis.sh

Comment thread deploy/docker/fs/opt/appsmith/memory-analysis.sh
Comment thread deploy/docker/fs/opt/appsmith/memory-analysis.sh Outdated
…rors

Two issues caught by review:

1. Last commit's unconditional <3 clamp regressed --threads by clamping
   the default SAMPLE_SECS=0 up to 3, which then triggered the stuck-
   thread sampling section. Introduce WITH_THREAD_SAMPLE to distinguish
   "sampling explicitly requested" from "default value," and gate the
   clamp on it. Plain --threads now correctly leaves SAMPLE_SECS=0 and
   skips sampling.

2. The Mongo probe-failure line printed raw mongosh/mongo error output,
   which can include the connection string with credentials. Apply the
   same URI-redaction sed to a safe_out variable used only for display.
Copy link
Copy Markdown
Contributor

@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.

♻️ Duplicate comments (1)
deploy/docker/fs/opt/appsmith/memory-analysis.sh (1)

205-205: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use a POSIX-compliant pgrep pattern for the JVM lookup.

Line 205 uses \s, which pgrep -f does not treat as whitespace, and it also requires server.jar to appear immediately after -jar. That can miss a normal -jar /path/to/server.jar argv and skip the entire JVM section.

Suggested fix
-java_pid=$(pgrep -f -- "-jar\s*server\.jar" | head -1 || true)
+java_pid=$(pgrep -f -- "-jar[[:space:]]+.*server\.jar" | head -1 || true)
#!/bin/bash
set -u

bash -c 'exec -a "java -jar /opt/appsmith/server/server.jar" sleep 20' &
pid=$!
trap 'kill "$pid" 2>/dev/null || true' EXIT
sleep 1

echo "argv:"
ps -p "$pid" -o args=

echo
echo "Current pattern match?"
if pgrep -f -- '-jar\s*server\.jar' | grep -qx "$pid"; then
  echo "matched"
else
  echo "not matched"
fi

echo
echo "POSIX-compliant pattern match?"
if pgrep -f -- '-jar[[:space:]]+.*server\.jar' | grep -qx "$pid"; then
  echo "matched"
else
  echo "not matched"
fi
🤖 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 `@deploy/docker/fs/opt/appsmith/memory-analysis.sh` at line 205, The pgrep
pattern used to set java_pid (pgrep -f -- "-jar\s*server\.jar") is not
POSIX-compliant and misses cases like "-jar /path/to/server.jar"; update the
pattern used in the java_pid assignment to a POSIX-compatible regex such as
'-jar[[:space:]]+.*server\.jar' so pgrep -f matches a -jar followed by
whitespace and any path to server.jar; modify the java_pid line (the pgrep
invocation that sets java_pid) to use this new pattern and ensure the pattern is
quoted.
🤖 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.

Duplicate comments:
In `@deploy/docker/fs/opt/appsmith/memory-analysis.sh`:
- Line 205: The pgrep pattern used to set java_pid (pgrep -f --
"-jar\s*server\.jar") is not POSIX-compliant and misses cases like "-jar
/path/to/server.jar"; update the pattern used in the java_pid assignment to a
POSIX-compatible regex such as '-jar[[:space:]]+.*server\.jar' so pgrep -f
matches a -jar followed by whitespace and any path to server.jar; modify the
java_pid line (the pgrep invocation that sets java_pid) to use this new pattern
and ensure the pattern is quoted.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b92b3996-636f-49e0-9c43-dbcbceb06a84

📥 Commits

Reviewing files that changed from the base of the PR and between 2fd6ea6 and 4055d63.

📒 Files selected for processing (1)
  • deploy/docker/fs/opt/appsmith/memory-analysis.sh

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