javacore-analyser 2.0rc1__py3-none-any.whl → 2.1__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/__main__.py +43 -0
- javacore_analyser/abstract_snapshot_collection.py +2 -2
- javacore_analyser/constants.py +2 -1
- javacore_analyser/data/expand.js +2 -0
- javacore_analyser/data/html/processing_data.html +17 -0
- javacore_analyser/data/jquery/search.js +22 -0
- javacore_analyser/data/jquery/wait2scripts.js +31 -7
- javacore_analyser/data/xml/javacores/javacore.xsl +126 -117
- javacore_analyser/data/xml/report.xsl +36 -20
- javacore_analyser/data/xml/threads/thread.xsl +162 -153
- javacore_analyser/javacore.py +5 -3
- javacore_analyser/javacore_analyser_batch.py +45 -22
- javacore_analyser/javacore_analyser_web.py +62 -26
- javacore_analyser/javacore_set.py +82 -43
- javacore_analyser/snapshot_collection_collection.py +5 -3
- javacore_analyser/stack_trace.py +2 -2
- javacore_analyser/stack_trace_element.py +1 -1
- javacore_analyser/templates/index.html +9 -4
- javacore_analyser/thread_snapshot.py +3 -2
- javacore_analyser/tips.py +5 -3
- javacore_analyser/verbose_gc.py +4 -2
- {javacore_analyser-2.0rc1.dist-info → javacore_analyser-2.1.dist-info}/METADATA +46 -20
- javacore_analyser-2.1.dist-info/RECORD +46 -0
- {javacore_analyser-2.0rc1.dist-info → javacore_analyser-2.1.dist-info}/WHEEL +1 -1
- javacore_analyser-2.0rc1.dist-info/RECORD +0 -44
- {javacore_analyser-2.0rc1.dist-info → javacore_analyser-2.1.dist-info}/entry_points.txt +0 -0
- {javacore_analyser-2.0rc1.dist-info → javacore_analyser-2.1.dist-info}/licenses/LICENSE +0 -0
@@ -20,177 +20,186 @@
|
|
20
20
|
<script type="text/javascript" src="../data/jquery/chart.js"> _ </script>
|
21
21
|
<script type="text/javascript" src="../data/jquery/chartjs-adapter-date-fns.bundle.min.js"> _ </script>
|
22
22
|
<script type="text/javascript" src="../data/jquery/wait2scripts.js"> _ </script>
|
23
|
-
|
23
|
+
<script src="../data/jquery/jquery.mark.min.js"> _ </script>
|
24
|
+
<script type="text/javascript" src="../data/jquery/search.js"> _ </script>
|
24
25
|
</head>
|
25
|
-
|
26
26
|
<body id="doc_body" height="100%">
|
27
|
-
<
|
28
|
-
|
29
|
-
|
30
|
-
<
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
<
|
42
|
-
<
|
43
|
-
<
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
<
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
</xsl:choose>
|
73
|
-
<xsl:choose>
|
74
|
-
<xsl:when test="position()=1">
|
75
|
-
<td>N/A</td>
|
76
|
-
</xsl:when>
|
77
|
-
<xsl:otherwise>
|
78
|
-
<td><xsl:value-of select='format-number(cpu_usage, "0.##")'/></td>
|
79
|
-
</xsl:otherwise>
|
80
|
-
</xsl:choose>
|
81
|
-
<xsl:choose>
|
27
|
+
<div class="searchbar">
|
28
|
+
<input id="search-input" type="search" />
|
29
|
+
<button data-search="search" id="search-button">Search</button>
|
30
|
+
<button data-search="next">Next</button>
|
31
|
+
<button data-search="prev">Prev</button>
|
32
|
+
<button data-search="clear">✖</button>
|
33
|
+
</div>
|
34
|
+
<div class="content">
|
35
|
+
<p class="right"><a href="../index.html"> Back to Main page </a></p>
|
36
|
+
<h2>Wait Report for thread: <b><xsl:value-of select="thread_name"/></b></h2>
|
37
|
+
<xsl:choose>
|
38
|
+
<xsl:when test="//javacore_count = 1">
|
39
|
+
System resource utilization data cannot be calculated with only a single javacore.
|
40
|
+
</xsl:when>
|
41
|
+
<xsl:otherwise>
|
42
|
+
<div class="chart-container" height="25%">
|
43
|
+
<canvas id="myChart" height="100%"></canvas>
|
44
|
+
</div>
|
45
|
+
</xsl:otherwise>
|
46
|
+
</xsl:choose>
|
47
|
+
<div id="all_threads">
|
48
|
+
<table id="all_threads_table_thread_xsl">
|
49
|
+
<thead>
|
50
|
+
<tr>
|
51
|
+
<th>Timestamp</th>
|
52
|
+
<th>Elapsed time (s)</th>
|
53
|
+
<th>CPU usage (s)</th>
|
54
|
+
<th>% CPU usage</th>
|
55
|
+
<th class='sixty'>Stack trace</th>
|
56
|
+
<th>State</th>
|
57
|
+
<th>Blocking</th>
|
58
|
+
</tr>
|
59
|
+
</thead>
|
60
|
+
<!-- Snapshot starts here -->
|
61
|
+
<xsl:for-each select="*[starts-with(name(), 'stack')]">
|
62
|
+
<tr>
|
63
|
+
<td>
|
64
|
+
<a>
|
65
|
+
<xsl:attribute name="href">
|
66
|
+
../javacores/<xsl:value-of select="file_name"/>.html
|
67
|
+
</xsl:attribute>
|
68
|
+
<xsl:value-of select='timestamp'/>
|
69
|
+
</a>
|
70
|
+
</td>
|
71
|
+
<xsl:choose>
|
82
72
|
<xsl:when test="position()=1">
|
83
73
|
<td>N/A</td>
|
84
74
|
</xsl:when>
|
85
75
|
<xsl:otherwise>
|
86
|
-
<td
|
76
|
+
<td>
|
77
|
+
<xsl:value-of select='format-number(elapsed_time, "0.##")'/>
|
78
|
+
</td>
|
87
79
|
</xsl:otherwise>
|
88
80
|
</xsl:choose>
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
<xsl:value-of select="current()"/>
|
101
|
-
</span>
|
102
|
-
<br/>
|
103
|
-
</xsl:for-each>
|
104
|
-
</p>
|
81
|
+
<xsl:choose>
|
82
|
+
<xsl:when test="position()=1">
|
83
|
+
<td>N/A</td>
|
84
|
+
</xsl:when>
|
85
|
+
<xsl:otherwise>
|
86
|
+
<td><xsl:value-of select='format-number(cpu_usage, "0.##")'/></td>
|
87
|
+
</xsl:otherwise>
|
88
|
+
</xsl:choose>
|
89
|
+
<xsl:choose>
|
90
|
+
<xsl:when test="position()=1">
|
91
|
+
<td>N/A</td>
|
105
92
|
</xsl:when>
|
106
93
|
<xsl:otherwise>
|
107
|
-
|
94
|
+
<td><xsl:value-of select='format-number(cpu_percentage, "0.#")'/></td>
|
108
95
|
</xsl:otherwise>
|
109
96
|
</xsl:choose>
|
110
|
-
|
111
|
-
|
112
|
-
<xsl:choose>
|
113
|
-
<xsl:when test="state='CW'">
|
114
|
-
<td class="waiting">
|
115
|
-
<xsl:choose>
|
116
|
-
<xsl:when test="blocked_by=''">
|
117
|
-
Waiting on condition
|
118
|
-
</xsl:when>
|
119
|
-
<xsl:otherwise>
|
120
|
-
<a target="_blank">
|
121
|
-
<xsl:attribute name="href">
|
122
|
-
<xsl:value-of select="concat('thread_', blocked_by/@thread_hash, '.html')"/>
|
123
|
-
</xsl:attribute>
|
124
|
-
<xsl:attribute name="title">
|
125
|
-
<xsl:value-of select="blocked_by/@name" />
|
126
|
-
</xsl:attribute>
|
127
|
-
Waiting for <xsl:value-of select="blocked_by/@thread_id"/>
|
128
|
-
</a>
|
129
|
-
</xsl:otherwise>
|
130
|
-
</xsl:choose>
|
131
|
-
</td>
|
132
|
-
</xsl:when>
|
133
|
-
<xsl:when test="state='R'">
|
134
|
-
<td class="runnable">Runnable</td>
|
135
|
-
</xsl:when>
|
136
|
-
<xsl:when test="state='P'">
|
137
|
-
<td class="parked">
|
97
|
+
<td class="left">
|
98
|
+
<div>
|
138
99
|
<xsl:choose>
|
139
|
-
<xsl:when test="
|
140
|
-
|
100
|
+
<xsl:when test="stack_depth > 0">
|
101
|
+
<div class="toggle_expand">
|
102
|
+
<a href="javaScript:;" class="show">[+] Expand</a>
|
103
|
+
</div>
|
104
|
+
<p class="stacktrace">
|
105
|
+
<xsl:for-each select="*[starts-with(name(), 'line')]">
|
106
|
+
<span>
|
107
|
+
<xsl:attribute name="class"><xsl:value-of select="@kind"/></xsl:attribute>
|
108
|
+
<xsl:value-of select="current()"/>
|
109
|
+
</span>
|
110
|
+
<br/>
|
111
|
+
</xsl:for-each>
|
112
|
+
</p>
|
141
113
|
</xsl:when>
|
142
114
|
<xsl:otherwise>
|
143
|
-
|
144
|
-
<xsl:attribute name="href">
|
145
|
-
<xsl:value-of select="concat('thread_', blocked_by/@thread_hash, '.html')"/>
|
146
|
-
</xsl:attribute>
|
147
|
-
<xsl:attribute name="title">
|
148
|
-
<xsl:value-of select="blocked_by/@name" />
|
149
|
-
</xsl:attribute>
|
150
|
-
Parked on <xsl:value-of select="blocked_by/@thread_id"/>
|
151
|
-
</a>
|
115
|
+
No Stack
|
152
116
|
</xsl:otherwise>
|
153
117
|
</xsl:choose>
|
154
|
-
</
|
155
|
-
</
|
156
|
-
<xsl:when test="state='B'">
|
157
|
-
<td class="blocked">
|
158
|
-
<a target="_blank">
|
159
|
-
<xsl:attribute name="href">
|
160
|
-
<xsl:value-of select="concat('thread_', blocked_by/@thread_hash, '.html')"/>
|
161
|
-
</xsl:attribute>
|
162
|
-
<xsl:attribute name="title">
|
163
|
-
<xsl:value-of select="blocked_by/@name" />
|
164
|
-
</xsl:attribute>
|
165
|
-
Blocked by <xsl:value-of select="blocked_by/@thread_id"/>
|
166
|
-
</a>
|
167
|
-
</td>
|
168
|
-
</xsl:when>
|
169
|
-
<xsl:otherwise>
|
170
|
-
<td><xsl:value-of select="state"/></td>
|
171
|
-
</xsl:otherwise>
|
172
|
-
</xsl:choose>
|
173
|
-
<td>
|
118
|
+
</div>
|
119
|
+
</td>
|
174
120
|
<xsl:choose>
|
175
|
-
|
176
|
-
|
177
|
-
<xsl:
|
178
|
-
<
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
<
|
183
|
-
<xsl:
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
121
|
+
<xsl:when test="state='CW'">
|
122
|
+
<td class="waiting">
|
123
|
+
<xsl:choose>
|
124
|
+
<xsl:when test="blocked_by=''">
|
125
|
+
Waiting on condition
|
126
|
+
</xsl:when>
|
127
|
+
<xsl:otherwise>
|
128
|
+
<a target="_blank">
|
129
|
+
<xsl:attribute name="href">
|
130
|
+
<xsl:value-of select="concat('thread_', blocked_by/@thread_hash, '.html')"/>
|
131
|
+
</xsl:attribute>
|
132
|
+
<xsl:attribute name="title">
|
133
|
+
<xsl:value-of select="blocked_by/@name" />
|
134
|
+
</xsl:attribute>
|
135
|
+
Waiting for <xsl:value-of select="blocked_by/@thread_id"/>
|
136
|
+
</a>
|
137
|
+
</xsl:otherwise>
|
138
|
+
</xsl:choose>
|
139
|
+
</td>
|
140
|
+
</xsl:when>
|
141
|
+
<xsl:when test="state='R'">
|
142
|
+
<td class="runnable">Runnable</td>
|
143
|
+
</xsl:when>
|
144
|
+
<xsl:when test="state='P'">
|
145
|
+
<td class="parked">
|
146
|
+
<xsl:choose>
|
147
|
+
<xsl:when test="blocked_by=''">
|
148
|
+
Parked
|
149
|
+
</xsl:when>
|
150
|
+
<xsl:otherwise>
|
151
|
+
<a target="_blank">
|
152
|
+
<xsl:attribute name="href">
|
153
|
+
<xsl:value-of select="concat('thread_', blocked_by/@thread_hash, '.html')"/>
|
154
|
+
</xsl:attribute>
|
155
|
+
<xsl:attribute name="title">
|
156
|
+
<xsl:value-of select="blocked_by/@name" />
|
157
|
+
</xsl:attribute>
|
158
|
+
Parked on <xsl:value-of select="blocked_by/@thread_id"/>
|
159
|
+
</a>
|
160
|
+
</xsl:otherwise>
|
161
|
+
</xsl:choose>
|
162
|
+
</td>
|
163
|
+
</xsl:when>
|
164
|
+
<xsl:when test="state='B'">
|
165
|
+
<td class="blocked">
|
166
|
+
<a target="_blank">
|
167
|
+
<xsl:attribute name="href">
|
168
|
+
<xsl:value-of select="concat('thread_', blocked_by/@thread_hash, '.html')"/>
|
169
|
+
</xsl:attribute>
|
170
|
+
<xsl:attribute name="title">
|
171
|
+
<xsl:value-of select="blocked_by/@name" />
|
172
|
+
</xsl:attribute>
|
173
|
+
Blocked by <xsl:value-of select="blocked_by/@thread_id"/>
|
174
|
+
</a>
|
175
|
+
</td>
|
176
|
+
</xsl:when>
|
177
|
+
<xsl:otherwise>
|
178
|
+
<td><xsl:value-of select="state"/></td>
|
179
|
+
</xsl:otherwise>
|
180
|
+
</xsl:choose>
|
181
|
+
<td>
|
182
|
+
<xsl:choose>
|
183
|
+
<xsl:when test="blocking/thread">
|
184
|
+
blocking:
|
185
|
+
<xsl:for-each select="blocking/thread">
|
186
|
+
<a target="_blank">
|
187
|
+
<xsl:attribute name="href">
|
188
|
+
<xsl:value-of select="concat('thread_', @thread_hash, '.html')"/>
|
189
|
+
</xsl:attribute>
|
190
|
+
<xsl:attribute name="title">
|
191
|
+
<xsl:value-of select="@name" />
|
192
|
+
</xsl:attribute>
|
193
|
+
<xsl:value-of select="@thread_id" />
|
194
|
+
</a>;
|
195
|
+
</xsl:for-each>
|
196
|
+
</xsl:when>
|
197
|
+
</xsl:choose>
|
198
|
+
</td>
|
199
|
+
</tr>
|
200
|
+
</xsl:for-each>
|
201
|
+
</table>
|
202
|
+
</div>
|
194
203
|
</div>
|
195
204
|
</body>
|
196
205
|
<script>loadChart();</script>
|
javacore_analyser/javacore.py
CHANGED
@@ -127,7 +127,8 @@ class Javacore:
|
|
127
127
|
def encode(self, string):
|
128
128
|
bts = str.encode(string, self.get_encoding(), 'ignore')
|
129
129
|
for i in range(0, len(bts)):
|
130
|
-
|
130
|
+
# fix for 'XML Syntax error PCDATA invalid char#405'
|
131
|
+
if bts[i] < 32 and bts[i] != 9 and bts[i] != 10 and bts[i] != 13 and bts[i] != 1:
|
131
132
|
raise CorruptedJavacoreException("Javacore " + self.filename + " is corrupted in line " + string)
|
132
133
|
string = bts.decode('utf-8', 'ignore')
|
133
134
|
return string
|
@@ -145,7 +146,7 @@ class Javacore:
|
|
145
146
|
break
|
146
147
|
line = self.encode(line)
|
147
148
|
if line.startswith(THREAD_INFO):
|
148
|
-
line =
|
149
|
+
line = Javacore.process_thread_name(line, file)
|
149
150
|
snapshot = ThreadSnapshot.create(line, file, self)
|
150
151
|
self.snapshots.append(snapshot)
|
151
152
|
except Exception as e:
|
@@ -158,7 +159,8 @@ class Javacore:
|
|
158
159
|
finally:
|
159
160
|
file.close()
|
160
161
|
|
161
|
-
|
162
|
+
@staticmethod
|
163
|
+
def process_thread_name(line, file):
|
162
164
|
count = line.count('"')
|
163
165
|
if count == 0: return line # anonymous native threads
|
164
166
|
while True:
|
@@ -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
|
|
@@ -12,10 +12,11 @@ import shutil
|
|
12
12
|
import sys
|
13
13
|
import tarfile
|
14
14
|
import tempfile
|
15
|
-
import traceback
|
16
15
|
import zipfile
|
17
16
|
|
17
|
+
import importlib_resources
|
18
18
|
import py7zr
|
19
|
+
from importlib_resources.abc import Traversable
|
19
20
|
|
20
21
|
from javacore_analyser import logging_utils
|
21
22
|
from javacore_analyser.constants import DEFAULT_FILE_DELIMITER
|
@@ -63,43 +64,49 @@ def extract_archive(input_archive_filename, output_path):
|
|
63
64
|
|
64
65
|
|
65
66
|
def main():
|
66
|
-
logging_utils.create_console_logging()
|
67
|
-
logging.info("IBM Javacore analyser")
|
68
|
-
logging.info("Python version: " + sys.version)
|
69
|
-
logging.info("Preferred encoding: " + locale.getpreferredencoding())
|
70
|
-
|
71
67
|
parser = argparse.ArgumentParser()
|
72
|
-
parser.add_argument("
|
73
|
-
|
68
|
+
parser.add_argument("input", help="Input javacore file(s) or directory with javacores. "
|
69
|
+
"The javacores can be packed "
|
70
|
+
"into one of the supported archive formats: zip, gz, bz2, lzma, 7z. "
|
71
|
+
"Additional the verbose GC logs from the time "
|
72
|
+
"when the javacores were collected can be added. "
|
73
|
+
"See doc: https://github.com/IBM/javacore-analyser/wiki")
|
74
|
+
parser.add_argument("output", help="Name of directory where report will be generated")
|
74
75
|
parser.add_argument("--separator",
|
75
76
|
help='Input files separator (default "' + DEFAULT_FILE_DELIMITER + '")',
|
76
77
|
default=DEFAULT_FILE_DELIMITER)
|
77
78
|
args = parser.parse_args()
|
78
79
|
|
79
|
-
input_param = args.
|
80
|
-
output_param = args.
|
80
|
+
input_param = args.input
|
81
|
+
output_param = args.output
|
81
82
|
files_separator = args.separator
|
82
83
|
|
84
|
+
batch_process(input_param, output_param, files_separator)
|
85
|
+
|
86
|
+
|
87
|
+
def batch_process(input_param, output_param, files_separator=DEFAULT_FILE_DELIMITER):
|
88
|
+
logging_utils.create_console_logging()
|
89
|
+
logging.info("IBM Javacore analyser")
|
90
|
+
logging.info("Python version: " + sys.version)
|
91
|
+
logging.info("Preferred encoding: " + locale.getpreferredencoding())
|
83
92
|
logging.info("Input parameter: " + input_param)
|
84
93
|
logging.info("Report directory: " + output_param)
|
85
|
-
|
94
|
+
output_param = os.path.normpath(output_param)
|
86
95
|
# Needs to be created once output file structure is ready.
|
87
96
|
logging_utils.create_file_logging(output_param)
|
88
|
-
|
89
97
|
# Check whether as input we got list of files or single file
|
90
98
|
# Semicolon is separation mark for list of input files
|
91
99
|
if files_separator in input_param or fnmatch.fnmatch(input_param, '*javacore*.txt'):
|
92
|
-
# Process list of the files (copy all or them to output dir
|
100
|
+
# Process list of the files (copy all or them to output dir)
|
93
101
|
files = input_param.split(files_separator)
|
94
102
|
else:
|
95
103
|
files = [input_param]
|
96
|
-
|
97
104
|
try:
|
105
|
+
files = [os.path.normpath(file) for file in files]
|
98
106
|
process_javacores_and_generate_report_data(files, output_param)
|
99
107
|
except Exception as ex:
|
100
|
-
|
101
|
-
logging.error("Processing was not successful. Correct the problem and try again. Exiting with error 13"
|
102
|
-
exc_info=True)
|
108
|
+
logging.exception(ex)
|
109
|
+
logging.error("Processing was not successful. Correct the problem and try again. Exiting with error 13")
|
103
110
|
exit(13)
|
104
111
|
|
105
112
|
|
@@ -115,12 +122,9 @@ def generate_javecore_set_data(files):
|
|
115
122
|
Returns:
|
116
123
|
- JavacoreSet: Generated JavacoreSet object containing the processed data.
|
117
124
|
"""
|
118
|
-
|
119
|
-
|
125
|
+
javacores_temp_dir = tempfile.TemporaryDirectory()
|
120
126
|
try:
|
121
127
|
# Location when we store extracted archive or copied javacores files
|
122
|
-
javacores_temp_dir = tempfile.TemporaryDirectory()
|
123
|
-
|
124
128
|
javacores_temp_dir_name = javacores_temp_dir.name
|
125
129
|
for file in files:
|
126
130
|
if os.path.isdir(file):
|
@@ -137,6 +141,24 @@ def generate_javecore_set_data(files):
|
|
137
141
|
javacores_temp_dir.cleanup()
|
138
142
|
|
139
143
|
|
144
|
+
def create_output_files_structure(output_dir):
|
145
|
+
if not os.path.isdir(output_dir):
|
146
|
+
os.mkdir(output_dir)
|
147
|
+
data_output_dir = os.path.normpath(os.path.join(output_dir, 'data'))
|
148
|
+
if not data_output_dir.startswith(output_dir):
|
149
|
+
raise Exception("Security exception: Uncontrolled data used in path expression")
|
150
|
+
if os.path.isdir(data_output_dir):
|
151
|
+
shutil.rmtree(data_output_dir, ignore_errors=True)
|
152
|
+
logging.info("Data dir: " + data_output_dir)
|
153
|
+
|
154
|
+
style_css_resource: Traversable = importlib_resources.files("javacore_analyser") / "data" / "style.css"
|
155
|
+
data_dir = os.path.dirname(str(style_css_resource))
|
156
|
+
os.mkdir(data_output_dir)
|
157
|
+
shutil.copytree(data_dir, data_output_dir, dirs_exist_ok=True)
|
158
|
+
shutil.copy2(os.path.join(data_output_dir, "html", "processing_data.html"),
|
159
|
+
os.path.join(output_dir, "index.html"))
|
160
|
+
|
161
|
+
|
140
162
|
# Assisted by WCA@IBM
|
141
163
|
# Latest GenAI contribution: ibm/granite-8b-code-instruct
|
142
164
|
def process_javacores_and_generate_report_data(input_files, output_dir):
|
@@ -150,6 +172,7 @@ def process_javacores_and_generate_report_data(input_files, output_dir):
|
|
150
172
|
Returns:
|
151
173
|
None
|
152
174
|
"""
|
175
|
+
create_output_files_structure(output_dir)
|
153
176
|
javacore_set = generate_javecore_set_data(input_files)
|
154
177
|
javacore_set.generate_report_files(output_dir)
|
155
178
|
|