Skip to content

Commit

Permalink
CAMEL-21150: camel-jbang - Make tracer in standby as default (#15383)
Browse files Browse the repository at this point in the history
* CAMEL-21150: camel-jbang - Make tracer in standby as default
  • Loading branch information
davsclaus authored Sep 1, 2024
1 parent 6868630 commit 73c798e
Show file tree
Hide file tree
Showing 8 changed files with 290 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ public class TraceDevConsole extends AbstractDevConsole {
*/
public static final String ENABLED = "enabled";

/**
* Whether to dump trace messages
*/
public static final String DUMP = "dump";

private Queue<BacklogTracerEventMessage> queue;

public TraceDevConsole() {
Expand All @@ -67,24 +72,44 @@ protected void doInit() throws Exception {
protected String doCallText(Map<String, Object> options) {
StringBuilder sb = new StringBuilder();
String enabled = (String) options.get(ENABLED);
String dump = (String) options.get(DUMP);

BacklogTracer tracer = getCamelContext().getCamelContextExtension().getContextPlugin(BacklogTracer.class);
if (tracer != null) {
if ("true".equals(enabled)) {
tracer.setEnabled(true);
sb.append("Enabled: ").append(tracer.isEnabled()).append("\n");
} else if ("false".equals(enabled)) {
tracer.setEnabled(false);
sb.append("Enabled: ").append(tracer.isEnabled()).append("\n");
} else {
sb.append("Enabled: ").append(tracer.isEnabled()).append("\n");
if (dump != null) {
for (BacklogTracerEventMessage t : tracer.dumpAllTracedMessages()) {
addMessage(t);
}
for (BacklogTracerEventMessage t : queue) {
String json = t.toJSon(0);
sb.append(json).append("\n");
}
} else {
if ("true".equals(enabled)) {
tracer.setEnabled(true);
} else if ("false".equals(enabled)) {
tracer.setEnabled(false);
}
sb.append("Enabled: ").append(tracer.isEnabled()).append("\n");
sb.append("Standby: ").append(tracer.isStandby()).append("\n");
sb.append("Trace Counter: ").append(tracer.getTraceCounter()).append("\n");
sb.append("Backlog Size: ").append(tracer.getBacklogSize()).append("\n");
sb.append("Queue Size: ").append(tracer.getQueueSize()).append("\n");
sb.append("Remove On Dump: ").append(tracer.isRemoveOnDump()).append("\n");
if (tracer.getTraceFilter() != null) {
sb.append("Trace Filter: ").append(tracer.getTraceFilter()).append("\n");
}
if (tracer.getTracePattern() != null) {
sb.append("Trace Pattern: ").append(tracer.getTracePattern()).append("\n");
}
sb.append("Trace Rests: ").append(tracer.isTraceRests()).append("\n");
sb.append("Trace Templates: ").append(tracer.isTraceTemplates()).append("\n");
sb.append("Body Max Chars: ").append(tracer.getBodyMaxChars()).append("\n");
sb.append("Body Include Files: ").append(tracer.isBodyIncludeFiles()).append("\n");
sb.append("Body Include Streams: ").append(tracer.isBodyIncludeStreams()).append("\n");
sb.append("Include Exchange Properties: ").append(tracer.isIncludeExchangeProperties()).append("\n");
sb.append("Include Exchange Variables: ").append(tracer.isIncludeExchangeVariables()).append("\n");
sb.append("Include Exception: ").append(tracer.isIncludeException()).append("\n");
}
}

Expand All @@ -105,27 +130,47 @@ private void addMessage(BacklogTracerEventMessage message) {
protected JsonObject doCallJson(Map<String, Object> options) {
JsonObject root = new JsonObject();
String enabled = (String) options.get(ENABLED);
String dump = (String) options.get(DUMP);

BacklogTracer tracer = getCamelContext().getCamelContextExtension().getContextPlugin(BacklogTracer.class);
if (tracer != null) {
if ("true".equals(enabled)) {
tracer.setEnabled(true);
root.put("enabled", tracer.isEnabled());
} else if ("false".equals(enabled)) {
tracer.setEnabled(false);
root.put("enabled", tracer.isEnabled());
} else {
if (dump != null) {
for (BacklogTracerEventMessage t : tracer.dumpAllTracedMessages()) {
addMessage(t);
}

JsonArray arr = new JsonArray();
root.put("enabled", tracer.isEnabled());
root.put("traces", arr);
for (BacklogTracerEventMessage t : queue) {
JsonObject jo = (JsonObject) t.asJSon();
arr.add(jo);
}
} else {
if ("true".equals(enabled)) {
tracer.setEnabled(true);
} else if ("false".equals(enabled)) {
tracer.setEnabled(false);
}
root.put("enabled", tracer.isEnabled());
root.put("standby", tracer.isStandby());
root.put("counter", tracer.getTraceCounter());
root.put("backlogSize", tracer.getBacklogSize());
root.put("queueSize", tracer.getQueueSize());
root.put("removeOnDump", tracer.isRemoveOnDump());
if (tracer.getTraceFilter() != null) {
root.put("traceFilter", tracer.getTraceFilter());
}
if (tracer.getTracePattern() != null) {
root.put("tracePattern", tracer.getTracePattern());
}
root.put("traceRests", tracer.isTraceRests());
root.put("traceTemplates", tracer.isTraceTemplates());
root.put("bodyMaxChars", tracer.getBodyMaxChars());
root.put("bodyIncludeFiles", tracer.isBodyIncludeFiles());
root.put("bodyIncludeStreams", tracer.isBodyIncludeStreams());
root.put("includeExchangeProperties", tracer.isIncludeExchangeProperties());
root.put("includeExchangeVariables", tracer.isIncludeExchangeVariables());
root.put("includeException", tracer.isIncludeException());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ public static void configureMain(CamelContext camelContext, String profile, Main
}

if ("dev".equals(profile)) {
boolean standby = config.tracerConfig().isStandby();
if (!standby) {
// make tracing enabled (if not configured to be standby) and limit to not capture too much data
config.tracerConfig().withEnabled(true);
// make tracing at least standby so we can use it in dev-mode
boolean enabled = config.tracerConfig().isEnabled();
if (!enabled) {
config.tracerConfig().withStandby(true);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,10 +349,10 @@ public void testBacklogDebuggerRemoveBodyAndHeader() throws Exception {
assertNotNull(xml);
log.info(xml);

assertTrue(xml.contains("<body>[Body is null]</body>"), "Should not contain our body");
assertTrue(xml.contains("<toNode>bar</toNode>"), "Should contain bar node");
assertFalse(xml.contains("<header"), "Should not contain any headers");
assertFalse(xml.contains("<exchangeProperty key=\"food\""), "Should not contain exchange property 'food'");
assertTrue(xml.contains("<body></body>"), "Should not contain our body");

resetMocks();
mock.expectedMessageCount(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1102,7 +1102,11 @@ public static JsonObject dumpAsJSonObject(
}
String data = extractBodyForLogging(message, null, allowCachedStreams, allowStreams, allowFiles, maxChars);
if (data != null) {
jb.put("value", Jsoner.escape(data));
if ("[Body is null]".equals(data)) {
jb.put("value", null);
} else {
jb.put("value", Jsoner.escape(data));
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ performing these copies has increased from 4096 bytes to 16384 bytes (the defaul
The tracer (`BacklogTracer`) has changed the `backlogSize` default value from `1000` to `100`, and `maxBodySize` from `128kb` to `32kb`.
This reduces the amount of data captured and stored and helps reduce the tracing overhead.

=== camel-jbang

The `camel trace` command has changed to show tracing status (by default). To dump traced messages use `camel trace --action=dump`.

=== Deprecated Components

The following components that were marked as deprecated:
Expand Down
37 changes: 34 additions & 3 deletions docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1611,20 +1611,51 @@ command but only display message tracing information. This allows you to see eve
The `trace` command has many options and can be used to _filter_, _grep_ or output on different detail _levels`.
The _exchange id_ is logged (and grouped by colour), so you can use that to correlate the events, when traces are interleaved.

For example if an existing integration is running named chuck, you can trace it as follows:
The trace command will by default list the status of whether tracing is enabled or not in the integrations:

[source,bash]
----
camel trace chuck
camel trace
PID NAME AGE STATUS TOTAL QUEUE FILTER PATTERN
6911 chuck 5s Standby 0 0
----

Here we can see that the tracer is in standby mode, and you need to start the tracer before Camel will capture messages:

TIP: Camel 4.8 onwards has tracing in standby mode (when using dev profile). You can enable tracing on startup by setting the configuration `camel.trace.enabled=true` in `application.properties`.

[source,bash]
----
camel trace --action=start
----

You can also trace all running integrations
And if you run `camel trace` again you can see the tracer is started:

[source,bash]
----
camel trace
PID NAME AGE STATUS TOTAL QUEUE FILTER PATTERN
6911 chuck 1m5s Started 16 4
----

And to show the traces you need to use the `dump` action as follows:

[source,bash]
----
camel trace chuck --action=dump
----

You can also dump traces from all running integrations:

[source,bash]
----
camel trace --action=dump
----

To stop tracing use `--action=stop`.

And you can also clear the already traced messages with `--action=clear`.

==== Running Camel integrations in background

The `run` command allows to run Camel in the background with the `--background` option.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ protected void actionTask() {
doActionBeanTask(root);
} else if ("kafka".equals(action)) {
doActionKafkaTask();
} else if ("trace".equals(action)) {
doActionTraceTask(root);
}
} catch (Exception e) {
// ignore
Expand Down Expand Up @@ -733,6 +735,24 @@ private void doActionKafkaTask() throws IOException {
}
}

private void doActionTraceTask(JsonObject root) throws IOException {
DevConsole dc = camelContext.getCamelContextExtension().getContextPlugin(DevConsoleRegistry.class)
.resolveById("trace");
if (dc != null) {
String enabled = root.getString("enabled");
JsonObject json;
if (enabled != null) {
json = (JsonObject) dc.call(DevConsole.MediaType.JSON, Map.of("enabled", enabled));
} else {
json = (JsonObject) dc.call(DevConsole.MediaType.JSON);
}
LOG.trace("Updating output file: {}", outputFile);
IOHelper.writeText(json.toJson(), outputFile);
} else {
IOHelper.writeText("{}", outputFile);
}
}

private void doActionBeanTask(JsonObject root) throws IOException {
String filter = root.getStringOrDefault("filter", "");
String properties = root.getStringOrDefault("properties", "true");
Expand Down Expand Up @@ -977,13 +997,20 @@ protected void statusTask() {
root.put("fault-tolerance", json);
}
}
DevConsole dc12a = dcr.resolveById("circuit-breaker");
if (dc12a != null) {
JsonObject json = (JsonObject) dc12a.call(DevConsole.MediaType.JSON);
DevConsole dc12 = dcr.resolveById("circuit-breaker");
if (dc12 != null) {
JsonObject json = (JsonObject) dc12.call(DevConsole.MediaType.JSON);
if (json != null && !json.isEmpty()) {
root.put("circuit-breaker", json);
}
}
DevConsole dc13 = dcr.resolveById("trace");
if (dc13 != null) {
JsonObject json = (JsonObject) dc13.call(DevConsole.MediaType.JSON);
if (json != null && !json.isEmpty()) {
root.put("trace", json);
}
}
DevConsole dc14 = dcr.resolveById("consumer");
if (dc14 != null) {
JsonObject json = (JsonObject) dc14.call(DevConsole.MediaType.JSON);
Expand Down Expand Up @@ -1069,7 +1096,7 @@ protected void traceTask() {
DevConsole dc12 = camelContext.getCamelContextExtension().getContextPlugin(DevConsoleRegistry.class)
.resolveById("trace");
if (dc12 != null) {
JsonObject json = (JsonObject) dc12.call(DevConsole.MediaType.JSON);
JsonObject json = (JsonObject) dc12.call(DevConsole.MediaType.JSON, Map.of("dump", "true"));
JsonArray arr = json.getCollection("traces");
// filter based on last uid
if (traceFilePos > 0) {
Expand Down
Loading

0 comments on commit 73c798e

Please sign in to comment.