javacore-analyser 2.3.0.dev1__tar.gz → 2.3.0.dev2__tar.gz

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.
Files changed (63) hide show
  1. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/CONTRIBUTING.md +44 -1
  2. javacore_analyser-2.3.0.dev2/Dockerfile +20 -0
  3. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/PKG-INFO +5 -4
  4. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/README.md +4 -3
  5. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/requirements.txt +0 -1
  6. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/constants.py +3 -1
  7. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/jquery/wait2scripts.js +7 -2
  8. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/xml/report.xsl +14 -2
  9. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/xml/threads/thread.xsl +5 -1
  10. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/java_thread.py +13 -0
  11. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/javacore_set.py +18 -0
  12. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/thread_snapshot.py +14 -12
  13. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/tips.py +3 -3
  14. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/verbose_gc.py +6 -18
  15. javacore_analyser-2.3.0.dev1/Dockerfile +0 -15
  16. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  17. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  18. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/.github/dco.yml +0 -0
  19. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/.gitignore +0 -0
  20. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/.travis.yml +0 -0
  21. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/CHANGELOG.md +0 -0
  22. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/CODE_OF_CONDUCT.md +0 -0
  23. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/LICENSE +0 -0
  24. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/MAINTAINERS.md +0 -0
  25. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/REQUIREMENTS.md +0 -0
  26. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/SECURITY.md +0 -0
  27. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/docs/ClassDiagram.png +0 -0
  28. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/docs/dom_example.py +0 -0
  29. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/pyproject.toml +0 -0
  30. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/__init__.py +0 -0
  31. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/__main__.py +0 -0
  32. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/abstract_snapshot_collection.py +0 -0
  33. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/code_snapshot_collection.py +0 -0
  34. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/expand.js +0 -0
  35. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/html/error.html +0 -0
  36. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/html/processing_data.html +0 -0
  37. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/jquery/chart.js +0 -0
  38. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/jquery/chartjs-adapter-date-fns.bundle.min.js +0 -0
  39. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/jquery/jq.css +0 -0
  40. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/jquery/jquery.mark.min.js +0 -0
  41. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/jquery/jquery.min.js +0 -0
  42. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/jquery/jquery.tablesorter.min.js +0 -0
  43. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/jquery/jquery.tablesorter.widgets.min.js +0 -0
  44. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/jquery/search.js +0 -0
  45. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/jquery/sorting.js +0 -0
  46. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/jquery/theme.blue.css +0 -0
  47. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/jquery/theme.default.min.css +0 -0
  48. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/style.css +0 -0
  49. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/xml/index.xml +0 -0
  50. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/xml/javacores/javacore.xml +0 -0
  51. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/xml/javacores/javacore.xsl +0 -0
  52. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/data/xml/threads/thread.xml +0 -0
  53. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/har_file.py +0 -0
  54. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/javacore.py +0 -0
  55. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/javacore_analyser_batch.py +0 -0
  56. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/javacore_analyser_web.py +0 -0
  57. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/logging_utils.py +0 -0
  58. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/snapshot_collection.py +0 -0
  59. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/snapshot_collection_collection.py +0 -0
  60. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/stack_trace.py +0 -0
  61. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/stack_trace_element.py +0 -0
  62. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/stack_trace_kind.py +0 -0
  63. {javacore_analyser-2.3.0.dev1 → javacore_analyser-2.3.0.dev2}/src/javacore_analyser/templates/index.html +0 -0
@@ -94,7 +94,7 @@ To run web application:
94
94
 
95
95
  ## Build pip package
96
96
  Follow the steps from [Packaging projects](https://packaging.python.org/en/latest/tutorials/packaging-projects/).
97
- Currently Chris has an API keys for test and production pypi
97
+ Currently Chris and Tad have an API keys for test and production pypi
98
98
 
99
99
  ## Build container localy
100
100
  To build a container:
@@ -104,6 +104,11 @@ or
104
104
 
105
105
  `docker build -t javacore-analyser .`
106
106
 
107
+ If you want to build a particular version, you need to add `--build-arg version=` argument, for example:
108
+ `podman build --build-arg version='==2.1' -t javacore-analyser .`
109
+ or
110
+ `podman build --build-arg version='<2.1' -t javacore-analyser .`
111
+
107
112
  To start the container:
108
113
  `podman run -it --rm --name javacore-analyser --mount type=bind,src="local-dir-on-fs",target=/reports -p 5001:5000 javacore-analyser`
109
114
 
@@ -115,6 +120,43 @@ or
115
120
  `-p` specifies port mapping. The application in container is running on port 5000. You can map it to another port on
116
121
  your machine (5001 in this example).
117
122
 
123
+
124
+ ## Publish the container to ghcr.io/ibm/javacore-analyser
125
+ Once you built the container locally, you might need to publish it on ghcr.io/ibm/javacore-analyser.
126
+ Here are the instructions:
127
+ https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry.
128
+ Steps:
129
+ 1. Generate the token by navigating to https://github.com/settings/tokens/new?scopes=write:packages.
130
+ * Select the read:packages scope to download container images and read their metadata.
131
+ * Select the write:packages scope to download and upload container images and read and write their metadata.
132
+ * Select the delete:packages scope to delete container images.
133
+ NOTE: you can use the same token for multiple pushes until it does not expire.
134
+ 2. Tag image:
135
+ ```commandline
136
+ podman image tag localhost/javacore-analyser ghcr.io/ibm/javacore-analyser:latest
137
+ podman image tag localhost/javacore-analyser ghcr.io/ibm/javacore-analyser:2.1
138
+ ```
139
+ 3. Push the image:
140
+ ```commandline
141
+ export CR_PAT=<token-id generated in step 1>
142
+ echo $CR_PAT | podman login ghcr.io -u USERNAME --password-stdin
143
+ podman push ghcr.io/ibm/javacore-analyser:2.1
144
+ podman push ghcr.io/ibm/javacore-analyser:latest
145
+ ```
146
+
147
+ ## Build and Publish multiplatform image
148
+ To publish the image for multiple platforms, follow these instructions:
149
+ https://developers.redhat.com/articles/2023/11/03/how-build-multi-architecture-container-images#benefits_of_multi_architecture_containers
150
+ ```commandline
151
+ <Generate token if you do not have it yet>
152
+ export CR_PAT=<token-id generated in step 1>
153
+ echo $CR_PAT | podman login ghcr.io -u USERNAME --password-stdin
154
+ podman manifest create javacore-analyser:2.1
155
+ podman build --platform linux/amd64,linux/arm64,linux/i386 --manifest javacore-analyser:2.1 .
156
+ podman manifest push javacore-analyser:2.1 docker://ghcr.io/ibm/javacore-analyser:2.1
157
+ podman manifest push javacore-analyser:2.1 docker://ghcr.io/ibm/javacore-analyser:latest
158
+ ```
159
+
118
160
  ## Releasing a new version
119
161
  Release a new version is partially automated by Travis. Here are the steps:
120
162
  1. Make sure you are on `main` branch in your repository.
@@ -162,6 +204,7 @@ https://github.com/settings/tokens/new
162
204
  6. Publish release.
163
205
  7. Copy release notes to [CHANGELOG.md](CHANGELOG.md) file.
164
206
 
207
+
165
208
  ## Testing
166
209
  As default the tests in Pycharm are ran in the current selected directory. However we want to run them in main
167
210
  directory of the tool (**javacore-analyser** directory, not **test** directory).
@@ -0,0 +1,20 @@
1
+ #
2
+ # Copyright IBM Corp. 2024 - 2025
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ #
5
+
6
+ FROM python:3
7
+
8
+ LABEL org.opencontainers.image.source="https://github.com/IBM/javacore-analyser"
9
+ LABEL org.opencontainers.image.description="This is a tool to analyse IBM Javacore files and provide the report used to analyse hang/outage and performance issues."
10
+ LABEL org.opencontainers.image.licenses="Apache-2.0"
11
+
12
+ EXPOSE 5000/tcp
13
+ RUN mkdir /reports
14
+ VOLUME ["/reports"]
15
+
16
+ # As default we do not set the version to have the latest one for build.
17
+ ARG version=""
18
+ #RUN ["pip", "install", "--no-cache-dir", "--root-user-action", "ignore", "javacore-analyser${version}"]
19
+ RUN pip install --no-cache-dir --root-user-action ignore javacore-analyser${version}
20
+ CMD ["javacore_analyser_web", "--port=5000", "--reports-dir=/reports"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: javacore_analyser
3
- Version: 2.3.0.dev1
3
+ Version: 2.3.0.dev2
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
@@ -312,19 +312,20 @@ You can type the following command to obtain the help:
312
312
  or
313
313
  `python -m javacore_analyser web --port=5000 --reports-dir=/data/reports_dir`
314
314
 
315
+
315
316
  The first parameter set the port to use by application. If not specified, 5000 will be used.
316
317
  The second parameter sets where the reports need to be stored. If not set, then the `reports` dir will be created in current location.
317
318
 
318
319
  Now you can type (http://localhost:5000/).
319
320
 
320
321
  ### Running container image
321
- There is an unofficial Docker/Podman container managed by one of projects developers. Use the following command
322
+ There is a Docker/Podman container managed by one of projects developers. Use the following command
322
323
  to start it:
323
324
 
324
- `podman run -it --rm --name javacore-analyser --mount type=bind,src="/local-reports-dir",target=/reports -p 5001:5000 ghcr.io/kkazmierczyk/javacore-analyser:latest`
325
+ `podman run -it --rm --name javacore-analyser --mount type=bind,src="/local-reports-dir",target=/reports -p 5001:5000 ghcr.io/ibm/javacore-analyser:latest`
325
326
 
326
327
  or
327
- `docker run -it --rm --name javacore-analyser --mount type=bind,src="/local-reports-dir",target=/reports -p 5001:5000 ghcr.io/kkazmierczyk/javacore-analyser:latest`
328
+ `docker run -it --rm --name javacore-analyser --mount type=bind,src="/local-reports-dir",target=/reports -p 5001:5000 ghcr.io/ibm/javacore-analyser:latest`
328
329
 
329
330
  The `mount` option specifies where you want locally to store the reports. The reports in the container are stored in
330
331
  `/reports` directory. If you remove mount option, the application will work but the reports will not persist after
@@ -73,19 +73,20 @@ You can type the following command to obtain the help:
73
73
  or
74
74
  `python -m javacore_analyser web --port=5000 --reports-dir=/data/reports_dir`
75
75
 
76
+
76
77
  The first parameter set the port to use by application. If not specified, 5000 will be used.
77
78
  The second parameter sets where the reports need to be stored. If not set, then the `reports` dir will be created in current location.
78
79
 
79
80
  Now you can type (http://localhost:5000/).
80
81
 
81
82
  ### Running container image
82
- There is an unofficial Docker/Podman container managed by one of projects developers. Use the following command
83
+ There is a Docker/Podman container managed by one of projects developers. Use the following command
83
84
  to start it:
84
85
 
85
- `podman run -it --rm --name javacore-analyser --mount type=bind,src="/local-reports-dir",target=/reports -p 5001:5000 ghcr.io/kkazmierczyk/javacore-analyser:latest`
86
+ `podman run -it --rm --name javacore-analyser --mount type=bind,src="/local-reports-dir",target=/reports -p 5001:5000 ghcr.io/ibm/javacore-analyser:latest`
86
87
 
87
88
  or
88
- `docker run -it --rm --name javacore-analyser --mount type=bind,src="/local-reports-dir",target=/reports -p 5001:5000 ghcr.io/kkazmierczyk/javacore-analyser:latest`
89
+ `docker run -it --rm --name javacore-analyser --mount type=bind,src="/local-reports-dir",target=/reports -p 5001:5000 ghcr.io/ibm/javacore-analyser:latest`
89
90
 
90
91
  The `mount` option specifies where you want locally to store the reports. The reports in the container are stored in
91
92
  `/reports` directory. If you remove mount option, the application will work but the reports will not persist after
@@ -6,4 +6,3 @@ waitress # Production WSGI server
6
6
  flask # WSGI server for development the code
7
7
  tqdm
8
8
  haralyzer
9
-
@@ -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
 
@@ -24,8 +24,10 @@ UNKNOWN = 'Unknown'
24
24
  STACK_TRACE = '4XESTACKTRACE'
25
25
  NATIVE_STACK_TRACE = '4XENATIVESTACK'
26
26
  DATETIME = '1TIDATETIME'
27
+ STARTTIME = '1CISTARTTIME'
27
28
  SIGINFO = '1TISIGINFO'
28
29
  ENCODING = '1TICHARSET'
30
+ CMD_LINE = '1CICMDLINE'
29
31
 
30
32
  DATA_OUTPUT_SUBDIR = '/data/'
31
33
  DEFAULT_FILE_DELIMITER = ';'
@@ -260,8 +260,13 @@ const loadChart = function () {
260
260
 
261
261
  for(let i=1; i<snapshotsNumber; i++){
262
262
  let rowEl = document.getElementById('all_threads_table_thread_xsl').rows[i];
263
- inputData.push(Number(rowEl.cells[3].innerHTML));
264
- labels.push(String(rowEl.cells[0].innerHTML));
263
+ let value = Number(rowEl.cells[3].innerText);
264
+
265
+ // verify the input data
266
+ if(!isNaN(value)){
267
+ inputData.push(Number(rowEl.cells[3].innerText));
268
+ labels.push(String(rowEl.cells[0].innerText));
269
+ }
265
270
  }
266
271
 
267
272
  new Chart(ctx, {
@@ -159,7 +159,7 @@
159
159
  <button data-search="clear">✖</button>
160
160
  </div>
161
161
  <div class="content">
162
- <h1>Wait Report</h1>
162
+ <h1>Javacore Analyser Report</h1>
163
163
  <div class="margined">
164
164
  from data between
165
165
  <b><xsl:value-of select="doc/report_info/javacores_generation_time/starting_time"/></b> and
@@ -383,6 +383,14 @@
383
383
  <td>Os level</td>
384
384
  <td class="left"><xsl:value-of select="doc/system_info/os_level"/></td>
385
385
  </tr>
386
+ <tr>
387
+ <td>JVM startup time</td>
388
+ <td class="left"><xsl:value-of select="doc/system_info/jvm_start_time"/></td>
389
+ </tr>
390
+ <tr>
391
+ <td>Command line</td>
392
+ <td class="left"><xsl:value-of select="doc/system_info/cmd_line"/></td>
393
+ </tr>
386
394
  </tbody>
387
395
  </table>
388
396
  <h4>Java Arguments</h4>
@@ -533,6 +541,7 @@
533
541
  that may be reused for unrelated tasks. Two tasks with different thread names are therefore treated
534
542
  as separate threads for the purpose of this report, even if they are executed in the scope of the same
535
543
  Thread java object.
544
+ The address of the java Thread object is included for each thread. This corresponds to the address reported in Java heapdumps.
536
545
  The table can be sorted by clicking on any column header.
537
546
  The following information is displayed for each thread:
538
547
  <ul>
@@ -586,7 +595,9 @@
586
595
  <a>
587
596
  <xsl:attribute name="id"><xsl:value-of select="concat('toggle_thread_name',$i)"/></xsl:attribute>
588
597
  <xsl:attribute name="href"><xsl:value-of select="concat('javascript:expand_stack(stack',$i,',toggle_thread_name',$i,')')"/></xsl:attribute>
589
- <xsl:attribute name="class">expandit</xsl:attribute><xsl:value-of select="thread_name"/></a>
598
+ <xsl:attribute name="class">expandit</xsl:attribute>
599
+ <xsl:value-of select="thread_name"/>
600
+ </a>
590
601
  <a class="right" target="_blank">
591
602
  <xsl:attribute name="href">
592
603
  <xsl:value-of select="concat('threads/thread_', thread_hash, '.html')"/>
@@ -596,6 +607,7 @@
596
607
  <br/>
597
608
  <div style="display:none;" >
598
609
  <xsl:attribute name="id"><xsl:value-of select="concat('stack',$i)"/></xsl:attribute>
610
+ java/lang/Thread:<xsl:value-of select="thread_address"/>
599
611
  <xsl:for-each select="*[starts-with(name(), 'stack')]">
600
612
  <div>
601
613
  <xsl:choose>
@@ -33,7 +33,11 @@
33
33
  </div>
34
34
  <div class="content">
35
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>
36
+ <h2>
37
+ Wait Report for thread: <b><xsl:value-of select="thread_name"/></b>
38
+ <br/>
39
+ java/lang/Thread:<xsl:value-of select="thread_address"/>
40
+ </h2>
37
41
  <xsl:choose>
38
42
  <xsl:when test="//javacore_count = 1">
39
43
  System resource utilization data cannot be calculated with only a single javacore.
@@ -8,6 +8,14 @@ from javacore_analyser.abstract_snapshot_collection import AbstractSnapshotColle
8
8
 
9
9
  class Thread(AbstractSnapshotCollection):
10
10
 
11
+ def __init__(self):
12
+ super().__init__()
13
+ self.thread_address = ""
14
+
15
+ def create(self, thread_snapshot):
16
+ super().create(thread_snapshot)
17
+ self.thread_address = thread_snapshot.thread_address
18
+
11
19
  def get_hash(self):
12
20
  id_str = self.name + str(self.id)
13
21
  hashcode = abs(hash(id_str))
@@ -26,6 +34,11 @@ class Thread(AbstractSnapshotCollection):
26
34
  name_node.appendChild(doc.createTextNode(self.name + " (" + str(self.id) + ")"))
27
35
  thread_node.appendChild(name_node)
28
36
 
37
+ # thread address
38
+ thread_address_node = doc.createElement("thread_address")
39
+ thread_address_node.appendChild(doc.createTextNode(self.thread_address))
40
+ thread_node.appendChild(thread_address_node)
41
+
29
42
  # hash
30
43
  hash_node = doc.createElement("thread_hash")
31
44
  hash_node.appendChild(doc.createTextNode(self.get_hash()))
@@ -68,6 +68,8 @@ class JavacoreSet:
68
68
  self.os_level = ""
69
69
  self.architecture = ""
70
70
  self.java_version = ""
71
+ self.jvm_start_time = ""
72
+ self.cmd_line = ""
71
73
  self.user_args = []
72
74
  # end of static information
73
75
  self.files = []
@@ -191,6 +193,8 @@ class JavacoreSet:
191
193
  logging.debug("Architecture: {}".format(self.architecture))
192
194
  logging.debug("Java version: {}".format(self.java_version))
193
195
  logging.debug("OS Level: {}".format(self.os_level))
196
+ logging.debug("JVM Startup time: {}".format(self.jvm_start_time))
197
+ logging.debug("Command line: {}".format(self.cmd_line))
194
198
 
195
199
  @staticmethod
196
200
  def create(path):
@@ -267,6 +271,12 @@ class JavacoreSet:
267
271
  elif line.startswith(JAVA_VERSION):
268
272
  self.java_version = line[len(JAVA_VERSION) + 1:].strip()
269
273
  continue
274
+ elif line.startswith(STARTTIME):
275
+ self.jvm_start_time = line[line.find(":") + 1:].strip()
276
+ continue
277
+ elif line.startswith(CMD_LINE):
278
+ self.cmd_line = line[len(CMD_LINE) + 1:].strip()
279
+ continue
270
280
  except Exception as ex:
271
281
  logging.exception(ex)
272
282
  logging.error(f'Error during processing file: {file.name} \n'
@@ -472,6 +482,14 @@ class JavacoreSet:
472
482
  system_info_node.appendChild(os_level_node)
473
483
  os_level_node.appendChild(self.doc.createTextNode(self.os_level))
474
484
 
485
+ jvm_startup_time = self.doc.createElement("jvm_start_time")
486
+ system_info_node.appendChild(jvm_startup_time)
487
+ jvm_startup_time.appendChild(self.doc.createTextNode(self.jvm_start_time))
488
+
489
+ cmd_line = self.doc.createElement("cmd_line")
490
+ system_info_node.appendChild(cmd_line)
491
+ cmd_line.appendChild(self.doc.createTextNode(self.cmd_line))
492
+
475
493
  doc_node.appendChild(self.get_blockers_xml())
476
494
  doc_node.appendChild(self.threads.get_xml(self.doc))
477
495
  doc_node.appendChild(self.stacks.get_xml(self.doc))
@@ -21,6 +21,7 @@ class ThreadSnapshot:
21
21
  self.allocated_mem = 0
22
22
  self.name = None
23
23
  self.thread_id = None
24
+ self.thread_address = None
24
25
  self.thread = None
25
26
  self.javacore = None
26
27
  self.blocker = None
@@ -38,6 +39,7 @@ class ThreadSnapshot:
38
39
  snapshot.file = file
39
40
  snapshot.javacore = javacore
40
41
  snapshot.name = snapshot.get_thread_name(line)
42
+ snapshot.thread_address = snapshot.get_thread_address(line)
41
43
  snapshot.parse_state(line)
42
44
  snapshot.parse_snapshot_data()
43
45
  return snapshot
@@ -76,6 +78,18 @@ class ThreadSnapshot:
76
78
  name = name.translate(str.maketrans({"\01": "[SOH]"}))
77
79
  return name
78
80
 
81
+ def get_thread_address(self, line):
82
+ """ assuming line format:
83
+ 3XMTHREADINFO "Default Executor-thread-27781" J9VMThread:0x0000000009443300,
84
+ omrthread_t:0x000000A8B62C3758, java/lang/Thread:0x00000008432D4140, state:B, prio=5 """
85
+ match = re.search("(java/lang/Thread:)(0x[0-9a-fA-F]+)", line)
86
+ address = ""
87
+ if match: # native threads don't have an address
88
+ address = match.group(2)
89
+ if self.javacore:
90
+ address = self.javacore.encode(address)
91
+ return address
92
+
79
93
  def get_thread_hash(self):
80
94
  if self.thread:
81
95
  return self.thread.get_hash()
@@ -198,18 +212,6 @@ class ThreadSnapshot:
198
212
  file_name = ""
199
213
  if self.file:
200
214
  file_name = self.javacore.filename.split(os.sep)[-1].strip()
201
- # thread name
202
- thread_name_node = doc.createElement("thread_name")
203
- thread_name_node.appendChild(doc.createTextNode(self.name))
204
- thread_snapshot_node.appendChild(thread_name_node)
205
- # thread id
206
- thread_name_node = doc.createElement("thread_id")
207
- thread_name_node.appendChild(doc.createTextNode(str(self.get_thread_id())))
208
- thread_snapshot_node.appendChild(thread_name_node)
209
- # thread hash
210
- thread_hash_node = doc.createElement("thread_hash")
211
- thread_hash_node.appendChild(doc.createTextNode(str(self.get_thread_hash())))
212
- thread_snapshot_node.appendChild(thread_hash_node)
213
215
  # CPU usage
214
216
  cpu_usage_node = doc.createElement("cpu_usage")
215
217
  cpu_usage_node.appendChild(doc.createTextNode(str(self.get_cpu_usage_inc())))
@@ -73,8 +73,8 @@ class DifferentIssuesTip:
73
73
  MAX_INTERVAL_FOR_JAVACORES = 330 # 330 seconds (5 minutes and a little more time)
74
74
  DIFFERENT_ISSUES_MESSAGE = """[WARNING] The time interval between javacore {0} and {1} is {2:.0f} seconds, while
75
75
  the recommended maximum interval between two javacores is 300 seconds (5 minutes). It is likely that these
76
- two javacores do not correspond to one occurrence of a single issue. Please review the list of javacores received
77
- from the customer and run WAIT2 only against the ones that are applicable for the issue you are investigating. """
76
+ two javacores do not correspond to one occurrence of a single issue. Please review the list of javacores
77
+ and the tool only against the ones that are applicable for the issue you are investigating. """
78
78
 
79
79
  @staticmethod
80
80
  def generate(javacore_set):
@@ -103,7 +103,7 @@ class TooFewJavacoresTip:
103
103
 
104
104
  MIN_NUMBER_OF_JAVACORES = 10
105
105
 
106
- ONE_JAVACORE_WARNING = '''[WARNING] You generated this WAIT2 report with only one javacore.
106
+ ONE_JAVACORE_WARNING = '''[WARNING] You generated this the report with only one javacore.
107
107
  CPU usage calculation is not possible.'''
108
108
 
109
109
  NOT_ENOUGH_JAVACORES_MESSAGE = """[WARNING] You ran the tool against {0} Javacores. The analysis
@@ -1,11 +1,12 @@
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
 
6
6
  import logging
7
7
  import ntpath
8
8
  from datetime import datetime
9
+ from pathlib import Path
9
10
  from xml.dom.minidom import Element, parseString
10
11
 
11
12
  from tqdm import tqdm
@@ -110,22 +111,11 @@ class VerboseGcFile:
110
111
  self.__parse()
111
112
 
112
113
  def __parse(self):
113
- # read in the file as collection of lines
114
- file = None
115
114
  try:
116
- xml_text = ""
117
- root_closing_tag_available = False
118
- file = open(self.__path, 'r+')
119
- lines = file.readlines()
120
- # find the last non-empty line
121
- for line in lines:
122
- line = line.strip()
123
- # workaround for https://github.com/eclipse-openj9/openj9/issues/17978
124
- line = line.replace("&#x1;", "?")
125
- xml_text = xml_text + line
126
- if line == ROOT_CLOSING_TAG: root_closing_tag_available = True
127
-
128
- if not root_closing_tag_available:
115
+ file = Path(self.__path)
116
+ xml_text = file.read_text()
117
+ xml_text = xml_text.replace("&#x1;", "?")
118
+ if ROOT_CLOSING_TAG not in xml_text:
129
119
  xml_text = xml_text + ROOT_CLOSING_TAG
130
120
  logging.debug("adding closing tag")
131
121
 
@@ -133,8 +123,6 @@ class VerboseGcFile:
133
123
  self.__root = self.__doc.documentElement
134
124
  except Exception as ex:
135
125
  raise GcVerboseProcessingException() from ex
136
- finally:
137
- if not file.closed: file.close()
138
126
 
139
127
  def get_file_name(self):
140
128
  head, tail = ntpath.split(self.__path)
@@ -1,15 +0,0 @@
1
- #
2
- # Copyright IBM Corp. 2024 - 2024
3
- # SPDX-License-Identifier: Apache-2.0
4
- #
5
-
6
- FROM python:3
7
-
8
- EXPOSE 5000/tcp
9
- ENV REPORTS_DIR=/reports
10
- RUN mkdir /reports
11
- VOLUME ["/reports"]
12
-
13
- RUN pip install --no-cache-dir --root-user-action ignore javacore-analyser
14
-
15
- CMD [ "javacore_analyser_web" ]