DBDelve
Dive deep into your data. A fast, native, multi-engine database client written in Rust. Free and open source, no telemetry.
Análise de thread dump JVM com IA: detecte deadlocks, CPU spikes, thread leaks e pinning de virtual threads (Loom). Nota A–F e causa raiz em segundos, sem instalar nada.
Translation pending
Developer toolsJava · ShellGitHub @maschiojvOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Anonymize JVM thread dumps locally before uploading to ThreadMine - deterministic HMAC tokenization, local-only vault, zero network code. Audit it yourself.
Translation pending
Loading the full README.
Read the full README ↗tm-anon)Anonymize a JVM thread dump on your own machine, before it goes anywhere.
tm-anon replaces your application's package, class, method and thread names
with deterministic pseudonyms, keeps everything an analyzer needs to work
(structure, JDK/framework frames, lock addresses, states, pool suffixes), and
stores the reverse mapping in a local vault file. You can then upload the masked
dump to an analysis service such as ThreadMine's online thread dump analyzer, and
run the analysis output back through tm-anon unmask to read it with your real
names again.
The jar contains zero network code: no HTTP client, no java.net usage, and
a test in this repo that fails the build if anyone adds either. See
Why you can trust this.
Thread dumps are the fastest way to find out why a JVM is stuck. They are also
full of your internal names: com.acme.payment.LedgerService, thread names that
carry tenant ids, routes, or customer identifiers. In a lot of companies that is
exactly why pasting a dump into a third-party analyzer is against policy.
tm-anon makes the dump boring before it leaves the machine:
jstack <pid> > dump.txt
tm-anon mask dump.txt # -> dump.anon.txt, and nothing is written
# unless the compliance check passes
# upload dump.anon.txt, get the analysis back
tm-anon unmask report.html # -> report.unmasked.html, your real
# names, back on your machine
tm-anon verify dump.txt dump.anon.txt # the same check on demand: CI, reviewers,
# a file you masked last month
The masked dump is still analyzable: the same detections fire and the same
health score comes out, because everything the detectors match by name is on a
published, auditable allowlist and stays verbatim
(JDK internals, http-nio-8080-exec-1, ForkJoinPool-1-worker-3,
Tomcat/Netty/Kafka frames, GC threads), while everything that is yours becomes a
token.
Requires a JDK 21 or newer. Pick one:
# 1. jar (primary artifact)
curl -LO https://github.com/maschiojv/threadmine-anonymizer/releases/latest/download/tm-anon.jar
java -jar tm-anon.jar
# 2. jbang (nothing to install beyond a JDK) - resolves this repo's catalog
jbang tm-anon@maschiojv/threadmine-anonymizer mask dump.txt
jbang alias add --name tm-anon tm-anon@maschiojv/threadmine-anonymizer # then just: jbang tm-anon ...
# 3. native binary, no JVM needed to run it: tm-anon-linux-amd64,
# tm-anon-macos-arm64, tm-anon-windows-amd64.exe — attached to each release
# 4. from source
./mvnw package # -> target/tm-anon-<version>.jar
A downloaded jar gives you no tm-anon command. Run it as you would any jar,
which works everywhere with no setup:
java -jar tm-anon.jar init
java -jar tm-anon.jar mask dump.txt
The rest of this README writes the short tm-anon form. To get it, either put
the native binary for your OS on your PATH (on Windows, rename it to
tm-anon.exe), or, on Linux and macOS, alias the jar:
alias tm-anon='java -jar /path/to/tm-anon.jar'
Windows cmd and PowerShell have no shell aliases — use the native binary or
the java -jar form. The tool's own help prints whichever form you launched it
with, so a mistyped command always answers with something you can actually run.
Everything below is real output, produced by running the jar against
corpus/fixtures/jstack-jdk17-synchronizers.txt
(copied to payments-prod.txt). Nothing here is illustrative fiction.
$ tm-anon init
Created vault: /home/you/work/tm-anon-vault.json
Back this file up. It holds the HMAC key and the token dictionary:
- lose it and you can never unmask an already masked dump;
- share it and anyone can unmask those dumps.
Never commit it, never upload it, never attach it to a ticket.
When the working directory is a git repository, init also adds the vault to
.gitignore.
$ tm-anon mask payments-prod.txt
masked payments-prod.txt -> payments-prod.anon.txt
lines: 78 preserved, 10 tokenized, 22 stripped, 0 redacted
verify: PASS - no identifier survived and the structure is intact.
Reminder: upload the masked file under a neutral file name and title -
the original name often carries the very identifiers you just masked.
That verify line is not a summary of what masking believes it did: before
writing the file, mask hands its own output to the compliance verifier — the
same code the standalone verify command runs, which re-derives every
identifier from the masked text instead of trusting the rewriter. A FAIL
means no file is written at all (exit 4).
Before:
"pgto-worker-1" #15 prio=5 os_prio=31 cpu=4211.03ms elapsed=410.55s tid=0x00007fb2a3813200 nid=0x5203 runnable [0x000000016d0be000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0([email protected]/Native Method)
at java.net.SocketInputStream.read([email protected]/SocketInputStream.java:168)
at com.acme.payment.gateway.AcquirerClient.capture(AcquirerClient.java:133)
at com.acme.payment.LedgerService.applyEntry(LedgerService.java:95)
at com.acme.payment.PaymentFacade.settle(PaymentFacade.java:41)
at java.util.concurrent.ThreadPoolExecutor.runWorker([email protected]/ThreadPoolExecutor.java:1136)
at java.lang.Thread.run([email protected]/Thread.java:833)
Locked ownable synchronizers:
- <0x000000061f8a2b40> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
After:
This is the beginning of the README. Read the rest at the original. Read the full README ↗