{"id":13610292,"url":"https://github.com/spotify/threaddump-analyzer","last_synced_at":"2025-04-12T22:33:22.048Z","repository":{"id":22977189,"uuid":"26327324","full_name":"spotify/threaddump-analyzer","owner":"spotify","description":"A JVM threaddump analyzer","archived":true,"fork":false,"pushed_at":"2022-12-07T17:53:12.000Z","size":502,"stargazers_count":488,"open_issues_count":5,"forks_count":92,"subscribers_count":115,"default_branch":"gh-pages","last_synced_at":"2024-08-01T19:54:46.083Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spotify.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-11-07T16:17:06.000Z","updated_at":"2024-07-30T06:04:34.000Z","dependencies_parsed_at":"2023-01-13T22:33:09.583Z","dependency_job_id":null,"html_url":"https://github.com/spotify/threaddump-analyzer","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spotify%2Fthreaddump-analyzer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spotify%2Fthreaddump-analyzer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spotify%2Fthreaddump-analyzer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spotify%2Fthreaddump-analyzer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spotify","download_url":"https://codeload.github.com/spotify/threaddump-analyzer/tar.gz/refs/heads/gh-pages","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223549175,"owners_count":17163607,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T19:01:43.334Z","updated_at":"2024-11-07T16:31:00.010Z","avatar_url":"https://github.com/spotify.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","others"],"sub_categories":[],"readme":"\u003c!--- -*-markdown-*- --\u003e\n\n# Java Thread Dump Analyzer\n\nThis is a Java thread dump analyzer written in Javascript.\n\n[Click here to get your Java thread dump analyzed.](http://spotify.github.io/threaddump-analyzer/)\n\n[Click here to run the unit tests.](http://spotify.github.io/threaddump-analyzer/test.html)\n\n# License\n\nThe Java Thread Dump Analyzer is licensed under\n[version 2.0 of the Apache license](http://www.apache.org/licenses/LICENSE-2.0.html),\nthe copyright belongs to Spotify AB.\n\n# Testing Locally\n\n```bash\nnpm install\nnpm test\n```\n\nTested with `npm` `6.13.7` and `node` `v13.8.0`.\n\n## TODO\n* Enable multiple threads to hold the same lock in the Synchronizers\n  section. This will happen when we have threads waiting on unnamed\n  locks and we can't find out which lock it's waiting for. And of\n  course it's wrong, but if we can't tell we can't tell.\n\n* In the Top Running Methods list, list thread names per top method\nand link them all to the stack traces list.\n\n* Support parsing gzipped thread dumps.\n\n* If one thread is holding multiple locks, this should be noted in the\nsynchronizers section for all involved locks. Add a \"Held with\" header\nto the involved locks, listing which the other locks are held\nsimultaneously with this one.\n\n* Make up new lock identifiers using the prettyClassName() +\ncounter. These should be more human-readable than the raw pointers.\n\n* Add a warnings section. To begin with, warn about threads holding\nlocks without running.\n\n* Warn about free locks that somebody wants to take. This would be an\ninternal error or a problem with the thread dump.\n\n* Add a table of contents before the first section, making sure only\nthe visible sections are in it.\n\n* If multiple threads have the same names in the Synchronizers\nsection, uniquify the thread names by appending their tids to their\nnames.\n\n* Change toString test methods into toHtml test methods and remove the\ncorresponding toString methods from the source code.\n\n* Add a line above each \\\u003ch2\\\u003e element in the CSS and remove some \\\u003chr\\\u003es\nfrom the HTML code.\n\n* If all lines share the same prefix, strip it away before analyzing\nso we can parse dumps like this one: \u003chttp://pastebin.com/fcSqxsku\u003e\n\n* If a thread is waiting for another thread to release a lock, make\nsure there's a clickable reference from the waiter to the holder.\n\n* Detect deadlocks and display deadlock information prominently at the\ntop if detected.\n\n* Support parsing multiple consecutive thread dumps.\n\n* Auto detect if somebody copies a thread dump to the clipboard and\nspontaneously analyze that.\n\n* If two or more threads share both thread header and stack, print\nonly one thread header line prefixed by \"N x \".\n\n* Instead of showing the thread dump as text, show it in a tree with\nexpandable nodes.\n\n## DONE\n* Publish the web page using Github pages.\n\n* Make submit button call a Javascript function.\n\n* Connect the submit button to a Javascript function that simply\ncopies the whole thread dump to below the line.\n\n* HTML escape the text before writing it below the line.\n\n* Make an Analyzer class / prototype.\n\n* Parse the thread dump and reconstruct it below the line.\n\n* Handle thread names containing linefeeds.\n\n* Add tests, unit or otherwise.\n\n* Apply Apache License.\n\n* Our example thread dump contains 297 threads. Make sure we get all\nof them on the web page.\n\n* Add thread stack traces to the parse result.\n\n* Add thread stacks to the output.\n\n* Group threads with the same stacks and show the most common stack\ntraces and their names first.\n\n* Put \\\u003cempty stack trace\\\u003e threads last, no matter how many they are.\n\n* If there are five or more threads in a group, prefix the group with a\nline saying: \"NN threads with stack trace:\"\n\n* Publish on public Github.\n\n* Update the README.md links to point to the public Analyzer location.\n\n* Put links to the Github project and the unit tests page on index.html.\n\n* Put an actual thread dump and the expected outcome of analyzing it\nin test.html and make a test that verifies that analyzing that dump\ngives the expected result.\n\n* Add a \"report bug\" link right after the analysis.\n\n* Add a Travis configuration.\n\n* Make Travis run the unit tests and fail the build if they fail.\n\n* If two stacks are just as common, use the stack trace contents itself\nas the secondary sort key. This way similar stacks will end up closer to\neach other.\n\n* Sort thread names in each group alphabetically.\n\n* Make Travis run a Javascript code checker and fail the build if there\nare warnings.\n\n* Make Travis validate the HTML and fail verifictaion on HTML\nproblems.\n\n* Dump all input lines we failed to parse in red at the end so it's\nobvious if we need to add something.\n\n* Move styling into CSS.\n\n* Turn the Ignored Lines section at the bottom into an HTML table.\n\n* List top RUNNING methods before everything else. I have a thread\n  dump taken on a system that was swapping basically getting the GC\n  stuck. With a list of top RUNNING methods it should be possible to\n  see this from the analysis.\n\n* Add a Clear button next to the Analyze button.\n\n* For top running methods belonging to only one thread, make a link\nfrom the top list method to the thread executing it.\n\n* For threads with a method in the top running methods at the start of\nthe page, make a link from the top frame of the full stack back up to\nthe Top Running Methods section.\n\n* N/A: Accessing iframes isn't possible because of the Javascript\n  security model: Move unit test data from test.html into iframes of\n  test.html and put each unit test data block in its own file,\n  referenced from test.html.\n\n* Make the Thread class parse held locks, waited-for locks and\nwaited-for condition variables from the thread dump.\n\n* List all synchronization things at the end; both locks and condition\n  variables in the same list. For each, list who's holding it, who's\n  waiting for the lock, and who's waiting for notification. All\n  references should be clickable.\n\n* Add clickable links from each thread in the thread list to whatever\n  synchronization thingie(s) it is involved with (if any).\n\n* Highlight the link target if the user clicks on an in-page cross\nreference.\n\n* If a synchronizer has five or more lock waiters or synchronization\nwaiters, print the count before the headline.\n\n* Sort the synchronizers section by number of threads involved, class\nname and address, in that order.\n\n* Say \"... threads with no stack\" for threads with no stack, rather\n  than \"... threads with this stack\".\n\n* If a thread is listed as holding the same lock more than once,\nremove duplicates from that list.\n\n* Support uploading thread dumps from the local file system:\n\u003chttp://www.html5rocks.com/en/tutorials/file/dndfiles/\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspotify%2Fthreaddump-analyzer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspotify%2Fthreaddump-analyzer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspotify%2Fthreaddump-analyzer/lists"}