diff --git a/CNAME b/CNAME new file mode 100644 index 000000000..147ef2e07 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +btrace.io diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..2e22aa93b --- /dev/null +++ b/Gemfile @@ -0,0 +1,5 @@ +source "https://rubygems.org" + +gem "jekyll", "~> 4.4" +gem "jekyll-theme-hacker" +gem "jekyll-paginate" diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 000000000..b93ee4408 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,247 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.9.0) + public_suffix (>= 2.0.2, < 8.0) + base64 (0.3.0) + bigdecimal (4.1.2) + colorator (1.1.0) + concurrent-ruby (1.3.7) + csv (3.3.5) + em-websocket (0.5.3) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0) + eventmachine (1.2.7) + ffi (1.17.4) + ffi (1.17.4-aarch64-linux-gnu) + ffi (1.17.4-aarch64-linux-musl) + ffi (1.17.4-arm-linux-gnu) + ffi (1.17.4-arm-linux-musl) + ffi (1.17.4-arm64-darwin) + ffi (1.17.4-x86-linux-gnu) + ffi (1.17.4-x86-linux-musl) + ffi (1.17.4-x86_64-darwin) + ffi (1.17.4-x86_64-linux-gnu) + ffi (1.17.4-x86_64-linux-musl) + forwardable-extended (2.6.0) + google-protobuf (4.35.1) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.1-aarch64-linux-gnu) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.1-aarch64-linux-musl) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.1-arm64-darwin) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.1-x86-linux-gnu) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.1-x86-linux-musl) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.1-x86_64-darwin) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.1-x86_64-linux-gnu) + bigdecimal + rake (~> 13.3) + google-protobuf (4.35.1-x86_64-linux-musl) + bigdecimal + rake (~> 13.3) + http_parser.rb (0.8.1) + i18n (1.15.2) + concurrent-ruby (~> 1.0) + jekyll (4.4.1) + addressable (~> 2.4) + base64 (~> 0.2) + colorator (~> 1.0) + csv (~> 3.0) + em-websocket (~> 0.5) + i18n (~> 1.0) + jekyll-sass-converter (>= 2.0, < 4.0) + jekyll-watch (~> 2.0) + json (~> 2.6) + kramdown (~> 2.3, >= 2.3.1) + kramdown-parser-gfm (~> 1.0) + liquid (~> 4.0) + mercenary (~> 0.3, >= 0.3.6) + pathutil (~> 0.9) + rouge (>= 3.0, < 5.0) + safe_yaml (~> 1.0) + terminal-table (>= 1.8, < 4.0) + webrick (~> 1.7) + jekyll-paginate (1.1.0) + jekyll-sass-converter (3.1.0) + sass-embedded (~> 1.75) + jekyll-seo-tag (2.9.0) + jekyll (>= 3.8, < 5.0) + jekyll-theme-hacker (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-watch (2.2.1) + listen (~> 3.0) + json (2.21.0) + kramdown (2.5.2) + rexml (>= 3.4.4) + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.4) + listen (3.10.0) + logger + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + logger (1.7.0) + mercenary (0.4.0) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + public_suffix (7.0.5) + rake (13.4.2) + rb-fsevent (0.11.2) + rb-inotify (0.11.1) + ffi (~> 1.0) + redcarpet (3.6.1) + rexml (3.4.4) + rouge (4.7.0) + safe_yaml (1.0.5) + sass-embedded (1.101.0) + google-protobuf (~> 4.31) + rake (>= 13) + sass-embedded (1.101.0-aarch64-linux-android) + google-protobuf (~> 4.31) + sass-embedded (1.101.0-aarch64-linux-gnu) + google-protobuf (~> 4.31) + sass-embedded (1.101.0-aarch64-linux-musl) + google-protobuf (~> 4.31) + sass-embedded (1.101.0-arm-linux-androideabi) + google-protobuf (~> 4.31) + sass-embedded (1.101.0-arm-linux-gnueabihf) + google-protobuf (~> 4.31) + sass-embedded (1.101.0-arm-linux-musleabihf) + google-protobuf (~> 4.31) + sass-embedded (1.101.0-arm64-darwin) + google-protobuf (~> 4.31) + sass-embedded (1.101.0-riscv64-linux-android) + google-protobuf (~> 4.31) + sass-embedded (1.101.0-riscv64-linux-gnu) + google-protobuf (~> 4.31) + sass-embedded (1.101.0-riscv64-linux-musl) + google-protobuf (~> 4.31) + sass-embedded (1.101.0-x86_64-darwin) + google-protobuf (~> 4.31) + sass-embedded (1.101.0-x86_64-linux-android) + google-protobuf (~> 4.31) + sass-embedded (1.101.0-x86_64-linux-gnu) + google-protobuf (~> 4.31) + sass-embedded (1.101.0-x86_64-linux-musl) + google-protobuf (~> 4.31) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) + unicode-display_width (2.6.0) + webrick (1.9.2) + +PLATFORMS + aarch64-linux-android + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-androideabi + arm-linux-gnu + arm-linux-gnueabihf + arm-linux-musl + arm-linux-musleabihf + arm64-darwin + riscv64-linux-android + riscv64-linux-gnu + riscv64-linux-musl + ruby + x86-linux-gnu + x86-linux-musl + x86_64-darwin + x86_64-linux-android + x86_64-linux-gnu + x86_64-linux-musl + +DEPENDENCIES + jekyll (~> 4.4) + jekyll-paginate + jekyll-theme-hacker + redcarpet + +CHECKSUMS + addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af + base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b + bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd + bundler (4.0.16) sha256=d6ca5dd440c24f9abce9844cf44cc8e18c6a553de65a47efb4544137af92c47d + colorator (1.1.0) sha256=e2f85daf57af47d740db2a32191d1bdfb0f6503a0dfbc8327d0c9154d5ddfc38 + concurrent-ruby (1.3.7) sha256=4412caec3a5ea2e5fdc52076724c071a81f2c0593d83b2ac8cbb8ca63b3151b0 + csv (3.3.5) sha256=6e5134ac3383ef728b7f02725d9872934f523cb40b961479f69cf3afa6c8e73f + em-websocket (0.5.3) sha256=f56a92bde4e6cb879256d58ee31f124181f68f8887bd14d53d5d9a292758c6a8 + eventmachine (1.2.7) sha256=994016e42aa041477ba9cff45cbe50de2047f25dd418eba003e84f0d16560972 + ffi (1.17.4) sha256=bcd1642e06f0d16fc9e09ac6d49c3a7298b9789bcb58127302f934e437d60acf + ffi (1.17.4-aarch64-linux-gnu) sha256=b208f06f91ffd8f5e1193da3cae3d2ccfc27fc36fba577baf698d26d91c080df + ffi (1.17.4-aarch64-linux-musl) sha256=9286b7a615f2676245283aef0a0a3b475ae3aae2bb5448baace630bb77b91f39 + ffi (1.17.4-arm-linux-gnu) sha256=d6dbddf7cb77bf955411af5f187a65b8cd378cb003c15c05697f5feee1cb1564 + ffi (1.17.4-arm-linux-musl) sha256=9d4838ded0465bef6e2426935f6bcc93134b6616785a84ffd2a3d82bc3cf6f95 + ffi (1.17.4-arm64-darwin) sha256=19071aaf1419251b0a46852abf960e77330a3b334d13a4ab51d58b31a937001b + ffi (1.17.4-x86-linux-gnu) sha256=38e150df5f4ca555e25beca4090823ae09657bceded154e3c52f8631c1ed72cf + ffi (1.17.4-x86-linux-musl) sha256=fbeec0fc7c795bcf86f623bb18d31ea1820f7bd580e1703a3d3740d527437809 + ffi (1.17.4-x86_64-darwin) sha256=aa70390523cf3235096cf64962b709b4cfbd5c082a2cb2ae714eb0fe2ccda496 + ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d + ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e + forwardable-extended (2.6.0) sha256=1bec948c469bbddfadeb3bd90eb8c85f6e627a412a3e852acfd7eaedbac3ec97 + google-protobuf (4.35.1) sha256=a3a6471331d918f58dfa4d014a8f6286f0af2cf4840216bde52fcf2ea3fe3726 + google-protobuf (4.35.1-aarch64-linux-gnu) sha256=50ca44d0eeff3f8475e630a1accdd974256f3510694d574e2c9d6119ea8bc9e1 + google-protobuf (4.35.1-aarch64-linux-musl) sha256=d5c65cef6bd6498a9e5ed5f88cf6cf7e341c10b0a005e32137d5d1a2b6e8c18a + google-protobuf (4.35.1-arm64-darwin) sha256=d9c957df04fa89c749fa9a72a7b383eb4296efc9b2303dc6fd6fbe39c698ad6b + google-protobuf (4.35.1-x86-linux-gnu) sha256=cc7492566b27ad8b5dfa3a7b6f9b11e905050cc53c2fa8ff22de375a9e7a70fb + google-protobuf (4.35.1-x86-linux-musl) sha256=ab403790b59e4dc588ffbed1eaacf05d4ca2f0d12ac9c13d6c64e69380d8c99e + google-protobuf (4.35.1-x86_64-darwin) sha256=66b62b4df00931018a692806df66393efa960d6d2b7da69735187249f950d3ee + google-protobuf (4.35.1-x86_64-linux-gnu) sha256=c786439087512a3fbd199e9897d265b855f951d4027e218ea55e858d45969edd + google-protobuf (4.35.1-x86_64-linux-musl) sha256=91890eb0002934a339fdb7d77a147c46b7474b6799db27872b747b905837f744 + http_parser.rb (0.8.1) sha256=9ae8df145b39aa5398b2f90090d651c67bd8e2ebfe4507c966579f641e11097a + i18n (1.15.2) sha256=00f9eb62412fe593b2a65a97daa75300d37abb8f7202ec748e94b6d46a9dd1b5 + jekyll (4.4.1) sha256=4c1144d857a5b2b80d45b8cf5138289579a9f8136aadfa6dd684b31fe2bc18c1 + jekyll-paginate (1.1.0) sha256=880aadf4b02529a93541d508c5cbb744f014cbfc071d0263a31f25ec9066eb64 + jekyll-sass-converter (3.1.0) sha256=83925d84f1d134410c11d0c6643b0093e82e3a3cf127e90757a85294a3862443 + jekyll-seo-tag (2.9.0) sha256=0260015a8e1df9bf195cdfb0c675b7b2883fd8cbf12556e1c1cbe36a831c6852 + jekyll-theme-hacker (0.2.0) sha256=816bf9f992ded0b1e1e69d8dece2574e8480efb5e9f84a2e1ac83bd717b8f78a + jekyll-watch (2.2.1) sha256=bc44ed43f5e0a552836245a54dbff3ea7421ecc2856707e8a1ee203a8387a7e1 + json (2.21.0) sha256=8de199e53f93450414b9fd49811012a73f3e3265b60468c7274d1cacebde1969 + kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa + kramdown-parser-gfm (1.1.0) sha256=fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729 + liquid (4.0.4) sha256=4fcfebb1a045e47918388dbb7a0925e7c3893e58d2bd6c3b3c73ec17a2d8fdb3 + listen (3.10.0) sha256=c6e182db62143aeccc2e1960033bebe7445309c7272061979bb098d03760c9d2 + logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + mercenary (0.4.0) sha256=b25a1e4a59adca88665e08e24acf0af30da5b5d859f7d8f38fba52c28f405138 + pathutil (0.16.2) sha256=e43b74365631cab4f6d5e4228f812927efc9cb2c71e62976edcb252ee948d589 + public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 + rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701 + rb-fsevent (0.11.2) sha256=43900b972e7301d6570f64b850a5aa67833ee7d87b458ee92805d56b7318aefe + rb-inotify (0.11.1) sha256=a0a700441239b0ff18eb65e3866236cd78613d6b9f78fea1f9ac47a85e47be6e + redcarpet (3.6.1) sha256=d444910e6aa55480c6bcdc0cdb057626e8a32c054c29e793fa642ba2f155f445 + rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 + rouge (4.7.0) sha256=dba5896715c0325c362e895460a6d350803dbf6427454f49a47500f3193ea739 + safe_yaml (1.0.5) sha256=a6ac2d64b7eb027bdeeca1851fe7e7af0d668e133e8a88066a0c6f7087d9f848 + sass-embedded (1.101.0) sha256=57dbc3409e2c0a2c581a4c9945c2bd72ec88e71ec98017bd02dd1da8a76b22f4 + sass-embedded (1.101.0-aarch64-linux-android) sha256=ad0a35c6ff5cdc4e31c5d8261a768ef460c6c7d1458081183e42170e1474c4b5 + sass-embedded (1.101.0-aarch64-linux-gnu) sha256=8f6926349e880dbb4fda75fb182086fb60aa821b756bcbfc8e5b2b23b1f269d6 + sass-embedded (1.101.0-aarch64-linux-musl) sha256=0a02b4b75db305160db1b0512f040762242128a9b5c01b0fa7a504f2b24557f2 + sass-embedded (1.101.0-arm-linux-androideabi) sha256=88e762531f90d4a2eef55ffafeba337585e1bb24b22307ebd7fe5505de9a4476 + sass-embedded (1.101.0-arm-linux-gnueabihf) sha256=358df7f98d13ff53739ebc45f5c5acd4dd96833bf87f39c74d11f798081d4158 + sass-embedded (1.101.0-arm-linux-musleabihf) sha256=d993a3ad017250d46d1312bc10cfded5ab4585906d37a60a56494bd662182d3a + sass-embedded (1.101.0-arm64-darwin) sha256=9fed684380b49499dfc856aba0d026a0748f924bd78044ffff2bae1537aea73e + sass-embedded (1.101.0-riscv64-linux-android) sha256=1bd35527e1ca24af6aa2ba9db797bc9b72331ebbec9ff6e99ea02b24f83b3da1 + sass-embedded (1.101.0-riscv64-linux-gnu) sha256=7805a249ed4c31b58b2f7d054d14f0ed24c61a836f579cd76ed2367088142bcf + sass-embedded (1.101.0-riscv64-linux-musl) sha256=8bd60eb9ebe6f9f2740a4e9ddb792a3db1fbba282e3375103844b4979eb7c731 + sass-embedded (1.101.0-x86_64-darwin) sha256=20ff4afd7c052b3f8d7b4abe511e8114985a07dff7616750a43ee1fc2759fb28 + sass-embedded (1.101.0-x86_64-linux-android) sha256=472b72114ededa00a22e13553dd31f98d1a92d52bdbe2e738a4dbac2dd50c779 + sass-embedded (1.101.0-x86_64-linux-gnu) sha256=ff48452b2351eaaf4e6e02f59de0e9e35f6f163e8456d520db49b4d87cf73c27 + sass-embedded (1.101.0-x86_64-linux-musl) sha256=2286feef3c7a8d9bbb075aa1651e1a81942aca1213f7c2d30cc1d6f4eb5b4104 + terminal-table (3.0.2) sha256=f951b6af5f3e00203fb290a669e0a85c5dd5b051b3b023392ccfd67ba5abae91 + unicode-display_width (2.6.0) sha256=12279874bba6d5e4d2728cef814b19197dbb10d7a7837a869bab65da943b7f5a + webrick (1.9.2) sha256=beb4a15fc474defed24a3bda4ffd88a490d517c9e4e6118c3edce59e45864131 + +BUNDLED WITH + 4.0.16 diff --git a/_config.yml b/_config.yml index 8ce2a138d..3d6c62368 100644 --- a/_config.yml +++ b/_config.yml @@ -1,12 +1,12 @@ -name: BTrace::blog +name: BTrace -url: http://jbachorik.github.io -baseurl: /btrace -description: BTrace - a safe, dynamic tracing tool for the Java platform +url: https://btrace.io +baseurl: "" +description: Open-source tools for understanding Java applications. source: . -github: 'jbachorik/btrace' +github: 'btraceio' gaaccount: 'UA-55468921-2' disqus: 'btrace' @@ -15,10 +15,10 @@ comments: true permalink: /:year/:month/:title paginate: 3 -highlighter: pygments -markdown: redcarpet -redcarpet: - extensions: ["no_intra_emphasis", "fenced_code_blocks", "autolink", "tables", "with_toc_data"] +highlighter: rouge +markdown: kramdown +plugins: + - jekyll-paginate exclude: ['README.md', 'LICENSE'] @@ -30,4 +30,4 @@ exclude: ['README.md', 'LICENSE'] # values: # is_post: true # automatically set is_post=true for all posts -theme: jekyll-theme-hacker \ No newline at end of file +theme: jekyll-theme-hacker diff --git a/assets/btrace-logo.png b/assets/btrace-logo.png new file mode 100644 index 000000000..f31f9cd16 Binary files /dev/null and b/assets/btrace-logo.png differ diff --git a/assets/favicon.svg b/assets/favicon.svg new file mode 100644 index 000000000..6eb1db21c --- /dev/null +++ b/assets/favicon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/btrace-avatar.png b/assets/icons/btrace-avatar.png new file mode 100644 index 000000000..35b858754 Binary files /dev/null and b/assets/icons/btrace-avatar.png differ diff --git a/assets/icons/btrace-compact.png b/assets/icons/btrace-compact.png new file mode 100644 index 000000000..25e287372 Binary files /dev/null and b/assets/icons/btrace-compact.png differ diff --git a/assets/icons/btrace-favicon.png b/assets/icons/btrace-favicon.png new file mode 100644 index 000000000..588e64b58 Binary files /dev/null and b/assets/icons/btrace-favicon.png differ diff --git a/assets/icons/btrace-monochrome.png b/assets/icons/btrace-monochrome.png new file mode 100644 index 000000000..ae615ab00 Binary files /dev/null and b/assets/icons/btrace-monochrome.png differ diff --git a/assets/icons/btrace-primary.png b/assets/icons/btrace-primary.png new file mode 100644 index 000000000..d3d1cf40e Binary files /dev/null and b/assets/icons/btrace-primary.png differ diff --git a/assets/icons/btrace-reversed.png b/assets/icons/btrace-reversed.png new file mode 100644 index 000000000..68af2f029 Binary files /dev/null and b/assets/icons/btrace-reversed.png differ diff --git a/assets/icons/btrace-rounded.png b/assets/icons/btrace-rounded.png new file mode 100644 index 000000000..7776ee453 Binary files /dev/null and b/assets/icons/btrace-rounded.png differ diff --git a/assets/probe-composer.js b/assets/probe-composer.js new file mode 100644 index 000000000..7624a8f31 --- /dev/null +++ b/assets/probe-composer.js @@ -0,0 +1,92 @@ +(() => { + const form = document.querySelector('#probe-form'); + const goal = document.querySelector('#probe-goal'); + const className = document.querySelector('#probe-class'); + const method = document.querySelector('#probe-method'); + const threshold = document.querySelector('#probe-threshold'); + const targetFields = document.querySelector('#custom-target-fields'); + const thresholdField = document.querySelector('#threshold-field'); + const note = document.querySelector('#probe-note'); + const command = document.querySelector('#generated-command'); + const script = document.querySelector('#generated-script'); + const title = document.querySelector('#probe-result-title'); + const explainer = document.querySelector('#probe-explainer'); + const docLink = document.querySelector('#probe-doc-link'); + const copyStatus = document.querySelector('#copy-status'); + const copyButtons = document.querySelectorAll('[data-copy]'); + const escapeJava = (value) => value.replace(/\\/g, '\\\\').replace(/"/g, '\\"'); + const safeValue = (input, fallback) => input.trim() || fallback; + + const templates = { + slow: { + title: 'Slow method probe', explanation: 'Hooks method returns and prints only calls above the selected latency budget.', + docs: 'https://github.com/btraceio/btrace/blob/develop/docs/OnelinerGuide.md#performance-debugging', + note: 'Specific patterns and a duration threshold keep tracing overhead low.', + command: (clazz, meth, ms) => `jbang btrace@btraceio -n '${clazz}::${meth} @return if duration>${ms}ms { print method, duration }' `, + script: (clazz, meth, ms) => `@BTrace\npublic class SlowMethodProbe {\n @OnMethod(clazz = "${escapeJava(clazz)}", method = "${escapeJava(meth)}", location = @Location(Kind.RETURN))\n public static void onReturn(@ProbeMethodName String method, @Duration long duration) {\n if (duration > ${ms}_000_000L) {\n println(method + " took " + str(duration / 1_000_000L) + " ms");\n }\n }\n}` + }, + calls: { + title: 'Method call probe', explanation: 'Hooks method entry and prints the method name with the arguments BTrace receives.', + docs: 'https://github.com/btraceio/btrace/blob/develop/docs/OnelinerGuide.md#monitoring-method-calls', + note: 'Start with a specific class; printing arguments can be expensive on a hot path.', + command: (clazz, meth) => `jbang btrace@btraceio -n '${clazz}::${meth} @entry { print method, args }' `, + script: (clazz, meth) => `@BTrace\npublic class MethodCallProbe {\n @OnMethod(clazz = "${escapeJava(clazz)}", method = "${escapeJava(meth)}")\n public static void onEntry(@ProbeMethodName String method, AnyType[] args) {\n println(method);\n printArray(args);\n }\n}` + }, + errors: { + title: 'Exception path probe', explanation: 'Runs only when the chosen method exits by throwing and prints a bounded stack trace.', + docs: 'https://github.com/btraceio/btrace/blob/develop/docs/OnelinerGuide.md#exception-tracking', + note: 'Keep stack depth bounded. Start with the method where the failure is observed.', + command: (clazz, meth) => `jbang btrace@btraceio -n '${clazz}::${meth} @error { print method, stack(5) }' `, + script: (clazz, meth) => `@BTrace\npublic class ExceptionPathProbe {\n @OnMethod(clazz = "${escapeJava(clazz)}", method = "${escapeJava(meth)}", location = @Location(Kind.ERROR))\n public static void onError(@ProbeMethodName String method) {\n println(method);\n jstack(5);\n }\n}` + }, + count: { + title: 'Invocation counter', explanation: 'Counts matching calls and emits a running count without printing every invocation.', + docs: 'https://github.com/btraceio/btrace/blob/develop/docs/OnelinerGuide.md#count---count-invocations', + note: 'This counter is printed from the BTrace client menu. For periodic summaries or grouped metrics, move to a Java probe.', + command: (clazz, meth) => `jbang btrace@btraceio -n '${clazz}::${meth} @entry { count }' `, + script: (clazz, meth) => `@BTrace\npublic class InvocationCounterProbe {\n private static long calls;\n\n @OnMethod(clazz = "${escapeJava(clazz)}", method = "${escapeJava(meth)}")\n public static void onEntry() {\n calls++;\n }\n\n @OnTimer(5000)\n public static void report() {\n println("calls: " + str(calls));\n }\n}` + }, + sql: { + title: 'Slow SQL probe', explanation: 'Times JDBC Statement execution and reports calls that exceed the selected threshold.', + docs: 'https://github.com/btraceio/btrace/blob/develop/docs/OnelinerGuide.md#performance-debugging', + note: 'This template targets JDBC Statement execution. Adjust the threshold to avoid noisy output.', + command: (_clazz, _meth, ms) => `jbang btrace@btraceio -n 'java.sql.Statement::execute* @return if duration>${ms}ms { print method, duration }' `, + script: (_clazz, _meth, ms) => `@BTrace\npublic class SlowSqlProbe {\n @OnMethod(clazz = "java.sql.Statement", method = "execute*", location = @Location(Kind.RETURN))\n public static void onReturn(@ProbeMethodName String method, @Duration long duration) {\n if (duration > ${ms}_000_000L) {\n println(method + " took " + str(duration / 1_000_000L) + " ms");\n }\n }\n}` + } + }; + + function update() { + const selected = templates[goal.value]; + const clazz = safeValue(className.value, 'com.myapp.OrderService'); + const meth = safeValue(method.value, '*'); + const ms = Math.max(1, Math.min(60000, Number.parseInt(threshold.value, 10) || 200)); + const sql = goal.value === 'sql'; + const timed = goal.value === 'slow' || sql; + targetFields.hidden = sql; + thresholdField.hidden = !timed; + note.textContent = selected.note; + title.textContent = selected.title; + explainer.textContent = selected.explanation; + docLink.href = selected.docs; + command.textContent = selected.command(clazz, meth, ms); + script.textContent = selected.script(clazz, meth, ms); + } + + form.addEventListener('input', update); + form.addEventListener('change', update); + document.querySelectorAll('[data-goal]').forEach((link) => link.addEventListener('click', () => { goal.value = link.dataset.goal; update(); })); + copyButtons.forEach((button) => button.addEventListener('click', async () => { + const source = button.dataset.copy === 'script' ? script.textContent : command.textContent; + try { + await navigator.clipboard.writeText(source); + const original = button.textContent; + button.textContent = 'Copied'; + copyStatus.textContent = `${button.dataset.copy === 'script' ? 'Java probe' : 'Command'} copied to clipboard.`; + window.setTimeout(() => { button.textContent = original; }, 1600); + } catch (_) { + button.textContent = 'Select text to copy'; + copyStatus.textContent = 'Clipboard access is unavailable. Select the text and copy it manually.'; + } + })); + update(); +})(); diff --git a/assets/site.css b/assets/site.css new file mode 100644 index 000000000..20bab45e7 --- /dev/null +++ b/assets/site.css @@ -0,0 +1,78 @@ +:root { --primary:#00A1FE; --primary-dark:#007FC8; --accent:#FD6801; --accent-dark:#D95000; --text:#0A2034; --background:#FFFFFF; --surface-dark:#0A2034; --ink:var(--text); --muted:#52677a; --faint:#70869a; --line:#dce7ef; --night:var(--background); --night-2:#f5f9fc; --panel:#eef5fa; --mint:var(--primary); --mint-dark:var(--text); --blue:var(--primary-dark); --warm:var(--accent); --danger:#c73f2c; } +* { box-sizing:border-box; } +html { scroll-behavior:smooth; } +body { margin:0; color:var(--ink); background:var(--background); font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; line-height:1.55; } +a { color:inherit; text-decoration:none; } +button,input,select { font:inherit; } +.skip-link { position:absolute; z-index:10; top:-4rem; left:1rem; padding:.65rem .9rem; color:#000; background:#fff; }.skip-link:focus { top:1rem; } +.site-header,main,footer { max-width:1180px; margin:auto; padding-right:32px; padding-left:32px; } +.site-header { position:sticky; top:0; z-index:20; display:flex; align-items:center; justify-content:space-between; height:82px; border-bottom:1px solid rgba(220,231,239,.8); background:rgba(255,255,255,.94); backdrop-filter:blur(14px); } +.brand { display:inline-flex; align-items:center; gap:.6rem; }.brand-logo { display:block; width:34px; height:34px; object-fit:contain; }.brand-name { color:var(--text); font-size:1.16rem; font-weight:780; letter-spacing:-.035em; } +nav { display:flex; gap:1.45rem; color:#b6c8d4; font-size:.88rem; } nav a:hover,footer a:hover { color:var(--mint); }.nav-github { color:var(--mint); } +h1,h2,h3,p { margin-top:0; } h1,h2,h3 { letter-spacing:-.055em; line-height:1.06; } +.hero { position:relative; display:grid; min-height:615px; grid-template-columns:1fr .92fr; gap:5rem; align-items:center; padding-top:62px; padding-bottom:78px; overflow:hidden; }.hero:before { position:absolute; top:-180px; right:-160px; width:630px; height:630px; content:""; background:radial-gradient(circle,rgba(35,135,169,.25),transparent 66%); pointer-events:none; }.hero-copy,.signal-panel { position:relative; z-index:1; }.eyebrow { margin:0 0 1rem; color:var(--mint); font-size:.71rem; font-weight:760; letter-spacing:.14em; text-transform:uppercase; }.eyebrow span { display:inline-block; width:23px; height:1px; margin:0 .55rem .15rem 0; background:var(--mint); vertical-align:middle; } +h1 { max-width:650px; margin-bottom:1.5rem; font-size:clamp(3.1rem,6vw,5.55rem); } h1 em { color:var(--mint); font-family:Georgia,serif; font-weight:400; }.hero-text { max-width:560px; color:var(--muted); font-size:1.11rem; }.hero-actions { display:flex; flex-wrap:wrap; gap:.85rem; margin-top:2rem; }.button { display:inline-flex; align-items:center; justify-content:center; gap:.7rem; padding:.76rem 1.05rem; border-radius:7px; font-size:.91rem; font-weight:690; }.button-primary { color:var(--mint-dark); background:var(--mint); }.button-primary:hover { background:#a5f9da; }.button-secondary { border:1px solid var(--line); color:#d4e1eb; }.button-secondary:hover { border-color:var(--blue); }.hero-facts { display:flex; flex-wrap:wrap; gap:.75rem 1.35rem; margin-top:2rem; color:var(--muted); font-size:.77rem; }.hero-facts b { color:#d7e6ee; } +.signal-panel { overflow:hidden; padding:1.25rem; border:1px solid rgba(127,198,229,.22); border-radius:13px; background:linear-gradient(135deg,rgba(15,39,57,.96),rgba(8,23,36,.96)); box-shadow:0 30px 85px rgba(0,0,0,.3); font-family:"SFMono-Regular",Consolas,monospace; font-size:.77rem; }.panel-bar { display:flex; align-items:center; gap:6px; padding-bottom:1rem; border-bottom:1px solid var(--line); color:#718999; }.panel-bar span { width:8px; height:8px; border-radius:50%; background:#426275; }.panel-bar span:first-child { background:#f07c73; }.panel-bar span:nth-child(2) { background:#f5c265; }.panel-bar code { margin-left:.45rem; }.panel-bar em { margin-left:auto; color:var(--mint); font-size:.65rem; font-style:normal; }.trace-line { display:grid; grid-template-columns:25px 1fr auto; gap:.3rem; padding:.86rem 0; border-bottom:1px solid rgba(155,193,216,.11); }.trace-line span { color:#547084; }.trace-line b { color:var(--mint); }.trace-line strong { color:var(--warm); font-weight:600; }.trace-line.muted { display:block; color:#7890a0; }.trace-line.muted span { display:inline-block; width:25px; }.trace-line i { color:var(--mint); } +.trust-strip { display:grid; grid-template-columns:minmax(0,1fr) auto; grid-template-rows:1fr 1fr; gap:1px; border:1px solid var(--line); background:var(--line); }.trust-strip p,.trust-strip a { display:flex; align-items:flex-start; margin:0; padding:1rem 1.2rem; background:var(--night-2); color:var(--muted); font-size:.78rem; }.trust-copy { display:block; flex:1 1 auto; min-width:0; }.trust-strip b { color:#d9e6f0; white-space:nowrap; }.trust-strip a { grid-column:2; grid-row:1 / span 2; align-items:center; color:var(--mint); font-weight:650; }.dot { flex:0 0 auto; width:7px; height:7px; margin:.45rem .55rem 0 0; border-radius:50%; background:var(--mint); }.dot.blue { background:var(--blue); } +.composer { padding-top:120px; padding-bottom:118px; }.section-heading { max-width:650px; }.section-heading h2,.progression h2,.safety h2,.ai-section h2 { margin-bottom:1rem; font-size:clamp(2.5rem,4.5vw,4rem); }.section-heading>p:last-child { color:var(--muted); font-size:1.04rem; }.composer-grid { display:grid; grid-template-columns:.82fr 1.18fr; gap:16px; margin-top:3rem; }.probe-form,.probe-result { padding:1.65rem; border:1px solid var(--line); border-radius:10px; background:#0a1b2a; }.probe-form label { display:block; margin:1.22rem 0 .46rem; color:#d8e5ee; font-size:.84rem; font-weight:690; }.probe-form label:first-child { margin-top:0; }.probe-form select,.probe-form input { width:100%; border:1px solid rgba(146,188,209,.25); border-radius:6px; padding:.74rem .8rem; color:#e7f2f8; background:#06141f; outline:none; }.probe-form select:focus,.probe-form input:focus { border-color:var(--mint); box-shadow:0 0 0 3px rgba(128,244,197,.13); }.threshold-input { display:flex; overflow:hidden; border:1px solid rgba(146,188,209,.25); border-radius:6px; background:#06141f; }.threshold-input input { border:0; }.threshold-input span { display:flex; align-items:center; padding:0 .8rem; border-left:1px solid rgba(146,188,209,.17); color:var(--muted); font-size:.83rem; }.field-help,.form-note { margin:.42rem 0 0; color:var(--faint); font-size:.74rem; }.form-note { margin-top:1.5rem; padding-top:1rem; border-top:1px solid var(--line); }.field-help code { color:#b7d3e5; }.result-heading { display:flex; align-items:start; justify-content:space-between; gap:1rem; }.result-label { margin:0 0 .25rem; color:var(--mint); font-size:.67rem; font-weight:760; letter-spacing:.12em; text-transform:uppercase; }.result-heading h3 { margin:0; font-size:1.55rem; }.copy-button { flex:none; padding:.5rem .7rem; border:1px solid rgba(128,244,197,.48); border-radius:6px; color:var(--mint); background:transparent; font-size:.75rem; font-weight:680; cursor:pointer; }.copy-button:hover { background:rgba(128,244,197,.12); }.generated-command,.script-ladder pre { overflow:auto; margin:1.45rem 0 .4rem; padding:1.1rem; border-radius:7px; background:#06131e; color:#d6e7ef; font:500 .77rem/1.7 "SFMono-Regular",Consolas,monospace; white-space:pre-wrap; word-break:break-word; }.copy-status { min-height:1.2rem; margin:.35rem 0 0; color:var(--mint); font-size:.74rem; }.result-meta { display:flex; gap:1.2rem; align-items:start; justify-content:space-between; margin-top:1.2rem; color:var(--muted); font-size:.85rem; }.result-meta p { max-width:400px; margin:0; }.result-meta a,.script-ladder a { flex:none; color:var(--mint); font-size:.8rem; font-weight:650; }.script-ladder { margin-top:1.7rem; padding-top:1.1rem; border-top:1px solid var(--line); }.script-ladder summary { color:#d8e7ef; font-size:.86rem; font-weight:700; cursor:pointer; }.script-ladder p { margin:1rem 0 0; color:var(--muted); font-size:.82rem; }.script-ladder .copy-script { margin-right:.8rem; } +.use-cases { padding:112px 0; border-top:1px solid var(--line); }.use-case-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:13px; margin-top:3rem; }.use-case-card { display:flex; min-height:228px; flex-direction:column; padding:1.45rem; border:1px solid var(--line); border-radius:8px; background:#091a29; transition:border-color .18s,transform .18s; }.use-case-card:hover { border-color:rgba(128,244,197,.55); transform:translateY(-3px); }.use-case-card.primary { background:linear-gradient(145deg,#123642,#0a1e2c); }.case-icon { display:grid; width:30px; height:30px; place-items:center; border-radius:7px; color:var(--blue); background:#16354a; font-weight:800; }.primary .case-icon { color:#062018; background:var(--mint); }.use-case-card h3 { margin:1.2rem 0 .55rem; font-size:1.28rem; }.use-case-card p { color:var(--muted); font-size:.86rem; }.use-case-card>span:last-child { margin-top:auto; color:var(--mint); font-size:.79rem; font-weight:680; } +.progression { display:grid; grid-template-columns:.78fr 1.22fr; gap:5rem; padding:110px 0; }.progression ol { display:grid; grid-template-columns:1fr 1fr; gap:0; margin:0; padding:0; list-style:none; border-top:1px solid var(--line); border-left:1px solid var(--line); }.progression li { display:flex; gap:.9rem; padding:1.45rem; border-right:1px solid var(--line); border-bottom:1px solid var(--line); }.progression li>span { color:var(--blue); font:600 .72rem "SFMono-Regular",monospace; }.progression h3 { margin:.1rem 0 .45rem; font-size:1.14rem; }.progression p { margin:0; color:var(--muted); font-size:.82rem; } +.deployment { padding:105px 0; border-top:1px solid var(--line); }.deployment-grid { display:grid; grid-template-columns:repeat(4,1fr); gap:13px; margin-top:3rem; }.deployment-grid article { display:flex; min-height:260px; flex-direction:column; padding:1.35rem; border:1px solid var(--line); border-radius:8px; background:#0a1b2a; }.deployment-index { color:var(--blue); font:600 .72rem "SFMono-Regular",monospace; }.deployment-grid h3 { margin:1rem 0 .55rem; font-size:1.25rem; }.deployment-grid p { color:var(--muted); font-size:.84rem; }.deployment-grid code { margin-top:auto; padding:.6rem; overflow:auto; border-radius:5px; color:#cde4f2; background:#06131e; font-size:.68rem; white-space:nowrap; }.deployment-grid a { margin-top:1rem; color:var(--mint); font-size:.78rem; font-weight:680; } +.safety { display:grid; grid-template-columns:.9fr 1.1fr; gap:5rem; padding:105px 0; }.safety>div>p:last-child { color:var(--muted); font-size:1rem; }.safety-list { border-top:1px solid var(--line); }.safety-list>div { padding:1.12rem 0; border-bottom:1px solid var(--line); }.safety-list b { color:#dbe9f1; font-size:.91rem; }.safety-list p { margin:.35rem 0 0; color:var(--muted); font-size:.83rem; }.safety-list>a { display:inline-block; margin-top:1.3rem; color:var(--mint); font-size:.83rem; font-weight:680; } +.ai-section { display:grid; grid-template-columns:1.08fr .92fr; gap:4rem; align-items:center; padding:4.2rem; border-radius:13px; background:linear-gradient(125deg,#123344,#0c1c30 62%,#10273b); }.ai-section>div>p:not(.eyebrow) { max-width:600px; color:#aec1cf; }.ai-section h2 { font-size:clamp(2.1rem,3.8vw,3.3rem); }.ai-chat { padding:1.2rem; border:1px solid rgba(128,244,197,.22); border-radius:9px; background:rgba(4,15,25,.53); font-size:.84rem; }.ai-chat p { margin:0 0 .9rem; padding:.7rem .85rem; border-radius:7px; }.chat-user { margin-left:2.3rem!important; color:#dfeaf1; background:#18364a; }.chat-tool { color:#a8c6d5; background:#0d2838; }.chat-tool span { color:var(--mint); font-weight:700; }.chat-result { color:#c9dbe5; background:#0b1d2b; }.chat-result b { color:var(--mint); } +.projects { padding:118px 0; }.project-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:16px; margin-top:3rem; }.project-card { display:flex; min-height:245px; flex-direction:column; padding:1.55rem; border:1px solid var(--line); border-radius:9px; background:#0a1a29; transition:transform .2s,border-color .2s; }.project-card:hover { border-color:rgba(128,244,197,.55); transform:translateY(-4px); }.project-card.featured { grid-row:span 2; background:linear-gradient(155deg,#102b3a,#0a1d2d 60%); }.project-top { display:flex; align-items:center; justify-content:space-between; }.icon { display:grid; width:31px; height:31px; place-items:center; border-radius:8px; color:var(--blue); background:#17354a; font-weight:800; }.icon-pulse { color:#08251d; background:var(--mint); }.tag { color:#98adbb; font-size:.64rem; letter-spacing:.1em; text-transform:uppercase; }.project-card h3 { margin:1.65rem 0 .7rem; font-size:1.62rem; }.project-card p { color:var(--muted); font-size:.9rem; }.project-card ul { margin:0 0 1.4rem; padding:0; list-style:none; color:#b6c8d3; font-size:.81rem; }.project-card li { margin:.45rem 0; }.project-card li:before { margin-right:.45rem; color:var(--mint); content:"✓"; }.project-card a,.all-projects { margin-top:auto; color:var(--mint); font-size:.84rem; font-weight:680; }.all-projects { display:inline-block; margin-top:1.7rem; } +footer { display:grid; min-height:115px; grid-template-columns:auto 1fr auto; gap:1.5rem; align-items:center; border-top:1px solid var(--line); color:var(--muted); font-size:.83rem; } footer p { margin:0; } footer div { display:flex; gap:1rem; } +@media (max-width:900px) { .hero { grid-template-columns:1fr; gap:3rem; }.hero:before { right:-280px; }.trust-strip { grid-template-columns:1fr; grid-template-rows:auto; }.trust-strip a { grid-column:auto; grid-row:auto; }.composer-grid,.safety,.ai-section { grid-template-columns:1fr; gap:2rem; }.use-case-grid { grid-template-columns:1fr 1fr; }.progression { grid-template-columns:1fr; gap:2rem; }.deployment-grid { grid-template-columns:1fr 1fr; }.project-grid { grid-template-columns:1fr 1fr; }.project-card.featured { grid-row:auto; grid-column:span 2; }.ai-section { padding:2.3rem; } } +@media (max-width:620px) { .site-header,main,footer { padding-right:20px; padding-left:20px; }.site-header { height:68px; } nav { gap:.85rem; } nav a:not(.nav-github) { display:none; }.hero { min-height:auto; padding-top:52px; padding-bottom:60px; }.hero-actions { flex-direction:column; align-items:stretch; }.trust-strip { grid-template-columns:1fr; }.trust-strip a { grid-column:auto; }.composer,.projects { padding-top:76px; padding-bottom:76px; }.use-cases,.deployment,.safety { padding-top:75px; padding-bottom:75px; }.composer-grid { margin-top:2rem; }.result-heading,.result-meta { display:block; }.result-heading .copy-button { margin-top:.8rem; }.result-meta a { display:inline-block; margin-top:.9rem; }.use-case-grid,.deployment-grid,.project-grid { grid-template-columns:1fr; }.progression ol { grid-template-columns:1fr; }.project-card.featured { grid-column:auto; }.ai-section { margin:0 -6px; padding:1.45rem; }.ai-section .hero-actions { align-items:flex-start; }.ai-section .button { width:100%; }.trace-line { font-size:.67rem; }.signal-panel { padding:.9rem; } footer { grid-template-columns:1fr; gap:.65rem; padding-top:1.8rem; padding-bottom:1.8rem; } } + +/* BTrace brand palette */ +nav { color:var(--muted); } +.hero:before { background:radial-gradient(circle,rgba(0,161,254,.18),transparent 66%); } +.button-primary { background:var(--primary); } +.button-primary:hover { background:var(--primary-dark); color:#fff; } +.button-secondary { border-color:var(--primary); color:var(--primary-dark); } +.button-secondary:hover { border-color:var(--accent); color:var(--accent-dark); } +.signal-panel { border-color:rgba(0,161,254,.35); background:linear-gradient(135deg,#123b59,var(--surface-dark)); } +.trust-strip { background:var(--line); } +.trust-strip p,.trust-strip a { background:var(--background); } +.probe-form,.probe-result { border-color:var(--line); background:var(--night-2); } +.probe-form select,.probe-form input { border-color:#b9cfde; color:var(--text); background:var(--background); } +.generated-command,.script-ladder pre { background:var(--surface-dark); color:#eaf6ff; } +.use-case-card,.deployment-grid article,.project-card { border-color:var(--line); background:var(--background); } +.use-case-card.primary { background:linear-gradient(145deg,#e5f6ff,#f7fbfe); } +.progression ol,.progression li { border-color:var(--line); } +.ai-section { background:linear-gradient(125deg,#e7f6ff,#dceeff 62%,#eef8ff); } +.ai-section>div>p:not(.eyebrow) { color:var(--muted); } +.ai-chat { border-color:rgba(0,127,200,.25); background:rgba(255,255,255,.7); } +.chat-user { color:var(--text); background:#dceeff; } +.chat-tool { color:var(--muted); background:#e8f6ff; } +.chat-result { color:var(--text); background:#f5faff; } +.project-card.featured { background:linear-gradient(155deg,#e5f6ff,#f7fbfe 60%); } +.icon { background:#e5f3fb; } +.tag { color:var(--muted); } +footer { color:var(--muted); } +h1,h2,h3 { color:var(--text); } +nav a { color:var(--muted); } +.nav-github { color:var(--primary-dark); } +.hero-facts b { color:var(--text); } +.button-secondary { color:var(--primary-dark); } +.probe-form label { color:var(--text); } +.field-help code { color:var(--primary-dark); } +.result-heading h3,.script-ladder summary { color:var(--text); } +.copy-button { border-color:var(--primary); color:var(--primary-dark); } +.copy-button:hover { background:rgba(0,161,254,.1); } +.use-case-card>span:last-child,.deployment-grid a,.result-meta a,.script-ladder a,.project-card a,.all-projects,.safety-list>a { color:var(--primary-dark); } +.deployment-grid code { color:var(--text); background:#eaf5fb; } +.safety-list b,.project-card h3 { color:var(--text); } +.project-card ul { color:var(--muted); } +.icon-pulse { color:#fff; background:var(--primary); } +.project-card li:before { color:var(--accent); } + +/* Keep the light brand surfaces explicit, even when the legacy theme is present. */ +body, .trust-strip p, .trust-strip a, .probe-form, .probe-result, .use-case-card, .deployment-grid article, .project-card { background-color:var(--background) !important; } +body, h1, h2, h3, .brand-name, .probe-form label, .result-heading h3, .script-ladder summary, .safety-list b, .project-card h3 { color:var(--text) !important; } +nav, .hero-text, .hero-facts, .section-heading>p:last-child, .use-case-card p, .deployment-grid p, .safety>div>p:last-child, .safety-list p, .project-card p, .project-card ul, footer { color:var(--muted) !important; } +.eyebrow, .result-label, .trust-strip a, .nav-github, .button-secondary, .copy-button { color:var(--primary-dark) !important; } +.button-primary { color:#fff !important; background:var(--primary) !important; } +.button-primary:hover { background:var(--primary-dark) !important; } +.trust-strip b { color:var(--text) !important; } diff --git a/index.html b/index.html index a74b0a189..625380744 100644 --- a/index.html +++ b/index.html @@ -1,46 +1,166 @@ --- -layout: default +layout: null --- + + + + + + + + + + + + + BTrace · Java observability tools + + + + + + -
-
-

BTrace - a safe, dynamic tracing tool for the Java platform

-
BTrace is a safe, dynamic tracing tool for the Java platform.
- - BTrace can be used to dynamically trace a running Java program - (similar to DTrace for OpenSolaris applications and OS). - BTrace dynamically instruments the classes of the target - application to inject tracing code ("bytecode tracing"). - {% if site.github != '' %} - [more] - {% endif %} -
-
- -{% for post in paginator.posts %} -
-
-

{{ post.date | date: "%b %-d, %Y" }} - {{ post.title }}

- {% if site.comments == true and post.comments == true and site.disqus != '' %} -

Comments

- {% endif %} -
- {{ post.content }} -
-
-
-{% endfor %} - - +
+
+
+

Open-source Java diagnostics

+

Ask your JVM
what it’s doing.

+

BTrace helps you safely trace and diagnose live Java applications. Find the slow call, reveal the swallowed exception, and move on—without a restart or redeploy.

+ +
Live JVM diagnosticsModern JVM supportZero code changes
+
+
+
example-outputillustrative
+
01$ btrace -n 'OrderService::* @return if duration>200ms { print method, duration }' 8421
+
02 chargeCard306 ms
+
03 processOrder331 ms
+
04watching live methods · ctrl-c to detach
+
+
+ +
+

BTrace + JFR: generate targeted probes live and add custom events to a continuous recording.

+

More context: JFR keeps the history while BTrace adds on-demand instrumentation when questions arise.

+ Explore the workflow +
+ +
+
+

Start with a question

+

Build your first probe.

+

Pick a diagnostic goal. The command is generated in your browser and never leaves your machine.

+
+
+
+ + +
+ + +

Use * for a wildcard, for example com.myapp.*.

+ + +
+
+ +
ms
+
+

Specific patterns and thresholds keep tracing overhead low.

+
+
+

Your BTrace oneliner

Slow method probe

+
+

+ +
+ Need state, multiple hooks, fields, or aggregations? +

That is a reusable Java probe. Start with this equivalent script, then add the advanced feature you need.

+
+ + Learn when to move from an oneliner to a script +
+
+
+
+ +
+
+

Start where it hurts

+

Useful answers, not more dashboards.

+

BTrace is most useful when you have a concrete question about a running process.

+
+ +
+ +
+

Grow with the question

From one line to a durable diagnostic.

+
    +
  1. 01

    Ask once

    Attach an oneliner to answer a focused live question.

  2. +
  3. 02

    Make it repeatable

    Turn the oneliner into a Java probe and keep it with your service.

  4. +
  5. 03

    Measure the pattern

    Add thread-local state, sampling, aggregations, metrics, or JFR events.

  6. +
  7. 04

    Package the answer

    Ship a startup agent or fat agent when the diagnostic belongs in deployment.

  8. +
+
+ +
+

Fit your environment

Run it where your JVM runs.

Choose the smallest deployment step that answers the question.

+
+
01

Attach now

Best for ad-hoc diagnosis on a reachable live JVM.

btrace <PID> probe.javaAttach guide →
+
02

Start with an agent

Best when you know the probe before the application starts.

-javaagent:btrace.jarAgent guide →
+
03

Use a sidecar

Best for interactive troubleshooting in Docker and Kubernetes.

shareProcessNamespace: trueSidecar guide →
+
04

Build a fat agent

Best when extensions and the agent must travel as one artifact.

./gradlew fatAgentJarFat-agent guide →
+
+
+ +
+

Targeted by design

Make the next observation a good one.

BTrace is built for safe, temporary instrumentation—not permanent fleet monitoring or application behavior changes.

+
Keep probes narrow

Prefer exact classes and methods. Use thresholds, sampling, and shallow stacks on hot paths.

Know the attachment boundary

Attach normally requires the same OS user, an attachable JVM, and the right container permissions.

Choose the right recorder

Use JFR for continuous, low-overhead history; use BTrace for targeted custom instrumentation.

Read the decision guide →
+
+ +
+

New diagnostic workflows

Give an AI assistant a careful way to inspect a JVM.

The BTrace MCP server lets compatible AI clients deploy probes and surface results through a diagnostic conversation. BTrace also ships reusable agent plugins that connect BTrace, JFR, and async-profiler into evidence-driven performance workflows.

+

Which methods in my service take more than 100 ms?

BTrace attaching a bounded latency probe…

Found 2 methods
PaymentClient.authorize · p95 243 ms
OrderService.checkout · p95 271 ms

+
+ +
+

The BTrace ecosystem

Tools for knowing your JVM.

Focused open-source projects for Java developers and operators.

+
+ +
Add-ons

BTrace extensions

Curated integrations and richer diagnostic capabilities for BTrace.

Open project →
+
Experimental

Jafar

An experimental Java Flight Recorder parser for exploring JVM event data.

Open project →
+
AI workflows

Agent plugins

Reusable skills for Claude Code, Codex, and Pi that connect live tracing with JFR and async-profiler analysis.

Open project →
+
+ See every BTrace project on GitHub → +
+
+ + + + + diff --git a/robots.txt b/robots.txt new file mode 100644 index 000000000..8d309f4fa --- /dev/null +++ b/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://btrace.io/sitemap.xml diff --git a/serve-local.sh b/serve-local.sh new file mode 100755 index 000000000..aa573c374 --- /dev/null +++ b/serve-local.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "$0")" + +if [[ -f Gemfile ]] && command -v bundle >/dev/null 2>&1; then + exec bundle exec jekyll serve --baseurl="" "$@" +fi + +if ! command -v jekyll >/dev/null 2>&1; then + echo "jekyll is not installed or is not on PATH" >&2 + echo "Install it with: gem install jekyll bundler" >&2 + exit 1 +fi + +exec jekyll serve --baseurl="" "$@" diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 000000000..2ab6c4949 --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,6 @@ + + + + https://btrace.io/ + +