javacore-analyser 2.1rc5__py3-none-any.whl → 2.2rc1__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.
@@ -0,0 +1,43 @@
1
+ #
2
+ # Copyright IBM Corp. 2024 - 2024
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ #
5
+ import argparse
6
+
7
+ from javacore_analyser import javacore_analyser_batch, constants, javacore_analyser_web
8
+
9
+
10
+ def main():
11
+ parser = argparse.ArgumentParser(prog="python -m javacore_analyser")
12
+ subparsers = parser.add_subparsers(dest="type", help="Application type", required=True)
13
+
14
+ batch = subparsers.add_parser("batch", description="Run batch application")
15
+ batch.add_argument("input", help="Input file(s) or directory")
16
+ batch.add_argument("output", help="Destination report directory")
17
+ batch.add_argument("--separator", default=constants.DEFAULT_FILE_DELIMITER)
18
+
19
+ web = subparsers.add_parser("web", description="Run web application")
20
+ web.add_argument("--debug", help="Debug mode. Use True only for app development", default=False)
21
+ web.add_argument("--port", help="Application port", default=constants.DEFAULT_PORT)
22
+ web.add_argument("--reports-dir", help="Directory to store reports data",
23
+ default=constants.DEFAULT_REPORTS_DIR)
24
+
25
+ args = parser.parse_args()
26
+
27
+ app_type: str = args.type
28
+
29
+ if app_type.lower() == "web":
30
+ print("Running web application")
31
+ javacore_analyser_web.run_web(args.debug, args.port, args.reports_dir)
32
+ elif app_type.lower() == "batch":
33
+ print("Running batch application")
34
+ javacore_analyser_batch.batch_process(args.input, args.output, args.separator)
35
+ else:
36
+ print('Invalid application type. Available types: "batch" or "web"')
37
+
38
+
39
+ if __name__ == '__main__':
40
+ # This is the code to be able to run the app from command line.
41
+ # Try this:
42
+ # python -m javacore_analyser -h
43
+ main()
@@ -0,0 +1,22 @@
1
+ <!DOCTYPE html>
2
+
3
+ <!--
4
+ # Copyright IBM Corp. 2024 - 2025
5
+ # SPDX-License-Identifier: Apache-2.0
6
+ -->
7
+
8
+ <html lang="en">
9
+ <head>
10
+ <meta charset="UTF-8">
11
+ <title>Processing failed</title>
12
+ </head>
13
+ <body>
14
+ <p>
15
+ Processing failed with an error. Check the log file. If the issue is a product defect, rais it on
16
+ <a href="https://github.com/IBM/javacore-analyser/issues/new?template=bug_report.md">Bug report</a> page.
17
+ </p>
18
+ <p>Please attach the stack trace</p>
19
+ <p>Stack trace: </p>
20
+ <code> {stacktrace} </code>
21
+ </body>
22
+ </html>
@@ -1,6 +1,8 @@
1
- /*************
2
- Blue Theme
3
- *************/
1
+ /*
2
+ Copyright IBM Corp. 2024 - 2025
3
+ SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
4
6
  /* overall */
5
7
  .tablesorter-blue {
6
8
  width: 100%;
@@ -109,6 +111,10 @@
109
111
  background-color: red
110
112
  }
111
113
 
114
+ .tablesorter-blue td.http_failure {
115
+ background-color: red
116
+ }
117
+
112
118
  /* hovered row colors
113
119
  you'll need to add additional lines for
114
120
  rows with more than 2 child rows
@@ -99,7 +99,9 @@ const loadChartGC = function() {
99
99
  }
100
100
 
101
101
  const sysResourceE3Elem = document.getElementById('systemresources_myChartGC');
102
- sysResourceE3Elem.classList.remove('hide');
102
+ if (sysResourceE3Elem) {
103
+ sysResourceE3Elem.classList.remove('hide');
104
+ }
103
105
 
104
106
  const ctx = document.getElementById('myChartGC');
105
107
 
@@ -125,7 +127,7 @@ const loadChartGC = function() {
125
127
  startingPoint = timestamp;
126
128
 
127
129
  if(endingPoint < timestamp)
128
- endingPoint > timestamp;
130
+ endingPoint = timestamp;
129
131
  }
130
132
 
131
133
  coresTimeRange['startTime'] = startingPoint;
@@ -1,3 +1,8 @@
1
+ /*
2
+ Copyright IBM Corp. 2024 - 2025
3
+ SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
1
6
  table.heading {
2
7
  border: none;
3
8
  width: 100%;
@@ -100,6 +105,28 @@ td {
100
105
  text-align: left;
101
106
  }
102
107
 
108
+ .info {
109
+ position: relative;
110
+ display: inline-block;
111
+ border-bottom: 1px dotted black; /* If you want dots under the hoverable text */
112
+ color: orange
113
+ }
114
+
115
+ /* Tooltip text */
116
+ .info .infotooltip {
117
+ visibility: hidden;
118
+ width: 120px;
119
+ background-color: black;
120
+ color: #fff;
121
+ text-align: center;
122
+ padding: 5px 0;
123
+ border-radius: 6px;
124
+
125
+ /* Position the tooltip text - see examples below! */
126
+ position: absolute;
127
+ z-index: 1;
128
+ }
129
+
103
130
  .warning {
104
131
  position: relative;
105
132
  display: inline-block;
@@ -142,6 +169,11 @@ mark.current {
142
169
  background: orange;
143
170
  }
144
171
 
172
+ /* Show the tooltip text when you mouse over the tooltip container */
173
+ .info:hover .infotooltip {
174
+ visibility: visible;
175
+ }
176
+
145
177
  /* Show the tooltip text when you mouse over the tooltip container */
146
178
  .warning:hover .warningtooltip {
147
179
  visibility: visible;
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
 
3
3
  <!--
4
- # Copyright IBM Corp. 2024 - 2024
4
+ # Copyright IBM Corp. 2024 - 2025
5
5
  # SPDX-License-Identifier: Apache-2.0
6
6
  -->
7
7
 
@@ -59,6 +59,15 @@
59
59
  },
60
60
  });
61
61
 
62
+ $('#har_files_table').tablesorter({
63
+ theme : 'blue',
64
+ headers: {
65
+ 0: { sorter: false },
66
+ 1: { sorter: false },
67
+ 2: { sorter: false }
68
+ },
69
+ });
70
+
62
71
  $('#java_arguments_table').tablesorter({
63
72
  theme : 'blue',
64
73
  widgets : ['zebra', 'columns'],
@@ -122,6 +131,21 @@
122
131
  sortReset : true,
123
132
  sortRestart : true
124
133
  });
134
+
135
+ $('#HttpCallTable').tablesorter({
136
+ theme : 'blue',
137
+ widgets : ['zebra', 'columns'],
138
+ sortList: [
139
+ [2, 1]
140
+ ],
141
+ sortInitialOrder: 'asc',
142
+ headers : {
143
+ 0 : { sortInitialOrder: 'asc' }
144
+ },
145
+ usNumberFormat : false,
146
+ sortReset : true,
147
+ sortRestart : true
148
+ });
125
149
  });
126
150
  </script>
127
151
  </head>
@@ -262,6 +286,49 @@
262
286
  </xsl:when>
263
287
  <xsl:otherwise> No verbose GC files </xsl:otherwise>
264
288
  </xsl:choose>
289
+ <xsl:choose>
290
+ <xsl:when test="doc/har_files">
291
+ <h4>HAR files</h4>
292
+ <a id="togglehardoc" href="javascript:expand_it(hardoc,togglehardoc)" class="expandit">
293
+ What does this table tell me?</a>
294
+ <div id="hardoc" style="display:none;">
295
+ This table shows all the HAR files that are included in the data set.
296
+ <ul>
297
+ <li>
298
+ <strong>File Name</strong>
299
+ is the name of the HAR file.
300
+ </li>
301
+ <li>
302
+ <strong>Hostname</strong>
303
+ is the name of the server machine for which the HAR file was collected.
304
+ </li>
305
+ <li>
306
+ <strong>Browser</strong>
307
+ contains information about the browser that was used to collect the HAR file.
308
+ </li>
309
+ </ul>
310
+ </div>
311
+ <table id="har_files_table">
312
+ <thead>
313
+ <tr>
314
+ <th class="sixty">File Name</th>
315
+ <th class="ten">Hostname</th>
316
+ <th class="ten">Browser</th>
317
+ </tr>
318
+ </thead>
319
+ <tbody>
320
+ <xsl:for-each select="doc/har_files/har_file">
321
+ <tr>
322
+ <td class="left"><xsl:value-of select="@filename"/></td>
323
+ <td class="left"><xsl:value-of select="@hostname"/></td>
324
+ <td class="left"><xsl:value-of select="@browser"/></td>
325
+ </tr>
326
+ </xsl:for-each>
327
+ </tbody>
328
+ </table>
329
+ </xsl:when>
330
+ <!-- xsl:otherwise> No HAR files </xsl:otherwise -->
331
+ </xsl:choose>
265
332
  </div>
266
333
  <h3><a id="toggle_system_properties"
267
334
  href="javascript:expand_it(system_properties, toggle_system_properties)"
@@ -355,25 +422,41 @@
355
422
  <h4>Garbage Collection Activity</h4>
356
423
  <a id="togglememusagedoc" href="javascript:expand_it(memusagedoc,togglememusagedoc)" class="expandit">
357
424
  What does this chart tell me?</a>
358
- <div id="memusagedoc" style="display:none;">
359
- This chart shows all the garbage collections that happened between the time
360
- of the first and the last javacore in the data set.
361
- Garbage collections that happened before the first
362
- or after the last javacore generation time are not included.
363
- <ul>
364
- <li><strong>Heap Usage</strong>
365
- is the available Java heap memory over time,
366
- based on the garbage collection data from the verbose GC log files.
367
- </li>
368
- <li><strong>Total Heap</strong>
369
- is the maximum size of the Java heap, configured by using the Xmx Java argument,
370
- expressed in megabytes.
371
- </li>
372
- </ul>
373
- </div>
374
- <div id="systemresources_myChartGC" class="chart-container hide">
375
- <canvas id="myChartGC" height="200"></canvas>
376
- </div>
425
+ <xsl:choose>
426
+ <xsl:when test="doc/report_info/verbose_gc_list/verbose_gc">
427
+ <xsl:choose>
428
+ <xsl:when test="//verbose_gc_list/@total_collects_in_time_limits = 0">
429
+ <br/>
430
+ There were no garbage collections withing the javacore time limits
431
+ </xsl:when>
432
+ <xsl:otherwise>
433
+ <div id="memusagedoc" style="display:none;">
434
+ This chart shows all the garbage collections that happened between the time
435
+ of the first and the last javacore in the data set.
436
+ Garbage collections that happened before the first
437
+ or after the last javacore generation time are not included.
438
+ <ul>
439
+ <li><strong>Heap Usage</strong>
440
+ is the available Java heap memory over time,
441
+ based on the garbage collection data from the verbose GC log files.
442
+ </li>
443
+ <li><strong>Total Heap</strong>
444
+ is the maximum size of the Java heap, configured by using the Xmx Java argument,
445
+ expressed in megabytes.
446
+ </li>
447
+ </ul>
448
+ </div>
449
+ <div id="systemresources_myChartGC" class="chart-container hide">
450
+ <canvas id="myChartGC" height="200"></canvas>
451
+ </div>
452
+ </xsl:otherwise>
453
+ </xsl:choose>
454
+ </xsl:when>
455
+ <xsl:otherwise>
456
+ <br/>
457
+ No verbosegc logs were provided
458
+ </xsl:otherwise>
459
+ </xsl:choose>
377
460
  <h4>CPU Load</h4>
378
461
  <a id="togglecpuloaddoc" href="javascript:expand_it(cpuloaddoc,togglecpuloaddoc)" class="expandit">
379
462
  What does this chart tell me?</a>
@@ -746,6 +829,70 @@
746
829
  </table>
747
830
  </div>
748
831
 
832
+ <xsl:choose>
833
+ <xsl:when test="doc/har_files">
834
+ <h3><a id="toggle_http_calls" href="javascript:expand_it(http_calls,toggle_http_calls)" class="expandit">HTTP calls</a></h3>
835
+ <div id="http_calls" style="display:none;" >
836
+ <a id="togglehttpcallsdoc" href="javascript:expand_it(httpcallsdoc,togglehttpcallsdoc)" class="expandit">
837
+ What does this table tell me?</a>
838
+ <div id="httpcallsdoc" style="display:none;">
839
+ The table shows the HTTP calls that are included in the HAR files from the data set.
840
+ The table can be sorted by clicking on a column header.
841
+ <ul>
842
+ <li><strong>URL</strong>
843
+ is the URL of the HTTP request.
844
+ </li>
845
+ <li><strong>Status</strong>
846
+ is the HTTP response code.
847
+ </li>
848
+ <li><strong>Start time</strong>
849
+ is the time when the HTTP request was made.
850
+ </li>
851
+ <li><strong>Duration</strong>
852
+ is the amount of time it took to complete the HTTP call, in milliseconds.
853
+ </li>
854
+ <li><strong>Size</strong>
855
+ is size of the response body, in bytes.
856
+ </li>
857
+ </ul>
858
+ </div>
859
+ <table id="HttpCallTable" class="tablesorter">
860
+ <thead>
861
+ <tr>
862
+ <th class="sixty">URL</th>
863
+ <th>Status</th>
864
+ <th>Start Time</th>
865
+ <th>Duration</th>
866
+ <th>Size</th>
867
+ </tr>
868
+ </thead>
869
+ <tbody>
870
+ <xsl:for-each select="//http_call">
871
+ <tr>
872
+ <td class="left"><xsl:value-of select="@url"/></td>
873
+ <td>
874
+ <xsl:choose>
875
+ <xsl:when test="@success='False'">
876
+ <xsl:attribute name="class">http_failure</xsl:attribute>
877
+ </xsl:when>
878
+ </xsl:choose>
879
+ <xsl:value-of select="@status"/>
880
+ </td>
881
+ <td><xsl:value-of select="@start_time"/></td>
882
+ <td>
883
+ <div class="info"><xsl:value-of select="@duration"/>
884
+ <span class="infotooltip"><xsl:value-of select="@timings"/></span>
885
+ </div>
886
+ </td>
887
+ <td><xsl:value-of select="@size"/></td>
888
+ </tr>
889
+ </xsl:for-each>
890
+ </tbody>
891
+ </table>
892
+ </div>
893
+ </xsl:when>
894
+ </xsl:choose>
895
+
749
896
  <p></p>
750
897
  <div class="margined">
751
898
  <a href="https://github.com/IBM/javacore-analyser/wiki" target="_blank">Documentation</a>
@@ -0,0 +1,65 @@
1
+ #
2
+ # Copyright IBM Corp. 2024 - 2025
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ #
5
+ import os
6
+
7
+ from haralyzer import HarParser
8
+ import json
9
+
10
+
11
+ class HarFile:
12
+
13
+ def __init__(self, path):
14
+ self.path = path
15
+ with open(path, 'r') as f:
16
+ self.har = HarParser(json.loads(f.read()))
17
+
18
+ def get_xml(self, doc):
19
+ har_file_node = doc.createElement("har_file")
20
+ har_file_node.setAttribute("filename", os.path.basename(self.path))
21
+ har_file_node.setAttribute("hostname", str(self.har.hostname))
22
+ har_file_node.setAttribute("browser", str(self.har.browser))
23
+ for page in self.har.pages:
24
+ for entry in page.entries:
25
+ http_call = HttpCall(entry)
26
+ har_file_node.appendChild(http_call.get_xml(doc))
27
+ return har_file_node
28
+
29
+
30
+ class HttpCall:
31
+
32
+ def __init__(self, call):
33
+ self.call = call
34
+ self.url = call.url
35
+ self.status = str(call.status)
36
+ self.start_time = str(call.startTime)
37
+ self.duration = str(self.get_total_time())
38
+ self.timings = str(call.timings)
39
+ self.size = str(call.response.bodySize)
40
+ self.success = str(self.get_success())
41
+
42
+ def get_total_time(self):
43
+ total = 0
44
+ if len(self.call.timings) > 0:
45
+ for key in self.call.timings.keys():
46
+ time = int(self.call.timings[key])
47
+ if time > 0:
48
+ total += time
49
+ return total
50
+
51
+ def get_success(self):
52
+ if self.status.startswith('4') or self.status.startswith('5'):
53
+ return False
54
+ return True
55
+
56
+ def get_xml(self, doc):
57
+ http_call_node = doc.createElement("http_call")
58
+ http_call_node.setAttribute("url", self.url)
59
+ http_call_node.setAttribute("status", self.status)
60
+ http_call_node.setAttribute("start_time", self.start_time)
61
+ http_call_node.setAttribute("duration", self.duration)
62
+ http_call_node.setAttribute("timings", self.timings)
63
+ http_call_node.setAttribute("size", self.size)
64
+ http_call_node.setAttribute("success", self.success)
65
+ return http_call_node
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright IBM Corp. 2024 - 2024
2
+ # Copyright IBM Corp. 2024 - 2025
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
  #
5
5
 
@@ -12,6 +12,7 @@ import shutil
12
12
  import sys
13
13
  import tarfile
14
14
  import tempfile
15
+ import traceback
15
16
  import zipfile
16
17
 
17
18
  import importlib_resources
@@ -64,11 +65,6 @@ def extract_archive(input_archive_filename, output_path):
64
65
 
65
66
 
66
67
  def main():
67
- logging_utils.create_console_logging()
68
- logging.info("IBM Javacore analyser")
69
- logging.info("Python version: " + sys.version)
70
- logging.info("Preferred encoding: " + locale.getpreferredencoding())
71
-
72
68
  parser = argparse.ArgumentParser()
73
69
  parser.add_argument("input", help="Input javacore file(s) or directory with javacores. "
74
70
  "The javacores can be packed "
@@ -86,12 +82,19 @@ def main():
86
82
  output_param = args.output
87
83
  files_separator = args.separator
88
84
 
85
+ batch_process(input_param, output_param, files_separator)
86
+
87
+
88
+ def batch_process(input_param, output_param, files_separator=DEFAULT_FILE_DELIMITER):
89
+ logging_utils.create_console_logging()
90
+ logging.info("IBM Javacore analyser")
91
+ logging.info("Python version: " + sys.version)
92
+ logging.info("Preferred encoding: " + locale.getpreferredencoding())
89
93
  logging.info("Input parameter: " + input_param)
90
94
  logging.info("Report directory: " + output_param)
91
-
95
+ output_param = os.path.normpath(output_param)
92
96
  # Needs to be created once output file structure is ready.
93
97
  logging_utils.create_file_logging(output_param)
94
-
95
98
  # Check whether as input we got list of files or single file
96
99
  # Semicolon is separation mark for list of input files
97
100
  if files_separator in input_param or fnmatch.fnmatch(input_param, '*javacore*.txt'):
@@ -100,6 +103,7 @@ def main():
100
103
  else:
101
104
  files = [input_param]
102
105
  try:
106
+ files = [os.path.normpath(file) for file in files]
103
107
  process_javacores_and_generate_report_data(files, output_param)
104
108
  except Exception as ex:
105
109
  logging.exception(ex)
@@ -156,6 +160,15 @@ def create_output_files_structure(output_dir):
156
160
  os.path.join(output_dir, "index.html"))
157
161
 
158
162
 
163
+ def generate_error_page(output_dir, exception):
164
+ error_page_text = importlib_resources.read_text("javacore_analyser", "data/html/error.html")
165
+ tb = traceback.format_exc()
166
+ file = os.path.join(output_dir, "index.html")
167
+ f = open(file, "w")
168
+ f.write(error_page_text.format(stacktrace=tb))
169
+ f.close()
170
+
171
+
159
172
  # Assisted by WCA@IBM
160
173
  # Latest GenAI contribution: ibm/granite-8b-code-instruct
161
174
  def process_javacores_and_generate_report_data(input_files, output_dir):
@@ -169,9 +182,14 @@ def process_javacores_and_generate_report_data(input_files, output_dir):
169
182
  Returns:
170
183
  None
171
184
  """
172
- create_output_files_structure(output_dir)
173
- javacore_set = generate_javecore_set_data(input_files)
174
- javacore_set.generate_report_files(output_dir)
185
+ try:
186
+ create_output_files_structure(output_dir)
187
+ javacore_set = generate_javecore_set_data(input_files)
188
+ javacore_set.generate_report_files(output_dir)
189
+ except Exception as ex:
190
+ logging.exception(ex)
191
+ logging.error("Processing was not successful. Correct the problem and try again.")
192
+ generate_error_page(output_dir, ex)
175
193
 
176
194
 
177
195
  if __name__ == "__main__":
@@ -132,9 +132,14 @@ def main():
132
132
  args = parser.parse_args()
133
133
  debug = args.debug
134
134
  port = args.port
135
- global reports_dir
136
- reports_dir = args.reports_dir
135
+ reports_directory = args.reports_dir
136
+
137
+ run_web(debug, port, reports_directory)
138
+
137
139
 
140
+ def run_web(debug=False, port=5000, reports_directory=DEFAULT_REPORTS_DIR):
141
+ global reports_dir
142
+ reports_dir = reports_directory
138
143
  create_console_logging()
139
144
  logging.info("Javacore analyser")
140
145
  logging.info("Python version: " + sys.version)
@@ -142,7 +147,6 @@ def main():
142
147
  logging.info("Reports directory: " + reports_dir)
143
148
  create_file_logging(reports_dir)
144
149
  create_temp_data_in_reports_dir(reports_dir)
145
-
146
150
  if debug:
147
151
  app.run(debug=True, port=port) # Run Flask for development
148
152
  else:
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright IBM Corp. 2024 - 2024
2
+ # Copyright IBM Corp. 2024 - 2025
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
  #
5
5
 
@@ -22,6 +22,7 @@ from tqdm import tqdm
22
22
  from javacore_analyser import tips
23
23
  from javacore_analyser.code_snapshot_collection import CodeSnapshotCollection
24
24
  from javacore_analyser.constants import *
25
+ from javacore_analyser.har_file import HarFile
25
26
  from javacore_analyser.java_thread import Thread
26
27
  from javacore_analyser.javacore import Javacore
27
28
  from javacore_analyser.snapshot_collection import SnapshotCollection
@@ -87,6 +88,7 @@ class JavacoreSet:
87
88
  self.blocked_snapshots = []
88
89
  self.tips = []
89
90
  self.gc_parser = VerboseGcParser()
91
+ self.har_files = []
90
92
 
91
93
  # Assisted by WCA@IBM
92
94
  # Latest GenAI contribution: ibm/granite-8b-code-instruct
@@ -140,16 +142,18 @@ class JavacoreSet:
140
142
 
141
143
  @staticmethod
142
144
  def __generate_placeholder_htmls(placeholder_file, directory, collection, file_prefix):
145
+ logging.info("Generating placeholder htmls")
143
146
  if os.path.exists(directory):
144
147
  shutil.rmtree(directory)
145
148
  os.mkdir(directory)
146
149
 
147
- for element in tqdm(collection, desc="Generating placeholder htmls", unit=" file"):
150
+ for element in tqdm(collection, desc="Generating placeholder htmls", unit=" files"):
148
151
  filename = file_prefix + "_" + element.get_id() + ".html"
149
152
  if filename.startswith("_"):
150
153
  filename = filename[1:]
151
154
  file_path = os.path.join(directory, filename)
152
155
  shutil.copy2(placeholder_file, file_path)
156
+ logging.info("Finished generating placeholder htmls")
153
157
 
154
158
  def __generate_htmls_for_threads(self, output_dir, temp_dir_name):
155
159
  _create_xml_xsl_for_collection(os.path.join(temp_dir_name, "threads"),
@@ -230,6 +234,9 @@ class JavacoreSet:
230
234
  if fnmatch.fnmatch(file, '*verbosegc*.txt*'):
231
235
  self.gc_parser.add_file(dirpath + os.sep + file)
232
236
  logging.info("VerboseGC file found: " + file)
237
+ if fnmatch.fnmatch(file, "*.har"):
238
+ self.har_files.append(HarFile(dirpath + os.sep + file))
239
+ logging.info("HAR file found: " + file)
233
240
 
234
241
  # sorting files by name.
235
242
  # Unless the user changed the javacore file name format, this is equivalent to sorting by date
@@ -385,6 +392,8 @@ class JavacoreSet:
385
392
 
386
393
  verbose_gc_list_node = self.doc.createElement("verbose_gc_list")
387
394
  report_info_node.appendChild(verbose_gc_list_node)
395
+
396
+ total_collects_in_time_limits = 0
388
397
  for vgc in self.gc_parser.get_files():
389
398
  verbose_gc_node = self.doc.createElement("verbose_gc")
390
399
  verbose_gc_list_node.appendChild(verbose_gc_node)
@@ -394,9 +403,17 @@ class JavacoreSet:
394
403
  verbose_gc_collects_node = self.doc.createElement("verbose_gc_collects")
395
404
  verbose_gc_node.appendChild(verbose_gc_collects_node)
396
405
  verbose_gc_collects_node.appendChild(self.doc.createTextNode(str(vgc.get_number_of_collects())))
406
+ total_collects_in_time_limits += vgc.get_number_of_collects()
397
407
  verbose_gc_total_collects_node = self.doc.createElement("verbose_gc_total_collects")
398
408
  verbose_gc_node.appendChild(verbose_gc_total_collects_node)
399
409
  verbose_gc_total_collects_node.appendChild(self.doc.createTextNode(str(vgc.get_total_number_of_collects())))
410
+ verbose_gc_list_node.setAttribute("total_collects_in_time_limits", str(total_collects_in_time_limits))
411
+
412
+ if len(self.har_files) > 0:
413
+ har_files_node = self.doc.createElement("har_files")
414
+ doc_node.appendChild(har_files_node)
415
+ for har in self.har_files:
416
+ har_files_node.appendChild(har.get_xml(self.doc))
400
417
 
401
418
  system_info_node = self.doc.createElement("system_info")
402
419
  doc_node.appendChild(system_info_node)
@@ -155,7 +155,6 @@ class VerboseGcFile:
155
155
  gets the total number of gc collections in this VerboseGcFile
156
156
  regardless of the time when tey occurred with regards to the javacores
157
157
  '''
158
-
159
158
  def get_total_number_of_collects(self):
160
159
  if self.__total_number_of_collects < 0:
161
160
  self.get_collects()
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: javacore_analyser
3
- Version: 2.1rc5
3
+ Version: 2.2rc1
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
7
- Project-URL: Changelog, https://github.com/IBM/javacore-analyser/CHANGELOG.md
7
+ Project-URL: Changelog, https://github.com/IBM/javacore-analyser/blob/main/CHANGELOG.md
8
8
  Project-URL: Source, https://github.com/IBM/javacore-analyser
9
9
  Author-email: Krzysztof Kazmierczyk <kazm@ibm.com>, Piotr Aniola <Piotr.Aniola@ibm.com>, Tadeusz Janasiewicz <t.janasiewicz@ibm.com>
10
10
  License: Apache License
@@ -228,6 +228,7 @@ Classifier: Programming Language :: Python :: 3.12
228
228
  Classifier: Programming Language :: Python :: 3.13
229
229
  Requires-Python: >=3.9
230
230
  Requires-Dist: flask
231
+ Requires-Dist: haralyzer
231
232
  Requires-Dist: importlib-resources
232
233
  Requires-Dist: lxml
233
234
  Requires-Dist: py7zr
@@ -239,8 +240,18 @@ Description-Content-Type: text/markdown
239
240
  <!-- This should be the location of the title of the repository, normally the short name -->
240
241
  # Javacore Analyser
241
242
 
243
+ ![GitHub License](https://img.shields.io/github/license/IBM/javacore-analyser)
244
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/javacore-analyser)
245
+ ![GitHub contributors](https://img.shields.io/github/contributors/IBM/javacore-analyser)
242
246
  <!-- Build Status, is a great thing to have at the top of your repository, it shows that you take your CI/CD as first class citizens -->
243
247
  [![Build Status](https://app.travis-ci.com/IBM/javacore-analyser.svg?token=w3i4X11XppEi2tJQsxDb&branch=main)](https://app.travis-ci.com/IBM/javacore-analyser)
248
+ ![GitHub last commit](https://img.shields.io/github/last-commit/IBM/javacore-analyser)
249
+ ![GitHub Release Date](https://img.shields.io/github/release-date/IBM/javacore-analyser)
250
+ ![GitHub commit activity](https://img.shields.io/github/commit-activity/t/IBM/javacore-analyser)
251
+ ![GitHub Issues or Pull Requests](https://img.shields.io/github/issues-pr/IBM/javacore-analyser)
252
+ ![GitHub Issues or Pull Requests](https://img.shields.io/github/issues-pr-closed/IBM/javacore-analyser)
253
+ ![PyPI - Downloads](https://img.shields.io/pypi/dm/javacore-analyser)
254
+
244
255
 
245
256
  <!-- Not always needed, but a scope helps the user understand in a short sentance like below, why this repo exists -->
246
257
  ## Scope
@@ -267,7 +278,7 @@ Steps:
267
278
  3. Run the following command:
268
279
  `pip install javacore-analyser`
269
280
  OR
270
- `pip install --extra-index-url https://test.pypi.org/simple/ javacore-analyser` - if you want an experimental version
281
+ `pip install --pre --extra-index-url https://test.pypi.org/simple/ javacore-analyser` - if you want an experimental version
271
282
 
272
283
  #### Installing from sources
273
284
  This is recommended for geeks only:
@@ -281,23 +292,29 @@ This is recommended for geeks only:
281
292
  #### Running cmd application:
282
293
  1. Install application if not done yet
283
294
  2. Activate your created virtual environment according to activate Virtual Environment according to [Creating virtual environments](https://docs.python.org/3/tutorial/venv.html#creating-virtual-environments)
284
- 3. Run the following command from cmd: `javacore-analyser-batch <input-data> <generated-reports-dir>`
295
+ 3. Run the following command from cmd:
296
+ `javacore-analyser-batch <input-data> <generated-reports-dir>`
297
+ or
298
+ `python -m javacore_analyser batch <input-data> <generated-reports-dir>`
299
+
285
300
  Where `<input-data>` is one of the following:
286
301
  * The directory containing javacores and optionally verbose gc
287
302
  * Archive (7z, zip, tar.gz, tar.bz2) containing the same
288
303
  * List of the javacores separated by `;` character. Optionally you can add `--separator` option to define your own separator.
289
304
  You can type the following command to obtain the help:
290
- `javacore-analyser-batch --help`
305
+ `javacore-analyser-batch --help` or `python -m javacore_analyser batch --help`
291
306
 
292
307
  #### Running web application:
293
308
  1. Repeat steps 1-3 from cmd application
294
309
  2. Execute the following command from cmd:
295
- `javacore_analyser_web --port=500 --reports-dir=/data/reports_dir`
310
+ `javacore_analyser_web --port=5000 --reports-dir=/data/reports_dir`
311
+ or
312
+ `python -m javacore_analyser web --port=5000 --reports-dir=/data/reports_dir`
296
313
 
297
- The first parameter set the port to use by application. If not specified, 5000 will be used.
298
- The second parameter sets where the reports need to be stored. If not set, then the `reports` dir will be created in current location.
314
+ The first parameter set the port to use by application. If not specified, 5000 will be used.
315
+ The second parameter sets where the reports need to be stored. If not set, then the `reports` dir will be created in current location.
299
316
 
300
- Now you can type (http://localhost:5000/).
317
+ Now you can type (http://localhost:5000/).
301
318
 
302
319
  ### Running container image
303
320
  There is an unofficial Docker/Podman container managed by one of projects developers. Use the following command
@@ -1,12 +1,14 @@
1
1
  javacore_analyser/__init__.py,sha256=Sw2ZeqcI2Kx1cDDv083n1SiSY_FDRCmidTuzaN1uRSw,76
2
+ javacore_analyser/__main__.py,sha256=wQCPgu8Gp7XczyNckNGmY30c5YMUMRByW7jrdFO0OBY,1694
2
3
  javacore_analyser/abstract_snapshot_collection.py,sha256=jGfd2XgujurRlKgEtlJjqNJK9sUvTdFsdgFnX9oLzt4,5589
3
4
  javacore_analyser/code_snapshot_collection.py,sha256=6_C5myag5ocjOTwXVDbBamN6Lf1szgS3ylSHEEjUdVg,2655
4
5
  javacore_analyser/constants.py,sha256=iGYAznPK8AySq6uqk-cpCU8Dbjbq6PrCh6q2mF8oeu8,1003
6
+ javacore_analyser/har_file.py,sha256=grXpfIyPek9xQ5jp3_AYOB5JDELd17o4O4rYELxWO7w,2131
5
7
  javacore_analyser/java_thread.py,sha256=4zUfmmlH47SrIxgfPmrJHl_YUziVJXVNVedD5X25vXY,4464
6
8
  javacore_analyser/javacore.py,sha256=_2abTyvXEaZ6Tx8r9d3NEzRCIBcf4Is8lSjpKyPu-R8,6884
7
- javacore_analyser/javacore_analyser_batch.py,sha256=g6xVPYFDHTaXDbaruyMRUrD3g2IlJK3Ht-XUzHv3LoQ,6802
8
- javacore_analyser/javacore_analyser_web.py,sha256=Ef91ZTI5TBaJPJhl0FtzrFHvzJNPLe07fmvbvik3OJQ,5788
9
- javacore_analyser/javacore_set.py,sha256=YM6ZKUhbfqzjuKE5y7Jy19Hbl-BSLA1i5gIsP7NbX38,31241
9
+ javacore_analyser/javacore_analyser_batch.py,sha256=D9H6ct_PBAXR_PvTqGtKw_FIx9Q9KuJSFBeEZ2FIkbo,7607
10
+ javacore_analyser/javacore_analyser_web.py,sha256=o-Spq119Wi7w4pvBa7M7ZrxiZnzKmWqDhCdGtEReQAU,5951
11
+ javacore_analyser/javacore_set.py,sha256=R3QiyDfDOBtzTUwQzS8ft2-Ca7fkReSD5KJzgZl6oVY,32103
10
12
  javacore_analyser/logging_utils.py,sha256=vLob0ikezysjGv9XGqv9GbLekxu4eO_csq22M-gtLiQ,966
11
13
  javacore_analyser/snapshot_collection.py,sha256=fLEnwg9-cOjVVUUludtzI7R2yO9BBVgJgxkhvqG5QDg,443
12
14
  javacore_analyser/snapshot_collection_collection.py,sha256=1PV1TX4QQk01dAbX-k-kTpgKr6Il867Bw6X7HHBuv-Q,1346
@@ -15,9 +17,10 @@ javacore_analyser/stack_trace_element.py,sha256=pZPrK1ACBUDE7YsVOFhTfewXequ1m5P-
15
17
  javacore_analyser/stack_trace_kind.py,sha256=lOdfb_F3XrwDLciPk_ZgM_fmMn5JoXsIUjr7pjvmU4M,157
16
18
  javacore_analyser/thread_snapshot.py,sha256=2Do8NPBXdpUezQrUI_9nyGbtU4b2s5euPnHqcuuKq7U,13255
17
19
  javacore_analyser/tips.py,sha256=EhwLUAha0FvFJtO5kmvba9a1nKXGdqNHFa2jFbHZr4U,8655
18
- javacore_analyser/verbose_gc.py,sha256=LLJ-PS2maOkP6zfW-RBGoEoHQBI99Reejb1tqpZispY,6872
20
+ javacore_analyser/verbose_gc.py,sha256=r5ZOZVhdrrgFTGo1Rx-FFPFNRpvX1jflP6AkNATMpIQ,6871
19
21
  javacore_analyser/data/expand.js,sha256=KwqvNUoO7yMDeQKcnLDywfMdR3Zsjan5L8QoPsQQLGo,956
20
- javacore_analyser/data/style.css,sha256=YzHl0NSnfRik4ar6AInp7pZ_re1rirQy6L5jqdbKoKg,2246
22
+ javacore_analyser/data/style.css,sha256=HSKPajW3EItHjye6mSGNMRPEzfE2r7o1Gq-BEAI54Ts,2879
23
+ javacore_analyser/data/html/error.html,sha256=dJI5RdeNL1E4Y-zaU7NTBqrsxCuAovVc1Cebrk5GcYA,520
21
24
  javacore_analyser/data/html/processing_data.html,sha256=S1S2GMXQ8oQdqdYTcPzVMxUib-NLtM4ffT3OJaIIO7w,421
22
25
  javacore_analyser/data/jquery/chart.js,sha256=tgiW1vJqfIKxE0F2uVvsXbgUlTyrhPMY_sm30hh_Sxc,203464
23
26
  javacore_analyser/data/jquery/chartjs-adapter-date-fns.bundle.min.js,sha256=6nqzDSbDjc8fLSa7Q-c6lFN7WPGQb1XhpUbdCTIbVhU,50650
@@ -28,18 +31,18 @@ javacore_analyser/data/jquery/jquery.tablesorter.min.js,sha256=dtGH1XcAyKopMui5x
28
31
  javacore_analyser/data/jquery/jquery.tablesorter.widgets.min.js,sha256=GxbszpUzg-iYIcyDGyNVLz9Y0dQvzmQgXXVk5cHJbw0,53100
29
32
  javacore_analyser/data/jquery/search.js,sha256=Jwi-cBJ9YKDHJwqIlcKXqrpcM1BX-wx93uKAR44JLww,4200
30
33
  javacore_analyser/data/jquery/sorting.js,sha256=HsuVLa7F70IM4ZMXZpjj7wtVI1TXL1SPbZGWenv0Jp8,369
31
- javacore_analyser/data/jquery/theme.blue.css,sha256=mI0RCGd6G5GOKSG7BPagp0N58xipSjPXUKvrcHJ4h1Q,7528
34
+ javacore_analyser/data/jquery/theme.blue.css,sha256=cPcj8KaUj_zNy_xtDfrodSLue94nnYgyVNIZRusggCw,7624
32
35
  javacore_analyser/data/jquery/theme.default.min.css,sha256=5sgExNTnkN8NcApKIU73_aqgZmqq_zJp9-9zXf9aSEw,4502
33
- javacore_analyser/data/jquery/wait2scripts.js,sha256=CMbSqte7Ln0hP9ZScESGdIDfWEmxJwvfLZjDfYNc1Sg,8427
36
+ javacore_analyser/data/jquery/wait2scripts.js,sha256=z6zmSAak0R6bjh7BeHlIOSImiZSy5Y3z5ygMiN-sPxI,8460
34
37
  javacore_analyser/data/xml/index.xml,sha256=9VH2rmri3FQpXcW39kbyi2dON94C5XTiaQn0ioExCe8,282
35
- javacore_analyser/data/xml/report.xsl,sha256=XEwgf0qfXL1fXjj-X5iYYwt-D0cPjI9mLjhTmRvyNnk,49697
38
+ javacore_analyser/data/xml/report.xsl,sha256=_0b2i97QvCnauC-ZiNWndTQZzWGM18DH_hU7k4kUIno,58761
36
39
  javacore_analyser/data/xml/javacores/javacore.xml,sha256=6dG89Whx1_kpEYVS_F6Upa2XuXnXorlQATFc8kD5Mfc,280
37
40
  javacore_analyser/data/xml/javacores/javacore.xsl,sha256=5cnIp08Q9FccljHH8duoJQYofyW8lwUCGtpdzz5Y0Y8,11644
38
41
  javacore_analyser/data/xml/threads/thread.xml,sha256=6dG89Whx1_kpEYVS_F6Upa2XuXnXorlQATFc8kD5Mfc,280
39
42
  javacore_analyser/data/xml/threads/thread.xsl,sha256=rkqr5GQ2aZ_xrdhUjl2QZDCZ-09zxqUmtV8DFZVjTAA,13927
40
43
  javacore_analyser/templates/index.html,sha256=aEuyry-HZ9HlQNwfbugugvqbSxwlo7LrQnrDmqO34YE,1682
41
- javacore_analyser-2.1rc5.dist-info/METADATA,sha256=CMlVgoGP1Fnpof2ycHYf2Auj6XOLRdrO5Q7Jcgr5oVo,21226
42
- javacore_analyser-2.1rc5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
43
- javacore_analyser-2.1rc5.dist-info/entry_points.txt,sha256=W3S799zI58g5-jWMsC3wY9xksz21LPEMYOILv8sayfM,160
44
- javacore_analyser-2.1rc5.dist-info/licenses/LICENSE,sha256=xllut76FgcGL5zbIRvuRc7aezPbvlMUTWJPsVr2Sugg,11358
45
- javacore_analyser-2.1rc5.dist-info/RECORD,,
44
+ javacore_analyser-2.2rc1.dist-info/METADATA,sha256=k0X6Ym946yfW7F5FPJsEdKit9HJENda2Vw4F1syALSA,22285
45
+ javacore_analyser-2.2rc1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
46
+ javacore_analyser-2.2rc1.dist-info/entry_points.txt,sha256=W3S799zI58g5-jWMsC3wY9xksz21LPEMYOILv8sayfM,160
47
+ javacore_analyser-2.2rc1.dist-info/licenses/LICENSE,sha256=xllut76FgcGL5zbIRvuRc7aezPbvlMUTWJPsVr2Sugg,11358
48
+ javacore_analyser-2.2rc1.dist-info/RECORD,,