pgdexter 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 16f61626f5003a801ec12cda3f663390a57e69d8
4
- data.tar.gz: 238ee1b24dab3f473accc2ca9a5156fd31e8d19e
3
+ metadata.gz: 78c0747c456e498798accd4e4881a8041d246e07
4
+ data.tar.gz: c4c9cffe3e04d07675c36abf0532db3634e356ea
5
5
  SHA512:
6
- metadata.gz: ccae6266196fc84ea0fc69177b80144f8747996ff0693b6a7492e34d095b2cb400e9ce3299741326c50a5eb267ef48be368384a2ab27553002eb93ac7b6d0922
7
- data.tar.gz: 944bc27bb1ffff546c2f33aa10aa1b8371ba43ae2be889a6b9445c3d3a93ca36fee0cfd57487134a5ea807e37583f74b1e5e9de7714fa30364ab28f64a5679e8
6
+ metadata.gz: df826f95f34809bd94cb7450cc43d4bd6beed81606e6e7079842dd4a05e983d4041bf956645c09a290cf8fa37140917da1a12fe332d6268969da5310f688e148
7
+ data.tar.gz: f7015b408e7864bfe7e4e136cbb60acbe837cbbe640ec4f43dfb2d9631f2d4cb2b4c86826cb58051d68941bdfa6fd6625029babe7c1609e084db1a4f92a23652
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.3.1
2
+
3
+ - Added support for queries with bind variables
4
+ - Fixed error with streaming logs as csv format
5
+ - Handle malformed CSV gracefully
6
+
1
7
  ## 0.3.0
2
8
 
3
9
  - Added support for schemas
data/README.md CHANGED
@@ -130,7 +130,7 @@ Specify the format
130
130
  dexter --input-format csv
131
131
  ```
132
132
 
133
- When steaming logs, specify the time to wait between processing queries
133
+ When streaming logs, specify the time to wait between processing queries
134
134
 
135
135
  ```sh
136
136
  dexter --interval 60 # seconds
@@ -150,6 +150,14 @@ Homebrew on Mac
150
150
  tail -F -n +1 /usr/local/var/postgres/server.log | dexter dbname
151
151
  ```
152
152
 
153
+ ## Analyze
154
+
155
+ For best results, make sure your tables have been recently analyzed so statistics are up-to-date. You can ask Dexter to analyze tables it comes across that haven’t been analyzed in the past hour with:
156
+
157
+ ```sh
158
+ dexter --analyze
159
+ ```
160
+
153
161
  ## Tables
154
162
 
155
163
  You can exclude large or write-heavy tables from indexing with:
@@ -172,14 +180,6 @@ See how Dexter is processing queries with:
172
180
  dexter --log-sql --log-level debug2
173
181
  ```
174
182
 
175
- ## Analyze
176
-
177
- For best results, make sure your tables have been recently analyzed so statistics are up-to-date. You can ask Dexter to analyze tables it comes across that haven’t been analyzed in the past hour with:
178
-
179
- ```sh
180
- dexter --analyze
181
- ```
182
-
183
183
  ## Hosted Postgres
184
184
 
185
185
  Some hosted providers like Amazon RDS and Heroku do not support the HypoPG extension, which Dexter needs to run. See [how to use Dexter](guides/Hosted-Postgres.md) in these cases.
@@ -3,11 +3,15 @@ require "csv"
3
3
  module Dexter
4
4
  class CsvLogParser < LogParser
5
5
  def perform
6
- CSV.foreach(@logfile.file) do |row|
6
+ CSV.new(@logfile).each do |row|
7
7
  if (m = REGEX.match(row[13]))
8
- process_entry(m[3], m[1].to_f)
8
+ active_line = m[3]
9
+ add_parameters(active_line, row[14]) if row[14]
10
+ process_entry(active_line, m[1].to_f)
9
11
  end
10
12
  end
13
+ rescue CSV::MalformedCSVError => e
14
+ abort "ERROR: #{e.message}"
11
15
  end
12
16
  end
13
17
  end
@@ -130,18 +130,22 @@ module Dexter
130
130
 
131
131
  def calculate_plan(queries)
132
132
  queries.each do |query|
133
+ if @log_explain
134
+ puts "Explaining query"
135
+ puts
136
+ end
133
137
  begin
134
138
  query.plans << plan(query.statement)
135
139
  if @log_explain
136
- log "Explaining query"
137
- puts
138
140
  # Pass format to prevent ANALYZE
139
141
  puts execute("EXPLAIN (FORMAT TEXT) #{safe_statement(query.statement)}").map { |r| r["QUERY PLAN"] }.join("\n")
140
- puts
141
142
  end
142
- rescue PG::Error
143
- # do nothing
143
+ rescue PG::Error => e
144
+ if @log_explain
145
+ log e.message
146
+ end
144
147
  end
148
+ puts if @log_explain
145
149
  end
146
150
  end
147
151
 
@@ -1,7 +1,8 @@
1
1
  module Dexter
2
2
  class LogParser
3
- REGEX = /duration: (\d+\.\d+) ms (statement|execute <unnamed>|parse <unnamed>): (.+)/
3
+ REGEX = /duration: (\d+\.\d+) ms (statement|execute <unnamed>): (.+)/
4
4
  LINE_SEPERATOR = ": ".freeze
5
+ DETAIL_LINE = "DETAIL: ".freeze
5
6
 
6
7
  def initialize(logfile, collector)
7
8
  @logfile = logfile
@@ -14,7 +15,9 @@ module Dexter
14
15
 
15
16
  @logfile.each_line do |line|
16
17
  if active_line
17
- if line.include?(LINE_SEPERATOR)
18
+ if line.include?(DETAIL_LINE)
19
+ add_parameters(active_line, line.chomp.split(DETAIL_LINE)[1])
20
+ elsif line.include?(LINE_SEPERATOR)
18
21
  process_entry(active_line, duration)
19
22
  active_line = nil
20
23
  else
@@ -35,5 +38,18 @@ module Dexter
35
38
  def process_entry(query, duration)
36
39
  @collector.add(query, duration)
37
40
  end
41
+
42
+ def add_parameters(active_line, details)
43
+ if details.start_with?("parameters: ")
44
+ params = Hash[details[12..-1].split(", ").map { |s| s.split(" = ", 2) }]
45
+
46
+ # make sure parsing was successful
47
+ unless params.values.include?(nil)
48
+ params.each do |k, v|
49
+ active_line.sub!(k, v)
50
+ end
51
+ end
52
+ end
53
+ end
38
54
  end
39
55
  end
@@ -43,7 +43,7 @@ module Dexter
43
43
  begin
44
44
  @log_parser.perform
45
45
  rescue Errno::ENOENT => e
46
- abort e.message
46
+ abort "ERROR: #{e.message}"
47
47
  end
48
48
 
49
49
  process_queries
@@ -1,3 +1,3 @@
1
1
  module Dexter
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pgdexter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-12-23 00:00:00.000000000 Z
11
+ date: 2017-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: slop