juan_pelota 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 775db30433abf9c077d94b7f31005eaf7bf27511
4
+ data.tar.gz: 87c6efdefee9cc7b2f06a85283508433427c206e
5
+ SHA512:
6
+ metadata.gz: f6151cfaece2183e9f03ea56c233330ada563c71a13aca7987d67674697f194a713ff6397d2bd3b2557b0a1f0d767b872e797d204babd50a2acaf4ec4982e475
7
+ data.tar.gz: 54c8a9a2c8ae575dd61dc15ba7901c6bf813c8afedff37261c936a29ddf39e6c9ce695e245cecb4101f964cdd847c413e36704cd07155c92695abfa7b8c2c50d
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Jeff Felchner
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,63 @@
1
+ # JuanPelota
2
+
3
+ At [Springest](http://www.springest.com), we use
4
+ [Logstash](http://logstash.net/) to ship all our logs to
5
+ [Elasticsearch](http://www.elasticsearch.org/). An Elasticsearch index
6
+ consists of JSON documents. To make it possible to make fine grained
7
+ queries on [Sidekiq](http://sidekiq.org/) logs, we needed logging in
8
+ JSON format. This gem contains that logger.
9
+
10
+ ### Example log entry:
11
+
12
+ ```json
13
+ {
14
+ "@timestamp": "2014-06-05T12:38:42Z",
15
+ "pid": 8630,
16
+ "tid": "TID-osammcf2k",
17
+ "context": "TrainingIndexer::Work JID-177066e96052c2314dcad8c7",
18
+ "severity": "INFO",
19
+ "program_name": "TrainingIndexer::Work",
20
+ "type": "sidekiq",
21
+ "message": "2014-06-05T12:38:42Z 8630 TID-osammcf2k TrainingIndexer::Work JID-177066e96052c2314dcad8c7 INFO: done: 51.579 sec",
22
+ "status": "done",
23
+ "run_time": 51.579
24
+ }
25
+ ```
26
+
27
+ ## Installation
28
+
29
+ Add this line to your application's Gemfile:
30
+
31
+ ```ruby
32
+ gem 'juan_pelota'
33
+ ```
34
+
35
+ And then execute:
36
+
37
+ ```bash
38
+ $ bundle
39
+ ```
40
+
41
+ Or install it yourself as:
42
+
43
+ ```bash
44
+ $ gem install juan_pelota
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ Add this to your Sidekiq configuration:
50
+
51
+ ```ruby
52
+ require 'juan_pelota'
53
+
54
+ Sidekiq.logger.formatter = JuanPelota::Logger.new
55
+ ```
56
+
57
+ ## Contributing
58
+
59
+ 1. Fork it ( https://github.com/[my-github-username]/juan_pelota/fork )
60
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
61
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
62
+ 4. Push to the branch (`git push origin my-new-feature`)
63
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,2 @@
1
+ require 'juan_pelota/middlewares/logging'
2
+ require 'juan_pelota/logger'
@@ -0,0 +1,90 @@
1
+ require 'juan_pelota/version'
2
+ require 'juan_pelota'
3
+ require 'json'
4
+
5
+ module JuanPelota
6
+ class Logger < Sidekiq::Logging::Pretty
7
+ attr_accessor :severity,
8
+ :timestamp,
9
+ :program_name,
10
+ :raw_message
11
+
12
+ def call(severity, time, program_name, message)
13
+ self.severity = severity
14
+ self.timestamp = time.utc.iso8601
15
+ self.program_name = program_name
16
+ self.raw_message = message
17
+
18
+ {
19
+ '@type' => 'sidekiq',
20
+ '@timestamp' => timestamp,
21
+ '@status' => status,
22
+ '@severity' => severity.downcase,
23
+ '@run_time' => run_time,
24
+ '@message' => message,
25
+ '@fields' => {
26
+ pid: self.class.pid,
27
+ tid: self.class.tid,
28
+ context: context,
29
+ program_name: program_name,
30
+ worker: worker_name,
31
+ arguments: arguments,
32
+ },
33
+ }.to_json + "\n"
34
+ end
35
+
36
+ private
37
+
38
+ def raw_message
39
+ if @raw_message.is_a? Hash
40
+ @raw_message
41
+ elsif @raw_message.respond_to?(:match) &&
42
+ @raw_message.match(/^queueing/)
43
+ {
44
+ 'status' => 'queueing',
45
+ 'class' => @raw_message.split(' ')[1],
46
+ }
47
+ else
48
+ {
49
+ 'message' => @raw_message,
50
+ }
51
+ end
52
+ end
53
+
54
+ def status
55
+ return 'exception' if message.is_a? Exception
56
+
57
+ if raw_message['retry']
58
+ 'retry'
59
+ elsif raw_message['status']
60
+ raw_message['status']
61
+ else
62
+ 'dead'
63
+ end
64
+ end
65
+
66
+ def message
67
+ raw_message['message']
68
+ end
69
+
70
+ def arguments
71
+ raw_message['args']
72
+ end
73
+
74
+ def run_time
75
+ raw_message['run_time']
76
+ end
77
+
78
+ def worker_name
79
+ raw_message['class']
80
+ end
81
+
82
+ def self.pid
83
+ ::Process.pid
84
+ end
85
+
86
+ def self.tid
87
+ ::Thread.current.object_id.to_s(36)
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,50 @@
1
+ module JuanPelota
2
+ module Middlewares
3
+ class Logging
4
+ # rubocop:disable Lint/RescueException, Metrics/AbcSize
5
+ def call(worker, job, _queue)
6
+ start = Time.now
7
+
8
+ logger.info(
9
+ 'status' => 'start',
10
+ 'jid' => job['jid'],
11
+ 'bid' => job['bid'],
12
+ 'run_time' => nil,
13
+ 'class' => worker.class.to_s,
14
+ 'args' => job['args'],
15
+ )
16
+
17
+ yield
18
+
19
+ logger.info(
20
+ 'status' => 'done',
21
+ 'jid' => job['jid'],
22
+ 'bid' => job['bid'],
23
+ 'run_time' => elapsed(start),
24
+ 'class' => worker.class.to_s,
25
+ 'args' => job['args'],
26
+ )
27
+ rescue Exception
28
+ logger.info(
29
+ 'status' => 'fail',
30
+ 'jid' => job['jid'],
31
+ 'bid' => job['bid'],
32
+ 'run_time' => elapsed(start),
33
+ 'class' => worker.class.to_s,
34
+ 'args' => job['args'],
35
+ )
36
+
37
+ raise
38
+ end
39
+ # rubocop:enable Lint/RescueException, Metrics/AbcSize
40
+
41
+ def elapsed(start)
42
+ (Time.now - start).to_f.round(3)
43
+ end
44
+
45
+ def logger
46
+ Sidekiq.logger
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,3 @@
1
+ module JuanPelota
2
+ VERSION = '0.0.2'
3
+ end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ module JuanPelota
4
+ describe Logger do
5
+ it 'takes message as a hash and logs what we want', :time_mock do
6
+ json = JuanPelota::Logger.new.call('high',
7
+ Time.now.utc,
8
+ 'our tests',
9
+ 'args' => 'my_args',
10
+ 'class' => 'my_worker',
11
+ 'run_time' => 100,
12
+ 'message' => 'my message',
13
+ 'status' => 'my_status')
14
+
15
+ json_data = JSON.parse(json)
16
+
17
+ expect(json_data).to include(
18
+ '@type' => 'sidekiq',
19
+ '@timestamp' => '2012-07-26T18:00:00Z',
20
+ '@status' => 'my_status',
21
+ '@severity' => 'high',
22
+ '@run_time' => 100,
23
+ '@message' => {
24
+ 'args' => 'my_args',
25
+ 'class' => 'my_worker',
26
+ 'run_time' => 100,
27
+ 'message' => 'my message',
28
+ 'status' => 'my_status',
29
+ },
30
+ '@fields' => include(
31
+ 'pid' => be_a(Integer),
32
+ 'tid' => match(/[a-z0-9]+/),
33
+ 'context' => nil,
34
+ 'program_name' => 'our tests',
35
+ 'worker' => 'my_worker',
36
+ 'arguments' => 'my_args',
37
+ ),
38
+ )
39
+ end
40
+
41
+ it 'take message as a string and picks up if its a worker that is being queued',
42
+ :time_mock do
43
+
44
+ json = JuanPelota::Logger.new.call('high',
45
+ Time.now.utc,
46
+ 'our tests',
47
+ 'queueing MyWorkerClass')
48
+
49
+ json_data = JSON.parse(json)
50
+
51
+ expect(json_data).to include(
52
+ '@status' => 'queueing',
53
+ '@message' => 'queueing MyWorkerClass',
54
+ '@fields' => include(
55
+ 'worker' => 'MyWorkerClass',
56
+ ),
57
+ )
58
+ end
59
+
60
+ it 'set the status to dead and returns a nil worker if it gets a string without ' \
61
+ '"queueing" in the message',
62
+ :time_mock do
63
+
64
+ json = JuanPelota::Logger.new.call('high',
65
+ Time.now.utc,
66
+ 'our tests',
67
+ 'My Message')
68
+
69
+ json_data = JSON.parse(json)
70
+
71
+ expect(json_data).to include(
72
+ '@status' => 'dead',
73
+ '@message' => 'My Message',
74
+ '@fields' => include(
75
+ 'worker' => nil,
76
+ ),
77
+ )
78
+ end
79
+
80
+ it 'set the status to "Exception" if the message is one', :time_mock do
81
+ json = JuanPelota::Logger.new.call('high',
82
+ Time.now.utc,
83
+ 'our tests',
84
+ Exception.new)
85
+
86
+ json_data = JSON.parse(json)
87
+
88
+ expect(json_data).to include(
89
+ '@status' => 'exception',
90
+ )
91
+ end
92
+
93
+ it 'sets the status to retry if retry is passed in as key to the message', :time_mock do
94
+ json = JuanPelota::Logger.new.call('high',
95
+ Time.now.utc,
96
+ 'our tests',
97
+ 'retry' => true)
98
+
99
+ json_data = JSON.parse(json)
100
+
101
+ expect(json_data).to include(
102
+ '@status' => 'retry',
103
+ )
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,3 @@
1
+ require 'rspectacular'
2
+ require 'sidekiq'
3
+ require 'juan_pelota'
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: juan_pelota
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - thekompanee
8
+ - goodscout
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-02-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sidekiq
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '3.0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '3.0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rspec
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '3.1'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '3.1'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspectacular
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: 0.58.0
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: 0.58.0
56
+ - !ruby/object:Gem::Dependency
57
+ name: fuubar
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '2.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '2.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: timecop
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: 0.7.1
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: 0.7.1
84
+ description: ''
85
+ email: scoutsquad@goodscout.io
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - LICENSE
91
+ - README.md
92
+ - Rakefile
93
+ - lib/juan_pelota.rb
94
+ - lib/juan_pelota/logger.rb
95
+ - lib/juan_pelota/middlewares/logging.rb
96
+ - lib/juan_pelota/version.rb
97
+ - spec/juan_pelota/logger_spec.rb
98
+ - spec/spec_helper.rb
99
+ homepage: https://github.com/goodscout/juan_pelota
100
+ licenses:
101
+ - MIT
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.2.2
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: Log Sidekiq messages in JSON format
123
+ test_files:
124
+ - spec/juan_pelota/logger_spec.rb
125
+ - spec/spec_helper.rb
126
+ has_rdoc: