-
Notifications
You must be signed in to change notification settings - Fork 803
[service_discovery][jmx] enabling for JMX-based integrations (GRPC) #2933
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4058485
d38a5bc
71e362e
187b274
8c4046d
66f130f
90a0ca2
74eda87
6f745ce
9f196ed
108a148
b8e202f
86135e8
4482736
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -123,6 +123,9 @@ gce_updated_hostname: yes | |
| # and modify its value. | ||
| # sd_template_dir: /datadog/check_configs | ||
| # | ||
| # JMX Service Disocvery | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need this flag ? Let's add some comments about why it's needed or not |
||
| # sd_jmx_enable: no | ||
| # | ||
| # ========================================================================== # | ||
| # Other # | ||
| # ========================================================================== # | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,11 +27,13 @@ | |
| get_config, | ||
| get_logging_config, | ||
| PathNotFound, | ||
| _is_affirmative | ||
| ) | ||
| from util import yLoader | ||
| from utils.jmx import JMX_FETCH_JAR_NAME, JMXFiles | ||
| from utils.platform import Platform | ||
| from utils.subprocess_output import subprocess | ||
| from utils.service_discovery.config import SD_DEFAULT_RPC_WAIT | ||
|
|
||
| log = logging.getLogger('jmxfetch') | ||
|
|
||
|
|
@@ -46,6 +48,7 @@ | |
| } | ||
|
|
||
| _JVM_DEFAULT_MAX_MEMORY_ALLOCATION = " -Xmx200m" | ||
| _JVM_DEFAULT_SD_MAX_MEMORY_ALLOCATION = " -Xmx512m" | ||
| _JVM_DEFAULT_INITIAL_MEMORY_ALLOCATION = " -Xms50m" | ||
| JMXFETCH_MAIN_CLASS = "org.datadog.jmxfetch.App" | ||
| JMX_CHECKS = [ | ||
|
|
@@ -81,6 +84,7 @@ def __init__(self, confd_path, agentConfig): | |
| self.agentConfig = agentConfig | ||
| self.logging_config = get_logging_config() | ||
| self.check_frequency = DEFAULT_CHECK_FREQUENCY | ||
| self.service_discovery = _is_affirmative(self.agentConfig.get('sd_jmx_enable', False)) | ||
|
|
||
| self.jmx_process = None | ||
| self.jmx_checks = None | ||
|
|
@@ -93,6 +97,10 @@ def _handle_sigterm(self, signum, frame): | |
| log.debug("Caught sigterm. Stopping subprocess.") | ||
| self.jmx_process.terminate() | ||
|
|
||
| def _handle_sigreload(self, signum, frame): | ||
| # Terminate jmx process on SIGTERM signal | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need a new signal handler if we are using gRPC ? |
||
| log.debug("Caught sigusr. Prompting reload...") | ||
|
|
||
| def register_signal_handlers(self): | ||
| """ | ||
| Enable SIGTERM and SIGINT handlers | ||
|
|
@@ -104,6 +112,9 @@ def register_signal_handlers(self): | |
| # Handle Keyboard Interrupt | ||
| signal.signal(signal.SIGINT, self._handle_sigterm) | ||
|
|
||
| # Handle Config reload... | ||
| signal.signal(signal.SIGUSR1, self._handle_sigreload) | ||
|
|
||
| except ValueError: | ||
| log.exception("Unable to register signal handlers.") | ||
|
|
||
|
|
@@ -148,7 +159,7 @@ def run(self, command=None, checks_list=None, reporter=None, redirect_std_stream | |
| except Exception: | ||
| log.exception("Error while writing JMX status file") | ||
|
|
||
| if len(self.jmx_checks) > 0: | ||
| if len(self.jmx_checks) > 0 or self.service_discovery: | ||
| return self._start(self.java_bin_path, self.java_options, self.jmx_checks, | ||
| command, reporter, self.tools_jar_path, self.custom_jar_paths, redirect_std_streams) | ||
| else: | ||
|
|
@@ -273,13 +284,18 @@ def _start(self, path_to_java, java_run_opts, jmx_checks, command, reporter, too | |
| subprocess_args.insert(len(subprocess_args) - 1, '--exit_file_location') | ||
| subprocess_args.insert(len(subprocess_args) - 1, path_to_exit_file) | ||
|
|
||
| subprocess_args.insert(4, '--check') | ||
| for check in jmx_checks: | ||
| subprocess_args.insert(5, check) | ||
| if self.service_discovery: | ||
| subprocess_args.insert(4, '--rpc_wait') | ||
| subprocess_args.insert(5, str(SD_DEFAULT_RPC_WAIT)) | ||
|
|
||
| if jmx_checks: | ||
| subprocess_args.insert(4, '--check') | ||
| for check in jmx_checks: | ||
| subprocess_args.insert(5, check) | ||
|
|
||
| # Specify a maximum memory allocation pool for the JVM | ||
| if "Xmx" not in java_run_opts and "XX:MaxHeapSize" not in java_run_opts: | ||
| java_run_opts += _JVM_DEFAULT_MAX_MEMORY_ALLOCATION | ||
| java_run_opts += _JVM_DEFAULT_SD_MAX_MEMORY_ALLOCATION if self.service_discovery else _JVM_DEFAULT_MAX_MEMORY_ALLOCATION | ||
| # Specify the initial memory allocation pool for the JVM | ||
| if "Xms" not in java_run_opts and "XX:InitialHeapSize" not in java_run_opts: | ||
| java_run_opts += _JVM_DEFAULT_INITIAL_MEMORY_ALLOCATION | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| syntax = "proto3"; | ||
|
|
||
| option java_multiple_files = true; | ||
| option java_package = "org.datadog.jmxfetch"; | ||
| option java_outer_classname = "ServiceDiscoveryProto"; | ||
|
|
||
| package servicediscovery; | ||
|
|
||
| // Interface exported by the server. | ||
| service ServiceDiscovery { | ||
|
|
||
| // A simple RPC. | ||
| // | ||
| // Attempts to set a YAML service discovery configuration. | ||
| // | ||
| // A confirmation message is returned with the status of the | ||
| // operation. | ||
| rpc SetConfig(SDConfig) returns (Confirmation) {} | ||
|
|
||
| } | ||
|
|
||
| message Confirmation { | ||
| bool success = 1; | ||
| } | ||
|
|
||
| message SDConfig { | ||
| string name = 1; | ||
| string config = 2; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -124,6 +124,37 @@ def check_yaml(conf_path): | |
| else: | ||
| return check_config | ||
|
|
||
| def config_to_yaml(config): | ||
| ''' | ||
| Convert a config dict to YAML | ||
| ''' | ||
| assert 'init_config' in config, "No 'init_config' section found" | ||
| assert 'instances' in config, "No 'instances' section found" | ||
|
|
||
| valid_instances = True | ||
| if config['instances'] is None or not isinstance(config['instances'], list): | ||
| valid_instances = False | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You might as well raise here. |
||
| else: | ||
| yaml_output = yaml.safe_dump(config, default_flow_style=False) | ||
|
|
||
| if not valid_instances: | ||
| raise Exception('You need to have at least one instance defined in your config.') | ||
|
|
||
| return yaml_output | ||
|
|
||
| def dump_yaml(path, config): | ||
| ''' | ||
| Dump config dict to YAML file in path | ||
| ''' | ||
| try: | ||
| yaml = config_to_yaml(config) | ||
| except Exception as e: | ||
| log.exception("Unable to convert config to YAML: %s", e) | ||
| else: | ||
| with open(path, 'w+') as f: | ||
| f.write(yaml) | ||
|
|
||
|
|
||
| class Watchdog(object): | ||
| """ | ||
| Simple signal-based watchdog. Restarts the process when: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -275,7 +275,7 @@ def crawl_config_template(self): | |
| # Initialize the config index reference | ||
| if self.previous_config_index is None: | ||
| self.previous_config_index = config_index | ||
| return False | ||
| return True | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the reason for this change ? |
||
| # Config has been modified since last crawl | ||
| # in this case a full config reload is triggered and the identifier_to_checks cache is rebuilt | ||
| if config_index != self.previous_config_index: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick but that's 3rd party