detector 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 803cfd73b761e5b098dac4d15062b3a47e768d70d862c61301f3e8444c011762
4
- data.tar.gz: f96d8885689baed71e8dfd8aa986ee24a6b0620c2745ff91a60e541d9324b781
3
+ metadata.gz: 160f91ff5337a5e65db122754c58acf167ea6c92a2628b6c4cae37dfbebbd2e9
4
+ data.tar.gz: '0691d5918ca772909057ebf059947f4f1b08cd8b5388f0cc7836842d980bf677'
5
5
  SHA512:
6
- metadata.gz: ec4621a88022efbac688c988275d21077dc260139a630659fef4f9257f4baa1409805add6f8056fe6c5a53b2329db849abc685839a5ace170b309089b9a909b3
7
- data.tar.gz: ec584db3cb9ea42c2ce979c17cbc2d0facd7831d08105ab5ed1de0559c5ec5ca6e80fd32734851142ebb45eac676317fd8ac2f8fa72cd44eac41a5189c39bfe1
6
+ metadata.gz: a192f06a2497b21ac4475d2686615450eb800a888367a02eefb36dcf3ae5f7959712a49f4a33012aaa554fabd4d18390aac08e9671dddef38f6f4d8d97c9e561
7
+ data.tar.gz: f9426467573fae22f8fb192b342d376cc1fd04036079821c62c354f3dc0fe426417cdf34a8e3a18e7b09bda36ee2478176fcd1d70d2ac4c3642ea4b10aaa69e6
data/bin/detector CHANGED
@@ -48,7 +48,10 @@ puts "Detected: #{detector.kind}"
48
48
  puts "Version: #{detector.version}"
49
49
  puts "Host: #{detector.host}:#{detector.port}"
50
50
 
51
- if detector.connection_count && detector.connection_limit
51
+ if detector.respond_to?(:connection_info) && detector.connection_info
52
+ conn_info = detector.connection_info
53
+ puts "Connections: global #{conn_info[:connection_count][:global]}/#{conn_info[:connection_limits][:global]} (user #{conn_info[:connection_count][:user]}/#{conn_info[:connection_limits][:user]})"
54
+ elsif detector.connection_count && detector.connection_limit
52
55
  usage = detector.connection_usage_percentage
53
56
  puts "Connections: #{detector.connection_count}/#{detector.connection_limit} (#{usage}%)"
54
57
  end
@@ -53,6 +53,27 @@ module Detector
53
53
  end
54
54
  end
55
55
 
56
+ def connection_info
57
+ return nil unless connection
58
+ begin
59
+ user_limit = connection.query("SELECT @@max_user_connections AS `limit`").first['limit'].to_i
60
+ user_count = connection.query("SELECT COUNT(*) AS count FROM information_schema.PROCESSLIST WHERE user = USER()").first['count'].to_i
61
+ global_limit = connection.query("SELECT @@max_connections AS `limit`").first['limit'].to_i
62
+ global_count = connection.query("SELECT COUNT(*) AS count FROM information_schema.PROCESSLIST").first['count'].to_i
63
+
64
+ # If user limit is 0, it means no specific per-user limit (use global)
65
+ user_limit = global_limit if user_limit == 0
66
+
67
+ {
68
+ connection_count: { user: user_count, global: global_count },
69
+ connection_limits: { user: user_limit, global: global_limit }
70
+ }
71
+ rescue => e
72
+ puts "Error getting connection info: #{e.message}"
73
+ nil
74
+ end
75
+ end
76
+
56
77
  def tables(database_name)
57
78
  return [] unless connection
58
79
 
@@ -12,7 +12,8 @@ module Detector
12
12
  end
13
13
 
14
14
  def connection
15
- @conn ||= Mysql2::Client.new(
15
+ # Create a new connection each time without caching
16
+ Mysql2::Client.new(
16
17
  host: host,
17
18
  username: uri.user,
18
19
  password: uri.password,
@@ -93,6 +94,26 @@ module Detector
93
94
  connection.query("SHOW VARIABLES LIKE 'max_connections'").first['Value'].to_i
94
95
  end
95
96
 
97
+ def connection_info
98
+ return nil unless connection
99
+ begin
100
+ user_limit = connection.query("SELECT @@max_user_connections AS `limit`").first['limit'].to_i
101
+ user_count = connection.query("SELECT COUNT(*) AS count FROM information_schema.PROCESSLIST WHERE user = USER()").first['count'].to_i
102
+ global_limit = connection.query("SELECT @@max_connections AS `limit`").first['limit'].to_i
103
+ global_count = connection.query("SELECT COUNT(*) AS count FROM information_schema.PROCESSLIST").first['count'].to_i
104
+
105
+ # If user limit is 0, it means no specific per-user limit (use global)
106
+ user_limit = global_limit if user_limit == 0
107
+
108
+ {
109
+ connection_count: { user: user_count, global: global_count },
110
+ connection_limits: { user: user_limit, global: global_limit }
111
+ }
112
+ rescue => e
113
+ nil
114
+ end
115
+ end
116
+
96
117
  def cli_name
97
118
  "mysql"
98
119
  end
@@ -12,7 +12,8 @@ module Detector
12
12
  end
13
13
 
14
14
  def connection
15
- @conn ||= PG::Connection.new(uri) rescue nil
15
+ # Create a new connection each time without caching
16
+ PG::Connection.new(uri) rescue nil
16
17
  end
17
18
 
18
19
  def version
@@ -146,6 +147,28 @@ module Detector
146
147
  connection.exec("SELECT current_setting('max_connections')").first['current_setting'].to_i
147
148
  end
148
149
 
150
+ def connection_info
151
+ return nil unless connection
152
+ begin
153
+ global_limit = connection.exec("SELECT current_setting('max_connections')").first['current_setting'].to_i
154
+ global_count = connection.exec("SELECT count(*) FROM pg_stat_activity").first['count'].to_i
155
+
156
+ # For PostgreSQL user connections - depends on per-user limits if set
157
+ user_limit_result = connection.exec("SELECT rolconnlimit FROM pg_roles WHERE rolname = current_user").first
158
+ user_limit = user_limit_result['rolconnlimit'].to_i
159
+ user_limit = global_limit if user_limit <= 0 # If unlimited, use global limit
160
+
161
+ user_count = connection.exec("SELECT count(*) FROM pg_stat_activity WHERE usename = current_user").first['count'].to_i
162
+
163
+ {
164
+ connection_count: { user: user_count, global: global_count },
165
+ connection_limits: { user: user_limit, global: global_limit }
166
+ }
167
+ rescue => e
168
+ nil
169
+ end
170
+ end
171
+
149
172
  def cli_name
150
173
  "psql"
151
174
  end
@@ -13,12 +13,11 @@ module Detector
13
13
  end
14
14
 
15
15
  def connection
16
- return @conn if @conn
17
-
16
+ # Create a new connection each time without caching
18
17
  if uri.scheme == 'rediss'
19
- @conn = ::Redis.new(url: @url, port: uri.port, timeout: 5.0, ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE }) rescue nil
18
+ ::Redis.new(url: @url, port: uri.port, timeout: 5.0, ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE }) rescue nil
20
19
  else
21
- @conn = ::Redis.new(url: @url, timeout: 5.0) rescue nil
20
+ ::Redis.new(url: @url, timeout: 5.0) rescue nil
22
21
  end
23
22
  end
24
23
 
@@ -69,6 +68,22 @@ module Detector
69
68
  info['maxclients'].to_i rescue 0
70
69
  end
71
70
 
71
+ def connection_info
72
+ return nil unless info
73
+ begin
74
+ # Redis doesn't have per-user connection limits, so user = global
75
+ global_count = info['connected_clients'].to_i rescue 0
76
+ global_limit = info['maxclients'].to_i rescue 0
77
+
78
+ {
79
+ connection_count: { user: global_count, global: global_count },
80
+ connection_limits: { user: global_limit, global: global_limit }
81
+ }
82
+ rescue => e
83
+ nil
84
+ end
85
+ end
86
+
72
87
  def cli_name
73
88
  "redis-cli"
74
89
  end
@@ -12,13 +12,12 @@ module Detector
12
12
  end
13
13
 
14
14
  def connection
15
- return @conn if @conn
16
-
15
+ # Create a new connection each time without caching
17
16
  begin
18
- @conn = Net::SMTP.new(host, port)
19
- @conn.open_timeout = 5
20
- @conn.start('detector.local', uri.user, uri.password, :login)
21
- @conn
17
+ conn = Net::SMTP.new(host, port)
18
+ conn.open_timeout = 5
19
+ conn.start('detector.local', uri.user, uri.password, :login)
20
+ conn
22
21
  rescue => e
23
22
  nil
24
23
  end
data/lib/detector/base.rb CHANGED
@@ -123,9 +123,24 @@ module Detector
123
123
  end
124
124
 
125
125
  def connection
126
+ # Default implementation returns nil
127
+ # Each addon should implement its own connection method
128
+ # that creates a new connection for each request
126
129
  nil
127
130
  end
128
131
 
132
+ def with_connection
133
+ conn = connection
134
+ return yield(nil) unless conn
135
+
136
+ begin
137
+ result = yield(conn)
138
+ return result
139
+ ensure
140
+ close
141
+ end
142
+ end
143
+
129
144
  def ping
130
145
  return nil unless valid?
131
146
  transport?
@@ -233,6 +248,15 @@ module Detector
233
248
  (connection_count.to_f / connection_limit.to_f * 100).round(1)
234
249
  end
235
250
 
251
+ def connection_info
252
+ # Default implementation for databases without user-specific limits
253
+ return nil unless connection_count && connection_limit
254
+ {
255
+ connection_count: { user: connection_count, global: connection_count },
256
+ connection_limits: { user: connection_limit, global: connection_limit }
257
+ }
258
+ end
259
+
236
260
  def estimated_row_count(table:, database: nil)
237
261
  nil
238
262
  end
@@ -1,3 +1,3 @@
1
1
  module Detector
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: detector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Siegel