{"id":49284575,"url":"https://github.com/abasheger/stacklens","last_synced_at":"2026-04-25T21:00:43.503Z","repository":{"id":351159395,"uuid":"1178459920","full_name":"AbaSheger/stacklens","owner":"AbaSheger","description":"Offline Java CLI that analyzes Spring Boot logs and stack traces — detects 13   failure types, shows exact location (class + line), occurrence counts, and     severity. Pipe from kubectl or docker logs","archived":false,"fork":false,"pushed_at":"2026-04-25T19:02:18.000Z","size":1923,"stargazers_count":2,"open_issues_count":5,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-25T20:28:25.303Z","etag":null,"topics":["cli","debugging","developer-tools","devops","devtools","java","log-analysis","logging","open-source","spring-boot","stack-traces"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AbaSheger.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-11T03:28:30.000Z","updated_at":"2026-04-25T19:02:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"8a4fcecc-eaf9-4121-af36-5e2e1917522b","html_url":"https://github.com/AbaSheger/stacklens","commit_stats":null,"previous_names":["abasheger/stacklens"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/AbaSheger/stacklens","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbaSheger%2Fstacklens","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbaSheger%2Fstacklens/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbaSheger%2Fstacklens/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbaSheger%2Fstacklens/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AbaSheger","download_url":"https://codeload.github.com/AbaSheger/stacklens/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AbaSheger%2Fstacklens/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32276628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T18:29:39.964Z","status":"ssl_error","status_checked_at":"2026-04-25T18:29:32.149Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","debugging","developer-tools","devops","devtools","java","log-analysis","logging","open-source","spring-boot","stack-traces"],"created_at":"2026-04-25T21:00:24.607Z","updated_at":"2026-04-25T21:00:43.485Z","avatar_url":"https://github.com/AbaSheger.png","language":"Java","readme":"# StackLens\n\n\u003e Point it at a log. Know what's broken, where, and how to fix it — in seconds.\n\n[![CI](https://github.com/AbaSheger/stacklens/actions/workflows/ci.yml/badge.svg)](https://github.com/AbaSheger/stacklens/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Java 17+](https://img.shields.io/badge/Java-17%2B-blue.svg)](https://adoptium.net/)\n[![Version](https://img.shields.io/badge/version-1.2.0-blue.svg)](https://github.com/AbaSheger/stacklens/releases)\n\n![StackLens demo](docs/demo.gif)\n\n---\n\n```\n$ java -jar stacklens.jar analyze app.log\n\nStackLens Analysis Report — Source: app.log\n────────────────────────────────────────────────────────────\n✗ 3 issue type(s) detected  (73 total occurrences)\n  1 CRITICAL   1 ERROR   1 WARNING\n\n[CRITICAL]  Issue #1: SpringBeanFailure\n\n  Location:  UserServiceConfig.configure(UserServiceConfig.java:34)\n\n  Explanation:\n    Spring failed to start. A bean could not be created because a\n    required dependency is missing or misconfigured.\n\n  Suggested fixes:\n    1. Check the full startup log — the root cause is usually a few lines below\n    2. Ensure all @Component classes are in a package scanned by @SpringBootApplication\n    ...\n\n[ERROR]  Issue #2: NullPointerException  ×47\n\n  Location:  OrderService.createOrder(OrderService.java:42)\n  ...\n\n[WARNING]  Issue #3: TimeoutError  ×25\n\n  Location:  OrderRepository.findAll(OrderRepository.java:88)\n  ...\n```\n\n---\n\n## Why StackLens?\n\nYou open a production log. There are 800 lines. Somewhere in there is the reason your service went down at 3am.\n\nStackLens reads the log and tells you:\n\n| Without StackLens | With StackLens |\n|---|---|\n| Scroll through 800 lines | Instant summary |\n| Grep for exception names | Exact class + line number |\n| Google the error | Explanation + fixes inline |\n| No idea how often it happened | `NullPointerException ×47` |\n| Works per-request | Pipe `kubectl logs` straight in |\n\nIt's offline, dependency-free, and works with any Java or Spring Boot application.\n\n---\n\n## Features\n\n- Analyze log **files**, **paste stack traces**, or **pipe from stdin** (`kubectl logs`, `docker logs`)\n- Detects **13 common backend failure types** out of the box\n- **Severity levels**: CRITICAL / ERROR / WARNING so you know what to fix first\n- **Occurrence counting**: \"NullPointerException ×47\" tells you how bad it really is\n- **Stack trace context**: shows the first app-owned frame so you know exactly where to look\n- **`--summary` mode**: one-line-per-issue table for quick triage\n- Outputs **human-readable** or **JSON** format\n- **Exit codes** for scripting: `0` = clean, `2` = issues found\n- Extensible: add new detectors by implementing one interface\n\n### Detected Error Types\n\n| Severity | Error Type | Example Pattern |\n|---|---|---|\n| CRITICAL | `OutOfMemoryError` | `OutOfMemoryError: Java heap space` |\n| CRITICAL | `ThreadPoolExhaustion` | `RejectedExecutionException: Task rejected` |\n| CRITICAL | `StackOverflowError` | `java.lang.StackOverflowError` |\n| CRITICAL | `SpringBeanFailure` | `NoSuchBeanDefinitionException`, `BeanCreationException` |\n| ERROR | `NullPointerException` | `java.lang.NullPointerException at ...` |\n| ERROR | `DatabaseConnectionFailure` | `Unable to acquire JDBC Connection` |\n| ERROR | `ConnectionRefused` | `Connection refused: localhost:8080` |\n| ERROR | `LazyInitializationException` | `could not initialize proxy - no Session` |\n| ERROR | `ClassCastException` | `cannot be cast to` |\n| ERROR | `ConcurrentModificationException` | `java.util.ConcurrentModificationException` |\n| ERROR | `Http500InternalServerError` | `500 Internal Server Error` |\n| WARNING | `TimeoutError` | `SocketTimeoutException: Read timed out` |\n| WARNING | `AuthenticationError` | `401 Unauthorized`, `Bad credentials`, `JWT expired` |\n\n---\n\n## Installation\n\n### Prerequisites\n\n- Java 17 or higher\n\n### Download (Recommended)\n\nDownload the latest pre-built JAR from the [Releases page](https://github.com/AbaSheger/stacklens/releases/latest).\n\n**Linux/macOS:**\n```bash\ncurl -L https://github.com/AbaSheger/stacklens/releases/latest/download/stacklens.jar -o stacklens.jar\njava -jar stacklens.jar analyze app.log\n```\n\n**Windows PowerShell:**\n```powershell\nInvoke-WebRequest https://github.com/AbaSheger/stacklens/releases/latest/download/stacklens.jar -OutFile stacklens.jar\njava -jar stacklens.jar analyze app.log\n```\n\n### Build from Source\n\n```bash\ngit clone https://github.com/AbaSheger/stacklens.git\ncd stacklens\nmvn clean package -DskipTests\n```\n\nThis produces `target/stacklens.jar`.\n\n### Create a Shell Alias (Optional)\n\nFor convenience, add this to your `~/.bashrc` or `~/.zshrc`:\n\n```bash\nalias stacklens='java -jar /path/to/stacklens.jar'\n```\n\nThen reload your shell:\n\n```bash\nsource ~/.bashrc\n```\n\n---\n\n## Usage\n\n### Analyze a log file\n\n```bash\njava -jar stacklens.jar analyze app.log\n```\n\n### Analyze an inline stack trace\n\n```bash\njava -jar stacklens.jar analyze --text \"java.lang.NullPointerException at OrderService.java:42\"\n```\n\n### Pipe from stdin (kubectl, docker, etc.)\n\n```bash\nkubectl logs my-pod | java -jar stacklens.jar analyze -\ndocker logs my-container | java -jar stacklens.jar analyze -\n```\n\n### Quick summary table\n\n```bash\njava -jar stacklens.jar analyze app.log --summary\n```\n\n### Output as JSON\n\n```bash\njava -jar stacklens.jar analyze app.log --output json\n```\n\n### Disable ANSI colors (for CI or log files)\n\n```bash\njava -jar stacklens.jar analyze app.log --no-color\n```\n\n### Get help\n\n```bash\njava -jar stacklens.jar --help\njava -jar stacklens.jar analyze --help\n```\n\n---\n\n## Example Output\n\n### Human-Readable\n\n```\nStackLens Analysis Report\nSource: samples/sample-npe.log\n────────────────────────────────────────────────────────────\n\n✗ 1 issue type(s) detected (1 total occurrence(s))\n  1 ERROR\n\n────────────────────────────────────────────────────────────\n[ERROR]  Issue #1: NullPointerException\n\nLocation:\n  OrderService.createOrder(OrderService.java:42)\n\nDetected in:\n  java.lang.NullPointerException: Cannot invoke \"com.example.User.getEmail()\" because \"user\" is null\n  at com.example.OrderService.createOrder(OrderService.java:42)\n  at com.example.OrderController.createOrder(OrderController.java:28)\n  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n  ... 2 more frame(s)\n\nExplanation:\n  A null object reference was accessed. This happens when code calls a\n  method or accesses a field on an object that has not been initialized\n  (is null).\n\nSuggested fixes:\n  1. Ensure all objects are properly initialized before use\n  2. Add null checks before accessing object fields or methods\n  3. Use Optional\u003cT\u003e to express that a value may be absent\n  4. Validate method parameters at the start of each method\n  5. Check if a dependency injection (e.g. @Autowired) is missing or failed\n```\n\n### Summary Mode (`--summary`)\n\n```\nStackLens Summary — Source: app.log\n──────────────────────────────────────────────────────────────────────\n\n4 issue type(s)  •  73 total occurrence(s)\n\n[CRITICAL]     SpringBeanFailure                   ×1    —\n[CRITICAL]     ThreadPoolExhaustion                ×3    RequestDispatcher.dispatch(RequestDispatcher.java:88)\n[ERROR]        NullPointerException                ×47   OrderService.createOrder(OrderService.java:42)\n[WARNING]      TimeoutError                        ×22   OrderRepository.findAll(OrderRepository.java:33)\n```\n\n### JSON Output\n\n```json\n{\n  \"source\": \"samples/sample-npe.log\",\n  \"issueCount\": 1,\n  \"totalOccurrences\": 1,\n  \"issues\": [ {\n    \"issue\": \"NullPointerException\",\n    \"severity\": \"ERROR\",\n    \"occurrences\": 1,\n    \"location\": \"OrderService.createOrder(OrderService.java:42)\",\n    \"matchedLine\": \"java.lang.NullPointerException: ...\",\n    \"stackContext\": [\n      \"at com.example.OrderService.createOrder(OrderService.java:42)\",\n      \"at com.example.OrderController.createOrder(OrderController.java:28)\"\n    ],\n    \"explanation\": \"A null object reference was accessed...\",\n    \"suggestions\": [\n      \"Ensure all objects are properly initialized before use\",\n      \"Add null checks before accessing object fields or methods\"\n    ]\n  } ]\n}\n```\n\n### Clean Log\n\n```\nStackLens Analysis Report\nSource: samples/sample-healthy.log\n────────────────────────────────────────────────────────────\n\n✓ No known issues detected in the provided log.\n  The log looks clean, but always review warnings manually.\n```\n\n---\n\n## Exit Codes\n\nStackLens uses exit codes to support shell scripting:\n\n| Code | Meaning |\n|---|---|\n| `0` | No issues detected |\n| `1` | Error (file not found, invalid arguments) |\n| `2` | One or more issues detected |\n\n**Example: fail a CI build if issues are found:**\n\n```bash\njava -jar stacklens.jar analyze app.log || exit 1\n```\n\n---\n\n## Sample Log Files\n\nThe `samples/` directory contains log files you can use to try StackLens:\n\n| File | Contains |\n|---|---|\n| `sample-npe.log` | NullPointerException |\n| `sample-db-failure.log` | Database connection failure |\n| `sample-oom.log` | OutOfMemoryError |\n| `sample-mixed-errors.log` | Auth failure, timeout, thread pool exhaustion, HTTP 500 |\n| `sample-healthy.log` | Clean log (no errors) |\n\n```bash\njava -jar target/stacklens.jar analyze samples/sample-mixed-errors.log\n```\n\n---\n\n## Architecture\n\nStackLens follows a clean, layered architecture that makes it easy to extend:\n\n```\nCLI (picocli)\n    └── AnalyzeCommand\n            └── LogAnalyzer          (reads files / text, drives analysis)\n                    └── IssueClassifier   (applies all detectors to each line)\n                            └── IssueDetector (interface)\n                                    ├── NullPointerDetector\n                                    ├── DatabaseConnectionDetector\n                                    ├── TimeoutDetector\n                                    ├── ConnectionRefusedDetector\n                                    ├── OutOfMemoryDetector\n                                    ├── AuthenticationErrorDetector\n                                    ├── ThreadPoolExhaustionDetector\n                                    └── Http500Detector\n            └── HumanReadableFormatter / JsonFormatter\n```\n\n### Adding a New Detector\n\n1. Create a class implementing `IssueDetector`\n2. Register it in `IssueClassifier`\n\nThat's it. No other changes required. See [CONTRIBUTING.md](CONTRIBUTING.md) for a step-by-step guide.\n\n---\n\n## Project Structure\n\n```\nstacklens/\n├── src/\n│   ├── main/java/com/stacklens/\n│   │   ├── cli/           # CLI commands\n│   │   ├── analyzer/      # LogAnalyzer — entry point for analysis\n│   │   ├── classifier/    # IssueClassifier — orchestrates detectors\n│   │   ├── detector/      # One class per error type\n│   │   ├── model/         # Issue, AnalysisResult\n│   │   └── output/        # HumanReadableFormatter, JsonFormatter\n│   └── test/java/com/stacklens/\n│       ├── analyzer/      # LogAnalyzerTest\n│       ├── detector/      # Per-detector unit tests\n│       └── cli/           # CLI integration tests\n├── samples/               # Sample log files for manual testing\n├── docs/                  # Additional documentation\n├── .github/\n│   ├── workflows/ci.yml   # GitHub Actions CI\n│   └── ISSUE_TEMPLATE/    # Bug and feature request templates\n├── pom.xml\n├── README.md\n├── CONTRIBUTING.md\n├── CHANGELOG.md\n└── LICENSE\n```\n\n---\n\n## Running Tests\n\n```bash\nmvn test\n```\n\n---\n\n## Roadmap\n\n- [ ] **AI explanations** — use an LLM API to generate context-aware, code-specific explanations\n- [ ] **Spring Boot structured logs** — parse JSON log format from Logback\n- [ ] **Watch mode** — tail a log file and detect issues in real time\n- [ ] **Plugin system** — load custom detectors from external JARs\n- [ ] **HTML report** — generate a standalone HTML report file\n- [ ] **IntelliJ / VS Code plugin** — surface StackLens output inside the IDE\n\n---\n\n## Contributing\n\nContributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) to get started.\n\nThe most impactful contributions are **new error detectors**. If you've seen a common Java or Spring Boot error that StackLens doesn't detect yet, please add it!\n\n---\n\n## License\n\nStackLens is released under the [MIT License](LICENSE).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabasheger%2Fstacklens","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabasheger%2Fstacklens","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabasheger%2Fstacklens/lists"}