Skip to content

Stop attaching a stack trace to every cleanup SQL statement - #1988

Merged
jcschaff merged 1 commit into
masterfrom
fix/1987-drop-cleanup-stacktrace
Aug 18, 2026
Merged

Stop attaching a stack trace to every cleanup SQL statement#1988
jcschaff merged 1 commit into
masterfrom
fix/1987-drop-cleanup-stacktrace

Conversation

@jcschaff

Copy link
Copy Markdown
Member

Closes #1987.

DbDriver.StackTraceGenerationException is an empty marker exception, constructed on purpose and handed to the logger so log4j prints a call stack next to the message. In DBBackupAndClean.executeUpdate that stack is invariant — the method is only ever reached from the cleanup thread through this one path — so it identified nothing the message and logger name did not.

It is not free. cbit.vcell.modeldb is at debug on the db container (docker/build/vcell-db.log4j.xml:25), so every statement the cleanup runs was logged with a full synthetic stack trace: ~948 lines/day on production, roughly a quarter of that container's 3823.

Before / after

Both forms logged side by side through a debug configuration:

---- OLD ----
DEBUG DBBackupAndClean - executeUpdate() SQL: 'DELETE FROM vc_simulation WHERE ...'
cbit.vcell.modeldb.DbDriver$StackTraceGenerationException
	at LogShape.main(LogShape.java:10)

---- NEW ----
DEBUG DBBackupAndClean - executeUpdate() SQL: 'DELETE FROM vc_simulation WHERE ...'

Same DEBUG line, same SQL, no stack trace. The visibility the debug level was presumably enabled for is kept.

Switched to a parameterized call, which also lets the isDebugEnabled() guard go — log4j2 does not build the string unless the level is on.

Deliberately narrow

The idiom appears 56 times in vcell-server, and they should not all be treated alike:

level count
lg.error 20 keep — fire on genuinely unexpected conditions such as changed != 1 after an update (DbDriver:3585), where the stack is the only thing identifying which of many call paths produced it
lg.trace 19 cost nothing while nothing enables trace
lg.debug 16 only this one is generating volume in a deployed configuration

One line changed, in the one place that is actually noisy.

🤖 Generated with Claude Code

DbDriver.StackTraceGenerationException is an empty marker exception, constructed on purpose
and handed to the logger so log4j prints a call stack next to the message. In
DBBackupAndClean.executeUpdate that stack is invariant -- the method is only ever reached from
the cleanup thread through this one path -- so it identified nothing the message and logger
name did not.

It is not free. cbit.vcell.modeldb is set to debug on the db container
(docker/build/vcell-db.log4j.xml:25), so every statement the database cleanup runs was logged
with a full synthetic stack trace: about 948 lines a day on production, roughly a quarter of
that container's 3823.

The message is unchanged, so the SQL visibility the debug level was presumably enabled for is
kept. Switched to a parameterized call, which also lets the isDebugEnabled() guard go -- log4j2
does not build the string unless the level is on.

Verified by logging both forms side by side through a debug configuration: same DEBUG line,
same SQL, no StackTraceGenerationException underneath it.

Deliberately narrow. The idiom appears 56 times in vcell-server: 20 at lg.error, 19 at
lg.trace, 16 at lg.debug. The lg.error ones are worth keeping -- they fire on genuinely
unexpected conditions such as changed != 1 after an update (DbDriver:3585), where the call
stack is the only thing that says which of many call paths produced it. The trace ones cost
nothing while nothing enables trace. Only this one is generating volume in a deployed
configuration.

Closes #1987

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jcschaff
jcschaff merged commit d9df68e into master Aug 18, 2026
9 checks passed
@jcschaff
jcschaff deleted the fix/1987-drop-cleanup-stacktrace branch August 18, 2026 05:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Database cleanup logs a synthetic stack trace per SQL statement — ~25% of prod's db container log

1 participant