Skip to content

Commit 3e5d0c1

Browse files
authored
Added cmdline argument to Java app ID based on a regex filter (#328)
* Added cmdline argument to Java app ID based on a regex filter * import issue fix * import issue fix
1 parent 4a21069 commit 3e5d0c1

File tree

4 files changed

+57
-17
lines changed

4 files changed

+57
-17
lines changed

gprofiler/main.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
from typing import Any, Iterable, Optional, Type, cast
1818

1919
import configargparse
20+
21+
from gprofiler.metadata.enrichment import EnrichmentOptions
2022
from granulate_utils.linux.ns import is_running_in_init_pid
2123
from granulate_utils.linux.process import is_process_running
2224
from psutil import NoSuchProcess, Process
@@ -28,7 +30,8 @@
2830
from gprofiler.exceptions import APIError, SystemProfilerInitFailure
2931
from gprofiler.gprofiler_types import ProcessToStackSampleCounters, UserArgs, positive_integer
3032
from gprofiler.log import RemoteLogsHandler, initial_root_logger_setup
31-
from gprofiler.merge import EnrichmentOptions, concatenate_profiles, merge_profiles
33+
from gprofiler.merge import concatenate_profiles, merge_profiles
34+
from gprofiler.metadata.application_identifiers import set_enrichment_options
3235
from gprofiler.metadata.metadata_collector import get_current_metadata, get_static_metadata
3336
from gprofiler.metadata.metadata_type import Metadata
3437
from gprofiler.metadata.system_metadata import get_hostname, get_run_mode, get_static_system_info
@@ -543,6 +546,14 @@ def parse_cmd_args() -> Any:
543546
help="Disable identification of applications by heuristics",
544547
)
545548

549+
parser.add_argument(
550+
"--app-id-args-filter",
551+
action="append",
552+
default=list(),
553+
dest="app_id_args_filters",
554+
help="A regex based filter for adding relevant arguments to the app id",
555+
)
556+
546557
parser.add_argument(
547558
"--disable-application-metadata",
548559
action="store_false",
@@ -734,9 +745,12 @@ def main() -> None:
734745
profile_api_version=args.profile_api_version,
735746
container_names=args.container_names,
736747
application_identifiers=args.identify_applications,
748+
application_identifier_args_filters=args.app_id_args_filters,
737749
application_metadata=args.application_metadata,
738750
)
739751

752+
set_enrichment_options(enrichment_options)
753+
740754
gprofiler = GProfiler(
741755
args.output_dir,
742756
args.flamegraph,

gprofiler/merge.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from gprofiler.log import get_logger_adapter
1717
from gprofiler.metadata import application_identifiers
1818
from gprofiler.metadata.application_metadata import get_application_metadata
19+
from gprofiler.metadata.enrichment import EnrichmentOptions
1920
from gprofiler.metadata.metadata_type import Metadata
2021
from gprofiler.system_metrics import Metrics
2122

@@ -33,18 +34,6 @@
3334
FRAME_REGEX = re.compile(r"^\s*[0-9a-f]+ (.*?) \((.*)\)$")
3435

3536

36-
@dataclass
37-
class EnrichmentOptions:
38-
"""
39-
Profile enrichment options.
40-
"""
41-
42-
profile_api_version: str # profile protocol version. v1 does not support container_names and application_metadata.
43-
container_names: bool # Include container names for each stack in result profile
44-
application_identifiers: bool # Attempt to produce & include appid frames for each stack in result profile
45-
application_metadata: bool # Include specialized metadata per application, e.g for Python - the Python version
46-
47-
4837
def parse_one_collapsed(collapsed: str, add_comm: Optional[str] = None) -> StackToSampleCount:
4938
"""
5039
Parse a stack-collapsed listing.

gprofiler/metadata/application_identifiers.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from abc import ABCMeta, abstractmethod
99
from typing import List, Optional, TextIO, Tuple, Union
1010

11+
from gprofiler.metadata.enrichment import EnrichmentOptions
1112
from granulate_utils.linux.ns import resolve_host_path, resolve_proc_root_links
1213
from psutil import NoSuchProcess, Process
1314

@@ -91,6 +92,8 @@ def _append_file_to_proc_wd(process: Process, file_path: str) -> str:
9192

9293

9394
class _ApplicationIdentifier(metaclass=ABCMeta):
95+
enrichment_options: Optional[EnrichmentOptions] = None
96+
9497
@abstractmethod
9598
def get_application_name(self, process: Process) -> Optional[str]:
9699
pass
@@ -262,11 +265,25 @@ def get_application_name(self, process: Process) -> Optional[str]:
262265
return None
263266

264267
try:
265-
java_properties = run_process([jattach_path(), str(process.pid), "properties"]).stdout.decode()
268+
java_properties = run_process([jattach_path(), str(process.pid), "jcmd", "VM.command_line"]).stdout.decode()
269+
java_command = None
270+
java_args = []
266271
for line in java_properties.splitlines():
267-
if line.startswith("sun.java.command"):
268-
app_id = line[line.find("=") + 1 :].split(" ", 1)[0]
269-
return f"java: {app_id}"
272+
if line.startswith("jvm_args:"):
273+
if (
274+
self.enrichment_options is not None
275+
and self.enrichment_options.application_identifier_args_filters
276+
):
277+
for arg in line[line.find(":") + 1 :].strip().split(" "):
278+
if any(
279+
re.search(flag_filter, arg)
280+
for flag_filter in self.enrichment_options.application_identifier_args_filters
281+
):
282+
java_args.append(arg)
283+
if line.startswith("java_command:"):
284+
java_command = line[line.find(":") + 1 :].strip().split(" ", 1)[0]
285+
if java_command:
286+
return f"java: {java_command}{' (' + ' '.join(java_args) + ')' if java_args else ''}"
270287
except CalledProcessError as e:
271288
_logger.warning(f"Couldn't get Java properties for process {process.pid}: {e.stderr}")
272289

@@ -286,6 +303,10 @@ def get_application_name(self, process: Process) -> Optional[str]:
286303
]
287304

288305

306+
def set_enrichment_options(enrichment_options: EnrichmentOptions) -> None:
307+
_ApplicationIdentifier.enrichment_options = enrichment_options
308+
309+
289310
def get_application_name(process: Union[int, Process]) -> Optional[str]:
290311
"""
291312
Tries to identify the application running in a given process, application identification is fully heuristic,

gprofiler/metadata/enrichment.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from typing import List
2+
3+
from dataclasses import dataclass
4+
5+
6+
@dataclass
7+
class EnrichmentOptions:
8+
"""
9+
Profile enrichment options.
10+
"""
11+
12+
profile_api_version: str # profile protocol version. v1 does not support container_names and application_metadata.
13+
container_names: bool # Include container names for each stack in result profile
14+
application_identifiers: bool # Attempt to produce & include appid frames for each stack in result profile
15+
application_identifier_args_filters: List[str] # A list of regex filters to add cmdline arguments to the app id
16+
application_metadata: bool # Include specialized metadata per application, e.g for Python - the Python version

0 commit comments

Comments
 (0)