Class: MySampler::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/mysampler/client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeClient

Returns a new instance of Client.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/mysampler/client.rb', line 8

def initialize
  @user           = nil
  @pass           = nil
  @port           = 3306
  @socket         = nil
  @host           = "localhost"
  @query          = 'SHOW /*!50002 GLOBAL */ STATUS'
  @interval       = 10
  @relative       = false
  @output         = CSVOUT
  @prev_rows      = {}
  @outputfn       = nil
  @rotateinterval = FileRotating::HOUR
  @rf             = nil
  @graphitehost   = nil
  @graphite       = nil
  @mysql_hostname = nil
end

Instance Attribute Details

#graphitehostObject

Returns the value of attribute graphitehost.



6
7
8
# File 'lib/mysampler/client.rb', line 6

def graphitehost
  @graphitehost
end

#hostObject

Returns the value of attribute host.



6
7
8
# File 'lib/mysampler/client.rb', line 6

def host
  @host
end

#intervalObject

Returns the value of attribute interval.



6
7
8
# File 'lib/mysampler/client.rb', line 6

def interval
  @interval
end

#outputObject

Returns the value of attribute output.



6
7
8
# File 'lib/mysampler/client.rb', line 6

def output
  @output
end

#outputfnObject

Returns the value of attribute outputfn.



6
7
8
# File 'lib/mysampler/client.rb', line 6

def outputfn
  @outputfn
end

#passObject

Returns the value of attribute pass.



6
7
8
# File 'lib/mysampler/client.rb', line 6

def pass
  @pass
end

#portObject

Returns the value of attribute port.



6
7
8
# File 'lib/mysampler/client.rb', line 6

def port
  @port
end

#relativeObject

Returns the value of attribute relative.



6
7
8
# File 'lib/mysampler/client.rb', line 6

def relative
  @relative
end

#rotateintervalObject

Returns the value of attribute rotateinterval.



6
7
8
# File 'lib/mysampler/client.rb', line 6

def rotateinterval
  @rotateinterval
end

#socketObject

Returns the value of attribute socket.



6
7
8
# File 'lib/mysampler/client.rb', line 6

def socket
  @socket
end

#userObject

Returns the value of attribute user.



6
7
8
# File 'lib/mysampler/client.rb', line 6

def user
  @user
end

Instance Method Details

#calc_relative(rows) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/mysampler/client.rb', line 100

def calc_relative(rows)
  result = {}
  rows.each do |k,v|
    if @prev_rows[k] && numeric?(v) && is_counter?(k)
      result[k] = v - @prev_rows[k]
    else 
      result[k] = v
    end
  end
  @prev_rows = rows
  return result
end

#conn_to_graphiteObject



68
69
70
71
# File 'lib/mysampler/client.rb', line 68

def conn_to_graphite
  @graphite = Graphite::Logger.new(@graphitehost)
#    @graphite.logger = Logger.new('graphite.out')
end

#db_connectObject



160
161
162
163
164
165
166
167
# File 'lib/mysampler/client.rb', line 160

def db_connect
  params = { :host => @host, 
             :user => @user, 
             :port => @port,
             :password => @pass }
  params[:socket] = @socket if @socket    
  @sequel = Sequel.mysql(params)
end

#get_header_rowsObject



60
61
62
# File 'lib/mysampler/client.rb', line 60

def get_header_rows
  @sequel[@query].to_hash(:Variable_name,:Value).keys
end

#get_mysql_hostnameObject

get the real hostname of the MySQL Server that we are connected to



56
57
58
# File 'lib/mysampler/client.rb', line 56

def get_mysql_hostname 
  @mysql_hostname = @sequel["SELECT @@hostname;"].first[:@@hostname]
end

#hash_to_csv(rows, header = false) ⇒ Object



154
155
156
157
158
# File 'lib/mysampler/client.rb', line 154

def hash_to_csv ( rows, header = false )
  str = header ?  "Time" : "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}" 
  rows.sort.each { |v| str += header ? ",#{v[0]}" : ",#{v[1]}" } 
  return str
end

#is_counter?(key) ⇒ Boolean

Returns:

  • (Boolean)


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/mysampler/client.rb', line 77

def is_counter? (key)
  # list lovingly stolen from pt-mysql-summary
  !%w[ Compression Delayed_insert_threads Innodb_buffer_pool_pages_data 
       Innodb_buffer_pool_pages_dirty Innodb_buffer_pool_pages_free 
       Innodb_buffer_pool_pages_latched Innodb_buffer_pool_pages_misc 
       Innodb_buffer_pool_pages_total Innodb_data_pending_fsyncs 
       Innodb_data_pending_reads Innodb_data_pending_writes 
       Innodb_os_log_pending_fsyncs Innodb_os_log_pending_writes 
       Innodb_page_size Innodb_row_lock_current_waits Innodb_row_lock_time_avg 
       Innodb_row_lock_time_max Key_blocks_not_flushed Key_blocks_unused 
       Key_blocks_used Last_query_cost Max_used_connections Ndb_cluster_node_id 
       Ndb_config_from_host Ndb_config_from_port Ndb_number_of_data_nodes 
       Not_flushed_delayed_rows Open_files Open_streams Open_tables 
       Prepared_stmt_count Qcache_free_blocks Qcache_free_memory 
       Qcache_queries_in_cache Qcache_total_blocks Rpl_status 
       Slave_open_temp_tables Slave_running Ssl_cipher Ssl_cipher_list 
       Ssl_ctx_verify_depth Ssl_ctx_verify_mode Ssl_default_timeout 
       Ssl_session_cache_mode Ssl_session_cache_size Ssl_verify_depth 
       Ssl_verify_mode Ssl_version Tc_log_max_pages_used Tc_log_page_size 
       Threads_cached Threads_connected Threads_running 
       Uptime_since_flush_status ].include? key
end

#numeric?(value) ⇒ Boolean

Returns:

  • (Boolean)


117
118
119
# File 'lib/mysampler/client.rb', line 117

def numeric? (value)
  true if Float(value) rescue false
end

#open_rotating_file(params) ⇒ Object



73
74
75
# File 'lib/mysampler/client.rb', line 73

def open_rotating_file (params)
  @rf = @outputfn ? FileRotating.new(params, @outputfn, "w") : STDOUT
end

#output_header(rows) ⇒ Object



64
65
66
# File 'lib/mysampler/client.rb', line 64

def output_header(rows)
  @rf.puts(header) if @rf && @outputfn
end

#output_query(rows) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/mysampler/client.rb', line 141

def output_query (rows )
  case @output
  when YAMLOUT then
#      result = YAML::dump({time => Time.now, rows})
  when GRAPHITEOUT then
    graphite_rows = prefix_keys(rows, "mysql.#{@mysql_hostname.split('.').reverse.join('.')}.")
    @graphite.log(Time.now.to_i, graphite_rows) if @graphite
  else # CSVOUT 
    @rf.puts(hash_to_csv(rows)) if @rf && @outputfn
  end
  true
end

#prefix_keys(h, prefix) ⇒ Object



113
114
115
# File 'lib/mysampler/client.rb', line 113

def prefix_keys ( h, prefix )
  Hash[h.map { |k,v| [ "#{prefix}#{k}", v] }]
end

#runObject



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/mysampler/client.rb', line 27

def run
  @sequel = db_connect
  if @output == GRAPHITEOUT 
    get_mysql_hostname 
    conn_to_graphite if @output == GRAPHITEOUT
  else
    headers = get_header_rows
    open_rotating_file(:header => headers.join(","), :interval => @rotateinterval) 
  end

  first_run = true
  loop do
    begin
      rows = @sequel[@query].to_hash(:Variable_name,:Value)
      rows = values_to_numeric(rows)
      rows = calc_relative(rows) if @relative
      rows = scale_values(rows) 
      output_query(rows) unless first_run && @relative
      first_run = false
    rescue Exception => e
      STDERR.puts "An error occurred #{e}"
    end

    sleep @interval
  end
  @rf.close if @rf && @outputfn
end

#scale_value(value) ⇒ Object

scale the value to be per @interval if recording relative values since it doesn’t make much sense to output values that are “per 5 seconds”



127
128
129
# File 'lib/mysampler/client.rb', line 127

def scale_value (value)
  (@relative && numeric?(value)) ? (value/@interval) : value
end

#scale_values(rows) ⇒ Object



131
132
133
134
135
# File 'lib/mysampler/client.rb', line 131

def scale_values ( rows )
  Hash[rows.map do |k,v| 
    is_counter?(k) ? [k, scale_value(v)] : [k, v]
  end]  
end

#to_numeric(value) ⇒ Object



121
122
123
# File 'lib/mysampler/client.rb', line 121

def to_numeric (value)
  numeric?(value) ? value.to_i : value
end

#values_to_numeric(h) ⇒ Object



137
138
139
# File 'lib/mysampler/client.rb', line 137

def values_to_numeric ( h )
  Hash[h.map { |k,v| [ k, to_numeric(v)] }]
end