-
Notifications
You must be signed in to change notification settings - Fork 8
/
meta.py
120 lines (100 loc) · 4.28 KB
/
meta.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
# -*- coding: utf-8 -*-
from amplify.agent.collectors.abstract import AbstractMetaCollector
from amplify.agent.common.context import context
from amplify.agent.common.util import subp, host
from amplify.agent.common.util.configtypes import boolean
from amplify.ext.mysql.util import LS_CMD, LS_CMD_FREEBSD, ls_parser
__author__ = "Andrew Alexeev"
__copyright__ = "Copyright (C) Nginx Inc. All rights reserved."
__license__ = ""
__maintainer__ = "Mike Belov"
__email__ = "dedm@nginx.com"
class MySQLMetaCollector(AbstractMetaCollector):
short_name = 'mysql_meta'
def __init__(self, **kwargs):
super(MySQLMetaCollector, self).__init__(**kwargs)
self._bin_path = None # cache for bin_path discovery
self._version = None # cache for version discovery
self._connection_location = None
self.register(
self.bin_path,
self.version,
self.connection_location
)
@property
def default_meta(self):
meta = {
'type': self.object.type,
'root_uuid': context.uuid,
'local_id': self.object.local_id,
'name': self.object.name,
'display_name': self.object.display_name,
'cmd': self.object.cmd,
'conf_path': self.object.conf_path,
'connection_location': None,
'bin_path': None,
'version': None,
'can_have_children': False
}
if not self.in_container:
meta['pid'] = self.object.pid
return meta
def bin_path(self):
"""
Finds and sets as a var the path to the running binary of the mysql server
"""
if '/' in self.object.cmd:
self._bin_path = self.object.cmd.split(' ')[0]
if boolean(context.app_config['mysql'].get('remote', False)):
self._bin_path = "unknown"
if self._bin_path is None:
ls_cmd_template = LS_CMD_FREEBSD if host.linux_name() == 'freebsd' else LS_CMD
ls_cmd = ls_cmd_template % self.object.pid
try:
ls, _ = subp.call(ls_cmd, check=False)
context.log.debug('ls "%s" output: %s' % (ls_cmd, ls))
except Exception as e:
exc_name = e.__class__.__name__
# this is being kept as an error because it has
# implications for meta collection success/failure
context.log.debug(
'failed to find MySQL bin path: "%s" failed due to %s' %
(ls_cmd, exc_name)
)
context.log.debug('additional info:', exc_info=True)
else:
try:
self._bin_path = ls_parser(ls[0])
except Exception as e:
exc_name = e.__class__.__name__
context.log.debug(
'failed to parse ls result "%s" due to %s' %
(ls[0], exc_name)
)
context.log.debug('additional info:', exc_info=True)
self.meta['bin_path'] = self._bin_path
def version(self):
"""
Finds and sets version
"""
if self._version is None:
# get data
conn = self.object.connect()
try:
with conn as cursor:
cursor.execute("SELECT version();")
self._version = ''.join(cursor.fetchone()).split('-')[0]
except Exception as e:
exception_name = e.__class__.__name__
context.log.debug('failed to collect MySQLd meta due to %s' % exception_name)
context.log.debug('additional info:', exc_info=True)
finally:
conn.close()
self.meta['version'] = self._version
def connection_location(self):
self._connection_location = self.object.connection_args.get('unix_socket', None)
if not self._connection_location:
# unix_socket is present only for local connection (remote needs host address)
ipv4_args = [self.object.connection_args.get(key) for key in ('host', 'port')]
self._connection_location = ':'.join([str(arg) for arg in ipv4_args if arg is not None])
self.meta['connection_location'] = self._connection_location