metric_system 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/metric_system.rb +1 -1
- data/lib/metric_system/database.rb +9 -6
- data/lib/metric_system/version.rb +1 -1
- data/lib/metric_system/web.rb +28 -12
- data/lib/metric_system/web/dashboard.erb +3 -7
- data/lib/sqlite3/database_extension.rb +16 -17
- data/lib/sqlite3/query.rb +34 -1
- data/test/benchmark.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c313b1e1c7d585f73c1210c3fb3bc610268d804
|
4
|
+
data.tar.gz: 26cf80941ed294412d5afb60e79b883ae13e2fa8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c2b87a70402f5f6090c33f39228c0762777abedbd9f0d27caee1092442a6943a782576a45a48e84b6aec0ce54b4db7080abb9dbbf1a0759575274f0262f847c
|
7
|
+
data.tar.gz: a8e41c77e9810bed3d53e7bbd6c3e30c167d1ffac75c09d41d7955e6b737534cf2f1d0e618d667e5fd979d0398002caf80fc9730c3a94fa6249cb504aa3ec317
|
data/lib/metric_system.rb
CHANGED
@@ -23,7 +23,7 @@ module MetricSystem
|
|
23
23
|
end
|
24
24
|
|
25
25
|
extend Forwardable
|
26
|
-
delegate [:aggregate, :select, :print, :run, :ask
|
26
|
+
delegate [:aggregate, :select, :print, :run, :ask] => :"@target"
|
27
27
|
delegate [:transaction] => :"@target"
|
28
28
|
delegate [:add_event] => :"@target"
|
29
29
|
delegate [:quit_server!] => :"@target"
|
@@ -1,12 +1,15 @@
|
|
1
1
|
class MetricSystem::Database
|
2
|
-
def initialize(path)
|
2
|
+
def initialize(path, readonly = false)
|
3
3
|
require_relative "./sqlite3_extensions"
|
4
4
|
open path
|
5
|
+
|
6
|
+
exec "PRAGMA query_only = 1" if readonly # This might or might not work.
|
7
|
+
@db.readonly = !!readonly
|
5
8
|
end
|
6
9
|
|
7
10
|
extend Forwardable
|
8
11
|
|
9
|
-
delegate [:exec, :select, :transaction, :rollback, :print, :run, :ask, :register] => :"@db"
|
12
|
+
delegate [:exec, :select, :transaction, :rollback, :print, :run, :ask, :register, :readonly?] => :"@db"
|
10
13
|
|
11
14
|
PERIODS = [
|
12
15
|
[ :year, 31536000, "strftime('%Y-01-01', starts_at, 'unixepoch')" ],
|
@@ -103,7 +106,7 @@ class MetricSystem::Database
|
|
103
106
|
aggregate_for_period :period => period, :source => :counters, :dest => :aggregated_counters, :aggregate => "sum"
|
104
107
|
end
|
105
108
|
|
106
|
-
|
109
|
+
exec "DELETE FROM counters"
|
107
110
|
end
|
108
111
|
|
109
112
|
transaction do
|
@@ -111,7 +114,7 @@ class MetricSystem::Database
|
|
111
114
|
aggregate_for_period :period => period, :source => :gauges, :dest => :aggregated_gauges, :aggregate => "CAST(sum AS FLOAT) / count"
|
112
115
|
end
|
113
116
|
|
114
|
-
|
117
|
+
exec "DELETE FROM gauges"
|
115
118
|
end
|
116
119
|
end
|
117
120
|
|
@@ -128,7 +131,7 @@ class MetricSystem::Database
|
|
128
131
|
# sql expression to calculate value from sum and count of event values
|
129
132
|
aggregate = source == :gauges ? "CAST(sum AS FLOAT) / count" : "sum"
|
130
133
|
|
131
|
-
|
134
|
+
exec <<-SQL
|
132
135
|
CREATE TEMPORARY TABLE batch AS
|
133
136
|
SELECT name, starts_at, SUM(sum) AS sum, SUM(count) AS count FROM
|
134
137
|
(
|
@@ -157,7 +160,7 @@ class MetricSystem::Database
|
|
157
160
|
FROM batch;
|
158
161
|
SQL
|
159
162
|
|
160
|
-
|
163
|
+
exec <<-SQL
|
161
164
|
DROP TABLE batch;
|
162
165
|
SQL
|
163
166
|
end
|
data/lib/metric_system/web.rb
CHANGED
@@ -1,27 +1,43 @@
|
|
1
1
|
require 'sinatra/base'
|
2
2
|
require 'to_js'
|
3
|
-
|
4
|
-
module GoogleCharts
|
5
|
-
extend self
|
6
|
-
|
7
|
-
def convert(results)
|
8
|
-
results.description.to_js
|
9
|
-
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
end
|
3
|
+
require 'metric_system/database'
|
14
4
|
|
15
5
|
class MetricSystem::Web < Sinatra::Base
|
16
6
|
set :environment, :development
|
17
7
|
set :raise_errors, true
|
18
8
|
set :views, "#{File.dirname(__FILE__)}/web"
|
19
9
|
set :dump_errors, true
|
10
|
+
set :database, nil
|
11
|
+
|
12
|
+
def self.register_query(name, query)
|
13
|
+
registry[name] = query
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.registry
|
17
|
+
@registry ||= {}
|
18
|
+
end
|
19
|
+
|
20
|
+
# return a database for the current thread
|
21
|
+
def self.connection
|
22
|
+
Thread.current[:"MetricSystem::Web.database"] ||= MetricSystem::Database.new(self.database, :readonly)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.select(query, *args)
|
26
|
+
expect! query => [ String, Symbol ]
|
27
|
+
|
28
|
+
if query.is_a?(Symbol)
|
29
|
+
expect! query => registry.keys
|
30
|
+
query = registry.fetch(query)
|
31
|
+
end
|
32
|
+
|
33
|
+
result = connection.select query, *args #period: "month"
|
34
|
+
result.data_table.to_js
|
35
|
+
end
|
20
36
|
|
21
37
|
helpers do
|
22
38
|
def select(query, *args)
|
23
39
|
@result_cache ||= {}
|
24
|
-
@result_cache[query] ||=
|
40
|
+
@result_cache[[query, args]] ||= self.class.select(query, *args, params)
|
25
41
|
end
|
26
42
|
end
|
27
43
|
|
@@ -116,22 +116,18 @@
|
|
116
116
|
<div>
|
117
117
|
<h3>Table</h3>
|
118
118
|
<div class="google-visualization">
|
119
|
-
<%=
|
120
|
-
select "SELECT date(starts_at), value FROM aggregates WHERE period='day'"
|
121
|
-
%>
|
119
|
+
<%= select "SELECT date(starts_at), value FROM aggregates WHERE period=:period" %>
|
122
120
|
</div>
|
123
121
|
</div>
|
124
122
|
<div>
|
125
123
|
<h3>Pie Chart</h3>
|
126
|
-
<div class="google-visualization" data-src="/value_by_day_name.js" data-chart="pie">
|
124
|
+
<div class="google-visualization" data-src="/value_by_day_name.js?period=month" data-chart="pie">
|
127
125
|
</div>
|
128
126
|
</div>
|
129
127
|
<div>
|
130
128
|
<h3>Area Chart</h3>
|
131
129
|
<div class="google-visualization" data-chart="area">
|
132
|
-
<%=
|
133
|
-
select "SELECT date(starts_at), value FROM aggregates WHERE period='day'"
|
134
|
-
%>
|
130
|
+
<%= select "SELECT date(starts_at), value FROM aggregates WHERE period=:period" %>
|
135
131
|
</div>
|
136
132
|
</div>
|
137
133
|
<div>
|
@@ -1,6 +1,16 @@
|
|
1
1
|
class SQLite3::Database
|
2
|
+
def readonly?
|
3
|
+
@readonly
|
4
|
+
end
|
5
|
+
|
6
|
+
def readonly=(readonly)
|
7
|
+
@readonly = readonly
|
8
|
+
end
|
9
|
+
|
2
10
|
# execute multiple SQL statements at once.
|
3
11
|
def exec(sql, *args)
|
12
|
+
raise "Cannot run nondestructive query: #{sql}" if readonly?
|
13
|
+
|
4
14
|
args = prepare_arguments(args)
|
5
15
|
|
6
16
|
while sql =~ /\S/ do
|
@@ -22,15 +32,14 @@ class SQLite3::Database
|
|
22
32
|
private
|
23
33
|
|
24
34
|
def query(sql)
|
25
|
-
expect! sql =>
|
26
|
-
|
27
|
-
if sql.is_a?(Symbol)
|
28
|
-
expect! sql => registry.keys
|
29
|
-
sql = registry.fetch(sql)
|
30
|
-
end
|
35
|
+
expect! sql => String
|
31
36
|
|
32
37
|
@queries ||= {}
|
33
|
-
@queries[sql] ||=
|
38
|
+
query = @queries[sql] ||= begin
|
39
|
+
query = SQLite3::Query.new sql, prepare(sql)
|
40
|
+
raise "Cannot run nondestructive query: #{sql}" if readonly? && query.destructive?
|
41
|
+
query
|
42
|
+
end
|
34
43
|
end
|
35
44
|
|
36
45
|
def prepare_arguments(args)
|
@@ -72,14 +81,4 @@ class SQLite3::Database
|
|
72
81
|
end
|
73
82
|
puts "=" * log_sql.length
|
74
83
|
end
|
75
|
-
|
76
|
-
# -- query registry
|
77
|
-
|
78
|
-
def registry
|
79
|
-
@registry ||= {}
|
80
|
-
end
|
81
|
-
|
82
|
-
def register(name, query)
|
83
|
-
registry[name] = query
|
84
|
-
end
|
85
84
|
end
|
data/lib/sqlite3/query.rb
CHANGED
@@ -1,12 +1,43 @@
|
|
1
|
+
class SQLite3::MissingParameters < RuntimeError
|
2
|
+
end
|
3
|
+
|
1
4
|
class SQLite3::Query
|
5
|
+
|
6
|
+
# all parameters in the query, as Symbols.
|
7
|
+
attr :parameters
|
8
|
+
|
2
9
|
def initialize(sql, statement)
|
3
10
|
expect! statement => SQLite3::Statement
|
4
11
|
|
5
12
|
@sql, @statement = sql, statement
|
13
|
+
@parameters = @sql.scan(/:([a-z]+)/).map(&:first).map(&:to_sym)
|
14
|
+
end
|
15
|
+
|
16
|
+
def destructive?
|
17
|
+
@sql !~ /\A\S*SELECT/i
|
6
18
|
end
|
7
19
|
|
8
20
|
def run(*args)
|
9
|
-
|
21
|
+
if parameters.length > 0
|
22
|
+
named_args = {}
|
23
|
+
|
24
|
+
if args.last.is_a?(Hash)
|
25
|
+
args.pop.each do |name, value|
|
26
|
+
named_args[name.to_sym] = value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
missing = parameters - named_args.keys
|
31
|
+
unless missing.empty?
|
32
|
+
raise SQLite3::MissingParameters, "Missing parameter(s): #{missing.inspect}"
|
33
|
+
end
|
34
|
+
|
35
|
+
named_args = named_args.select do |name, value|
|
36
|
+
parameters.include?(name)
|
37
|
+
end
|
38
|
+
args << named_args
|
39
|
+
end
|
40
|
+
|
10
41
|
@statement.execute *args
|
11
42
|
end
|
12
43
|
|
@@ -44,6 +75,8 @@ class SQLite3::Query
|
|
44
75
|
{ cols: cols, rows: rows }
|
45
76
|
end
|
46
77
|
|
78
|
+
private
|
79
|
+
|
47
80
|
def convert_record(record, cols)
|
48
81
|
values = cols.map do |col|
|
49
82
|
id, type = col.values_at(:id, :type)
|
data/test/benchmark.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metric_system
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- radiospiel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-04-
|
11
|
+
date: 2014-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: expectation
|