logeater 0.5.0.pre → 0.5.4.pre

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
- SHA1:
3
- metadata.gz: 4ccc1408222d5eb6f6af30a91d8cb63c51457c6a
4
- data.tar.gz: 83254c545dba4b4217510653a6e1f54c95ebf8bf
2
+ SHA256:
3
+ metadata.gz: cce28ddbf1036163a0b743d2bbc4ba5e93ce484015149e746a7542ab2ff61e94
4
+ data.tar.gz: 3260cbd40856778f7f28ca9ea0708b87bb35e74f4de8598cd173acc7fef5a2c5
5
5
  SHA512:
6
- metadata.gz: adc84e2364b1cb49120f206e21e007c6e0595567372c69cae4448a7bcaf360f17f23f0482de706f5f82b42db8d9870188c94a5b94a947ef460cb678342c6a748
7
- data.tar.gz: 06481c37537675e13b0f17cfd78b0004459a560994f6aed86ef62c0cff592ae7cf94e77de93a521bba6ee02a076bfb1f882ba474d02372ef42c900f897ec8183
6
+ metadata.gz: d960f461dcb370a50ab96083e2fae80eae3e24ee39870dbf5d82aed2a78197e87b59d21d307b1830cde3145a6d1c9916cdb747676f711df4aa20cd917b96415c
7
+ data.tar.gz: 751dc4a8370d1e441aece26e50ed1da36760bdc9501e83729dcd474e0af1be23b5181f260a68ff6b2ca889d8f238ab31e2276806b52b708a977c73c8fe378221
data/lib/logeater/cli.rb CHANGED
@@ -78,7 +78,23 @@ module Logeater
78
78
  started_all = Time.now
79
79
  $stderr.puts " > \e[34mImporting events since \e[1m#{timestamp}\e[0m\n"
80
80
 
81
- events = Logeater::Event.where(app: app).since(timestamp)
81
+ events = Logeater::Event.where(ep_app: app).since(timestamp)
82
+ import_file Logeater::Eventfile.new(events), app
83
+
84
+ finished_all = Time.now
85
+ seconds = finished_all - started_all
86
+ minutes = (seconds / 60).to_i
87
+ seconds -= (minutes * 60)
88
+ $stderr.puts "Total time %d minutes, %.2f seconds" % [minutes, seconds]
89
+ end
90
+
91
+
92
+ desc "import_new APP", "imports unimported log events"
93
+ def import_new(app)
94
+ started_all = Time.now
95
+ $stderr.puts " > \e[34mImporting unprocessed events for \e[1m#{app}\e[0m\n"
96
+
97
+ events = Logeater::Event.where(ep_app: app).unprocessed
82
98
  import_file Logeater::Eventfile.new(events), app
83
99
 
84
100
  finished_all = Time.now
@@ -7,5 +7,55 @@ module Logeater
7
7
  def self.since(timestamp)
8
8
  where(arel_table[:received_at].gteq(timestamp))
9
9
  end
10
+
11
+ def self.processed
12
+ where.not(processed_at: nil)
13
+ end
14
+
15
+ def self.unprocessed
16
+ where(processed_at: nil)
17
+ end
18
+
19
+ def logger_line
20
+ "#{severity_id}, [#{timestamp}] #{severity_label} -- : #{message}"
21
+ end
22
+
23
+ def severity_id
24
+ SEVERITY[log_level][:id]
25
+ end
26
+
27
+ def severity_label
28
+ SEVERITY[log_level][:label]
29
+ end
30
+
31
+ def timestamp
32
+ emitted_at.strftime("%FT%T.%6N")
33
+ end
34
+
35
+ private
36
+
37
+ def log_level
38
+ LOG_LEVELS.fetch(priority % 8)
39
+ end
40
+
41
+ LOG_LEVELS = {
42
+ 0 => Logger::FATAL, # Emergency: system is unusable
43
+ 1 => Logger::FATAL, # Alert: action must be taken immediately
44
+ 2 => Logger::FATAL, # Critical: critical conditions
45
+ 3 => Logger::ERROR, # Error: error conditions
46
+ 4 => Logger::WARN, # Warning: warning conditions
47
+ 5 => Logger::INFO, # Notice: normal but significant condition
48
+ 6 => Logger::INFO, # Informational: informational messages
49
+ 7 => Logger::DEBUG # Debug: debug-level messages
50
+ }.freeze
51
+
52
+ SEVERITY = {
53
+ Logger::FATAL => { id: "F", label: "FATAL" },
54
+ Logger::ERROR => { id: "E", label: "ERROR" },
55
+ Logger::WARN => { id: "W", label: "WARN" },
56
+ Logger::INFO => { id: "I", label: "INFO" },
57
+ Logger::DEBUG => { id: "D", label: "DEBUG" }
58
+ }.freeze
59
+
10
60
  end
11
61
  end
@@ -6,14 +6,21 @@ module Logeater
6
6
 
7
7
  def initialize(events)
8
8
  @events = events
9
- @filename = "events_#{events.count}"
9
+ @filename = "events_#{timestamp}"
10
10
  end
11
11
 
12
12
  def each_line
13
- events.pluck(:original).each do |event|
14
- yield event
13
+ events.find_each do |event|
14
+ yield event.logger_line
15
+ event.touch :processed_at
15
16
  end
16
17
  end
17
18
 
19
+ private
20
+
21
+ def timestamp
22
+ @timestamp ||= Time.now.strftime "%Y%m%d%H%M%S.%L"
23
+ end
24
+
18
25
  end
19
26
  end
@@ -71,6 +71,10 @@ module Logeater
71
71
  count
72
72
  end
73
73
 
74
+ def filename
75
+ file.filename
76
+ end
77
+
74
78
 
75
79
 
76
80
  private
@@ -1,3 +1,3 @@
1
1
  module Logeater
2
- VERSION = "0.5.0.pre"
2
+ VERSION = "0.5.4.pre"
3
3
  end
data/logeater.gemspec CHANGED
@@ -35,5 +35,6 @@ Gem::Specification.new do |spec|
35
35
  spec.add_development_dependency "minitest-reporters"
36
36
  spec.add_development_dependency "minitest-reporters-turn_reporter"
37
37
  spec.add_development_dependency "database_cleaner"
38
+ spec.add_development_dependency "heroku-log-parser"
38
39
 
39
40
  end
@@ -0,0 +1,15 @@
1
+ 243 <190>1 2018-04-06T19:14:09.352835+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] Started GET "/api/v1/holidays/2018-05-01-6189112395f7444881844271027c8c78" for 207.141.132.3 at 2018-04-06 19:14:09 +0000
2
+ 179 <190>1 2018-04-06T19:14:09.354663+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] Processing by BuilderApi::HolidaysController#show as JSON
3
+ 222 <190>1 2018-04-06T19:14:09.354762+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] Parameters: {"year"=>"2018", "month"=>"05", "day"=>"01", "id"=>"6189112395f7444881844271027c8c78"}
4
+ 300 <190>1 2018-04-06T19:14:09.358456+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] \x1B[1m\x1B[36mUser Load (1.5ms)\x1B[0m \x1B[1m\x1B[34mSELECT "users".* FROM "users" WHERE "users"."email" = $1 LIMIT $2\x1B[0m [["email", "user@example.com"], ["LIMIT", 1]]
5
+ 424 <190>1 2018-04-06T19:14:09.360877+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] \x1B[1m\x1B[36mUserRole Load (1.4ms)\x1B[0m \x1B[1m\x1B[34mSELECT "user_roles".* FROM "user_roles" WHERE "user_roles"."user_id" = $1 AND "user_roles"."tenant_id" = $2 LIMIT $3\x1B[0m [["user_id", "ed80a088ddc04be891131be2394f56f5"], ["tenant_id", "9324b816dbc24bcebc087feef8c0b21e"], ["LIMIT", 1]]
6
+ 288 <190>1 2018-04-06T19:14:09.363353+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] \x1B[1m\x1B[36mPublisher Load (1.2ms)\x1B[0m \x1B[1m\x1B[34mSELECT "publishers".* FROM "publishers" ORDER BY "publishers"."id" ASC LIMIT $1\x1B[0m [["LIMIT", 1]]
7
+ 657 <190>1 2018-04-06T19:14:09.369707+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] \x1B[1m\x1B[36mHoliday Load (1.7ms)\x1B[0m \x1B[1m\x1B[34mSELECT "holidays".* FROM "holidays" INNER JOIN "lectionaries" ON "holidays"."lectionary_id" = "lectionaries"."id" LEFT OUTER JOIN "categories" ON "categories"."id" = "holidays"."category_id" WHERE "lectionaries"."publisher_id" = $1 AND "holidays"."id" = $2 ORDER BY "lectionaries"."name" ASC, "categories"."position", "holidays"."position" ASC LIMIT $3\x1B[0m [["publisher_id", "1211d48bb65e420f84a4174918638072"], ["id", "6189112395f7444881844271027c8c78"], ["LIMIT", 1]]
8
+ 318 <190>1 2018-04-06T19:14:09.373153+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] \x1B[1m\x1B[36mTenant Load (1.2ms)\x1B[0m \x1B[1m\x1B[34mSELECT "tenants".* FROM "tenants" WHERE "tenants"."id" = $1 LIMIT $2\x1B[0m [["id", "9324b816dbc24bcebc087feef8c0b21e"], ["LIMIT", 1]]
9
+ 330 <190>1 2018-04-06T19:14:09.375802+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] \x1B[1m\x1B[36mPublisher Load (1.2ms)\x1B[0m \x1B[1m\x1B[34mSELECT "publishers".* FROM "publishers" WHERE "publishers"."id" = $1 LIMIT $2\x1B[0m [["id", "1211d48bb65e420f84a4174918638072"], ["LIMIT", 1]]
10
+ 363 <190>1 2018-04-06T19:14:09.379364+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] \x1B[1m\x1B[36mBible Load (1.3ms)\x1B[0m \x1B[1m\x1B[34mSELECT "bibles".* FROM "bibles" WHERE "bibles"."publisher_id" = $1 ORDER BY "bibles"."name" ASC LIMIT $2\x1B[0m [["publisher_id", "1211d48bb65e420f84a4174918638072"], ["LIMIT", 1]]
11
+ 491 <190>1 2018-04-06T19:14:09.383904+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] \x1B[1m\x1B[35m (1.5ms)\x1B[0m \x1B[1m\x1B[34mSELECT COUNT(*) AS "size", MAX("propers"."updated_at") AS timestamp FROM "propers" WHERE "propers"."holiday_id" = $1 AND "propers"."year" = $2 AND ("propers"."name" NOT IN ('Prayer of Thanksgiving', 'Proper Preface', 'Proper Preface (Jacobean)'))\x1B[0m [["holiday_id", "6189112395f7444881844271027c8c78"], ["year", 1]]
12
+ 207 <190>1 2018-04-06T19:14:09.384229+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] Cache read: proper/base/query-e05e570da916b2c6b24a534e61906087-8-20171010021720928483
13
+ 212 <190>1 2018-04-06T19:14:09.385266+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] Cache fetch_hit: proper/base/query-e05e570da916b2c6b24a534e61906087-8-20171010021720928483
14
+ 157 <190>1 2018-04-06T19:14:09.387137+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] \x1B[33msize: \x1B[1m6.89 KB\x1B[0m
15
+ 184 <190>1 2018-04-06T19:14:09.387366+00:00 host app web.2 - [www] [a0fe6527-2573-4c84-b3b7-6390939bc14e] [user@example.com] Completed 200 OK in 32ms (Views: 0.4ms | ActiveRecord: 10.9ms)
@@ -1,4 +1,5 @@
1
1
  require "test_helper"
2
+ require "heroku-log-parser"
2
3
 
3
4
  class LogeaterTest < ActiveSupport::TestCase
4
5
  attr_reader :logfile, :events
@@ -68,9 +69,9 @@ class LogeaterTest < ActiveSupport::TestCase
68
69
 
69
70
  context "Given an app and a timestamp, import_since" do
70
71
  setup do
71
- log_sample = File.open(File.expand_path("./test/data/single_request.log"))
72
+ log_sample = File.open(File.expand_path("./test/data/single_heroku_request.log"))
72
73
  log_sample.lines do |line|
73
- Logeater::Event.create(ep_app: app, original: line)
74
+ Logeater::Event.create HerokuLogParser.parse(line).first.merge(ep_app: app)
74
75
  end
75
76
  @events = Logeater::Event.all
76
77
  end
@@ -94,14 +95,14 @@ class LogeaterTest < ActiveSupport::TestCase
94
95
 
95
96
  context "Given a partial request in one import and the rest in a subsiquent import, it" do
96
97
  setup do
97
- @lines = File.open(File.expand_path("./test/data/single_request.log")).lines.to_a
98
+ @lines = File.open(File.expand_path("./test/data/single_heroku_request.log")).lines.to_a
98
99
  end
99
100
 
100
101
  should "save the request after having the full request" do
101
102
  # The first two lines will not be enough to describe a complete request
102
103
  # so Logeater will not be able to create a request from them...
103
104
  @lines[0...2].each do |line|
104
- Logeater::Event.create(ep_app: app, original: line)
105
+ Logeater::Event.create HerokuLogParser.parse(line).first.merge(ep_app: app)
105
106
  end
106
107
  @events = Logeater::Event.all
107
108
  assert_no_difference "Logeater::Request.count" do
@@ -111,7 +112,7 @@ class LogeaterTest < ActiveSupport::TestCase
111
112
  # ...but if we later discover the rest of the lines that describe a complete
112
113
  # request, it'd be good if Logeater could then recognize and import it.
113
114
  @lines[2..-1].each do |line|
114
- Logeater::Event.create(ep_app: app, original: line)
115
+ Logeater::Event.create HerokuLogParser.parse(line).first.merge(ep_app: app)
115
116
  end
116
117
  @events = Logeater::Event.all
117
118
  assert_difference "Logeater::Request.count", +1 do
@@ -0,0 +1,19 @@
1
+ require "test_helper"
2
+
3
+ class EventTest < ActiveSupport::TestCase
4
+ attr_reader :event
5
+
6
+ context "Given an event formatted using RFC 5424" do
7
+ setup do
8
+ @event = Logeater::Event.new(
9
+ emitted_at: Time.new(2018, 4, 6, 10, 15, 30),
10
+ priority: 190,
11
+ message: "Started GET or something")
12
+ end
13
+
14
+ should "generate a parseable logger line" do
15
+ assert_match Logeater::Parser::LINE_MATCHER, event.logger_line
16
+ end
17
+ end
18
+
19
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logeater
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0.pre
4
+ version: 0.5.4.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bob Lail
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-19 00:00:00.000000000 Z
11
+ date: 2019-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -252,6 +252,20 @@ dependencies:
252
252
  - - ">="
253
253
  - !ruby/object:Gem::Version
254
254
  version: '0'
255
+ - !ruby/object:Gem::Dependency
256
+ name: heroku-log-parser
257
+ requirement: !ruby/object:Gem::Requirement
258
+ requirements:
259
+ - - ">="
260
+ - !ruby/object:Gem::Version
261
+ version: '0'
262
+ type: :development
263
+ prerelease: false
264
+ version_requirements: !ruby/object:Gem::Requirement
265
+ requirements:
266
+ - - ">="
267
+ - !ruby/object:Gem::Version
268
+ version: '0'
255
269
  description: Parses log files and imports them into a database
256
270
  email:
257
271
  - bob.lail@cph.org
@@ -290,10 +304,12 @@ files:
290
304
  - lib/logeater/request.rb
291
305
  - lib/logeater/version.rb
292
306
  - logeater.gemspec
307
+ - test/data/single_heroku_request.log
293
308
  - test/data/single_request.gz
294
309
  - test/data/single_request.log
295
310
  - test/integration/logeater_test.rb
296
311
  - test/test_helper.rb
312
+ - test/unit/event_test.rb
297
313
  - test/unit/params_parser_test.rb
298
314
  - test/unit/parser_test.rb
299
315
  homepage: ''
@@ -315,15 +331,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
315
331
  - !ruby/object:Gem::Version
316
332
  version: 1.3.1
317
333
  requirements: []
318
- rubyforge_project:
319
- rubygems_version: 2.6.11
334
+ rubygems_version: 3.0.3
320
335
  signing_key:
321
336
  specification_version: 4
322
337
  summary: Parses log files and imports them into a database
323
338
  test_files:
339
+ - test/data/single_heroku_request.log
324
340
  - test/data/single_request.gz
325
341
  - test/data/single_request.log
326
342
  - test/integration/logeater_test.rb
327
343
  - test/test_helper.rb
344
+ - test/unit/event_test.rb
328
345
  - test/unit/params_parser_test.rb
329
346
  - test/unit/parser_test.rb