elefant 0.0.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 +7 -0
- data/.gitignore +21 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +65 -0
- data/Rakefile +8 -0
- data/bin/elefant-web +3 -0
- data/config.ru +4 -0
- data/elefant.gemspec +32 -0
- data/lib/elefant.rb +22 -0
- data/lib/elefant/connection_adapter.rb +122 -0
- data/lib/elefant/postgres/size_queries.rb +31 -0
- data/lib/elefant/postgres/stat_queries.rb +91 -0
- data/lib/elefant/stats.rb +56 -0
- data/lib/elefant/version.rb +3 -0
- data/lib/elefant/web.rb +86 -0
- data/test/ar_connection_test.rb +55 -0
- data/test/config.yml.example +4 -0
- data/test/fixtures/teardown.sql +4 -0
- data/test/fixtures/test_models.sql +11 -0
- data/test/pg_connection_test.rb +12 -0
- data/test/stats_test.rb +32 -0
- data/test/test_helper.rb +37 -0
- data/test/webapp_test.rb +46 -0
- data/watchr.rb +34 -0
- data/web/locales/en.yml +33 -0
- data/web/public/css/_fonts.scss +36 -0
- data/web/public/css/_lists.scss +16 -0
- data/web/public/css/_nav.scss +75 -0
- data/web/public/css/_normalize.scss +427 -0
- data/web/public/css/_skeleton.scss +418 -0
- data/web/public/css/_tables.scss +36 -0
- data/web/public/css/_typography.scss +24 -0
- data/web/public/css/_variables.scss +2 -0
- data/web/public/css/elefant.css +13 -0
- data/web/public/css/elefant.css.map +7 -0
- data/web/public/css/elefant.scss +45 -0
- data/web/public/fonts/ClearSans-Bold.eot +0 -0
- data/web/public/fonts/ClearSans-Bold.svg +22646 -0
- data/web/public/fonts/ClearSans-Bold.ttf +0 -0
- data/web/public/fonts/ClearSans-Bold.woff +0 -0
- data/web/public/fonts/ClearSans-Light.eot +0 -0
- data/web/public/fonts/ClearSans-Light.svg +22411 -0
- data/web/public/fonts/ClearSans-Light.ttf +0 -0
- data/web/public/fonts/ClearSans-Light.woff +0 -0
- data/web/public/fonts/LICENSE-2.0.txt +202 -0
- data/web/public/img/postgresql.ico +0 -0
- data/web/public/img/postgresql_logo.svg +22 -0
- data/web/public/img/screenshot.png +0 -0
- data/web/public/js/zepto.min.js +2 -0
- data/web/views/activity.erb +27 -0
- data/web/views/indices.erb +12 -0
- data/web/views/layout.erb +58 -0
- data/web/views/partials/field_table.erb +18 -0
- data/web/views/partials/generic_table.erb +23 -0
- data/web/views/partials/list.erb +6 -0
- data/web/views/size.erb +23 -0
- data/web/views/summary.erb +18 -0
- data/web/views/tables.erb +5 -0
- metadata +255 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 088dc5c6b9b4cbaa02e1497445dc9fb3cb5d1f83
|
|
4
|
+
data.tar.gz: f7cf82d109b27295d28a8ed2c9726fa5c7eb0965
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 7f57ab871b8301a5671b8bbdaa914b5d90502ec160ab48694d6c0e7b904322db390ae9302453284cc02f1315dae0d02e9c893c7d029619084c522f8348e92a36
|
|
7
|
+
data.tar.gz: e84818a8ba32bb9bf34c1fba56d26eb7e16d4b79ae85d1e7d983c8fcc612acd070b2694c063ee7205db5f2baa219fddb222b717a7e380bf99e2063994b5e851f
|
data/.gitignore
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
.bundle
|
|
4
|
+
.config
|
|
5
|
+
.yardoc
|
|
6
|
+
Gemfile.lock
|
|
7
|
+
InstalledFiles
|
|
8
|
+
_yardoc
|
|
9
|
+
coverage
|
|
10
|
+
doc/
|
|
11
|
+
lib/bundler/man
|
|
12
|
+
pkg
|
|
13
|
+
rdoc
|
|
14
|
+
spec/reports
|
|
15
|
+
test/tmp
|
|
16
|
+
test/version_tmp
|
|
17
|
+
tmp
|
|
18
|
+
test/config.yml
|
|
19
|
+
.sass-cache
|
|
20
|
+
**/.DS_Store
|
|
21
|
+
|
data/.ruby-gemset
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
elefant-gem
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.0.0-p645
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2015 Christoph Sassenberg
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Elefant
|
|
2
|
+
|
|
3
|
+
[](https://travis-ci.org/defsprite/elefant)
|
|
4
|
+
|
|
5
|
+
When you are running a small / medium sized project, there is usually not a dedicated DBA and you rarely care about the database analytics that PostgreSQL gives you for free.
|
|
6
|
+
Elefant tries to help a little with that by providing web interface for some basic database analytics as a small mountable rack application.
|
|
7
|
+
|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
Add this line to your application's Gemfile:
|
|
13
|
+
|
|
14
|
+
gem 'elefant'
|
|
15
|
+
|
|
16
|
+
And then execute:
|
|
17
|
+
|
|
18
|
+
$ bundle
|
|
19
|
+
|
|
20
|
+
Or install it yourself as:
|
|
21
|
+
|
|
22
|
+
$ gem install elefant
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
### Standalone
|
|
27
|
+
|
|
28
|
+
Run the web interface as a standalone rack application:
|
|
29
|
+
|
|
30
|
+
$ DATABASE_URL=postgres:///some_db_connection_string elefant-web
|
|
31
|
+
|
|
32
|
+
or if you want to use a different database specifically for elefant:
|
|
33
|
+
|
|
34
|
+
$ ELEFANT_DATABASE_URL=postgres:///some_db_connection_string elefant-web
|
|
35
|
+
|
|
36
|
+
### Rails
|
|
37
|
+
|
|
38
|
+
You can mount the web interface in a rails application by adding this to `config/routes.rb`:
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
require 'elefant/web'
|
|
42
|
+
mount Elefant::Web => '/elefant'
|
|
43
|
+
```
|
|
44
|
+
It will pick up a connection from the `ActiveRecord` connection pool.
|
|
45
|
+
|
|
46
|
+
:warning: There is no authentication built in! Mounting it as described above is probably a bad idea! :warning:
|
|
47
|
+
|
|
48
|
+
In case you are using [Devise](https://github.com/plataformatec/devise), here is an example of mounting only for
|
|
49
|
+
authenticated users of the `:admin` scope:
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
authenticate(:admin) do
|
|
53
|
+
require 'elefant/web'
|
|
54
|
+
mount Elefant::Web => '/elefant'
|
|
55
|
+
end
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
## Contributing
|
|
60
|
+
|
|
61
|
+
1. Fork it
|
|
62
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
63
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
64
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
65
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/elefant-web
ADDED
data/config.ru
ADDED
data/elefant.gemspec
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'elefant/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |gem|
|
|
7
|
+
gem.name = "elefant"
|
|
8
|
+
gem.version = Elefant::VERSION
|
|
9
|
+
gem.authors = ["Christoph Sassenberg"]
|
|
10
|
+
gem.email = ["christoph.sassenberg@googlemail.com"]
|
|
11
|
+
gem.description = %q{The elefant gem gives you a few insights analytics about your PostgreSQL database}
|
|
12
|
+
gem.summary = %q{Know your PostgreSQL database}
|
|
13
|
+
gem.homepage = "http://github.com/defsprite/elefant"
|
|
14
|
+
gem.licenses = ["MIT"]
|
|
15
|
+
|
|
16
|
+
gem.files = `git ls-files`.split($/)
|
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
gem.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
gem.add_dependency 'pg', '~> 0.15'
|
|
22
|
+
gem.add_dependency 'sinatra', '~> 1.4'
|
|
23
|
+
gem.add_dependency 'sinatra-partial', '~> 0.4'
|
|
24
|
+
gem.add_dependency 'i18n', '~> 0.7'
|
|
25
|
+
|
|
26
|
+
gem.add_development_dependency 'rake', '~> 10.4'
|
|
27
|
+
gem.add_development_dependency 'minitest', '~> 5.5'
|
|
28
|
+
gem.add_development_dependency 'rack-test', '~> 0.6'
|
|
29
|
+
gem.add_development_dependency 'watchr', '~> 0.7'
|
|
30
|
+
gem.add_development_dependency 'activerecord', '~> 4.2'
|
|
31
|
+
gem.add_development_dependency 'sass', '~> 3.4'
|
|
32
|
+
end
|
data/lib/elefant.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "elefant/version"
|
|
2
|
+
require "elefant/stats"
|
|
3
|
+
|
|
4
|
+
module Elefant
|
|
5
|
+
|
|
6
|
+
def self.configuration
|
|
7
|
+
@configuration ||= Configuration.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.configure
|
|
11
|
+
configuration = self.configuration
|
|
12
|
+
yield(configuration)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class Configuration
|
|
16
|
+
attr_accessor :disable_ar
|
|
17
|
+
|
|
18
|
+
def initialize
|
|
19
|
+
@disable_ar = false
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
require "uri"
|
|
2
|
+
require "pg"
|
|
3
|
+
|
|
4
|
+
module Elefant
|
|
5
|
+
class ConnectionAdapter
|
|
6
|
+
|
|
7
|
+
attr_accessor :connection
|
|
8
|
+
|
|
9
|
+
def initialize(connection=nil)
|
|
10
|
+
@connection = connection.nil? ? establish_new : validate!(connection)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def execute(stmt, params = [])
|
|
14
|
+
begin
|
|
15
|
+
params = nil if params.empty?
|
|
16
|
+
r = @connection.exec(stmt, params)
|
|
17
|
+
result = []
|
|
18
|
+
r.each do |t|
|
|
19
|
+
result << t
|
|
20
|
+
end
|
|
21
|
+
result
|
|
22
|
+
rescue PGError => e
|
|
23
|
+
@connection.reset
|
|
24
|
+
raise e
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def disconnect
|
|
29
|
+
begin
|
|
30
|
+
if active_record?
|
|
31
|
+
@connection = nil
|
|
32
|
+
ActiveRecord::Base.clear_active_connections!
|
|
33
|
+
else
|
|
34
|
+
@connection.close
|
|
35
|
+
end
|
|
36
|
+
rescue => e
|
|
37
|
+
# TODO: log something and do sensible stuff
|
|
38
|
+
raise e
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def alive?
|
|
43
|
+
@connection.query "SELECT 1"
|
|
44
|
+
true
|
|
45
|
+
rescue PGError
|
|
46
|
+
false
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def info
|
|
50
|
+
@info ||= {
|
|
51
|
+
db_name: @connection.db,
|
|
52
|
+
server_version: version_str(connection.server_version),
|
|
53
|
+
client_version: (PG.respond_to?( :library_version ) ? version_str(PG.library_version) : 'unknown')
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def db_name
|
|
58
|
+
@connection.db
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def active_record?
|
|
62
|
+
defined?(ActiveRecord::Base) == "constant" && ActiveRecord::Base.class == Class && !Elefant.configuration.disable_ar
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def version_str(number)
|
|
68
|
+
number.to_s.tr('0','.').gsub(/(\.)+\z/, '')
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def validate!(c)
|
|
72
|
+
return c if c.is_a?(PG::Connection)
|
|
73
|
+
err = "connection must be an instance of PG::Connection, but was #{c.class}"
|
|
74
|
+
raise(ArgumentError, err)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def establish_new
|
|
78
|
+
#QC.log(:at => "establish_conn")
|
|
79
|
+
connection = if active_record?
|
|
80
|
+
establish_ar
|
|
81
|
+
else
|
|
82
|
+
establish_pg
|
|
83
|
+
end
|
|
84
|
+
connection.exec("SET application_name = 'Elefant Stats #{Elefant::VERSION}'")
|
|
85
|
+
connection
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def establish_pg
|
|
89
|
+
PGconn.connect(*normalize_db_url(db_url))
|
|
90
|
+
# if conn.status != PGconn::CONNECTION_OK
|
|
91
|
+
# log(:error => conn.error)
|
|
92
|
+
# end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def establish_ar
|
|
96
|
+
ActiveRecord::Base.connection.raw_connection
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def normalize_db_url(url)
|
|
100
|
+
host = url.host
|
|
101
|
+
host = host.gsub(/%2F/i, '/') if host
|
|
102
|
+
|
|
103
|
+
[
|
|
104
|
+
host, # host or percent-encoded socket path
|
|
105
|
+
url.port || 5432,
|
|
106
|
+
nil, "", #opts, tty
|
|
107
|
+
url.path.gsub('/', ''), # database name
|
|
108
|
+
url.user,
|
|
109
|
+
url.password
|
|
110
|
+
]
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def db_url
|
|
114
|
+
return @db_url if defined?(@db_url) && @db_url
|
|
115
|
+
|
|
116
|
+
url = ENV["ELEFANT_DATABASE_URL"] ||
|
|
117
|
+
ENV["DATABASE_URL"] ||
|
|
118
|
+
raise(ArgumentError, "missing ELEFANT_DATABASE_URL or DATABASE_URL")
|
|
119
|
+
@db_url = URI.parse(url)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Elefant
|
|
2
|
+
module Postgres
|
|
3
|
+
module SizeQueries
|
|
4
|
+
|
|
5
|
+
def top_sizes(limit = 20)
|
|
6
|
+
exec %Q{
|
|
7
|
+
SELECT
|
|
8
|
+
relname AS name,
|
|
9
|
+
relkind AS kind,
|
|
10
|
+
pg_size_pretty(pg_relation_size(pg_class.oid)) AS size
|
|
11
|
+
FROM
|
|
12
|
+
pg_class
|
|
13
|
+
ORDER BY
|
|
14
|
+
pg_relation_size(pg_class.oid) DESC
|
|
15
|
+
LIMIT #{limit}
|
|
16
|
+
}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def size
|
|
20
|
+
exec %Q{
|
|
21
|
+
SELECT
|
|
22
|
+
'#{@connection.db_name}' AS db_name,
|
|
23
|
+
count(oid) AS num_rels,
|
|
24
|
+
pg_size_pretty(pg_database_size('#{@connection.db_name}')) AS dbsize
|
|
25
|
+
FROM
|
|
26
|
+
pg_class
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module Elefant::Postgres
|
|
2
|
+
module StatQueries
|
|
3
|
+
|
|
4
|
+
def initialize(connection)
|
|
5
|
+
@connection = connection
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def activity
|
|
9
|
+
exec %Q{
|
|
10
|
+
SELECT
|
|
11
|
+
-- datid
|
|
12
|
+
-- datname
|
|
13
|
+
-- pid
|
|
14
|
+
-- usesysid
|
|
15
|
+
usename AS act_user,
|
|
16
|
+
application_name AS act_app,
|
|
17
|
+
client_addr AS act_c_addr,
|
|
18
|
+
client_hostname AS act_c_host,
|
|
19
|
+
client_port AS act_c_port,
|
|
20
|
+
backend_start AS act_bknd_start,
|
|
21
|
+
xact_start AS act_tx_start,
|
|
22
|
+
query_start AS act_q_start,
|
|
23
|
+
state_change AS act_st_chng,
|
|
24
|
+
waiting AS act_wtng,
|
|
25
|
+
state AS act_state,
|
|
26
|
+
query AS act_qry
|
|
27
|
+
FROM
|
|
28
|
+
pg_stat_activity
|
|
29
|
+
WHERE
|
|
30
|
+
datname = '%s';
|
|
31
|
+
} % [@connection.db_name]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def user_tables
|
|
35
|
+
exec %Q{
|
|
36
|
+
SELECT
|
|
37
|
+
relname AS rel_name,
|
|
38
|
+
heap_blks_read AS heap_blks_rd,
|
|
39
|
+
heap_blks_hit AS heap_blks_ht,
|
|
40
|
+
idx_blks_read AS idx_blks_rd,
|
|
41
|
+
idx_blks_hit AS idx_blks_ht
|
|
42
|
+
FROM
|
|
43
|
+
pg_statio_user_tables;
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def user_indexes
|
|
48
|
+
exec %Q{
|
|
49
|
+
SELECT
|
|
50
|
+
-- relid
|
|
51
|
+
-- indexrelid
|
|
52
|
+
-- schemaname
|
|
53
|
+
relname AS rel_name,
|
|
54
|
+
indexrelname AS idx_name,
|
|
55
|
+
idx_scan AS idx_scn,
|
|
56
|
+
idx_tup_read AS idx_tup_rd,
|
|
57
|
+
idx_tup_fetch AS idx_tup_ftch
|
|
58
|
+
FROM
|
|
59
|
+
pg_stat_user_indexes;
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def summary
|
|
64
|
+
exec %Q{
|
|
65
|
+
SELECT
|
|
66
|
+
now() AS db_time,
|
|
67
|
+
MAX(stat_db.xact_commit) AS commits,
|
|
68
|
+
MAX(stat_db.xact_rollback) AS rollbks,
|
|
69
|
+
MAX(stat_db.blks_read) AS blksrd,
|
|
70
|
+
MAX(stat_db.blks_hit) AS blkshit,
|
|
71
|
+
MAX(stat_db.numbackends) AS bkends,
|
|
72
|
+
SUM(stat_tables.seq_scan) AS seqscan,
|
|
73
|
+
SUM(stat_tables.seq_tup_read) AS seqtprd,
|
|
74
|
+
SUM(stat_tables.idx_scan) AS idxscn,
|
|
75
|
+
SUM(stat_tables.idx_tup_fetch) AS idxtrd,
|
|
76
|
+
SUM(stat_tables.n_tup_ins) AS ins,
|
|
77
|
+
SUM(stat_tables.n_tup_upd) AS upd,
|
|
78
|
+
SUM(stat_tables.n_tup_del) AS del,
|
|
79
|
+
MAX(stat_locks.locks) AS locks,
|
|
80
|
+
MAX(activity.sess) AS activeq
|
|
81
|
+
FROM
|
|
82
|
+
pg_stat_database AS stat_db,
|
|
83
|
+
pg_stat_user_tables AS stat_tables,
|
|
84
|
+
(SELECT COUNT(*) AS locks FROM pg_locks ) AS stat_locks,
|
|
85
|
+
(SELECT COUNT(*) AS sess FROM pg_stat_activity WHERE query <> '<IDLE>') AS activity
|
|
86
|
+
WHERE
|
|
87
|
+
stat_db.datname = '%s';
|
|
88
|
+
} % [@connection.db_name]
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|