@cryptotaxi247 / netdata-1 / commits / 97a4bf8dc

oracledb py module (#5421)

<!-- Describe the change in summary section, including rationale and degin decisions. Include "Fixes #nnn" if you are fixing an existing issue. In "Component Name" section write which component is changed in this PR. This will help us review your PR quicker. If you have more information you want to add, write them in "Additional Information" section. This is usually used to help others understand your motivation behind this change. A step-by-step reproduction of the problem is helpful if there is no related issue. --> ##### Summary Fixes: #1996 ##### Component Name python.d.plugin oracledb module ##### Additional Information #### Used queries: - [system metrics]: ```sql SELECT metric_name, value FROM gv$sysmetric ORDER BY begin_time ``` <details><summary>collected metrics</summary> <p> | name| |---| | average_active_sessions | | session_count | | session_limit_percent | | logons_per_sec | | physical_reads_per_sec | | physical_writes_per_sec | | disk_sort_per_sec | | long_table_scans_per_sec | | database_wait_time_ratio | | shared_pool_free_percent | | memory_sorts_ratio | | sql_service_response_time | | user_rollbacks_per_sec | | enqueue_timeouts_per_sec | | buffer_cache_hit_ratio | | cursor_cache_hit_ratio | | library_cache_hit_ratio | | row_cache_hit_ratio | | global_cache_blocks_corrupted | | global_cache_blocks_lost | </p> </details> </br> - [tablespace] ```sql SELECT m.tablespace_name, m.used_space * t.block_size AS used_bytes, m.tablespace_size * t.block_size AS max_bytes, m.used_percent FROM dba_tablespace_usage_metrics m JOIN dba_tablespaces t ON m.tablespace_name = t.tablespace_name ``` <details><summary>collected metrics</summary> <p> | name| |---| | tablespace_size | | tablespace_used | | tablespace_used_in_percent | </p> </details> </br> - [activities count] ```sql SELECT name, value FROM v$sysstat WHERE name IN ( 'parse count (total)', 'execute count', 'user commits', 'user rollbacks' ) ``` <details><summary>collected metrics</summary> <p> | name| |---| | activity_parse_count | | activity_execute_count | | activity_user_commits | | activity_user_rollbacks | </p> </details> </br> - wait time ```sql SELECT n.wait_class, round(m.time_waited / m.INTSIZE_CSEC, 3) FROM v$waitclassmetric m, v$system_wait_class n WHERE m.wait_class_id = n.wait_class_id AND n.wait_class != 'Idle' ```

Ilya Mashchenko committed Feb 28, 2019 at 13:35 UTC 97a4bf8dc11e5e71c28e31221651aee34e409cf5
6 files changed +890
collectors/python.d.plugin/Makefile.am
+1
@@ -78,6 +78,7 @@ include nsd/Makefile.inc
78 include ntpd/Makefile.inc
79 include ovpn_status_log/Makefile.inc
80 include openldap/Makefile.inc
81 +include oracledb/Makefile.inc
82 include phpfpm/Makefile.inc
83 include portcheck/Makefile.inc
84 include postfix/Makefile.inc
collectors/python.d.plugin/oracledb/Makefile.inc new
+13
@@ -0,0 +1,13 @@
1 +# SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +# THIS IS NOT A COMPLETE Makefile
4 +# IT IS INCLUDED BY ITS PARENT'S Makefile.am
5 +# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT
6 +
7 +# install these files
8 +dist_python_DATA += oracledb/oracledb.chart.py
9 +dist_pythonconfig_DATA += oracledb/oracledb.conf
10 +
11 +# do not install these files, but include them in the distribution
12 +dist_noinst_DATA += oracledb/README.md oracledb/Makefile.inc
13 +
collectors/python.d.plugin/oracledb/README.md new
+77
@@ -0,0 +1,77 @@
1 +# oracledb
2 +
3 +Module monitor oracledb performance and health metrics.
4 +
5 +**Requirements:**
6 + - `cx_Oracle` package.
7 + - Oracle Client (using `cx_Oracle` requires Oracle Client libraries to be installed).
8 +
9 +It produces following charts:
10 + - session activity
11 + - Session Count
12 + - Session Limit Usage
13 + - Logons
14 + - disk activity
15 + - Physical Disk Reads/Writes
16 + - Sorts On Disk
17 + - Full Table Scans
18 + - database and buffer activity
19 + - Database Wait Time Ratio
20 + - Shared Pool Free Memory
21 + - In-Memory Sorts Ratio
22 + - SQL Service Response Time
23 + - User Rollbacks
24 + - Enqueue Timeouts
25 + - cache
26 + - Cache Hit Ratio
27 + - Global Cache Blocks Events
28 + - activities
29 + - Activities
30 + - wait time
31 + - Wait Time
32 + - tablespace
33 + - Size
34 + - Usage
35 + - Usage In Percent
36 +
37 +### prerequisite
38 +
39 +To use the Oracle module do the following:
40 +
41 +1. Install `cx_Oracle` package ([link](https://cx-oracle.readthedocs.io/en/latest/installation.html#install-cx-oracle)).
42 +
43 +2. Install Oracle Client libraries ([link](https://cx-oracle.readthedocs.io/en/latest/installation.html#install-oracle-client)).
44 +
45 +3. Create a read-only netdata user with proper access to your Oracle Database Server.
46 +
47 +Connect to your Oracle database with an administrative user and execute:
48 +
49 +```
50 +ALTER SESSION SET "_ORACLE_SCRIPT"=true;
51 +
52 +CREATE USER netdata IDENTIFIED BY <PASSWORD>;
53 +
54 +GRANT CONNECT TO netdata;
55 +GRANT SELECT_CATALOG_ROLE TO netdata;
56 +
57 +```
58 +
59 +### configuration
60 +
61 +```yaml
62 +local:
63 + user: 'netdata'
64 + password: 'secret'
65 + server: 'localhost:1521'
66 + service: 'XE'
67 +
68 +remote:
69 + user: 'netdata'
70 + password: 'secret'
71 + server: '10.0.0.1:1521'
72 + service: 'XE'
73 +```
74 +
75 +All parameters are required. Without them module will fail to start.
76 +
77 +[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fpython.d.plugin%2Foracledb%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]()
collectors/python.d.plugin/oracledb/oracledb.chart.py new
+714
@@ -0,0 +1,714 @@
1 +# -*- coding: utf-8 -*-
2 +# Description: oracledb netdata python.d module
3 +# Author: ilyam8 (Ilya Mashchenko)
4 +# SPDX-License-Identifier: GPL-3.0-or-later
5 +
6 +from copy import deepcopy
7 +
8 +from bases.FrameworkServices.SimpleService import SimpleService
9 +
10 +try:
11 + import cx_Oracle
12 + HAS_ORACLE = True
13 +except ImportError:
14 + HAS_ORACLE = False
15 +
16 +
17 +ORDER = [
18 + 'session_count',
19 + 'session_limit_usage',
20 + 'logons',
21 + 'physical_disk_read_write',
22 + 'sorts_on_disk',
23 + 'full_table_scans',
24 + 'database_wait_time_ratio',
25 + 'shared_pool_free_memory',
26 + 'in_memory_sorts_ratio',
27 + 'sql_service_response_time',
28 + 'user_rollbacks',
29 + 'enqueue_timeouts',
30 + 'cache_hit_ratio',
31 + 'global_cache_blocks',
32 + 'activity',
33 + 'wait_time',
34 + 'tablespace_size',
35 + 'tablespace_usage',
36 + 'tablespace_usage_in_percent',
37 +]
38 +
39 +CHARTS = {
40 + 'session_count': {
41 + 'options': [None, 'Session Count', 'sessions', 'session activity', 'oracledb.session_count', 'line'],
42 + 'lines': [
43 + ['session_count', 'total', 'absolute', 1, 1000],
44 + ['average_active_sessions', 'active', 'absolute', 1, 1000],
45 + ]
46 + },
47 + 'session_limit_usage': {
48 + 'options': [None, 'Session Limit Usage', '%', 'session activity', 'oracledb.session_limit_usage', 'area'],
49 + 'lines': [
50 + ['session_limit_percent', 'usage', 'absolute', 1, 1000],
51 + ]
52 + },
53 + 'logons': {
54 + 'options': [None, 'Logons', 'events/s', 'session activity', 'oracledb.logons', 'area'],
55 + 'lines': [
56 + ['logons_per_sec', 'logons', 'absolute', 1, 1000],
57 + ]
58 + },
59 + 'physical_disk_read_write': {
60 + 'options': [None, 'Physical Disk Reads/Writes', 'events/s', 'disk activity',
61 + 'oracledb.physical_disk_read_writes', 'area'],
62 + 'lines': [
63 + ['physical_reads_per_sec', 'reads', 'absolute', 1, 1000],
64 + ['physical_writes_per_sec', 'writes', 'absolute', -1, 1000],
65 + ]
66 + },
67 + 'sorts_on_disk': {
68 + 'options': [None, 'Sorts On Disk', 'events/s', 'disk activity', 'oracledb.sorts_on_disks', 'line'],
69 + 'lines': [
70 + ['disk_sort_per_sec', 'sorts', 'absolute', 1, 1000],
71 + ]
72 + },
73 + 'full_table_scans': {
74 + 'options': [None, 'Full Table Scans', 'events/s', 'disk activity', 'oracledb.full_table_scans', 'line'],
75 + 'lines': [
76 + ['long_table_scans_per_sec', 'full table scans', 'absolute', 1, 1000],
77 + ]
78 + },
79 + 'database_wait_time_ratio': {
80 + 'options': [None, 'Database Wait Time Ratio', '%', 'database and buffer activity',
81 + 'oracledb.database_wait_time_ratio', 'line'],
82 + 'lines': [
83 + ['database_wait_time_ratio', 'wait time ratio', 'absolute', 1, 1000],
84 + ]
85 + },
86 + 'shared_pool_free_memory': {
87 + 'options': [None, 'Shared Pool Free Memory', '%', 'database and buffer activity',
88 + 'oracledb.shared_pool_free_memory', 'line'],
89 + 'lines': [
90 + ['shared_pool_free_percent', 'free memory', 'absolute', 1, 1000],
91 + ]
92 + },
93 + 'in_memory_sorts_ratio': {
94 + 'options': [None, 'In-Memory Sorts Ratio', '%', 'database and buffer activity',
95 + 'oracledb.in_memory_sorts_ratio', 'line'],
96 + 'lines': [
97 + ['memory_sorts_ratio', 'in-memory sorts', 'absolute', 1, 1000],
98 + ]
99 + },
100 + 'sql_service_response_time': {
101 + 'options': [None, 'SQL Service Response Time', 'seconds', 'database and buffer activity',
102 + 'oracledb.sql_service_response_time', 'line'],
103 + 'lines': [
104 + ['sql_service_response_time', 'time', 'absolute', 1, 1000],
105 + ]
106 + },
107 + 'user_rollbacks': {
108 + 'options': [None, 'User Rollbacks', 'events/s', 'database and buffer activity',
109 + 'oracledb.user_rollbacks', 'line'],
110 + 'lines': [
111 + ['user_rollbacks_per_sec', 'rollbacks', 'absolute', 1, 1000],
112 + ]
113 + },
114 + 'enqueue_timeouts': {
115 + 'options': [None, 'Enqueue Timeouts', 'events/s', 'database and buffer activity',
116 + 'oracledb.enqueue_timeouts', 'line'],
117 + 'lines': [
118 + ['enqueue_timeouts_per_sec', 'enqueue timeouts', 'absolute', 1, 1000],
119 + ]
120 + },
121 + 'cache_hit_ratio': {
122 + 'options': [None, 'Cache Hit Ratio', '%', 'cache', 'oracledb.cache_hit_ration', 'stacked'],
123 + 'lines': [
124 + ['buffer_cache_hit_ratio', 'buffer', 'absolute', 1, 1000],
125 + ['cursor_cache_hit_ratio', 'cursor', 'absolute', 1, 1000],
126 + ['library_cache_hit_ratio', 'library', 'absolute', 1, 1000],
127 + ['row_cache_hit_ratio', 'row', 'absolute', 1, 1000],
128 + ]
129 + },
130 + 'global_cache_blocks': {
131 + 'options': [None, 'Global Cache Blocks Events', 'events/s', 'cache', 'oracledb.global_cache_blocks', 'area'],
132 + 'lines': [
133 + ['global_cache_blocks_corrupted', 'corrupted', 'incremental', 1, 1000],
134 + ['global_cache_blocks_lost', 'lost', 'incremental', 1, 1000],
135 + ]
136 + },
137 + 'activity': {
138 + 'options': [None, 'Activities', 'events/s', 'activities', 'oracledb.activity', 'stacked'],
139 + 'lines': [
140 + ['activity_parse_count_total', 'parse count', 'incremental', 1, 1000],
141 + ['activity_execute_count', 'execute count', 'incremental', 1, 1000],
142 + ['activity_user_commits', 'user commits', 'incremental', 1, 1000],
143 + ['activity_user_rollbacks', 'user rollbacks', 'incremental', 1, 1000],
144 + ]
145 + },
146 + 'wait_time': {
147 + 'options': [None, 'Wait Time', 'ms', 'wait time', 'oracledb.wait_time', 'stacked'],
148 + 'lines': [
149 + ['wait_time_application', 'application', 'absolute', 1, 1000],
150 + ['wait_time_configuration', 'configuration', 'absolute', 1, 1000],
151 + ['wait_time_administrative', 'administrative', 'absolute', 1, 1000],
152 + ['wait_time_concurrency', 'concurrency', 'absolute', 1, 1000],
153 + ['wait_time_commit', 'commit', 'absolute', 1, 1000],
154 + ['wait_time_network', 'network', 'absolute', 1, 1000],
155 + ['wait_time_user_io', 'user I/O', 'absolute', 1, 1000],
156 + ['wait_time_system_io', 'system I/O', 'absolute', 1, 1000],
157 + ['wait_time_scheduler', 'scheduler', 'absolute', 1, 1000],
158 + ['wait_time_other', 'other', 'absolute', 1, 1000],
159 + ]
160 + },
161 + 'tablespace_size': {
162 + 'options': [None, 'Size', 'KiB', 'tablespace', 'oracledb.tablespace_size', 'line'],
163 + 'lines': [],
164 + },
165 + 'tablespace_usage': {
166 + 'options': [None, 'Usage', 'KiB', 'tablespace', 'oracledb.tablespace_usage', 'line'],
167 + 'lines': [],
168 + },
169 + 'tablespace_usage_in_percent': {
170 + 'options': [None, 'Usage', '%', 'tablespace', 'oracledb.tablespace_usage_in_percent', 'line'],
171 + 'lines': [],
172 + },
173 +}
174 +
175 +
176 +CX_CONNECT_STRING = "{0}/{1}@//{2}/{3}"
177 +
178 +QUERY_SYSTEM = '''
179 +SELECT
180 + metric_name,
181 + value
182 +FROM
183 + gv$sysmetric
184 +ORDER BY
185 + begin_time
186 +'''
187 +QUERY_TABLESPACE = '''
188 +SELECT
189 + m.tablespace_name,
190 + m.used_space * t.block_size AS used_bytes,
191 + m.tablespace_size * t.block_size AS max_bytes,
192 + m.used_percent
193 +FROM
194 + dba_tablespace_usage_metrics m
195 + JOIN dba_tablespaces t ON m.tablespace_name = t.tablespace_name
196 +'''
197 +QUERY_ACTIVITIES_COUNT = '''
198 +SELECT
199 + name,
200 + value
201 +FROM
202 + v$sysstat
203 +WHERE
204 + name IN (
205 + 'parse count (total)',
206 + 'execute count',
207 + 'user commits',
208 + 'user rollbacks'
209 + )
210 +'''
211 +QUERY_WAIT_TIME = '''
212 +SELECT
213 + n.wait_class,
214 + round(m.time_waited / m.INTSIZE_CSEC, 3)
215 +FROM
216 + v$waitclassmetric m,
217 + v$system_wait_class n
218 +WHERE
219 + m.wait_class_id = n.wait_class_id
220 + AND n.wait_class != 'Idle'
221 +'''
222 +# QUERY_SESSION_COUNT = '''
223 +# SELECT
224 +# status,
225 +# type
226 +# FROM
227 +# v$session
228 +# GROUP BY
229 +# status,
230 +# type
231 +# '''
232 +# QUERY_PROCESSES_COUNT = '''
233 +# SELECT
234 +# COUNT(*)
235 +# FROM
236 +# v$process
237 +# '''
238 +# QUERY_PROCESS = '''
239 +# SELECT
240 +# program,
241 +# pga_used_mem,
242 +# pga_alloc_mem,
243 +# pga_freeable_mem,
244 +# pga_max_mem
245 +# FROM
246 +# gv$process
247 +# '''
248 +
249 +# PROCESS_METRICS = [
250 +# 'pga_used_memory',
251 +# 'pga_allocated_memory',
252 +# 'pga_freeable_memory',
253 +# 'pga_maximum_memory',
254 +# ]
255 +
256 +
257 +SYS_METRICS = {
258 + 'Average Active Sessions': 'average_active_sessions',
259 + 'Session Count': 'session_count',
260 + 'Session Limit %': 'session_limit_percent',
261 + 'Logons Per Sec': 'logons_per_sec',
262 + 'Physical Reads Per Sec': 'physical_reads_per_sec',
263 + 'Physical Writes Per Sec': 'physical_writes_per_sec',
264 + 'Disk Sort Per Sec': 'disk_sort_per_sec',
265 + 'Long Table Scans Per Sec': 'long_table_scans_per_sec',
266 + 'Database Wait Time Ratio': 'database_wait_time_ratio',
267 + 'Shared Pool Free %': 'shared_pool_free_percent',
268 + 'Memory Sorts Ratio': 'memory_sorts_ratio',
269 + 'SQL Service Response Time': 'sql_service_response_time',
270 + 'User Rollbacks Per Sec': 'user_rollbacks_per_sec',
271 + 'Enqueue Timeouts Per Sec': 'enqueue_timeouts_per_sec',
272 + 'Buffer Cache Hit Ratio': 'buffer_cache_hit_ratio',
273 + 'Cursor Cache Hit Ratio': 'cursor_cache_hit_ratio',
274 + 'Library Cache Hit Ratio': 'library_cache_hit_ratio',
275 + 'Row Cache Hit Ratio': 'row_cache_hit_ratio',
276 + 'Global Cache Blocks Corrupted': 'global_cache_blocks_corrupted',
277 + 'Global Cache Blocks Lost': 'global_cache_blocks_lost',
278 +}
279 +
280 +
281 +class Service(SimpleService):
282 + def __init__(self, configuration=None, name=None):
283 + SimpleService.__init__(self, configuration=configuration, name=name)
284 + self.order = ORDER
285 + self.definitions = deepcopy(CHARTS)
286 + self.user = configuration.get('user')
287 + self.password = configuration.get('password')
288 + self.server = configuration.get('server')
289 + self.service = configuration.get('service')
290 + self.alive = False
291 + self.conn = None
292 + self.active_tablespaces = set()
293 +
294 + def connect(self):
295 + if self.conn:
296 + self.conn.close()
297 + self.conn = None
298 +
299 + try:
300 + self.conn = cx_Oracle.connect(
301 + CX_CONNECT_STRING.format(
302 + self.user,
303 + self.password,
304 + self.server,
305 + self.service,
306 + ))
307 + except cx_Oracle.DatabaseError as error:
308 + self.error(error)
309 + return False
310 +
311 + self.alive = True
312 + return True
313 +
314 + def reconnect(self):
315 + return self.connect()
316 +
317 + def check(self):
318 + if not HAS_ORACLE:
319 + self.error("'cx_Oracle' package is needed to use oracledb module")
320 + return False
321 +
322 + if not all([
323 + self.user,
324 + self.password,
325 + self.server,
326 + self.service,
327 + ]):
328 + self.error("one of these parameters is not specified: user, password, server, service")
329 + return False
330 +
331 + if not self.connect():
332 + return False
333 +
334 + return bool(self.get_data())
335 +
336 + def get_data(self):
337 + if not self.alive and not self.reconnect():
338 + return None
339 +
340 + data = dict()
341 +
342 + # SYSTEM
343 + try:
344 + rv = self.gather_system_metrics()
345 + except cx_Oracle.Error as error:
346 + self.error(error)
347 + self.alive = False
348 + return None
349 + else:
350 + for name, value in rv:
351 + if name not in SYS_METRICS:
352 + continue
353 + data[SYS_METRICS[name]] = int(float(value) * 1000)
354 +
355 + # ACTIVITIES COUNT
356 + try:
357 + rv = self.gather_activities_count()
358 + except cx_Oracle.Error as error:
359 + self.error(error)
360 + self.alive = False
361 + return None
362 + else:
363 + for name, amount in rv:
364 + cleaned = name.replace(' ', '_').replace('(', '').replace(')', '')
365 + new_name = 'activity_{0}'.format(cleaned)
366 + data[new_name] = int(float(amount) * 1000)
367 +
368 + # WAIT TIME
369 + try:
370 + rv = self.gather_wait_time_metrics()
371 + except cx_Oracle.Error as error:
372 + self.error(error)
373 + self.alive = False
374 + return None
375 + else:
376 + for name, amount in rv:
377 + cleaned = name.replace(' ', '_').replace('/', '').lower()
378 + new_name = 'wait_time_{0}'.format(cleaned)
379 + data[new_name] = amount
380 +
381 + # TABLESPACE
382 + try:
383 + rv = self.gather_tablespace_metrics()
384 + except cx_Oracle.Error as error:
385 + self.error(error)
386 + self.alive = False
387 + return None
388 + else:
389 + for name, offline, size, used, used_in_percent in rv:
390 + # TODO: skip offline?
391 + if not (not offline and self.charts):
392 + continue
393 + # TODO: remove inactive?
394 + if name not in self.active_tablespaces:
395 + self.active_tablespaces.add(name)
396 + self.add_tablespace_to_charts(name)
397 + data['{0}_tablespace_size'.format(name)] = int(size * 1000)
398 + data['{0}_tablespace_used'.format(name)] = int(used * 1000)
399 + data['{0}_tablespace_used_in_percent'.format(name)] = int(used_in_percent * 1000)
400 +
401 + return data or None
402 +
403 + def gather_system_metrics(self):
404 +
405 + """
406 + :return:
407 +
408 + [['Buffer Cache Hit Ratio', 100],
409 + ['Memory Sorts Ratio', 100],
410 + ['Redo Allocation Hit Ratio', 100],
411 + ['User Transaction Per Sec', 0],
412 + ['Physical Reads Per Sec', 0],
413 + ['Physical Reads Per Txn', 0],
414 + ['Physical Writes Per Sec', 0],
415 + ['Physical Writes Per Txn', 0],
416 + ['Physical Reads Direct Per Sec', 0],
417 + ['Physical Reads Direct Per Txn', 0],
418 + ['Physical Writes Direct Per Sec', 0],
419 + ['Physical Writes Direct Per Txn', 0],
420 + ['Physical Reads Direct Lobs Per Sec', 0],
421 + ['Physical Reads Direct Lobs Per Txn', 0],
422 + ['Physical Writes Direct Lobs Per Sec', 0],
423 + ['Physical Writes Direct Lobs Per Txn', 0],
424 + ['Redo Generated Per Sec', Decimal('4.66666666666667')],
425 + ['Redo Generated Per Txn', 280],
426 + ['Logons Per Sec', Decimal('0.0166666666666667')],
427 + ['Logons Per Txn', 1],
428 + ['Open Cursors Per Sec', 0.35],
429 + ['Open Cursors Per Txn', 21],
430 + ['User Commits Per Sec', 0],
431 + ['User Commits Percentage', 0],
432 + ['User Rollbacks Per Sec', 0],
433 + ['User Rollbacks Percentage', 0],
434 + ['User Calls Per Sec', Decimal('0.0333333333333333')],
435 + ['User Calls Per Txn', 2],
436 + ['Recursive Calls Per Sec', 14.15],
437 + ['Recursive Calls Per Txn', 849],
438 + ['Logical Reads Per Sec', Decimal('0.683333333333333')],
439 + ['Logical Reads Per Txn', 41],
440 + ['DBWR Checkpoints Per Sec', 0],
441 + ['Background Checkpoints Per Sec', 0],
442 + ['Redo Writes Per Sec', Decimal('0.0333333333333333')],
443 + ['Redo Writes Per Txn', 2],
444 + ['Long Table Scans Per Sec', 0],
445 + ['Long Table Scans Per Txn', 0],
446 + ['Total Table Scans Per Sec', Decimal('0.0166666666666667')],
447 + ['Total Table Scans Per Txn', 1],
448 + ['Full Index Scans Per Sec', 0],
449 + ['Full Index Scans Per Txn', 0],
450 + ['Total Index Scans Per Sec', Decimal('0.216666666666667')],
451 + ['Total Index Scans Per Txn', 13],
452 + ['Total Parse Count Per Sec', 0.35],
453 + ['Total Parse Count Per Txn', 21],
454 + ['Hard Parse Count Per Sec', 0],
455 + ['Hard Parse Count Per Txn', 0],
456 + ['Parse Failure Count Per Sec', 0],
457 + ['Parse Failure Count Per Txn', 0],
458 + ['Cursor Cache Hit Ratio', Decimal('52.3809523809524')],
459 + ['Disk Sort Per Sec', 0],
460 + ['Disk Sort Per Txn', 0],
461 + ['Rows Per Sort', 8.6],
462 + ['Execute Without Parse Ratio', Decimal('27.5862068965517')],
463 + ['Soft Parse Ratio', 100],
464 + ['User Calls Ratio', Decimal('0.235017626321974')],
465 + ['Host CPU Utilization (%)', Decimal('0.124311845142959')],
466 + ['Network Traffic Volume Per Sec', 0],
467 + ['Enqueue Timeouts Per Sec', 0],
468 + ['Enqueue Timeouts Per Txn', 0],
469 + ['Enqueue Waits Per Sec', 0],
470 + ['Enqueue Waits Per Txn', 0],
471 + ['Enqueue Deadlocks Per Sec', 0],
472 + ['Enqueue Deadlocks Per Txn', 0],
473 + ['Enqueue Requests Per Sec', Decimal('216.683333333333')],
474 + ['Enqueue Requests Per Txn', 13001],
475 + ['DB Block Gets Per Sec', 0],
476 + ['DB Block Gets Per Txn', 0],
477 + ['Consistent Read Gets Per Sec', Decimal('0.683333333333333')],
478 + ['Consistent Read Gets Per Txn', 41],
479 + ['DB Block Changes Per Sec', 0],
480 + ['DB Block Changes Per Txn', 0],
481 + ['Consistent Read Changes Per Sec', 0],
482 + ['Consistent Read Changes Per Txn', 0],
483 + ['CPU Usage Per Sec', 0],
484 + ['CPU Usage Per Txn', 0],
485 + ['CR Blocks Created Per Sec', 0],
486 + ['CR Blocks Created Per Txn', 0],
487 + ['CR Undo Records Applied Per Sec', 0],
488 + ['CR Undo Records Applied Per Txn', 0],
489 + ['User Rollback UndoRec Applied Per Sec', 0],
490 + ['User Rollback Undo Records Applied Per Txn', 0],
491 + ['Leaf Node Splits Per Sec', 0],
492 + ['Leaf Node Splits Per Txn', 0],
493 + ['Branch Node Splits Per Sec', 0],
494 + ['Branch Node Splits Per Txn', 0],
495 + ['PX downgraded 1 to 25% Per Sec', 0],
496 + ['PX downgraded 25 to 50% Per Sec', 0],
497 + ['PX downgraded 50 to 75% Per Sec', 0],
498 + ['PX downgraded 75 to 99% Per Sec', 0],
499 + ['PX downgraded to serial Per Sec', 0],
500 + ['Physical Read Total IO Requests Per Sec', Decimal('2.16666666666667')],
501 + ['Physical Read Total Bytes Per Sec', Decimal('35498.6666666667')],
502 + ['GC CR Block Received Per Second', 0],
503 + ['GC CR Block Received Per Txn', 0],
504 + ['GC Current Block Received Per Second', 0],
505 + ['GC Current Block Received Per Txn', 0],
506 + ['Global Cache Average CR Get Time', 0],
507 + ['Global Cache Average Current Get Time', 0],
508 + ['Physical Write Total IO Requests Per Sec', Decimal('0.966666666666667')],
509 + ['Global Cache Blocks Corrupted', 0],
510 + ['Global Cache Blocks Lost', 0],
511 + ['Current Logons Count', 49],
512 + ['Current Open Cursors Count', 64],
513 + ['User Limit %', Decimal('0.00000114087015416959')],
514 + ['SQL Service Response Time', 0],
515 + ['Database Wait Time Ratio', 0],
516 + ['Database CPU Time Ratio', 0],
517 + ['Response Time Per Txn', 0],
518 + ['Row Cache Hit Ratio', 100],
519 + ['Row Cache Miss Ratio', 0],
520 + ['Library Cache Hit Ratio', 100],
521 + ['Library Cache Miss Ratio', 0],
522 + ['Shared Pool Free %', Decimal('7.82380268491548')],
523 + ['PGA Cache Hit %', Decimal('98.0399767109115')],
524 + ['Process Limit %', Decimal('17.6666666666667')],
525 + ['Session Limit %', Decimal('15.2542372881356')],
526 + ['Executions Per Txn', 29],
527 + ['Executions Per Sec', Decimal('0.483333333333333')],
528 + ['Txns Per Logon', 0],
529 + ['Database Time Per Sec', 0],
530 + ['Physical Write Total Bytes Per Sec', 15308.8],
531 + ['Physical Read IO Requests Per Sec', 0],
532 + ['Physical Read Bytes Per Sec', 0],
533 + ['Physical Write IO Requests Per Sec', 0],
534 + ['Physical Write Bytes Per Sec', 0],
535 + ['DB Block Changes Per User Call', 0],
536 + ['DB Block Gets Per User Call', 0],
537 + ['Executions Per User Call', 14.5],
538 + ['Logical Reads Per User Call', 20.5],
539 + ['Total Sorts Per User Call', 2.5],
540 + ['Total Table Scans Per User Call', 0.5],
541 + ['Current OS Load', 0.0390625],
542 + ['Streams Pool Usage Percentage', 0],
543 + ['PQ QC Session Count', 0],
544 + ['PQ Slave Session Count', 0],
545 + ['Queries parallelized Per Sec', 0],
546 + ['DML statements parallelized Per Sec', 0],
547 + ['DDL statements parallelized Per Sec', 0],
548 + ['PX operations not downgraded Per Sec', 0],
549 + ['Session Count', 72],
550 + ['Average Synchronous Single-Block Read Latency', 0],
551 + ['I/O Megabytes per Second', 0.05],
552 + ['I/O Requests per Second', Decimal('3.13333333333333')],
553 + ['Average Active Sessions', 0],
554 + ['Active Serial Sessions', 1],
555 + ['Active Parallel Sessions', 0],
556 + ['Captured user calls', 0],
557 + ['Replayed user calls', 0],
558 + ['Workload Capture and Replay status', 0],
559 + ['Background CPU Usage Per Sec', Decimal('1.22578833333333')],
560 + ['Background Time Per Sec', 0.0147551],
561 + ['Host CPU Usage Per Sec', Decimal('0.116666666666667')],
562 + ['Cell Physical IO Interconnect Bytes', 3048448],
563 + ['Temp Space Used', 0],
564 + ['Total PGA Allocated', 200657920],
565 + ['Total PGA Used by SQL Workareas', 0],
566 + ['Run Queue Per Sec', 0],
567 + ['VM in bytes Per Sec', 0],
568 + ['VM out bytes Per Sec', 0]]
569 + """
570 +
571 + metrics = list()
572 + with self.conn.cursor() as cursor:
573 + cursor.execute(QUERY_SYSTEM)
574 + for metric_name, value in cursor.fetchall():
575 + metrics.append([metric_name, value])
576 + return metrics
577 +
578 + def gather_tablespace_metrics(self):
579 + """
580 + :return:
581 +
582 + [['SYSTEM', 874250240.0, 3233169408.0, 27.040038107400033, 0],
583 + ['SYSAUX', 498860032.0, 3233169408.0, 15.429443033997678, 0],
584 + ['TEMP', 0.0, 3233177600.0, 0.0, 0],
585 + ['USERS', 1048576.0, 3233169408.0, 0.03243182981397305, 0]]
586 + """
587 + metrics = list()
588 + with self.conn.cursor() as cursor:
589 + cursor.execute(QUERY_TABLESPACE)
590 + for tablespace_name, used_bytes, max_bytes, used_percent in cursor.fetchall():
591 + if used_bytes is None:
592 + offline = True
593 + used = 0
594 + else:
595 + offline = False
596 + used = float(used_bytes)
597 + if max_bytes is None:
598 + size = 0
599 + else:
600 + size = float(max_bytes)
601 + if used_percent is None:
602 + used_percent = 0
603 + else:
604 + used_percent = float(used_percent)
605 + metrics.append(
606 + [
607 + tablespace_name,
608 + offline,
609 + size,
610 + used,
611 + used_percent,
612 + ]
613 + )
614 + return metrics
615 +
616 + def gather_wait_time_metrics(self):
617 + """
618 + :return:
619 +
620 + [['Other', 0],
621 + ['Application', 0],
622 + ['Configuration', 0],
623 + ['Administrative', 0],
624 + ['Concurrency', 0],
625 + ['Commit', 0],
626 + ['Network', 0],
627 + ['User I/O', 0],
628 + ['System I/O', 0.002],
629 + ['Scheduler', 0]]
630 + """
631 + metrics = list()
632 + with self.conn.cursor() as cursor:
633 + cursor.execute(QUERY_WAIT_TIME)
634 + for wait_class_name, value in cursor.fetchall():
635 + metrics.append([wait_class_name, value])
636 + return metrics
637 +
638 + def gather_activities_count(self):
639 + """
640 + :return:
641 +
642 + [('user commits', 9104),
643 + ('user rollbacks', 17),
644 + ('parse count (total)', 483695),
645 + ('execute count', 2020356)]
646 + """
647 + with self.conn.cursor() as cursor:
648 + cursor.execute(QUERY_ACTIVITIES_COUNT)
649 + return cursor.fetchall()
650 +
651 + # def gather_process_metrics(self):
652 + # """
653 + # :return:
654 + #
655 + # [['PSEUDO', 'pga_used_memory', 0],
656 + # ['PSEUDO', 'pga_allocated_memory', 0],
657 + # ['PSEUDO', 'pga_freeable_memory', 0],
658 + # ['PSEUDO', 'pga_maximum_memory', 0],
659 + # ['oracle@localhost.localdomain (PMON)', 'pga_used_memory', 1793827],
660 + # ['oracle@localhost.localdomain (PMON)', 'pga_allocated_memory', 1888651],
661 + # ['oracle@localhost.localdomain (PMON)', 'pga_freeable_memory', 0],
662 + # ['oracle@localhost.localdomain (PMON)', 'pga_maximum_memory', 1888651],
663 + # ...
664 + # ...
665 + # """
666 + #
667 + # metrics = list()
668 + # with self.conn.cursor() as cursor:
669 + # cursor.execute(QUERY_PROCESS)
670 + # for row in cursor.fetchall():
671 + # for i, name in enumerate(PROCESS_METRICS, 1):
672 + # metrics.append([row[0], name, row[i]])
673 + # return metrics
674 +
675 + # def gather_processes_count(self):
676 + # with self.conn.cursor() as cursor:
677 + # cursor.execute(QUERY_PROCESSES_COUNT)
678 + # return cursor.fetchone()[0] # 53
679 +
680 + # def gather_sessions_count(self):
681 + # with self.conn.cursor() as cursor:
682 + # cursor.execute(QUERY_SESSION_COUNT)
683 + # total, active, inactive = 0, 0, 0
684 + # for status, _ in cursor.fetchall():
685 + # total += 1
686 + # active += status == 'ACTIVE'
687 + # inactive += status == 'INACTIVE'
688 + # return [total, active, inactive]
689 +
690 + def add_tablespace_to_charts(self, name):
691 + self.charts['tablespace_size'].add_dimension(
692 + [
693 + '{0}_tablespace_size'.format(name),
694 + name,
695 + 'absolute',
696 + 1,
697 + 1024 * 1000,
698 + ])
699 + self.charts['tablespace_usage'].add_dimension(
700 + [
701 + '{0}_tablespace_used'.format(name),
702 + name,
703 + 'absolute',
704 + 1,
705 + 1024 * 1000,
706 + ])
707 + self.charts['tablespace_usage_in_percent'].add_dimension(
708 + [
709 + '{0}_tablespace_used_in_percent'.format(name),
710 + name,
711 + 'absolute',
712 + 1,
713 + 1000,
714 + ])
collectors/python.d.plugin/oracledb/oracledb.conf new
+84
@@ -0,0 +1,84 @@
1 +# netdata python.d.plugin configuration for oracledb
2 +#
3 +# This file is in YaML format. Generally the format is:
4 +#
5 +# name: value
6 +#
7 +# There are 2 sections:
8 +# - global variables
9 +# - one or more JOBS
10 +#
11 +# JOBS allow you to collect values from multiple sources.
12 +# Each source will have its own set of charts.
13 +#
14 +# JOB parameters have to be indented (using spaces only, example below).
15 +
16 +# ----------------------------------------------------------------------
17 +# Global Variables
18 +# These variables set the defaults for all JOBs, however each JOB
19 +# may define its own, overriding the defaults.
20 +
21 +# update_every sets the default data collection frequency.
22 +# If unset, the python.d.plugin default is used.
23 +# update_every: 1
24 +
25 +# priority controls the order of charts at the netdata dashboard.
26 +# Lower numbers move the charts towards the top of the page.
27 +# If unset, the default for python.d.plugin is used.
28 +# priority: 60000
29 +
30 +# penalty indicates whether to apply penalty to update_every in case of failures.
31 +# Penalty will increase every 5 failed updates in a row. Maximum penalty is 10 minutes.
32 +# penalty: yes
33 +
34 +# autodetection_retry sets the job re-check interval in seconds.
35 +# The job is not deleted if check fails.
36 +# Attempts to start the job are made once every autodetection_retry.
37 +# This feature is disabled by default.
38 +# autodetection_retry: 0
39 +
40 +# ----------------------------------------------------------------------
41 +# JOBS (data collection sources)
42 +#
43 +# The default JOBS share the same *name*. JOBS with the same name
44 +# are mutually exclusive. Only one of them will be allowed running at
45 +# any time. This allows autodetection to try several alternatives and
46 +# pick the one that works.
47 +#
48 +# Any number of jobs is supported.
49 +#
50 +# All python.d.plugin JOBS (for all its modules) support a set of
51 +# predefined parameters. These are:
52 +#
53 +# job_name:
54 +# name: myname # the JOB's name as it will appear at the
55 +# # dashboard (by default is the job_name)
56 +# # JOBs sharing a name are mutually exclusive
57 +# update_every: 1 # the JOB's data collection frequency
58 +# priority: 60000 # the JOB's order on the dashboard
59 +# penalty: yes # the JOB's penalty
60 +# autodetection_retry: 0 # the JOB's re-check interval in seconds
61 +#
62 +# Additionally to the above, oracledb also supports the following:
63 +#
64 +# user: username # the username for the user account. Required.
65 +# password: password # the password for the user account. Required.
66 +# server: localhost:1521 # the IP address or hostname of the Oracle Database Server. Required.
67 +# service: XE # the Oracle Database service name. Required. To view the services available on your server,
68 +# run this query: `SELECT value FROM v$parameter WHERE name='service_names'`.
69 +#
70 +# ----------------------------------------------------------------------
71 +# AUTO-DETECTION JOBS
72 +# only one of them will run (they have the same name)
73 +
74 +#local:
75 +# user: 'netdata'
76 +# password: 'secret'
77 +# server: 'localhost:1521'
78 +# service: 'XE'
79 +
80 +#remote:
81 +# user: 'netdata'
82 +# password: 'secret'
83 +# server: '10.0.0.1:1521'
84 +# service: 'XE'
\ No newline at end of file
collectors/python.d.plugin/python.d.conf
+1
@@ -78,6 +78,7 @@ nginx_log: no
78 # nsd: yes
79 # ntpd: yes
80 # openldap: yes
81 +# oracledb: yes
82 # ovpn_status_log: yes
83 # phpfpm: yes
84 # portcheck: yes