Do I want this in production?
What Peekaboot changes while it is on, what it costs, and how to keep it out of a production build.
Peekaboot is built for one process on your own machine: the toolbar, the request’s trace, its queries and its logs, with no collector or backend to run. For anything across services or instances, use a tracing backend. Traces, limitations has the details.
When it is active
Peekaboot is on for a local run (IDE,
spring-boot:run, bootRun) and off for java -jar, wars, native images, containers and
tests. peekaboot.dev-toolbar, peekaboot.storage.enabled, peekaboot.error-page.enabled and
peekaboot.stack-trace.fold follow the same rule. peekaboot.security.enabled is the reverse:
on for a deployment launch, off for local runs and tests. An explicit value always wins.
Running your build output directly on a host that is not a container
(java -cp target/classes …) counts as a local run. Set peekaboot.enabled=false there.
With lifecycle summaries on (the default), the startup summary has a Peekaboot Dashboard:
line only while the dashboard is served.
What it changes while it is on
Everything Peekaboot sets sits below your own configuration, so a value you set wins.
| Change | Value | Applied when |
|---|---|---|
management.otlp.metrics.export.enabled |
false |
Always, even with Peekaboot off |
management.tracing.sampling.probability |
1.0: every request is sampled, for every exporter you have |
peekaboot.enabled, servlet application |
spring.jpa.properties.[hibernate.generate_statistics] |
true: Hibernate collects statistics |
peekaboot.enabled, servlet application |
management.info.env, .java, .os, .process.enabled |
true: /actuator/info carries that content if you expose it |
peekaboot.enabled, servlet application |
management.observations.annotations.enabled |
true: @Observed, @Timed and @Counted take effect |
peekaboot.enabled, servlet application |
| Handler and view spans | A span around each controller method and each rendered view, sent to every exporter | peekaboot.enabled, peekaboot.tracing.enabled |
| Async task spans | A span around each task a Spring task executor runs inside a trace, sent to every exporter. Turn off with peekaboot.tracing.async=false. |
peekaboot.enabled, peekaboot.tracing.enabled |
management.opentelemetry.tracing.export.schedule-delay |
200ms instead of 5s: spans reach every exporter about 25 times as often |
Dev toolbar on |
| HTML response buffering | text/html responses are buffered up to 2 MiB so the toolbar can be injected. Larger pages stream through without it. |
Dev toolbar on |
Server-Timing header |
Every response carries its trace id | Dev toolbar on |
| Log capture | A Logback appender receives every log event | Dev toolbar on |
An Actuator endpoint that keeps failing is logged once at WARN with its stack trace, then at
DEBUG. Peekaboot adds no /actuator exposure. See Security, Peekaboot leaves /actuator
alone and Configuration,
Spring Boot defaults Peekaboot
changes.
Memory
The trace store holds up to max-traces + max-error-traces + max-slow-traces traces
(1,000 + 100 + 100 at the defaults), each capped at max-spans-per-trace +
max-logs-per-trace entries (500 + 500). The worst case is about 1.2 million entries.
The Insights history is sized by peekaboot.insights.levels and by how many series the
enabled panels produce. Peekaboot logs the estimate at startup. See Insights, what it
costs.
To size either down, see Configuration, memory-constrained.
What it cannot do
- One process only. It does not join a request across services, aggregate across instances or alert.
- Short retention. The trace list keeps the latest 1,000 traces. Insights keeps 30 days at its default levels, and above the first level its percentiles are percentiles of aggregates.
- Minimal access control. Outside local development its fallback guard is HTTP Basic with one credential. It stands down for any request your own Spring Security chain has already authenticated. See Security, if nothing else secures it.
The starter is on the class path even when Peekaboot is off
With peekaboot.enabled=false the starter still brings:
spring-boot-starter-actuator. Spring Boot’s default exposure serves/actuatorand/actuator/healthover HTTP.- A
MeterRegistrywith Spring Boot’s JVM, system and Logback meters. - The OpenTelemetry SDK and OTLP exporters. Nothing is sent: metrics export is off (see the table above), and Spring Boot creates trace and log exporters only once you configure an endpoint.
- Peekaboot’s own jars, unused.
If that is not acceptable, keep the starter out of the artifact.
Running it on a shared server
Follow Security, running it on a shared or deployed server.
Keeping it out of the artifact entirely
Maven. Declare the starter in a profile that is active unless you build with
-Dproduction:
<profiles>
<profile>
<id>peekaboot</id>
<activation>
<property>
<name>!production</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>org.peekaboot</groupId>
<artifactId>peekaboot-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</profile>
</profiles>
Build the production artifact with mvn package -Dproduction. Your IDE and spring-boot:run
keep the starter.
Don’t use the Spring Boot Maven plugin’s <excludes> for this. It removes only the starter
jar, and Peekaboot’s auto-configuration jars still ship in the executable jar.
Gradle. Declare the starter developmentOnly instead of implementation. bootRun gets
it, and the executable jar does not:
developmentOnly("org.peekaboot:peekaboot-spring-boot-starter:1.0.0")