javacore-analyser 2.3.0.dev2__py3-none-any.whl → 2.3.0.dev16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- javacore_analyser/code_snapshot_collection.py +4 -2
- javacore_analyser/data/xml/report.xsl +13 -7
- javacore_analyser/java_thread.py +12 -2
- javacore_analyser/javacore.py +3 -0
- javacore_analyser/javacore_analyser_batch.py +4 -0
- javacore_analyser/javacore_set.py +18 -13
- javacore_analyser/properties.py +28 -0
- {javacore_analyser-2.3.0.dev2.dist-info → javacore_analyser-2.3.0.dev16.dist-info}/METADATA +2 -1
- {javacore_analyser-2.3.0.dev2.dist-info → javacore_analyser-2.3.0.dev16.dist-info}/RECORD +12 -11
- {javacore_analyser-2.3.0.dev2.dist-info → javacore_analyser-2.3.0.dev16.dist-info}/WHEEL +0 -0
- {javacore_analyser-2.3.0.dev2.dist-info → javacore_analyser-2.3.0.dev16.dist-info}/entry_points.txt +0 -0
- {javacore_analyser-2.3.0.dev2.dist-info → javacore_analyser-2.3.0.dev16.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright IBM Corp. 2024 -
|
2
|
+
# Copyright IBM Corp. 2024 - 2025
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
#
|
5
5
|
|
@@ -21,7 +21,6 @@ class CodeSnapshotCollection(AbstractSnapshotCollection):
|
|
21
21
|
"""
|
22
22
|
Returns list of the threads for which given stack appears
|
23
23
|
"""
|
24
|
-
|
25
24
|
def get_threads(self):
|
26
25
|
result = set()
|
27
26
|
for snapshot in self.thread_snapshots:
|
@@ -29,6 +28,9 @@ class CodeSnapshotCollection(AbstractSnapshotCollection):
|
|
29
28
|
result.add(thread)
|
30
29
|
return result
|
31
30
|
|
31
|
+
def is_interesting(self): # method is to be overloaded in subclasses, ignore the static warning
|
32
|
+
return True
|
33
|
+
|
32
34
|
def get_xml(self, doc):
|
33
35
|
snapshot_collection_node = super().get_xml(doc)
|
34
36
|
stack_strace = self.get_stack_trace()
|
@@ -550,6 +550,8 @@
|
|
550
550
|
of the code that the thread was executing in each of the javacores in which it appears.
|
551
551
|
Note that there may be multiple threads with the same name,
|
552
552
|
since the names of threads are not unique over time, and may be reused.
|
553
|
+
A 'More' link may appear next to the thread name to allow to drilldown into that thread's individual page
|
554
|
+
The drilldown may be supressed for threads that don't appear to be doing anything interesting.
|
553
555
|
</li>
|
554
556
|
<li><strong>Total CPU usage</strong>
|
555
557
|
is the total number of seconds the thread was using CPU time since the first javacore,
|
@@ -598,13 +600,17 @@
|
|
598
600
|
<xsl:attribute name="class">expandit</xsl:attribute>
|
599
601
|
<xsl:value-of select="thread_name"/>
|
600
602
|
</a>
|
601
|
-
<
|
602
|
-
|
603
|
-
<
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
603
|
+
<xsl:choose>
|
604
|
+
<xsl:when test="@has_drill_down='True'">
|
605
|
+
<a class="right" target="_blank">
|
606
|
+
<xsl:attribute name="href">
|
607
|
+
<xsl:value-of select="concat('threads/thread_', thread_hash, '.html')"/>
|
608
|
+
</xsl:attribute>
|
609
|
+
More...
|
610
|
+
</a>
|
611
|
+
<br/>
|
612
|
+
</xsl:when>
|
613
|
+
</xsl:choose>
|
608
614
|
<div style="display:none;" >
|
609
615
|
<xsl:attribute name="id"><xsl:value-of select="concat('stack',$i)"/></xsl:attribute>
|
610
616
|
java/lang/Thread:<xsl:value-of select="thread_address"/>
|
javacore_analyser/java_thread.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
#
|
2
|
-
# Copyright IBM Corp. 2024 -
|
2
|
+
# Copyright IBM Corp. 2024 - 2025
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
4
4
|
#
|
5
|
-
|
6
5
|
from javacore_analyser.abstract_snapshot_collection import AbstractSnapshotCollection
|
6
|
+
from javacore_analyser.properties import Properties
|
7
7
|
|
8
8
|
|
9
9
|
class Thread(AbstractSnapshotCollection):
|
@@ -16,6 +16,13 @@ class Thread(AbstractSnapshotCollection):
|
|
16
16
|
super().create(thread_snapshot)
|
17
17
|
self.thread_address = thread_snapshot.thread_address
|
18
18
|
|
19
|
+
def is_interesting(self):
|
20
|
+
if self.get_total_cpu() > 0: return True
|
21
|
+
if self.get_avg_mem() // (1024 * 1024) > 0: return True # memory in megabytes
|
22
|
+
if len(self.get_blocker_threads()) > 0: return True
|
23
|
+
if len(self.get_blocking_threads()) > 0: return True
|
24
|
+
return False
|
25
|
+
|
19
26
|
def get_hash(self):
|
20
27
|
id_str = self.name + str(self.id)
|
21
28
|
hashcode = abs(hash(id_str))
|
@@ -24,6 +31,9 @@ class Thread(AbstractSnapshotCollection):
|
|
24
31
|
def get_xml(self, doc):
|
25
32
|
thread_node = super().get_xml(doc)
|
26
33
|
|
34
|
+
thread_node.setAttribute("has_drill_down",
|
35
|
+
str(self.is_interesting() or not Properties.get_instance().skip_boring))
|
36
|
+
|
27
37
|
# thread ID
|
28
38
|
id_node = doc.createElement("thread_id")
|
29
39
|
id_node.appendChild(doc.createTextNode(str(self.id)))
|
javacore_analyser/javacore.py
CHANGED
@@ -42,6 +42,9 @@ class Javacore:
|
|
42
42
|
self.javacore_set = javacore_set
|
43
43
|
self.extract_thread_snapshots()
|
44
44
|
|
45
|
+
def is_interesting(self): # method is to be overloaded in subclasses, ignore the static warning
|
46
|
+
return True
|
47
|
+
|
45
48
|
def get_cpu_percentage(self):
|
46
49
|
if self.__total_cpu == -1:
|
47
50
|
self.__calculate_total_cpu_and_load()
|
@@ -22,6 +22,7 @@ from importlib_resources.abc import Traversable
|
|
22
22
|
from javacore_analyser import logging_utils
|
23
23
|
from javacore_analyser.constants import DEFAULT_FILE_DELIMITER
|
24
24
|
from javacore_analyser.javacore_set import JavacoreSet
|
25
|
+
from javacore_analyser.properties import Properties
|
25
26
|
|
26
27
|
SUPPORTED_ARCHIVES_FORMATS = {"zip", "gz", "tgz", "bz2", "lzma", "7z"}
|
27
28
|
|
@@ -76,11 +77,14 @@ def main():
|
|
76
77
|
parser.add_argument("--separator",
|
77
78
|
help='Input files separator (default "' + DEFAULT_FILE_DELIMITER + '")',
|
78
79
|
default=DEFAULT_FILE_DELIMITER)
|
80
|
+
parser.add_argument("--skip_boring", help='Skips drilldown page generation for threads that do not do anything',
|
81
|
+
default='True')
|
79
82
|
args = parser.parse_args()
|
80
83
|
|
81
84
|
input_param = args.input
|
82
85
|
output_param = args.output
|
83
86
|
files_separator = args.separator
|
87
|
+
Properties.get_instance().skip_boring = args.skip_boring != 'False'
|
84
88
|
|
85
89
|
batch_process(input_param, output_param, files_separator)
|
86
90
|
|
@@ -25,6 +25,7 @@ from javacore_analyser.constants import *
|
|
25
25
|
from javacore_analyser.har_file import HarFile
|
26
26
|
from javacore_analyser.java_thread import Thread
|
27
27
|
from javacore_analyser.javacore import Javacore
|
28
|
+
from javacore_analyser.properties import Properties
|
28
29
|
from javacore_analyser.snapshot_collection import SnapshotCollection
|
29
30
|
from javacore_analyser.snapshot_collection_collection import SnapshotCollectionCollection
|
30
31
|
from javacore_analyser.verbose_gc import VerboseGcParser
|
@@ -44,11 +45,14 @@ def _create_xml_xsl_for_collection(tmp_dir, templates_dir, xml_xsl_filename, col
|
|
44
45
|
filename = output_file_prefix + "_" + str(element_id) + extension
|
45
46
|
if filename.startswith("_"):
|
46
47
|
filename = filename[1:]
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
if element.is_interesting() or not Properties.get_instance().skip_boring:
|
49
|
+
file = os.path.join(tmp_dir, filename)
|
50
|
+
logging.debug("Writing file " + file)
|
51
|
+
f = open(file, "w")
|
52
|
+
f.write(file_content.format(id=element_id))
|
53
|
+
f.close()
|
54
|
+
else:
|
55
|
+
logging.debug("Skipping boring file: " + filename)
|
52
56
|
|
53
57
|
|
54
58
|
class JavacoreSet:
|
@@ -149,12 +153,13 @@ class JavacoreSet:
|
|
149
153
|
shutil.rmtree(directory)
|
150
154
|
os.mkdir(directory)
|
151
155
|
|
152
|
-
for element in tqdm(collection, desc="Generating placeholder htmls", unit="
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
156
|
+
for element in tqdm(collection, desc="Generating placeholder htmls", unit=" file"):
|
157
|
+
if element.is_interesting() or not Properties.get_instance().skip_boring:
|
158
|
+
filename = file_prefix + "_" + element.get_id() + ".html"
|
159
|
+
if filename.startswith("_"):
|
160
|
+
filename = filename[1:]
|
161
|
+
file_path = os.path.join(directory, filename)
|
162
|
+
shutil.copy2(placeholder_file, file_path)
|
158
163
|
logging.info("Finished generating placeholder htmls")
|
159
164
|
|
160
165
|
def __generate_htmls_for_threads(self, output_dir, temp_dir_name):
|
@@ -569,7 +574,7 @@ class JavacoreSet:
|
|
569
574
|
logging.info(f"Using {threads_no} threads to generate html files")
|
570
575
|
|
571
576
|
list_files = os.listdir(data_input_dir)
|
572
|
-
progress_bar = tqdm(desc="Generating html files", unit='
|
577
|
+
progress_bar = tqdm(desc="Generating html files", unit=' file')
|
573
578
|
|
574
579
|
# Generating list of tuples. This is required attribute for p.map function executed few lines below.
|
575
580
|
generate_html_from_xml_xsl_files_params = []
|
@@ -626,7 +631,7 @@ class JavacoreSet:
|
|
626
631
|
extensions = [".xsl", ".xml"]
|
627
632
|
for extension in extensions:
|
628
633
|
file_content = Path(xml_xsls_prefix_path + extension).read_text()
|
629
|
-
for element in tqdm(collection, desc="Creating xml/xsl files", unit="
|
634
|
+
for element in tqdm(collection, desc="Creating xml/xsl files", unit=" file"):
|
630
635
|
element_id = element.get_id()
|
631
636
|
filename = output_file_prefix + "_" + str(element_id) + extension
|
632
637
|
if filename.startswith("_"):
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#
|
2
|
+
# Copyright IBM Corp. 2024 - 2025
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
4
|
+
#
|
5
|
+
|
6
|
+
class Properties:
|
7
|
+
|
8
|
+
__instance = None
|
9
|
+
|
10
|
+
# Python doesn't have private constructors
|
11
|
+
# The key prevents creation of an object of this class from outside the class
|
12
|
+
__create_key = object()
|
13
|
+
|
14
|
+
@classmethod
|
15
|
+
def create(cls):
|
16
|
+
return Properties(cls.__create_key)
|
17
|
+
|
18
|
+
def __init__(self, create_key):
|
19
|
+
# the assertion below effectively makes the constructor private
|
20
|
+
assert (create_key == Properties.__create_key), \
|
21
|
+
"Properties objects must be created using Properties.create"
|
22
|
+
self.skip_boring = True
|
23
|
+
|
24
|
+
@staticmethod
|
25
|
+
def get_instance():
|
26
|
+
if not Properties.__instance:
|
27
|
+
Properties.__instance = Properties.create()
|
28
|
+
return Properties.__instance
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: javacore_analyser
|
3
|
-
Version: 2.3.0.
|
3
|
+
Version: 2.3.0.dev16
|
4
4
|
Summary: The tool to review IBM Javacore files
|
5
5
|
Project-URL: Homepage, https://github.com/IBM/javacore-analyser
|
6
6
|
Project-URL: Issues, https://github.com/IBM/javacore-analyser/issues
|
@@ -302,6 +302,7 @@ Where `<input-data>` is one of the following:
|
|
302
302
|
* The directory containing javacores and optionally verbose gc
|
303
303
|
* Archive (7z, zip, tar.gz, tar.bz2) containing the same
|
304
304
|
* List of the javacores separated by `;` character. Optionally you can add `--separator` option to define your own separator.
|
305
|
+
* You can specify `--skip_boring=False` if you want drill-down pages generated for all the threads, including the ones that do not do anything interesting.
|
305
306
|
You can type the following command to obtain the help:
|
306
307
|
`javacore-analyser-batch --help` or `python -m javacore_analyser batch --help`
|
307
308
|
|
@@ -1,15 +1,16 @@
|
|
1
1
|
javacore_analyser/__init__.py,sha256=Sw2ZeqcI2Kx1cDDv083n1SiSY_FDRCmidTuzaN1uRSw,76
|
2
2
|
javacore_analyser/__main__.py,sha256=wQCPgu8Gp7XczyNckNGmY30c5YMUMRByW7jrdFO0OBY,1694
|
3
3
|
javacore_analyser/abstract_snapshot_collection.py,sha256=jGfd2XgujurRlKgEtlJjqNJK9sUvTdFsdgFnX9oLzt4,5589
|
4
|
-
javacore_analyser/code_snapshot_collection.py,sha256=
|
4
|
+
javacore_analyser/code_snapshot_collection.py,sha256=yag25_O1JOQjz2uIK2gQzaTvovINnJ4ClnNhmrbC0Fg,2776
|
5
5
|
javacore_analyser/constants.py,sha256=7-gbGLzUMIMe2UvmLT17ymmy_r_izadpAyhrEKFonP8,1054
|
6
6
|
javacore_analyser/har_file.py,sha256=grXpfIyPek9xQ5jp3_AYOB5JDELd17o4O4rYELxWO7w,2131
|
7
|
-
javacore_analyser/java_thread.py,sha256=
|
8
|
-
javacore_analyser/javacore.py,sha256=
|
9
|
-
javacore_analyser/javacore_analyser_batch.py,sha256=
|
7
|
+
javacore_analyser/java_thread.py,sha256=nDFJiFQSO78jP9YdMpBr2d_M2RMT0te_kJxn5KY_RNo,5437
|
8
|
+
javacore_analyser/javacore.py,sha256=oqJ-nKkZvq8xk_zlF9Z4dX61isqLRndSVLnQob_KUG4,7006
|
9
|
+
javacore_analyser/javacore_analyser_batch.py,sha256=2JnRruA0jazWHspT60cXX-Yuwf4vFSA5ywXYPQ4-ZiM,7888
|
10
10
|
javacore_analyser/javacore_analyser_web.py,sha256=o-Spq119Wi7w4pvBa7M7ZrxiZnzKmWqDhCdGtEReQAU,5951
|
11
|
-
javacore_analyser/javacore_set.py,sha256=
|
11
|
+
javacore_analyser/javacore_set.py,sha256=5x16j8KfA_DXD3FlvKlRHfRJ2B1rj5j2EkMfb2dV3dg,33341
|
12
12
|
javacore_analyser/logging_utils.py,sha256=vLob0ikezysjGv9XGqv9GbLekxu4eO_csq22M-gtLiQ,966
|
13
|
+
javacore_analyser/properties.py,sha256=SVxe86mL4DM_vkPEBT-V0_xDeIbXp2vjYE1aD-Z_UCQ,805
|
13
14
|
javacore_analyser/snapshot_collection.py,sha256=fLEnwg9-cOjVVUUludtzI7R2yO9BBVgJgxkhvqG5QDg,443
|
14
15
|
javacore_analyser/snapshot_collection_collection.py,sha256=1PV1TX4QQk01dAbX-k-kTpgKr6Il867Bw6X7HHBuv-Q,1346
|
15
16
|
javacore_analyser/stack_trace.py,sha256=8sb8z4ac_L0yyxqJX1ukrTZRyngkHcA3zkXyqxG5ygA,1664
|
@@ -35,14 +36,14 @@ javacore_analyser/data/jquery/theme.blue.css,sha256=cPcj8KaUj_zNy_xtDfrodSLue94n
|
|
35
36
|
javacore_analyser/data/jquery/theme.default.min.css,sha256=5sgExNTnkN8NcApKIU73_aqgZmqq_zJp9-9zXf9aSEw,4502
|
36
37
|
javacore_analyser/data/jquery/wait2scripts.js,sha256=jORUs9xgz_o-VnRm0RxjKlraZOleQrPp5DmTyrMBwrM,8577
|
37
38
|
javacore_analyser/data/xml/index.xml,sha256=9VH2rmri3FQpXcW39kbyi2dON94C5XTiaQn0ioExCe8,282
|
38
|
-
javacore_analyser/data/xml/report.xsl,sha256=
|
39
|
+
javacore_analyser/data/xml/report.xsl,sha256=LlrleGFx9MC0VOhP6CBgII1uhP-kzhbo4pwro-HwAGo,60178
|
39
40
|
javacore_analyser/data/xml/javacores/javacore.xml,sha256=6dG89Whx1_kpEYVS_F6Upa2XuXnXorlQATFc8kD5Mfc,280
|
40
41
|
javacore_analyser/data/xml/javacores/javacore.xsl,sha256=5cnIp08Q9FccljHH8duoJQYofyW8lwUCGtpdzz5Y0Y8,11644
|
41
42
|
javacore_analyser/data/xml/threads/thread.xml,sha256=6dG89Whx1_kpEYVS_F6Upa2XuXnXorlQATFc8kD5Mfc,280
|
42
43
|
javacore_analyser/data/xml/threads/thread.xsl,sha256=1tg5tImtr1gyZ8Q61tqIukNtm1fQ6R8YoKC3EgIjLRA,14084
|
43
44
|
javacore_analyser/templates/index.html,sha256=aEuyry-HZ9HlQNwfbugugvqbSxwlo7LrQnrDmqO34YE,1682
|
44
|
-
javacore_analyser-2.3.0.
|
45
|
-
javacore_analyser-2.3.0.
|
46
|
-
javacore_analyser-2.3.0.
|
47
|
-
javacore_analyser-2.3.0.
|
48
|
-
javacore_analyser-2.3.0.
|
45
|
+
javacore_analyser-2.3.0.dev16.dist-info/METADATA,sha256=9NUAKH1SIQJ-se3hFLMkv3gYAzNv6mlUuBd7MY4zORQ,22370
|
46
|
+
javacore_analyser-2.3.0.dev16.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
47
|
+
javacore_analyser-2.3.0.dev16.dist-info/entry_points.txt,sha256=W3S799zI58g5-jWMsC3wY9xksz21LPEMYOILv8sayfM,160
|
48
|
+
javacore_analyser-2.3.0.dev16.dist-info/licenses/LICENSE,sha256=xllut76FgcGL5zbIRvuRc7aezPbvlMUTWJPsVr2Sugg,11358
|
49
|
+
javacore_analyser-2.3.0.dev16.dist-info/RECORD,,
|
File without changes
|
{javacore_analyser-2.3.0.dev2.dist-info → javacore_analyser-2.3.0.dev16.dist-info}/entry_points.txt
RENAMED
File without changes
|
{javacore_analyser-2.3.0.dev2.dist-info → javacore_analyser-2.3.0.dev16.dist-info}/licenses/LICENSE
RENAMED
File without changes
|