Index: weave/files/generic/ganglia/gmond.conf.weave-db =================================================================== --- weave/files/generic/ganglia/gmond.conf.weave-db (revision 0) +++ weave/files/generic/ganglia/gmond.conf.weave-db (revision 0) @@ -0,0 +1,349 @@ +/* This configuration is as close to 2.5.x default behavior as possible + The values closely match ./gmond/metric.h definitions in 2.5.x */ +globals { + daemonize = yes + setuid = yes + user = nobody + debug_level = 0 + max_udp_msg_len = 1472 + mute = no + deaf = no + allow_extra_data = yes + host_dmax = 0 /*secs */ + cleanup_threshold = 300 /*secs */ + gexec = no + send_metadata_interval = 0 /*secs */ +} + +/* + * The cluster attributes specified will be used as part of the + * tag that will wrap all hosts collected by this instance. + */ +cluster { + name = "Weave-DB" + owner = "Phoenix-Owner" + latlong = "unspecified" + url = "unspecified" +} + +/* The host section describes attributes of the host, like the location */ +host { + location = "unspecified" +} + +/* Feel free to specify as many udp_send_channels as you like. Gmond + used to only support having a single channel */ +udp_send_channel { + bind_hostname = yes # Highly recommended, soon to be default. + # This option tells gmond to use a source address + # that resolves to the machine's hostname. Without + # this, the metrics may appear to come from any + # interface and the DNS names associated with + # those IPs will be used to create the RRDs. + mcast_join = 239.2.11.71 + #host = wp-db01.phx.weave.mozilla.com + port = 8649 + ttl = 1 +} + +/* You can specify as many udp_recv_channels as you like as well. */ +udp_recv_channel { + mcast_join = 239.2.11.71 + port = 8649 +# bind = 239.2.11.71 +} + +/* You can specify as many tcp_accept_channels as you like to share + an xml description of the state of the cluster */ +tcp_accept_channel { + port = 8650 +} + +/* Each metrics module that is referenced by gmond must be specified and + loaded. If the module has been statically linked with gmond, it does + not require a load path. However all dynamically loadable modules must + include a load path. */ +modules { + module { + name = "core_metrics" + } + module { + name = "cpu_module" + path = "modcpu.so" + } + module { + name = "disk_module" + path = "moddisk.so" + } + module { + name = "load_module" + path = "modload.so" + } + module { + name = "mem_module" + path = "modmem.so" + } + module { + name = "net_module" + path = "modnet.so" + } + module { + name = "proc_module" + path = "modproc.so" + } + module { + name = "sys_module" + path = "modsys.so" + } +} + +include ('/etc/ganglia/conf.d/*.conf') + +/* The old internal 2.5.x metric array has been replaced by the following + collection_group directives. What follows is the default behavior for + collecting and sending metrics that is as close to 2.5.x behavior as + possible. */ + +/* This collection group will cause a heartbeat (or beacon) to be sent every + 20 seconds. In the heartbeat is the GMOND_STARTED data which expresses + the age of the running gmond. */ +collection_group { + collect_once = yes + time_threshold = 20 + metric { + name = "heartbeat" + } +} + +/* This collection group will send general info about this host every + 1200 secs. + This information doesn't change between reboots and is only collected + once. */ +collection_group { + collect_once = yes + time_threshold = 1200 + metric { + name = "cpu_num" + title = "CPU Count" + } + metric { + name = "cpu_speed" + title = "CPU Speed" + } + metric { + name = "mem_total" + title = "Memory Total" + } + /* Should this be here? Swap can be added/removed between reboots. */ + metric { + name = "swap_total" + title = "Swap Space Total" + } + metric { + name = "boottime" + title = "Last Boot Time" + } + metric { + name = "machine_type" + title = "Machine Type" + } + metric { + name = "os_name" + title = "Operating System" + } + metric { + name = "os_release" + title = "Operating System Release" + } + metric { + name = "location" + title = "Location" + } +} + +/* This collection group will send the status of gexecd for this host + every 300 secs.*/ +/* Unlike 2.5.x the default behavior is to report gexecd OFF. */ +collection_group { + collect_once = yes + time_threshold = 300 + metric { + name = "gexec" + title = "Gexec Status" + } +} + +/* This collection group will collect the CPU status info every 20 secs. + The time threshold is set to 90 seconds. In honesty, this + time_threshold could be set significantly higher to reduce + unneccessary network chatter. */ +collection_group { + collect_every = 20 + time_threshold = 90 + /* CPU status */ + metric { + name = "cpu_user" + value_threshold = "1.0" + title = "CPU User" + } + metric { + name = "cpu_system" + value_threshold = "1.0" + title = "CPU System" + } + metric { + name = "cpu_idle" + value_threshold = "5.0" + title = "CPU Idle" + } + metric { + name = "cpu_nice" + value_threshold = "1.0" + title = "CPU Nice" + } + metric { + name = "cpu_aidle" + value_threshold = "5.0" + title = "CPU aidle" + } + metric { + name = "cpu_wio" + value_threshold = "1.0" + title = "CPU wio" + } + /* The next two metrics are optional if you want more detail... + ... since they are accounted for in cpu_system. + metric { + name = "cpu_intr" + value_threshold = "1.0" + title = "CPU intr" + } + metric { + name = "cpu_sintr" + value_threshold = "1.0" + title = "CPU sintr" + } + */ +} + +collection_group { + collect_every = 20 + time_threshold = 90 + /* Load Averages */ + metric { + name = "load_one" + value_threshold = "1.0" + title = "One Minute Load Average" + } + metric { + name = "load_five" + value_threshold = "1.0" + title = "Five Minute Load Average" + } + metric { + name = "load_fifteen" + value_threshold = "1.0" + title = "Fifteen Minute Load Average" + } +} + +/* This group collects the number of running and total processes */ +collection_group { + collect_every = 80 + time_threshold = 950 + metric { + name = "proc_run" + value_threshold = "1.0" + title = "Total Running Processes" + } + metric { + name = "proc_total" + value_threshold = "1.0" + title = "Total Processes" + } +} + +/* This collection group grabs the volatile memory metrics every 40 secs and + sends them at least every 180 secs. This time_threshold can be increased + significantly to reduce unneeded network traffic. */ +collection_group { + collect_every = 40 + time_threshold = 180 + metric { + name = "mem_free" + value_threshold = "1024.0" + title = "Free Memory" + } + metric { + name = "mem_shared" + value_threshold = "1024.0" + title = "Shared Memory" + } + metric { + name = "mem_buffers" + value_threshold = "1024.0" + title = "Memory Buffers" + } + metric { + name = "mem_cached" + value_threshold = "1024.0" + title = "Cached Memory" + } + metric { + name = "swap_free" + value_threshold = "1024.0" + title = "Free Swap Space" + } +} + +collection_group { + collect_every = 40 + time_threshold = 300 + metric { + name = "bytes_out" + value_threshold = 4096 + title = "Bytes Sent" + } + metric { + name = "bytes_in" + value_threshold = 4096 + title = "Bytes Received" + } + metric { + name = "pkts_in" + value_threshold = 256 + title = "Packets Received" + } + metric { + name = "pkts_out" + value_threshold = 256 + title = "Packets Sent" + } +} + +/* Different than 2.5.x default since the old config made no sense */ +collection_group { + collect_every = 1800 + time_threshold = 3600 + metric { + name = "disk_total" + value_threshold = 1.0 + title = "Total Disk Space" + } +} + +collection_group { + collect_every = 40 + time_threshold = 180 + metric { + name = "disk_free" + value_threshold = 1.0 + title = "Disk Space Available" + } + metric { + name = "part_max_used" + value_threshold = 1.0 + title = "Maximum Disk Space Used" + } +} + Index: weave/files/generic/ganglia/mysql.pyconf =================================================================== --- weave/files/generic/ganglia/mysql.pyconf (revision 0) +++ weave/files/generic/ganglia/mysql.pyconf (revision 0) @@ -0,0 +1,228 @@ +modules { + module { + name = "mysql" + language = "python" + param host { + value = '127.0.0.1' + } + param user { + value = 'root' + } + param passwd { + value = '' + } + param get_master { + value = True + } + param get_slave { + value = True + } + } +} + +collection_group { + collect_every = 10 + time_threshold = 30 + + metric { name = "aborted_clients" } + metric { name = "aborted_connects" } + metric { name = "binlog_cache_disk_use" } + metric { name = "binlog_cache_use" } + metric { name = "bytes_received" } + metric { name = "bytes_sent" } + metric { name = "com_admin_commands" } + metric { name = "com_alter_db" } + metric { name = "com_alter_table" } + metric { name = "com_analyze" } + metric { name = "com_backup_table" } + metric { name = "com_begin" } + metric { name = "com_check" } + metric { name = "com_checksum" } + metric { name = "com_commit" } + metric { name = "com_dealloc_sql" } + metric { name = "com_delete" } + metric { name = "com_delete_multi" } + metric { name = "com_do" } + metric { name = "com_execute_sql" } + metric { name = "com_flush" } + metric { name = "com_insert" } + metric { name = "com_insert_select" } + metric { name = "com_kill" } + metric { name = "com_lock_tables" } + metric { name = "com_purge" } + metric { name = "com_repair" } + metric { name = "com_replace" } + metric { name = "com_replace_select" } + metric { name = "com_reset" } + metric { name = "com_rollback" } + metric { name = "com_savepoint" } + metric { name = "com_select" } + metric { name = "com_show_create_table" } + metric { name = "com_show_databases" } + metric { name = "com_show_grants" } + metric { name = "com_show_slave_status" } + metric { name = "com_show_tables" } + metric { name = "com_slave_start" } + metric { name = "com_slave_stop" } + metric { name = "com_stmt_execute" } + metric { name = "com_stmt_fetch" } + metric { name = "com_stmt_send_long_data" } + metric { name = "com_truncate" } + metric { name = "com_unlock_tables" } + metric { name = "com_update" } + metric { name = "com_update_multi" } + metric { name = "com_xa_commit" } + metric { name = "com_xa_end" } + metric { name = "com_xa_prepare" } + metric { name = "com_xa_recover" } + metric { name = "com_xa_rollback" } + metric { name = "com_xa_start" } + metric { name = "connections" } + metric { name = "created_tmp_disk_tables" } + metric { name = "created_tmp_files" } + metric { name = "created_tmp_tables" } + metric { name = "delayed_errors" } + metric { name = "delayed_insert_threads" } + metric { name = "delayed_writes" } + metric { name = "flush_commands" } + metric { name = "handler_commit" } + metric { name = "handler_delete" } + metric { name = "handler_discover" } + metric { name = "handler_prepare" } + metric { name = "handler_read_first" } + metric { name = "handler_read_key" } + metric { name = "handler_read_next" } + metric { name = "handler_read_prev" } + metric { name = "handler_read_rnd" } + metric { name = "handler_read_rnd_next" } + metric { name = "handler_rollback" } + metric { name = "handler_savepoint" } + metric { name = "handler_savepoint_rollback" } + metric { name = "handler_update" } + metric { name = "handler_write" } + metric { name = "innodb_buffer_pool_pages_data" } + metric { name = "innodb_buffer_pool_pages_dirty" } + metric { name = "innodb_buffer_pool_pages_flushed" } + metric { name = "innodb_buffer_pool_pages_free" } + metric { name = "innodb_buffer_pool_pages_misc" } + metric { name = "innodb_buffer_pool_pages_total" } + metric { name = "innodb_buffer_pool_read_ahead_rnd" } + metric { name = "innodb_buffer_pool_read_ahead_seq" } + metric { name = "innodb_buffer_pool_read_ahead_evicted" } + metric { name = "innodb_buffer_pool_read_requests" } + metric { name = "innodb_buffer_pool_reads" } + metric { name = "innodb_buffer_pool_wait_free" } + metric { name = "innodb_buffer_pool_write_requests" } + metric { name = "innodb_data_fsyncs" } + metric { name = "innodb_data_pending_fsyncs" } + metric { name = "innodb_data_pending_reads" } + metric { name = "innodb_data_pending_writes" } + metric { name = "innodb_data_read" } + metric { name = "innodb_data_reads" } + metric { name = "innodb_data_writes" } + metric { name = "innodb_data_written" } + metric { name = "innodb_dblwr_pages_written" } + metric { name = "innodb_dblwr_writes" } + metric { name = "innodb_history_list" } + metric { name = "innodb_ibuf_inserts" } + metric { name = "innodb_ibuf_merged" } + metric { name = "innodb_ibuf_merges" } + metric { name = "innodb_log_bytes_flushed" } + metric { name = "innodb_log_bytes_unflushed" } + metric { name = "innodb_log_bytes_written" } + metric { name = "innodb_log_waits" } + metric { name = "innodb_log_write_requests" } + metric { name = "innodb_log_writes" } + metric { name = "innodb_os_waits" } + metric { name = "innodb_os_log_fsyncs" } + metric { name = "innodb_os_log_pending_fsyncs" } + metric { name = "innodb_os_log_pending_writes" } + metric { name = "innodb_os_log_written" } + metric { name = "innodb_page_size" } + metric { name = "innodb_pages_created" } + metric { name = "innodb_pages_read" } + metric { name = "innodb_pages_written" } + metric { name = "innodb_pending_aio_log_ios" } + metric { name = "innodb_pending_aio_sync_ios" } + metric { name = "innodb_pending_buffer_pool_flushes" } + metric { name = "innodb_pending_chkp_writes" } + metric { name = "innodb_pending_ibuf_aio_reads" } + metric { name = "innodb_pending_log_flushes" } + metric { name = "innodb_pending_log_writes" } + metric { name = "innodb_pending_normal_aio_reads" } + metric { name = "innodb_pending_normal_aio_writes" } + metric { name = "innodb_queries_inside" } + metric { name = "innodb_queries_queued" } + metric { name = "innodb_read_views" } + metric { name = "innodb_row_lock_current_waits" } + metric { name = "innodb_row_lock_time" } + metric { name = "innodb_row_lock_time_avg" } + metric { name = "innodb_row_lock_time_max" } + metric { name = "innodb_row_lock_waits" } + metric { name = "innodb_rows_deleted" } + metric { name = "innodb_rows_inserted" } + metric { name = "innodb_rows_read" } + metric { name = "innodb_rows_updated" } + metric { name = "innodb_spin_rounds" } + metric { name = "innodb_spin_waits" } + metric { name = "innodb_transactions" } + metric { name = "innodb_transactions_purged" } + metric { name = "innodb_transactions_unpurged" } + metric { name = "key_blocks_not_flushed" } + metric { name = "key_blocks_unused" } + metric { name = "key_blocks_used" } + metric { name = "key_read_requests" } + metric { name = "key_reads" } + metric { name = "key_write_requests" } + metric { name = "key_writes" } + metric { name = "maria_pagecache_blocks_not_flushed" } + metric { name = "maria_pagecache_blocks_unused" } + metric { name = "maria_pagecache_blocks_used" } + metric { name = "maria_pagecache_read_requests" } + metric { name = "maria_pagecache_reads" } + metric { name = "maria_pagecache_write_requests" } + metric { name = "maria_pagecache_writes" } + metric { name = "max_used_connections" } + metric { name = "not_flushed_delayed_rows" } + metric { name = "open_files" } + metric { name = "open_streams" } + metric { name = "open_tables" } + metric { name = "opened_tables" } + metric { name = "prepared_stmt_count" } + metric { name = "qcache_free_blocks" } + metric { name = "qcache_free_memory" } + metric { name = "qcache_hits" } + metric { name = "qcache_inserts" } + metric { name = "qcache_lowmem_prunes" } + metric { name = "qcache_not_cached" } + metric { name = "qcache_queries_in_cache" } + metric { name = "qcache_total_blocks" } + metric { name = "queries" } + metric { name = "questions" } + metric { name = "rpl_status" } + metric { name = "select_full_join" } + metric { name = "select_full_range_join" } + metric { name = "select_range" } + metric { name = "select_range_check" } + metric { name = "select_scan" } + metric { name = "slave_open_temp_tables" } + metric { name = "slave_retried_transactions" } + metric { name = "slow_launch_threads" } + metric { name = "slow_queries" } + metric { name = "sort_merge_passes" } + metric { name = "sort_range" } + metric { name = "sort_rows" } + metric { name = "sort_scan" } + metric { name = "table_locks_immediate" } + metric { name = "table_locks_waited" } + metric { name = "tc_log_max_pages_used" } + metric { name = "tc_log_page_size" } + metric { name = "tc_log_page_waits" } + metric { name = "threads_cached" } + metric { name = "threads_connected" } + metric { name = "threads_created" } + metric { name = "threads_running" } + metric { name = "uptime" } + metric { name = "uptime_since_flush_status" } +} + Index: weave/files/generic/ganglia/gmond.conf.weave-web =================================================================== --- weave/files/generic/ganglia/gmond.conf.weave-web (revision 0) +++ weave/files/generic/ganglia/gmond.conf.weave-web (revision 0) @@ -0,0 +1,349 @@ +/* This configuration is as close to 2.5.x default behavior as possible + The values closely match ./gmond/metric.h definitions in 2.5.x */ +globals { + daemonize = yes + setuid = yes + user = nobody + debug_level = 0 + max_udp_msg_len = 1472 + mute = no + deaf = no + allow_extra_data = yes + host_dmax = 0 /*secs */ + cleanup_threshold = 300 /*secs */ + gexec = no + send_metadata_interval = 0 /*secs */ +} + +/* + * The cluster attributes specified will be used as part of the + * tag that will wrap all hosts collected by this instance. + */ +cluster { + name = "Weave-Web" + owner = "Phoenix-Owner" + latlong = "unspecified" + url = "unspecified" +} + +/* The host section describes attributes of the host, like the location */ +host { + location = "unspecified" +} + +/* Feel free to specify as many udp_send_channels as you like. Gmond + used to only support having a single channel */ +udp_send_channel { + bind_hostname = yes # Highly recommended, soon to be default. + # This option tells gmond to use a source address + # that resolves to the machine's hostname. Without + # this, the metrics may appear to come from any + # interface and the DNS names associated with + # those IPs will be used to create the RRDs. + mcast_join = 239.2.11.71 + #host = wp-db01.phx.weave.mozilla.com + port = 8649 + ttl = 1 +} + +/* You can specify as many udp_recv_channels as you like as well. */ +udp_recv_channel { + mcast_join = 239.2.11.71 + port = 8649 +# bind = 239.2.11.71 +} + +/* You can specify as many tcp_accept_channels as you like to share + an xml description of the state of the cluster */ +tcp_accept_channel { + port = 8650 +} + +/* Each metrics module that is referenced by gmond must be specified and + loaded. If the module has been statically linked with gmond, it does + not require a load path. However all dynamically loadable modules must + include a load path. */ +modules { + module { + name = "core_metrics" + } + module { + name = "cpu_module" + path = "modcpu.so" + } + module { + name = "disk_module" + path = "moddisk.so" + } + module { + name = "load_module" + path = "modload.so" + } + module { + name = "mem_module" + path = "modmem.so" + } + module { + name = "net_module" + path = "modnet.so" + } + module { + name = "proc_module" + path = "modproc.so" + } + module { + name = "sys_module" + path = "modsys.so" + } +} + +include ('/etc/ganglia/conf.d/*.conf') + +/* The old internal 2.5.x metric array has been replaced by the following + collection_group directives. What follows is the default behavior for + collecting and sending metrics that is as close to 2.5.x behavior as + possible. */ + +/* This collection group will cause a heartbeat (or beacon) to be sent every + 20 seconds. In the heartbeat is the GMOND_STARTED data which expresses + the age of the running gmond. */ +collection_group { + collect_once = yes + time_threshold = 20 + metric { + name = "heartbeat" + } +} + +/* This collection group will send general info about this host every + 1200 secs. + This information doesn't change between reboots and is only collected + once. */ +collection_group { + collect_once = yes + time_threshold = 1200 + metric { + name = "cpu_num" + title = "CPU Count" + } + metric { + name = "cpu_speed" + title = "CPU Speed" + } + metric { + name = "mem_total" + title = "Memory Total" + } + /* Should this be here? Swap can be added/removed between reboots. */ + metric { + name = "swap_total" + title = "Swap Space Total" + } + metric { + name = "boottime" + title = "Last Boot Time" + } + metric { + name = "machine_type" + title = "Machine Type" + } + metric { + name = "os_name" + title = "Operating System" + } + metric { + name = "os_release" + title = "Operating System Release" + } + metric { + name = "location" + title = "Location" + } +} + +/* This collection group will send the status of gexecd for this host + every 300 secs.*/ +/* Unlike 2.5.x the default behavior is to report gexecd OFF. */ +collection_group { + collect_once = yes + time_threshold = 300 + metric { + name = "gexec" + title = "Gexec Status" + } +} + +/* This collection group will collect the CPU status info every 20 secs. + The time threshold is set to 90 seconds. In honesty, this + time_threshold could be set significantly higher to reduce + unneccessary network chatter. */ +collection_group { + collect_every = 20 + time_threshold = 90 + /* CPU status */ + metric { + name = "cpu_user" + value_threshold = "1.0" + title = "CPU User" + } + metric { + name = "cpu_system" + value_threshold = "1.0" + title = "CPU System" + } + metric { + name = "cpu_idle" + value_threshold = "5.0" + title = "CPU Idle" + } + metric { + name = "cpu_nice" + value_threshold = "1.0" + title = "CPU Nice" + } + metric { + name = "cpu_aidle" + value_threshold = "5.0" + title = "CPU aidle" + } + metric { + name = "cpu_wio" + value_threshold = "1.0" + title = "CPU wio" + } + /* The next two metrics are optional if you want more detail... + ... since they are accounted for in cpu_system. + metric { + name = "cpu_intr" + value_threshold = "1.0" + title = "CPU intr" + } + metric { + name = "cpu_sintr" + value_threshold = "1.0" + title = "CPU sintr" + } + */ +} + +collection_group { + collect_every = 20 + time_threshold = 90 + /* Load Averages */ + metric { + name = "load_one" + value_threshold = "1.0" + title = "One Minute Load Average" + } + metric { + name = "load_five" + value_threshold = "1.0" + title = "Five Minute Load Average" + } + metric { + name = "load_fifteen" + value_threshold = "1.0" + title = "Fifteen Minute Load Average" + } +} + +/* This group collects the number of running and total processes */ +collection_group { + collect_every = 80 + time_threshold = 950 + metric { + name = "proc_run" + value_threshold = "1.0" + title = "Total Running Processes" + } + metric { + name = "proc_total" + value_threshold = "1.0" + title = "Total Processes" + } +} + +/* This collection group grabs the volatile memory metrics every 40 secs and + sends them at least every 180 secs. This time_threshold can be increased + significantly to reduce unneeded network traffic. */ +collection_group { + collect_every = 40 + time_threshold = 180 + metric { + name = "mem_free" + value_threshold = "1024.0" + title = "Free Memory" + } + metric { + name = "mem_shared" + value_threshold = "1024.0" + title = "Shared Memory" + } + metric { + name = "mem_buffers" + value_threshold = "1024.0" + title = "Memory Buffers" + } + metric { + name = "mem_cached" + value_threshold = "1024.0" + title = "Cached Memory" + } + metric { + name = "swap_free" + value_threshold = "1024.0" + title = "Free Swap Space" + } +} + +collection_group { + collect_every = 40 + time_threshold = 300 + metric { + name = "bytes_out" + value_threshold = 4096 + title = "Bytes Sent" + } + metric { + name = "bytes_in" + value_threshold = 4096 + title = "Bytes Received" + } + metric { + name = "pkts_in" + value_threshold = 256 + title = "Packets Received" + } + metric { + name = "pkts_out" + value_threshold = 256 + title = "Packets Sent" + } +} + +/* Different than 2.5.x default since the old config made no sense */ +collection_group { + collect_every = 1800 + time_threshold = 3600 + metric { + name = "disk_total" + value_threshold = 1.0 + title = "Total Disk Space" + } +} + +collection_group { + collect_every = 40 + time_threshold = 180 + metric { + name = "disk_free" + value_threshold = 1.0 + title = "Disk Space Available" + } + metric { + name = "part_max_used" + value_threshold = 1.0 + title = "Maximum Disk Space Used" + } +} + Index: weave/files/generic/ganglia/DBUtil.py =================================================================== --- weave/files/generic/ganglia/DBUtil.py (revision 0) +++ weave/files/generic/ganglia/DBUtil.py (revision 0) @@ -0,0 +1,179 @@ +""" +The MIT License + +Copyright (c) 2008 Gilad Raphaelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +if using < python2.5, http://code.activestate.com/recipes/523034/ works as a +pure python collections.defaultdict substitute +""" + +import defaultdict +import MySQLdb + +def longish(x): + if len(x): + try: + return long(x) + except ValueError: + return longish(x[:-1]) + else: + raise ValueError + +def parse_innodb_status(innodb_status_raw): + def sumof(status): + def new(*idxs): + return sum(map(lambda x: longish(status[x]), idxs)) + #new.func_name = 'sumof' #not ok in py2.3 + return new + + innodb_status = defaultdict.defaultdict(int) + innodb_status['active_transactions'] + + for line in innodb_status_raw: + istatus = line.split() + + isum = sumof(istatus) + + # SEMAPHORES + if "Mutex spin waits" in line: + innodb_status['spin_waits'] += longish(istatus[3]) + innodb_status['spin_rounds'] += longish(istatus[5]) + innodb_status['os_waits'] += longish(istatus[8]) + + elif "RW-shared spins" in line: + innodb_status['spin_waits'] += isum(2,8) + innodb_status['os_waits'] += isum(5,11) + + # TRANSACTIONS + elif "Trx id counter" in line: + innodb_status['transactions'] += isum(3,4) + + elif "Purge done for trx" in line: + innodb_status['transactions_purged'] += isum(6,7) + + elif "History list length" in line: + innodb_status['history_list'] = longish(istatus[3]) + + elif "---TRANSACTION" in line and innodb_status['transactions']: + innodb_status['current_transactions'] += 1 + if "ACTIVE" in line: + innodb_status['active_transactions'] += 1 + + elif "LOCK WAIT" in line and innodb_status['transactions']: + innodb_status['locked_transactions'] += 1 + + elif 'read views open inside' in line: + innodb_status['read_views'] = longish(istatus[0]) + + # FILE I/O + elif 'OS file reads' in line: + innodb_status['data_reads'] = longish(istatus[0]) + innodb_status['data_writes'] = longish(istatus[4]) + innodb_status['data_fsyncs'] = longish(istatus[8]) + + elif 'Pending normal aio' in line: + innodb_status['pending_normal_aio_reads'] = longish(istatus[4]) + innodb_status['pending_normal_aio_writes'] = longish(istatus[7]) + + elif 'ibuf aio reads' in line: + innodb_status['pending_ibuf_aio_reads'] = longish(istatus[3]) + innodb_status['pending_aio_log_ios'] = longish(istatus[6]) + innodb_status['pending_aio_sync_ios'] = longish(istatus[9]) + + elif 'Pending flushes (fsync)' in line: + innodb_status['pending_log_flushes'] = longish(istatus[4]) + innodb_status['pending_buffer_pool_flushes'] = longish(istatus[7]) + + # INSERT BUFFER AND ADAPTIVE HASH INDEX + elif 'merged recs' in line: + innodb_status['ibuf_inserts'] = longish(istatus[0]) + innodb_status['ibuf_merged'] = longish(istatus[2]) + innodb_status['ibuf_merges'] = longish(istatus[5]) + + # LOG + elif "log i/o's done" in line: + innodb_status['log_writes'] = longish(istatus[0]) + + elif "pending log writes" in line: + innodb_status['pending_log_writes'] = longish(istatus[0]) + innodb_status['pending_chkp_writes'] = longish(istatus[4]) + + elif "Log sequence number" in line: + innodb_status['log_bytes_written'] = isum(3,4) + + elif "Log flushed up to" in line: + innodb_status['log_bytes_flushed'] = isum(4,5) + + # BUFFER POOL AND MEMORY + elif "Buffer pool size" in line: + innodb_status['buffer_pool_pages_total'] = longish(istatus[3]) + + elif "Free buffers" in line: + innodb_status['buffer_pool_pages_free'] = longish(istatus[2]) + + elif "Database pages" in line: + innodb_status['buffer_pool_pages_data'] = longish(istatus[2]) + + elif "Modified db pages" in line: + innodb_status['buffer_pool_pages_dirty'] = longish(istatus[3]) + + elif "Pages read" in line: + innodb_status['pages_read'] = longish(istatus[2]) + innodb_status['pages_created'] = longish(istatus[4]) + innodb_status['pages_written'] = longish(istatus[6]) + + # ROW OPERATIONS + elif 'Number of rows inserted' in line: + innodb_status['rows_inserted'] = longish(istatus[4]) + innodb_status['rows_updated'] = longish(istatus[6]) + innodb_status['rows_deleted'] = longish(istatus[8]) + innodb_status['rows_read'] = longish(istatus[10]) + + elif "queries inside InnoDB" in line: + innodb_status['queries_inside'] = longish(istatus[0]) + innodb_status['queries_queued'] = longish(istatus[4]) + + # Some more stats + innodb_status['transactions_unpurged'] = innodb_status['transactions'] - innodb_status['transactions_purged'] + innodb_status['log_bytes_unflushed'] = innodb_status['log_bytes_written'] - innodb_status['log_bytes_flushed'] + + return innodb_status + +if __name__ == '__main__': + from optparse import OptionParser + + parser = OptionParser() + parser.add_option("-H", "--Host", dest="host", help="Host running mysql", default="localhost") + parser.add_option("-u", "--user", dest="user", help="user to connect as", default="") + parser.add_option("-p", "--password", dest="passwd", help="password", default="") + (options, args) = parser.parse_args() + + try: + conn = MySQLdb.connect(user=options.user, host=options.host, passwd=options.passwd) + + cursor = conn.cursor(MySQLdb.cursors.Cursor) + cursor.execute("SHOW /*!50000 ENGINE*/ INNODB STATUS") + innodb_status = parse_innodb_status(cursor.fetchone()[0].split('\n')) + cursor.close() + + conn.close() + except MySQLdb.OperationalError, (errno, errmsg): + raise Property changes on: weave/files/generic/ganglia/DBUtil.py ___________________________________________________________________ Added: svn:executable + * Index: weave/files/generic/ganglia/gmond.conf.weave-ldap =================================================================== --- weave/files/generic/ganglia/gmond.conf.weave-ldap (revision 0) +++ weave/files/generic/ganglia/gmond.conf.weave-ldap (revision 0) @@ -0,0 +1,349 @@ +/* This configuration is as close to 2.5.x default behavior as possible + The values closely match ./gmond/metric.h definitions in 2.5.x */ +globals { + daemonize = yes + setuid = yes + user = nobody + debug_level = 0 + max_udp_msg_len = 1472 + mute = no + deaf = no + allow_extra_data = yes + host_dmax = 0 /*secs */ + cleanup_threshold = 300 /*secs */ + gexec = no + send_metadata_interval = 0 /*secs */ +} + +/* + * The cluster attributes specified will be used as part of the + * tag that will wrap all hosts collected by this instance. + */ +cluster { + name = "Weave-LDAP" + owner = "Phoenix-Owner" + latlong = "unspecified" + url = "unspecified" +} + +/* The host section describes attributes of the host, like the location */ +host { + location = "unspecified" +} + +/* Feel free to specify as many udp_send_channels as you like. Gmond + used to only support having a single channel */ +udp_send_channel { + bind_hostname = yes # Highly recommended, soon to be default. + # This option tells gmond to use a source address + # that resolves to the machine's hostname. Without + # this, the metrics may appear to come from any + # interface and the DNS names associated with + # those IPs will be used to create the RRDs. + mcast_join = 239.2.11.71 + #host = wp-db01.phx.weave.mozilla.com + port = 8649 + ttl = 1 +} + +/* You can specify as many udp_recv_channels as you like as well. */ +udp_recv_channel { + mcast_join = 239.2.11.71 + port = 8649 +# bind = 239.2.11.71 +} + +/* You can specify as many tcp_accept_channels as you like to share + an xml description of the state of the cluster */ +tcp_accept_channel { + port = 8650 +} + +/* Each metrics module that is referenced by gmond must be specified and + loaded. If the module has been statically linked with gmond, it does + not require a load path. However all dynamically loadable modules must + include a load path. */ +modules { + module { + name = "core_metrics" + } + module { + name = "cpu_module" + path = "modcpu.so" + } + module { + name = "disk_module" + path = "moddisk.so" + } + module { + name = "load_module" + path = "modload.so" + } + module { + name = "mem_module" + path = "modmem.so" + } + module { + name = "net_module" + path = "modnet.so" + } + module { + name = "proc_module" + path = "modproc.so" + } + module { + name = "sys_module" + path = "modsys.so" + } +} + +include ('/etc/ganglia/conf.d/*.conf') + +/* The old internal 2.5.x metric array has been replaced by the following + collection_group directives. What follows is the default behavior for + collecting and sending metrics that is as close to 2.5.x behavior as + possible. */ + +/* This collection group will cause a heartbeat (or beacon) to be sent every + 20 seconds. In the heartbeat is the GMOND_STARTED data which expresses + the age of the running gmond. */ +collection_group { + collect_once = yes + time_threshold = 20 + metric { + name = "heartbeat" + } +} + +/* This collection group will send general info about this host every + 1200 secs. + This information doesn't change between reboots and is only collected + once. */ +collection_group { + collect_once = yes + time_threshold = 1200 + metric { + name = "cpu_num" + title = "CPU Count" + } + metric { + name = "cpu_speed" + title = "CPU Speed" + } + metric { + name = "mem_total" + title = "Memory Total" + } + /* Should this be here? Swap can be added/removed between reboots. */ + metric { + name = "swap_total" + title = "Swap Space Total" + } + metric { + name = "boottime" + title = "Last Boot Time" + } + metric { + name = "machine_type" + title = "Machine Type" + } + metric { + name = "os_name" + title = "Operating System" + } + metric { + name = "os_release" + title = "Operating System Release" + } + metric { + name = "location" + title = "Location" + } +} + +/* This collection group will send the status of gexecd for this host + every 300 secs.*/ +/* Unlike 2.5.x the default behavior is to report gexecd OFF. */ +collection_group { + collect_once = yes + time_threshold = 300 + metric { + name = "gexec" + title = "Gexec Status" + } +} + +/* This collection group will collect the CPU status info every 20 secs. + The time threshold is set to 90 seconds. In honesty, this + time_threshold could be set significantly higher to reduce + unneccessary network chatter. */ +collection_group { + collect_every = 20 + time_threshold = 90 + /* CPU status */ + metric { + name = "cpu_user" + value_threshold = "1.0" + title = "CPU User" + } + metric { + name = "cpu_system" + value_threshold = "1.0" + title = "CPU System" + } + metric { + name = "cpu_idle" + value_threshold = "5.0" + title = "CPU Idle" + } + metric { + name = "cpu_nice" + value_threshold = "1.0" + title = "CPU Nice" + } + metric { + name = "cpu_aidle" + value_threshold = "5.0" + title = "CPU aidle" + } + metric { + name = "cpu_wio" + value_threshold = "1.0" + title = "CPU wio" + } + /* The next two metrics are optional if you want more detail... + ... since they are accounted for in cpu_system. + metric { + name = "cpu_intr" + value_threshold = "1.0" + title = "CPU intr" + } + metric { + name = "cpu_sintr" + value_threshold = "1.0" + title = "CPU sintr" + } + */ +} + +collection_group { + collect_every = 20 + time_threshold = 90 + /* Load Averages */ + metric { + name = "load_one" + value_threshold = "1.0" + title = "One Minute Load Average" + } + metric { + name = "load_five" + value_threshold = "1.0" + title = "Five Minute Load Average" + } + metric { + name = "load_fifteen" + value_threshold = "1.0" + title = "Fifteen Minute Load Average" + } +} + +/* This group collects the number of running and total processes */ +collection_group { + collect_every = 80 + time_threshold = 950 + metric { + name = "proc_run" + value_threshold = "1.0" + title = "Total Running Processes" + } + metric { + name = "proc_total" + value_threshold = "1.0" + title = "Total Processes" + } +} + +/* This collection group grabs the volatile memory metrics every 40 secs and + sends them at least every 180 secs. This time_threshold can be increased + significantly to reduce unneeded network traffic. */ +collection_group { + collect_every = 40 + time_threshold = 180 + metric { + name = "mem_free" + value_threshold = "1024.0" + title = "Free Memory" + } + metric { + name = "mem_shared" + value_threshold = "1024.0" + title = "Shared Memory" + } + metric { + name = "mem_buffers" + value_threshold = "1024.0" + title = "Memory Buffers" + } + metric { + name = "mem_cached" + value_threshold = "1024.0" + title = "Cached Memory" + } + metric { + name = "swap_free" + value_threshold = "1024.0" + title = "Free Swap Space" + } +} + +collection_group { + collect_every = 40 + time_threshold = 300 + metric { + name = "bytes_out" + value_threshold = 4096 + title = "Bytes Sent" + } + metric { + name = "bytes_in" + value_threshold = 4096 + title = "Bytes Received" + } + metric { + name = "pkts_in" + value_threshold = 256 + title = "Packets Received" + } + metric { + name = "pkts_out" + value_threshold = 256 + title = "Packets Sent" + } +} + +/* Different than 2.5.x default since the old config made no sense */ +collection_group { + collect_every = 1800 + time_threshold = 3600 + metric { + name = "disk_total" + value_threshold = 1.0 + title = "Total Disk Space" + } +} + +collection_group { + collect_every = 40 + time_threshold = 180 + metric { + name = "disk_free" + value_threshold = 1.0 + title = "Disk Space Available" + } + metric { + name = "part_max_used" + value_threshold = 1.0 + title = "Maximum Disk Space Used" + } +} + Index: weave/files/generic/ganglia/mysql.py =================================================================== --- weave/files/generic/ganglia/mysql.py (revision 0) +++ weave/files/generic/ganglia/mysql.py (revision 0) @@ -0,0 +1,707 @@ +#!/usr/bin/python + +""" +The MIT License + +Copyright (c) 2008 Gilad Raphaelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +""" + +__version__ = '0.1.2' # 2009-01-12 + +import sys +import time +import MySQLdb + +import logging +logging.basicConfig(level=logging.ERROR, format="%(asctime)s - %(name)s - %(levelname)s - Thread-%(thread)d - %(message)s", filename='/tmp/mylog', filemode='w') +logging.warning('starting up') + +last_update = 0 +mysql_conn_opts = {} +mysql_stats = {} + +REPORT_MASTER = True +REPORT_SLAVE = True +REPORT_MARIA = True + +def update_stats(get_master=True, get_slave=True, get_maria=True): + logging.warning('updating stats') + global last_update + global mysql_stats + + if time.time() - last_update < 15: + return True + else: + last_update = time.time() + + logging.warning('refreshing stats') + mysql_stats = {} + + # Get info from DB + try: + conn = MySQLdb.connect(**mysql_conn_opts) + + cursor = conn.cursor(MySQLdb.cursors.DictCursor) + cursor.execute("SELECT GET_LOCK('gmetric-mysql', 0) as ok") + lock_stat = cursor.fetchone() + cursor.close() + + if lock_stat['ok'] == 0: + return False + + cursor = conn.cursor(MySQLdb.cursors.Cursor) + cursor.execute("SHOW VARIABLES") + #variables = dict(((k.lower(), v) for (k,v) in cursor)) + variables = {} + for (k,v) in cursor: + variables[k.lower()] = v + cursor.close() + + cursor = conn.cursor(MySQLdb.cursors.Cursor) + cursor.execute("SHOW /*!50002 GLOBAL */ STATUS") + #global_status = dict(((k.lower(), v) for (k,v) in cursor)) + global_status = {} + for (k,v) in cursor: + global_status[k.lower()] = v + cursor.close() + + # try not to fail ? + get_master = get_master and variables['log_bin'].lower() == 'on' + + if get_master: + cursor = conn.cursor(MySQLdb.cursors.Cursor) + cursor.execute("SHOW MASTER LOGS") + master_logs = cursor.fetchall() + cursor.close() + + if get_slave: + cursor = conn.cursor(MySQLdb.cursors.DictCursor) + cursor.execute("SHOW SLAVE STATUS") + slave_status = {} + res = cursor.fetchone() + if res: + for (k,v) in res.items(): + slave_status[k.lower()] = v + else: + get_slave = False + cursor.close() + + cursor = conn.cursor(MySQLdb.cursors.DictCursor) + cursor.execute("SELECT RELEASE_LOCK('gmetric-mysql') as ok") + cursor.close() + + conn.close() + except MySQLdb.OperationalError, (errno, errmsg): + logging.warning('error refreshing stats') + return False + + logging.warning('success refreshing stats') + # process variables + # http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html + mysql_stats['version'] = variables['version'] + + # process global status + # http://dev.mysql.com/doc/refman/5.0/en/server-status-variables.html + # i just did "show global status" on a 5.0.77 + interesting_global_status_vars = ( + 'aborted_clients', + 'aborted_connects', + 'binlog_cache_disk_use', + 'binlog_cache_use', + 'bytes_received', + 'bytes_sent', + 'com_admin_commands', + 'com_alter_db', + 'com_alter_table', + 'com_analyze', + 'com_backup_table', + 'com_begin', + 'com_check', + 'com_checksum', + 'com_commit', + 'com_dealloc_sql', + 'com_delete', + 'com_delete_multi', + 'com_do', + 'com_execute_sql', + 'com_flush', + 'com_insert', + 'com_insert_select', + 'com_kill', + 'com_lock_tables', + 'com_purge', + 'com_repair', + 'com_replace', + 'com_replace_select', + 'com_reset', + 'com_rollback', + 'com_savepoint', + 'com_select', + 'com_show_create_table', + 'com_show_databases', + 'com_show_grants', + 'com_show_slave_status', + 'com_show_tables', + 'com_slave_start', + 'com_slave_stop', + 'com_stmt_execute', + 'com_stmt_fetch', + 'com_stmt_send_long_data', + 'com_truncate', + 'com_unlock_tables', + 'com_update', + 'com_update_multi', + 'com_xa_commit', + 'com_xa_end', + 'com_xa_prepare', + 'com_xa_recover', + 'com_xa_rollback', + 'com_xa_start', + 'connections', + 'created_tmp_disk_tables', + 'created_tmp_files', + 'created_tmp_tables', + 'delayed_errors', + 'delayed_insert_threads', + 'delayed_writes', + 'flush_commands', + 'handler_commit', + 'handler_delete', + 'handler_discover', + 'handler_prepare', + 'handler_read_first', + 'handler_read_key', + 'handler_read_next', + 'handler_read_prev', + 'handler_read_rnd', + 'handler_read_rnd_next', + 'handler_rollback', + 'handler_savepoint', + 'handler_savepoint_rollback', + 'handler_update', + 'handler_write', + 'innodb_buffer_pool_pages_data', + 'innodb_buffer_pool_pages_dirty', + 'innodb_buffer_pool_pages_flushed', + 'innodb_buffer_pool_pages_free', + 'innodb_buffer_pool_pages_misc', + 'innodb_buffer_pool_pages_total', + 'innodb_buffer_pool_read_ahead_rnd', + 'innodb_buffer_pool_read_ahead_seq', + 'innodb_buffer_pool_read_ahead_evicted', + 'innodb_buffer_pool_read_requests', + 'innodb_buffer_pool_reads', + 'innodb_buffer_pool_wait_free', + 'innodb_buffer_pool_write_requests', + 'innodb_data_fsyncs', + 'innodb_data_pending_fsyncs', + 'innodb_data_pending_reads', + 'innodb_data_pending_writes', + 'innodb_data_read', + 'innodb_data_reads', + 'innodb_data_writes', + 'innodb_data_written', + 'innodb_dblwr_pages_written', + 'innodb_dblwr_writes', + 'innodb_history_list', + 'innodb_ibuf_inserts', + 'innodb_ibuf_merged', + 'innodb_ibuf_merges', + 'innodb_log_bytes_flushed', + 'innodb_log_bytes_unflushed', + 'innodb_log_bytes_written', + 'innodb_log_waits', + 'innodb_log_write_requests', + 'innodb_log_writes', + 'innodb_os_waits', + 'innodb_os_log_fsyncs', + 'innodb_os_log_pending_fsyncs', + 'innodb_os_log_pending_writes', + 'innodb_os_log_written', + 'innodb_page_size', + 'innodb_pages_created', + 'innodb_pages_read', + 'innodb_pages_written', + 'innodb_pending_aio_log_ios', + 'innodb_pending_aio_sync_ios', + 'innodb_pending_buffer_pool_flushes', + 'innodb_pending_chkp_writes', + 'innodb_pending_ibuf_aio_reads', + 'innodb_pending_log_flushes', + 'innodb_pending_log_writes', + 'innodb_pending_normal_aio_reads', + 'innodb_pending_normal_aio_writes', + 'innodb_queries_inside', + 'innodb_queries_queued', + 'innodb_read_views', + 'innodb_row_lock_current_waits', + 'innodb_row_lock_time', + 'innodb_row_lock_time_avg', + 'innodb_row_lock_time_max', + 'innodb_row_lock_waits', + 'innodb_rows_deleted', + 'innodb_rows_inserted', + 'innodb_rows_read', + 'innodb_rows_updated', + 'innodb_spin_rounds', + 'innodb_spin_waits', + 'innodb_transactions', + 'innodb_transactions_purged', + 'innodb_transactions_unpurged', + 'key_blocks_not_flushed', + 'key_blocks_unused', + 'key_blocks_used', + 'key_read_requests', + 'key_reads', + 'key_write_requests', + 'key_writes', + 'maria_pagecache_blocks_not_flushed', + 'maria_pagecache_blocks_unused', + 'maria_pagecache_blocks_used', + 'maria_pagecache_read_requests', + 'maria_pagecache_reads', + 'maria_pagecache_write_requests', + 'maria_pagecache_writes', + 'max_used_connections', + 'not_flushed_delayed_rows', + 'open_files', + 'open_streams', + 'open_tables', + 'opened_tables', + 'prepared_stmt_count', + 'qcache_free_blocks', + 'qcache_free_memory', + 'qcache_hits', + 'qcache_inserts', + 'qcache_lowmem_prunes', + 'qcache_not_cached', + 'qcache_queries_in_cache', + 'qcache_total_blocks', + 'queries', + 'questions', + 'rpl_status', + 'select_full_join', + 'select_full_range_join', + 'select_range', + 'select_range_check', + 'select_scan', + 'slave_open_temp_tables', + 'slave_retried_transactions', + 'slow_launch_threads', + 'slow_queries', + 'sort_merge_passes', + 'sort_range', + 'sort_rows', + 'sort_scan', + 'table_locks_immediate', + 'table_locks_waited', + 'tc_log_max_pages_used', + 'tc_log_page_size', + 'tc_log_page_waits', + 'threads_cached', + 'threads_connected', + 'threads_created', + 'threads_running', + 'uptime', + 'uptime_since_flush_status' + ) + + # don't put all of global_status in mysql_stats b/c it's so big + # also, i've put a (mostly) superset of stats in the list above, the + # mysql server may not support that stat, hence check if it's in + # the global_status dict before trying to copy it out + for key in interesting_global_status_vars: + if key in global_status: + mysql_stats[key] = global_status[key] + + mysql_stats['open_files_used'] = int(global_status['open_files']) / int(variables['open_files_limit']) + + # process master logs + if get_master: + mysql_stats['binlog_count'] = len(master_logs) + mysql_stats['binlog_space_current'] = master_logs[-1][1] + #mysql_stats['binlog_space_total'] = sum((long(s[1]) for s in master_logs)) + mysql_stats['binlog_space_total'] = 0 + for s in master_logs: + mysql_stats['binlog_space_total'] += int(s[1]) + mysql_stats['binlog_space_used'] = float(master_logs[-1][1]) / float(variables['max_binlog_size']) * 100 + + # process slave status + if get_slave: + mysql_stats['slave_exec_master_log_pos'] = slave_status['exec_master_log_pos'] + #mysql_stats['slave_io'] = 1 if slave_status['slave_io_running'].lower() == "yes" else 0 + if slave_status['slave_io_running'].lower() == "yes": + mysql_stats['slave_io'] = 1 + else: + mysql_stats['slave_io'] = 0 + #mysql_stats['slave_sql'] = 1 if slave_status['slave_sql_running'].lower() =="yes" else 0 + if slave_status['slave_sql_running'].lower() == "yes": + mysql_stats['slave_sql'] = 1 + else: + mysql_stats['slave_sql'] = 0 + mysql_stats['slave_seconds_behind_master'] = slave_status['seconds_behind_master'] + mysql_stats['slave_relay_log_pos'] = slave_status['relay_log_pos'] + mysql_stats['slave_relay_log_space'] = slave_status['relay_log_space'] + +def get_stat(name): + logging.info("getting stat: %s" % name) + global mysql_stats + logging.warning(mysql_stats) + + global REPORT_MASTER + global REPORT_SLAVE + global REPORT_MARIA + + ret = update_stats(REPORT_MASTER, REPORT_SLAVE, REPORT_MARIA) + + if ret: + if name.startswith('mysql_'): + label = name[6:] + else: + label = name + + logging.warning("fetching %s" % name) + try: + return mysql_stats[label] + except: + logging.warning("failed to fetch %s" % name) + return 0 + else: + return 0 + +def metric_init(params): + global descriptors + global mysql_conn_opts + global mysql_stats + + global REPORT_MASTER + global REPORT_SLAVE + + REPORT_MASTER = str(params.get('get_master', True)) == "True" + REPORT_SLAVE = str(params.get('get_slave', True)) == "True" + + logging.warning("init: " + str(params)) + + mysql_conn_opts = dict( + host = params.get('host', 'localhost'), + user = params.get('user'), + passwd = params.get('passwd'), + port = params.get('port', 3306), + connect_timeout = params.get('timeout', 30), + ) + + master_stats_descriptions = {} + slave_stats_descriptions = {} + + misc_stats_descriptions = {} + misc_stats_descriptions ['aborted_clients'] = { 'description': 'The number of connections that were aborted because the client died without closing the connection properly', 'units': 'clients', } + misc_stats_descriptions ['aborted_connects'] = { 'description': 'The number of failed attempts to connect to the MySQL server', 'units': 'conns', } + misc_stats_descriptions ['binlog_cache_disk_use'] = { 'description': 'The number of transactions that used the temporary binary log cache but that exceeded the value of binlog_cache_size and used a temporary file to store statements from the transaction', 'units': 'txns', } + misc_stats_descriptions ['binlog_cache_use'] = { 'description': ' The number of transactions that used the temporary binary log cache', 'units': 'txns', } + misc_stats_descriptions ['bytes_received'] = { 'description': 'The number of bytes received from all clients', 'units': 'bytes', } + misc_stats_descriptions ['bytes_sent'] = { 'description': ' The number of bytes sent to all clients', 'units': 'bytes', } + misc_stats_descriptions ['com_admin_commands'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_alter_db'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_alter_table'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_analyze'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_backup_table'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_begin'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_check'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_checksum'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_commit'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_dealloc_sql'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_delete'] = { 'description': 'The number of DELETE statements', 'units': 'stmts', } + misc_stats_descriptions ['com_delete_multi'] = { 'description': 'The number of multi-table DELETE statements', 'units': 'stmts', } + misc_stats_descriptions ['com_do'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_execute_sql'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_flush'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_insert'] = { 'description': 'The number of INSERT statements', 'units': 'stmts', } + misc_stats_descriptions ['com_insert_select'] = { 'description': 'The number of INSERT ... SELECT statements', 'units': 'stmts', } + misc_stats_descriptions ['com_kill'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_lock_tables'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_purge'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_repair'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_replace'] = { 'description': 'The number of REPLACE statements', 'units': 'stmts', } + misc_stats_descriptions ['com_replace_select'] = { 'description': 'The number of REPLACE ... SELECT statements', 'units': 'stmts', } + misc_stats_descriptions ['com_reset'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_rollback'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_savepoint'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_select'] = { 'description': 'The number of SELECT statements', 'units': 'stmts', } + misc_stats_descriptions ['com_show_create_table'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_show_databases'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_show_grants'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_show_slave_status'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_show_tables'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_slave_start'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_slave_stop'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_stmt_close'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_stmt_prepare'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_stmt_send_long_data'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_truncate'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_unlock_tables'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_update'] = { 'description': 'The number of UPDATE statements', 'units': 'stmts', } + misc_stats_descriptions ['com_update_multi'] = { 'description': 'The number of multi-table UPDATE statements', 'units': 'stmts', } + misc_stats_descriptions ['com_xa_commit'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_xa_end'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_xa_prepare'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_xa_recover'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_xa_rollback'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['com_xa_start'] = { 'description': 'None', 'units': 'cmds', } + misc_stats_descriptions ['connections'] = { 'description': 'The number of connection attempts (successful or not) to the MySQL server', 'units': 'conns', } + misc_stats_descriptions ['created_tmp_disk_tables'] = { 'description': 'The number of temporary tables on disk created automatically by the server while executing statements', 'units': 'tables', } + misc_stats_descriptions ['created_tmp_files'] = { 'description': 'The number of temporary files mysqld has created', 'units': 'files', } + misc_stats_descriptions ['created_tmp_tables'] = { 'description': 'The number of in-memory temporary tables created automatically by the server while executing statement', 'units': 'tables', } + misc_stats_descriptions ['delayed_errors'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['delayed_insert_threads'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['delayed_writes'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['flush_commands'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_commit'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_delete'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_discover'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_prepare'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_read_first'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_read_key'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_read_next'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_read_prev'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_read_rnd'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_read_rnd_next'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_rollback'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_savepoint'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_savepoint_rollback'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_update'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['handler_write'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_active_transactions'] = { 'description': "Active InnoDB transactions", 'value_type':'uint', 'units': 'txns', 'slope': 'both', } + misc_stats_descriptions ['innodb_current_transactions'] = { 'description': "Current InnoDB transactions", 'value_type':'uint', 'units': 'txns', 'slope': 'both', } + misc_stats_descriptions ['innodb_buffer_pool_pages_data'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'pages', } + misc_stats_descriptions ['innodb_buffer_pool_pages_dirty'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'pages', 'slope': 'both', } + misc_stats_descriptions ['innodb_data_fsyncs'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'fsyncs', } + misc_stats_descriptions ['innodb_data_reads'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'reads', } + misc_stats_descriptions ['innodb_data_writes'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'writes', } + misc_stats_descriptions ['innodb_buffer_pool_pages_free'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'pages', 'slope': 'both', } + misc_stats_descriptions ['innodb_history_list'] = { 'description': "InnoDB", 'units': 'length', 'slope': 'both', } + misc_stats_descriptions ['innodb_ibuf_inserts'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'inserts', } + misc_stats_descriptions ['innodb_ibuf_merged'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'recs', } + misc_stats_descriptions ['innodb_ibuf_merges'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'merges', } + misc_stats_descriptions ['innodb_log_bytes_flushed'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'bytes', } + misc_stats_descriptions ['innodb_log_bytes_unflushed'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'bytes', 'slope': 'both', } + misc_stats_descriptions ['innodb_log_bytes_written'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'bytes', } + misc_stats_descriptions ['innodb_log_writes'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'writes', } + misc_stats_descriptions ['innodb_os_waits'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'waits', } + misc_stats_descriptions ['innodb_pages_created'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'pages', } + misc_stats_descriptions ['innodb_pages_read'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'pages', } + misc_stats_descriptions ['innodb_pages_written'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'pages', } + misc_stats_descriptions ['innodb_pending_aio_log_ios'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'ops', } + misc_stats_descriptions ['innodb_pending_aio_sync_ios'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'ops', } + misc_stats_descriptions ['innodb_pending_buffer_pool_flushes'] = { 'description': "The number of pending buffer pool page-flush requests", 'value_type':'uint', 'units': 'reqs', 'slope': 'both', } + misc_stats_descriptions ['innodb_pending_chkp_writes'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'writes', } + misc_stats_descriptions ['innodb_pending_ibuf_aio_reads'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'reads', } + misc_stats_descriptions ['innodb_pending_log_flushes'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'reqs', } + misc_stats_descriptions ['innodb_pending_log_writes'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'writes', } + misc_stats_descriptions ['innodb_pending_normal_aio_reads'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'reads', } + misc_stats_descriptions ['innodb_pending_normal_aio_writes'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'writes', } + misc_stats_descriptions ['innodb_buffer_pool_pages_total'] = { 'description': "The total size of buffer pool, in pages", 'value_type':'uint', 'units': 'pages', 'slope': 'both', } + misc_stats_descriptions ['innodb_queries_inside'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'queries', } + misc_stats_descriptions ['innodb_queries_queued'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'queries', 'slope': 'both', } + misc_stats_descriptions ['innodb_read_views'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'views', } + misc_stats_descriptions ['innodb_rows_deleted'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'rows', } + misc_stats_descriptions ['innodb_rows_inserted'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'rows', } + misc_stats_descriptions ['innodb_rows_read'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'rows', } + misc_stats_descriptions ['innodb_rows_updated'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'rows', } + misc_stats_descriptions ['innodb_spin_rounds'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'spins', 'slope': 'both', } + misc_stats_descriptions ['innodb_spin_waits'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'spins', 'slope': 'both', } + misc_stats_descriptions ['innodb_transactions'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'txns', } + misc_stats_descriptions ['innodb_transactions_purged'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'txns', } + misc_stats_descriptions ['innodb_transactions_unpurged'] = { 'description': "InnoDB", 'value_type':'uint', 'units': 'txns', } + misc_stats_descriptions ['innodb_buffer_pool_pages_flushed'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_buffer_pool_pages_misc'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_buffer_pool_read_ahead_evicted'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_buffer_pool_read_ahead_rnd'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_buffer_pool_read_ahead_seq'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_buffer_pool_read_requests'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_buffer_pool_reads'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_buffer_pool_wait_free'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_buffer_pool_write_requests'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_data_pending_fsyncs'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_data_pending_reads'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_data_pending_writes'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_data_read'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_data_written'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_dblwr_pages_written'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_dblwr_writes'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_log_waits'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_log_write_requests'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_os_log_fsyncs'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_os_log_pending_fsyncs'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_os_log_pending_writes'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_os_log_written'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_page_size'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_row_lock_current_waits'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_row_lock_time_avg'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_row_lock_time'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_row_lock_time_max'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['innodb_row_lock_waits'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['key_blocks_not_flushed'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['key_blocks_unused'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['key_blocks_used'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['key_read_requests'] = { 'description': 'The number of requests to read a key block from the cache', 'units': 'reqs', } + misc_stats_descriptions ['key_reads'] = { 'description': 'The number of physical reads of a key block from disk', 'units': 'reads', } + misc_stats_descriptions ['key_write_requests'] = { 'description': 'The number of requests to write a key block to the cache', 'units': 'reqs', } + misc_stats_descriptions ['key_writes'] = { 'description': 'The number of physical writes of a key block to disk', 'units': 'writes', } + misc_stats_descriptions ['maria_pagecache_blocks_not_flushed'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['maria_pagecache_blocks_unused'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['maria_pagecache_blocks_used'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['maria_pagecache_read_requests'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['maria_pagecache_reads'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['maria_pagecache_write_requests'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['maria_pagecache_writes'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['max_used_connections'] = { 'description': 'The maximum number of connections that have been in use simultaneously since the server started', 'units': 'conns', 'slope': 'both', } + misc_stats_descriptions ['not_flushed_delayed_rows'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['opened_tables'] = { 'description': 'The number of tables that have been opened', 'units': 'tables', } + misc_stats_descriptions ['open_files'] = { 'description': 'The number of files that are open', 'units': 'files', 'slope': 'both', } + misc_stats_descriptions ['open_streams'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['open_tables'] = { 'description': 'The number of tables that are open', 'units': 'tables', 'slope': 'both', } + misc_stats_descriptions ['prepared_stmt_count'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['qcache_free_blocks'] = { 'description': 'The number of free memory blocks in the query cache', 'units': 'blocks', 'slope': 'both', } + misc_stats_descriptions ['qcache_free_memory'] = { 'description': 'The amount of free memory for the query cache', 'units': 'bytes', 'slope': 'both', } + misc_stats_descriptions ['qcache_hits'] = { 'description': 'The number of query cache hits', 'units': 'hits', } + misc_stats_descriptions ['qcache_inserts'] = { 'description': 'The number of queries added to the query cache', 'units': 'queries', } + misc_stats_descriptions ['qcache_lowmem_prunes'] = { 'description': 'The number of queries that were deleted from the query cache because of low memory', 'units': 'queries', } + misc_stats_descriptions ['qcache_not_cached'] = { 'description': 'The number of non-cached queries (not cacheable, or not cached due to the query_cache_type setting)', 'units': 'queries', } + misc_stats_descriptions ['qcache_queries_in_cache'] = { 'description': 'The number of queries registered in the query cache', 'units': 'queries', } + misc_stats_descriptions ['qcache_total_blocks'] = { 'description': 'The total number of blocks in the query cache', 'units': 'blocks', } + misc_stats_descriptions ['queries'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['questions'] = { 'description': 'The number of statements that clients have sent to the server', 'units': 'stmts', } + misc_stats_descriptions ['rpl_status'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['select_full_join'] = { 'description': 'The number of joins that perform table scans because they do not use indexes', 'units': 'joins', } + misc_stats_descriptions ['select_full_range_join'] = { 'description': 'The number of joins that used a range search on a reference table', 'units': 'joins', } + misc_stats_descriptions ['select_range_check'] = { 'description': 'The number of joins without keys that check for key usage after each row', 'units': 'joins', } + misc_stats_descriptions ['select_range'] = { 'description': 'The number of joins that used ranges on the first table', 'units': 'joins', } + misc_stats_descriptions ['select_scan'] = { 'description': 'The number of joins that did a full scan of the first table', 'units': 'joins', } + misc_stats_descriptions ['slave_open_temp_tables'] = { 'description': 'The number of temporary tables that the slave SQL thread currently has open', 'units': 'tables', 'slope': 'both', } + misc_stats_descriptions ['slave_retried_transactions'] = { 'description': 'The total number of times since startup that the replication slave SQL thread has retried transactions', 'units': 'count', } + misc_stats_descriptions ['slow_launch_threads'] = { 'description': 'The number of threads that have taken more than slow_launch_time seconds to create', 'units': 'threads', } + misc_stats_descriptions ['slow_queries'] = { 'description': 'The number of queries that have taken more than long_query_time seconds', 'units': 'queries', } + misc_stats_descriptions ['sort_merge_passes'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['sort_range'] = { 'description': 'The number of sorts that were done using ranges', 'units': 'sorts', } + misc_stats_descriptions ['sort_rows'] = { 'description': 'The number of sorted rows', 'units': 'rows', } + misc_stats_descriptions ['sort_scan'] = { 'description': 'The number of sorts that were done by scanning the table', 'units': 'sorts', } + misc_stats_descriptions ['table_locks_immediate'] = { 'description': 'The number of times that a request for a table lock could be granted immediately', 'units': 'count', } + misc_stats_descriptions ['table_locks_waited'] = { 'description': 'The number of times that a request for a table lock could not be granted immediately and a wait was needed', 'units': 'count', } + misc_stats_descriptions ['tc_log_max_pages_used'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['tc_log_page_size'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['tc_log_page_waits'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['threads_cached'] = { 'description': 'The number of threads in the thread cache', 'units': 'threads', 'slope': 'both', } + misc_stats_descriptions ['threads_connected'] = { 'description': 'The number of currently open connections', 'units': 'threads', 'slope': 'both', } + misc_stats_descriptions ['threads_created'] = { 'description': 'The number of threads created to handle connections', 'units': 'threads', } + misc_stats_descriptions ['threads_running'] = { 'description': 'The number of threads that are not sleeping', 'units': 'threads', 'slope': 'both', } + misc_stats_descriptions ['uptime'] = { 'description': 'The number of seconds that the server has been up', 'units': 'secs', 'slope': 'both', } + misc_stats_descriptions ['uptime_since_flush_status'] = { 'description': 'None', 'units': 'num', } + misc_stats_descriptions ['version'] = { 'description': "MySQL Version", 'value_type': 'string', } + + if REPORT_MASTER: + master_stats_descriptions = dict( + binlog_count = { 'description': "Number of binary logs", 'units': 'logs', 'slope': 'both', }, + binlog_space_current = { 'description': "Size of current binary log", 'units': 'bytes', 'slope': 'both', }, + binlog_space_total = { 'description': "Total space used by binary logs", 'units': 'bytes', 'slope': 'both', }, + binlog_space_used = { 'description': "Current binary log size / max_binlog_size", 'value_type': 'float', 'units': 'percent', 'slope': 'both', }, + ) + + if REPORT_SLAVE: + slave_stats_descriptions = dict( + slave_exec_master_log_pos = { 'description': "The position of the last event executed by the SQL thread from the master's binary log", 'units': 'bytes', 'slope': 'both', }, + slave_io = { 'description': "Whether the I/O thread is started and has connected successfully to the master", 'value_type': 'uint', 'units': 'True/False', 'slope': 'both', }, + slave_seconds_behind_master = { 'description': "Replication Lag", 'units': 'secs', 'slope': 'both', }, + slave_relay_log_pos = { 'description': "The position up to which the SQL thread has read and executed in the current relay log", 'units': 'bytes', 'slope': 'both', }, + slave_sql = { 'description': "Slave SQL Running", 'value_type': 'uint', 'units': 'True/False', 'slope': 'both', }, + ) + + descriptors = [] + + update_stats(REPORT_MASTER, REPORT_SLAVE, REPORT_MARIA) + + for stats_descriptions in (master_stats_descriptions, misc_stats_descriptions, slave_stats_descriptions): + for label in stats_descriptions: + if mysql_stats.has_key(label): + + d = { + 'name': label, + 'call_back': get_stat, + 'time_max': 90, + 'value_type': "uint", + 'units': "", + 'slope': "positive", + 'format': '%u', + 'description': "http://search.mysql.com/search?q=" + label, + 'groups': 'mysql', + } + + d.update(stats_descriptions[label]) + + descriptors.append(d) + + else: + logging.error("skipped " + label) + + logging.warning(str(descriptors)) + return descriptors + +def metric_cleanup(): + logging.shutdown() + # pass + +if __name__ == '__main__': + from optparse import OptionParser + import os + + logging.warning('running from cmd line') + parser = OptionParser() + parser.add_option("-H", "--Host", dest="host", help="Host running mysql", default="127.0.0.1") + parser.add_option("-u", "--user", dest="user", help="user to connect as", default="root") + parser.add_option("-p", "--password", dest="passwd", help="password", default="") + parser.add_option("-P", "--port", dest="port", help="port", default=3306, type="int") + parser.add_option("--no-maria", dest="get_maria", action="store_false", default=True) + parser.add_option("--no-master", dest="get_master", action="store_false", default=True) + parser.add_option("--no-slave", dest="get_slave", action="store_false", default=True) + parser.add_option("-b", "--gmetric-bin", dest="gmetric_bin", help="path to gmetric binary", default="/usr/bin/gmetric") + parser.add_option("-c", "--gmond-conf", dest="gmond_conf", help="path to gmond.conf", default="/etc/ganglia/gmond.conf") + parser.add_option("-g", "--gmetric", dest="gmetric", help="submit via gmetric", action="store_true", default=False) + parser.add_option("-q", "--quiet", dest="quiet", action="store_true", default=False) + + (options, args) = parser.parse_args() + + metric_init({ + 'host': options.host, + 'passwd': options.passwd, + 'user': options.user, + 'port': options.port, + 'get_master': options.get_master, + 'get_slave': options.get_slave, + }) + + for d in descriptors: + v = d['call_back'](d['name']) + if not options.quiet: + print '%s: %s %s [%s]' % (d['name'], v, d['units'], d['description']) + + if options.gmetric: + cmd = "%s --conf=%s --value='%s' --units='%s' --type='%s' --name='%s' --slope='%s'" % \ + (options.gmetric_bin, options.gmond_conf, v, d['units'], d['value_type'], d['name'], d['slope']) + os.system(cmd) Property changes on: weave/files/generic/ganglia/mysql.py ___________________________________________________________________ Added: svn:executable + * Index: weave/manifests/classes/weave.pp =================================================================== --- weave/manifests/classes/weave.pp (revision 7623) +++ weave/manifests/classes/weave.pp (working copy) @@ -59,6 +59,9 @@ file { "/etc/sysconfig/memcached": source => "puppet://$server/generic/weave/sysconfig/memcached"; + + "/etc/ganglia/gmond.conf": + source => "puppet://$server/generic/weave/ganglia/gmond.conf.weave-web"; } service { @@ -137,6 +140,11 @@ ensure => present; } + package { + mysql-python: + ensure => latest; + } + service { lldpd: hasstatus => true, @@ -149,6 +157,23 @@ munin_source => "munin/munin-node.conf"; } + file { + "/etc/ganglia/gmond.conf": + source => "puppet://$server/generic/weave/ganglia/gmond.conf.weave-db"; + require => Package['ganglia-gmond']; + + "/etc/ganglia/conf.d/mysql.pyconf": + source => "puppet://$server/generic/weave/ganglia/mysql.pyconf"; + require => Package['ganglia-gmond-modules-python']; + + "/usr/lib64/ganglia/python_modules/DBUtil.py": + source => "puppet://$server/generic/weave/ganglia/DBUtil.py"; + require => Package['ganglia-gmond-modules-python']; + + "/usr/lib64/ganglia/python_modules/mysql.py": + source => "puppet://$server/generic/weave/ganglia/mysql.py"; + require => Package['ganglia-gmond-modules-python']; + } } class weave-ldap-setup { @@ -158,6 +183,11 @@ munin_source => "munin/munin-node.conf"; } + file { + "/etc/ganglia/gmond.conf": + source => "puppet://$server/generic/weave/ganglia/gmond.conf.weave-ldap"; + require => Package['ganglia-gmond']; + } } class weave-zlb-setup { Index: weave/manifests/classes/base.pp =================================================================== --- weave/manifests/classes/base.pp (revision 7623) +++ weave/manifests/classes/base.pp (working copy) @@ -40,7 +40,9 @@ ruby-rdoc, strace, zabbix-agent, - sysstat + sysstat, + ganglia-gmond, + ganglia-gmond-modules-python ]: ensure => latest; logwatch: @@ -116,6 +118,12 @@ hasstatus => true, hasrestart => true, ensure => running; + gmond: + subscribe => Package['ganglia-gmond'], + enable => true, + hasstatus => true, + hasrestart => true, + ensure => running; } sshd_config {