forked from DataDog/dd-agent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
jmx.py
145 lines (124 loc) · 4.58 KB
/
jmx.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# std
import logging
import os
import tempfile
import time
# 3rd party
import yaml
# datadog
from config import _windows_commondata_path, get_confd_path
from util import yDumper
from utils.pidfile import PidFile
from utils.platform import Platform
# JMXFetch java version
JMX_FETCH_JAR_NAME = "jmxfetch-0.9.0-jar-with-dependencies.jar"
log = logging.getLogger(__name__)
def jmx_command(args, agent_config, redirect_std_streams=False):
"""
Run JMXFetch with the given command if it is valid (and print user-friendly info if it's not)
"""
from jmxfetch import JMX_LIST_COMMANDS, JMXFetch
if len(args) < 1 or args[0] not in JMX_LIST_COMMANDS.keys():
print "#" * 80
print "JMX tool to be used to help configuring your JMX checks."
print "See http://docs.datadoghq.com/integrations/java/ for more information"
print "#" * 80
print "\n"
print "You have to specify one of the following commands:"
for command, desc in JMX_LIST_COMMANDS.iteritems():
print " - %s [OPTIONAL: LIST OF CHECKS]: %s" % (command, desc)
print "Example: sudo /etc/init.d/datadog-agent jmx list_matching_attributes tomcat jmx solr"
print "\n"
else:
jmx_command = args[0]
checks_list = args[1:]
confd_directory = get_confd_path()
jmx_process = JMXFetch(confd_directory, agent_config)
jmx_process.configure()
should_run = jmx_process.should_run()
if should_run:
jmx_process.run(jmx_command, checks_list, reporter="console", redirect_std_streams=redirect_std_streams)
else:
print "Couldn't find any valid JMX configuration in your conf.d directory: %s" % confd_directory
print "Have you enabled any JMX check ?"
print "If you think it's not normal please get in touch with Datadog Support"
class JMXFiles(object):
"""
A small helper class for JMXFetch status & exit files.
"""
_STATUS_FILE = 'jmx_status.yaml'
_PYTHON_STATUS_FILE = 'jmx_status_python.yaml'
_JMX_EXIT_FILE = 'jmxfetch_exit'
@classmethod
def _get_dir(cls):
if Platform.is_win32():
path = os.path.join(_windows_commondata_path(), 'Datadog')
elif os.path.isdir(PidFile.get_dir()):
path = PidFile.get_dir()
else:
path = tempfile.gettempdir()
return path
@classmethod
def _get_file_path(cls, file):
return os.path.join(cls._get_dir(), file)
@classmethod
def get_status_file_path(cls):
return cls._get_file_path(cls._STATUS_FILE)
@classmethod
def get_python_status_file_path(cls):
return cls._get_file_path(cls._PYTHON_STATUS_FILE)
@classmethod
def get_python_exit_file_path(cls):
return cls._get_file_path(cls._JMX_EXIT_FILE)
@classmethod
def write_status_file(cls, invalid_checks):
data = {
'timestamp': time.time(),
'invalid_checks': invalid_checks
}
stream = file(os.path.join(cls._get_dir(), cls._PYTHON_STATUS_FILE), 'w')
yaml.dump(data, stream, Dumper=yDumper)
stream.close()
@classmethod
def write_exit_file(cls):
"""
Create a 'special' file, which acts as a trigger to exit JMXFetch.
Note: Windows only
"""
open(os.path.join(cls._get_dir(), cls._JMX_EXIT_FILE), 'a').close()
@classmethod
def clean_status_file(cls):
"""
Removes JMX status files
"""
try:
os.remove(os.path.join(cls._get_dir(), cls._STATUS_FILE))
except OSError:
pass
try:
os.remove(os.path.join(cls._get_dir(), cls._PYTHON_STATUS_FILE))
except OSError:
pass
@classmethod
def clean_exit_file(cls):
"""
Remove exit file trigger -may not exist-.
Note: Windows only
"""
try:
os.remove(os.path.join(cls._get_dir(), cls._JMX_EXIT_FILE))
except OSError:
pass
@classmethod
def get_jmx_appnames(cls):
"""
Retrieves the running JMX checks based on the {tmp}/jmx_status.yaml file
updated by JMXFetch (and the only communication channel between JMXFetch
and the collector since JMXFetch).
"""
check_names = []
jmx_status_path = os.path.join(cls._get_dir(), cls._STATUS_FILE)
if os.path.exists(jmx_status_path):
jmx_checks = yaml.load(file(jmx_status_path)).get('checks', {})
check_names = [name for name in jmx_checks.get('initialized_checks', {}).iterkeys()]
return check_names