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]

Reply via email to