davsclaus opened a new pull request, #28107: URL: https://github.com/apache/camel/pull/28107
[CAMEL-25784](https://issues.apache.org/jira/browse/CAMEL-25784): when an integration stopped, its log was gone. `camel run` deleted `~/.camel/<pid>.log` when the JVM ended, also when Camel failed to start. So nothing showed why an integration had stopped, and the next run had a new pid. In a benchmark of Oct 18-19 2026, an app died at startup after a restart in 4 of the first 6 runs of one example. Each look at its log then answered "No running Camel process matches". The model restarted the app three times and never saw the error. This PR is the CLI part. It follows `kubectl logs --previous` from Kubernetes. A second PR will make the AI tools use it. ## What - **`camel run` keeps its log when the run ends**, as `~/.camel/<name>-previous.log`, by the name of the integration (the name of its CamelContext). Next to it, `~/.camel/<name>-previous.json` says when and how the run ended: the pid, the directory, the start, the end, the exit code, and the error when it failed. This covers a failed start, `camel stop`, Ctrl+C and SIGTERM. - **The next run of that name that ends replaces both**, as Kubernetes keeps one previous log per container. Like Kubernetes, at most the last 10 MB of a log are kept. - **A process that was killed** (`kill -9`, or a JVM crash) leaves its `<pid>.log` behind. That log is kept under the name in its status file the next time a previous run is looked up, or an integration is run. A log left behind without a name is removed after a day. A log older than the previous run of its name is removed. - **`camel log <name> --previous`** prints the log. The first line, on stderr, says which run it was and how it ended: ``` $ camel log e2e-broken --previous The previous run of e2e-broken (pid 36811) ended at 2026-10-19 12:47:11 (12s ago) with exit code 70: Failed to create route: route1 ... 2026-10-19 12:47:11.498 INFO 36811 --- [ main] org.apache.camel.main.MainSupport : Apache Camel (JBang) 4.24.0-SNAPSHOT is starting ... ``` - `--tail`, `--since`, `--grep`, `--find` and `--startup` work as they do for a running integration. - A name finds a previous run as it finds a running integration: a prefix, `name!` for the exact name, or the pid the run had. A name that is the whole name of a previous run finds only that one. - **`camel log <name>` of an integration that is not running** says how its previous run ended: ``` ERROR: No running Camel integration matches: e2e-broken. camel log e2e-broken --previous prints the log of its previous run, which ended at 2026-10-19 12:47:11 (2s ago) with exit code 70: Failed to create route: route1 ... ``` - **`camel dirty`** does not count the files of a previous run, as they are kept on purpose. Which runs keep their log: - Only `camel run` on the command line, from `runKameletMain`, where Camel runs in the JVM of the CLI. - A Camel that another command runs in its own JVM (`camel cmd send --local`, `camel transform`, export) still removes its log, as before. - A `camel run` that starts the integration in another JVM (`--background`, `camel debug`, `--camel-version`) does not keep its own log. The other JVM keeps the log of the integration, which would otherwise be replaced by an almost empty one. - Not covered: the runtimes that run with Maven (`--runtime=spring-boot`, `quarkus` or `main`). They write their own `<name>.log` in five code paths, and each handles it differently. They can follow later. How the log is kept: - On macOS and Linux the log is moved, so the lines Camel logs while it stops still land in it. - When the move fails (Windows, while the file is open) or the log is over 10 MB, its end is copied, from the start of a line. - On Ctrl+C or SIGTERM the JVM exits while Camel stops. A shutdown hook gives the run up to 10 seconds to end and keep its log with the exit code, else it keeps the log without one. ## Tests - New `PreviousRunTest` (13): keep, replace, find by name, prefix, exact name and pid, the newest first, the end of a large log, the log of a killed process (kept, older than the previous run, without a name), the log of a running process, and the keeper (once, and as the JVM exits). - New `RunPreviousLogTest` (4): a failed start, a run without routes (kept by the name of its CamelContext), a stopped run, and a Camel of another command, which removes its log. - `CamelLogActionTest` (6 more) and `DirtyTest` (1 more). - All tests of camel-jbang-core pass (2329, 2 skipped, and 237). - End to end, with the camel launcher built from this branch, in a home directory of its own: a failed start (exit code 70), the hint, `kill -9` of an integration in the background, `camel stop`, SIGTERM of an integration in the foreground, and `camel dirty`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01STT6whBgK1AqsSsUKrnE8m -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
